Skip to main content
The Simkl API supports Cross-Origin Resource Sharing (CORS) on api.simkl.com — you can call it directly from a browser with fetch or XMLHttpRequest, from any origin.
Do not set User-Agent from browser code. It is a forbidden header name — the browser refuses to let you set it and sends its own. The User-Agent requirement in Headers and required parameters applies to server-side and native clients; identify your browser app with the app-name and app-version URL parameters instead.Setting Content-Type: application/json on a GET has a cost too: it turns a simple request into a preflighted one for no benefit. Send it only on requests that actually have a JSON body.

Authenticated calls from a browser

Authorization is named explicitly in the allowed request headers, so a bearer token works cross-origin:
That request is preflighted — the browser sends an OPTIONS first and Simkl answers it with 204 and an empty body. You do not need to do anything about it; just expect two requests in your network tab rather than one, and note that only the real request counts against your rate limit. The preflight is cached for 24 hours (Access-Control-Max-Age: 86400), so the extra round-trip happens once per browser session per endpoint shape, not on every call.
Never put a client_secret in browser code. Anything shipped to a browser can be read. Register a Mobile, desktop & browser apps client, which has no secret, and use the authorization code flow with PKCE — it is designed for exactly this case. If you need a secret, the exchange belongs on your own server.

Headers you can read

Browsers hide response headers from JavaScript unless the server opts them in. Simkl exposes seven:
The pagination headers are the reason a browser client does not need to count pages itself — see Pagination. For what the quota headers mean and when they are absent, see Rate limits. Any header not in that list is invisible to fetch from another origin; that is the browser’s rule, not Simkl’s.
Errors carry CORS headers too, including the ones answered at the edge before the request reaches Simkl’s application servers. A 401, 403 or 429 is readable from JavaScript exactly like a 200, so you can branch on error in the body rather than guessing from a network failure.An opaque “network error” with no status in a browser is almost always something else — an ad blocker, an extension, or the request never leaving the machine.