Skip to main content
Every registered Simkl app has a built-in Analytics view with up to 24 hours of individual requests your app made against api.simkl.com, plus a 7-day rollup of daily request totals. It’s the fastest way to confirm what your code is actually sending — without setting up your own logger.

Opening it

Developer dashboard

Open simkl.com/settings/developer/ while logged in. The page lists every app you’ve registered.

Your app's row

Click the app to land on its page (URL: simkl.com/settings/developer/{APP_ID}/). This is also where your Client ID and Client Secret live.

Debug link

Click Debug (top-right of the app card). The analytics view opens in a new tab.
The page is opened via a short-lived signed link. The link expires after 1 hour — close and re-open the Debug link from your developer dashboard for a fresh session. The dashboard page is what authorizes you; the analytics URL itself isn’t bookmarkable.

What you can do here

  • Confirm your code is actually hitting Simkl. Issue a request from your app, hit Refresh — if it doesn’t appear, your client never reached us (wrong host, blocked by a proxy, or missing the required headers so we can’t attribute it to your app).
  • Verify your sync loop matches the two-phase pattern the Sync guide requires. Apps that don’t follow it download the whole user library every poll and get rate-limited — sometimes blocked. The Debug view makes both halves easy to audit:
    1. Filter on Path equals /sync/activities — this is the cheap “did anything change?” check that has to fire first on every poll. If it isn’t there, your loop is broken.
    2. Filter on Path contains /sync/all-items and look at the Query column for every row. Each one should include date_from=<your_last_saved_timestamp> so Simkl returns only the delta. A /sync/all-items row with no date_from means your client is asking for the whole library — fix it before it gets throttled.
  • See exactly what your OAuth library / SDK puts on the wire. Wrappers and middleware obscure this; the Debug view shows the literal client_id, app-name, app-version, and User-Agent your library sent — useful for diagnosing empty_field and grant_error responses.
  • See the HTTP status Simkl returned, even when your client only shows a generic error. Some HTTP libraries surface “Network error” or “Bad Request” without the actual status code. The Edge and Origin columns show 200 / 401 / 403 / 412 etc. for every request — pair the code with /conventions/errors to map it back to the meaning. Response bodies aren’t recorded in the Debug view, but for GET requests the Link column re-fires the same URL in a new browser tab so you can read the live response body. POST / PUT / DELETE bodies still have to come from your own logging.
  • Spot retry loops, runaway timers, and duplicate calls. The red Burst column and High Traffic Burst Detected banner surface “N requests in 1 second from the same IP” patterns automatically — find which path your code is over-firing before the auto-blocker does.
  • Tell edge cache hits from real backend responses. When Edge=200 and Origin is blank, the response came from the edge cache without touching the backend — useful for understanding why a stale value sometimes persists after a write.
  • Compare staging vs prod, or app A vs app B. Filter on User agent or Client IP to slice traffic by deployment / machine and confirm each environment is sending what you think it is.
  • Export a CSV of the current filtered view to drop into a spreadsheet, share with support, or attach to a bug report.

Controls

What each column shows

Burst detector

When 3+ requests from the same IP land in the same second, the page surfaces a red High Traffic Burst Detected banner at the top of the table plus a X% BURST badge near the event count. The Burst column highlights the specific rows that fired it. The three usual culprits:
  • Retry loops without backoff — fix with exponential backoff + jitter.
  • Parallel requests — fire calls sequentially, awaiting each response before issuing the next. Don’t Promise.all the same endpoint, don’t let a new poll tick start before the previous one returned.
  • UI effects re-firing every render — gate your useEffect / equivalent on a stable dependency.
Repeatedly tripping the banner can get your client_id throttled or temporarily blocked. Fix the loop before the auto-blocker fires — recovery isn’t automatic.

Filters

The Filter results… box does a free-text match across all visible columns. + Add filter opens a composer. Pick a column, an operator (equals, not equals, contains, not contains, starts with, ends with, in, not in), and a value. The value field autocompletes from what’s actually in the data. Stack multiple filters — they AND together. A few recipes:
  • Just failures → Origin contains 4 (catches 4xx)
  • One endpoint → Path equals /sync/history
  • One country → Country equals US
  • One machine → Client IP equals e-JgphVReMb9 (click the IP in any row to filter to its sibling requests)
Exclude detail pages is a one-click filter that hides per-record detail endpoints (typically the chattier ones), so the burst detector and the table focus on your sync/scrobble calls.

Headers required to show up

Requests without identifying parameters don’t appear in your analytics. Simkl matches events to your app by the client_id it sees in the request — so every API call has to include:
  • client_id query parameter
  • app-name and app-version query parameters
  • User-Agent header in the form my-app-name/1.0
See Headers for the full reference. The minimum that works:
Calls without these get attributed to the anonymous bucket and never surface in your Debug view.

The view your users get

The Analytics view is scoped to your app. Your users have the mirror image of it at Connected Apps, which shows them every integration they have connected — yours among them. That matters for AUTH V2, where the daily allowance belongs to the user and is shared across every app they run. If a user reports that your app stopped syncing and your own numbers look normal, the cause is often another integration spending their allowance — which you cannot see and they can. Ask them to open that page and sort by today’s requests. It also names the apps responsible, so the conversation moves straight to the right place.

See also

Get an API key

Developer dashboard — register a new app or jump to your existing apps’ Debug views.

Connected Apps

What your users see: their daily allowance, and every app spending it.

Required headers

The client_id / app-name / app-version / User-Agent reference.

Rate limits

Per-app daily quotas, per-IP throttling, the 20-second write lock.

Errors

What each error envelope means when the Debug view shows a 4xx / 5xx row.