Skip to main content
This page is for AUTH V1, which is being retired around April 2027. If you are starting something new, or migrating, the equivalent is Client libraries (AUTH V2) — V2 is standards-compliant, so the library configuration is shorter and discovery actually works there.
Fastest path — skip the OAuth library entirely. Simkl’s OAuth flow is two HTTP steps:
  1. Redirect the user to https://simkl.com/oauth/authorize?response_type=code&client_id=...&redirect_uri=...&state=... — they approve in the browser, Simkl bounces back to your redirect_uri with ?code=...&state=... in the query string.
  2. POST that code to https://api.simkl.com/oauth/token with client_id, client_secret, redirect_uri, and grant_type=authorization_code in the body — the response is {"access_token": "...", "token_type": "bearer", "scope": "public", "expires_in": 157680000}. Send that token as Authorization: Bearer ... on every authenticated request.
That’s it. No refresh-token rotation, no scope dance — Simkl tokens are long-lived (expires_in is 5 years) and only invalidate when the user revokes from Connected Apps. For the full walkthroughs, see OAuth 2.0 flow (server-side with client_secret) or PKCE flow (mobile / SPA / desktop without client_secret).
Simkl’s POST /oauth/token accepts both application/x-www-form-urlencoded (the RFC 6749 §3.2 default) and application/json, and reads client credentials from either the request body or an Authorization: Basic header (RFC 6749 §2.3.1).
Do not use RFC 8414 discovery for a V1 app. The metadata document at https://simkl.com/.well-known/oauth-authorization-server describes OAuth V2, not the V1 flow on this page. A V1 app that auto-configures from it will point at the V2 endpoints, which reject V1 client IDs with invalid_client — and the error message talks about OAuth 2.0 not being enabled, which is confusing when you are already using OAuth.Every snippet on this page therefore sets the two endpoint URLs explicitly:Discovery is the right tool if you are building on OAuth V2, where the metadata is accurate and auto-configuration is the recommended path. See AUTH V2.

Quick library status

Every library below was driven through the full browser-consent → real authorize code → real token mint flow against api.simkl.com. Each one returned a real access_token we then used to call /users/settings successfully.
Three snippets — openid-client v6, oauth4webapi and Spring Security — originally configured themselves through RFC 8414 discovery, which is how they were tested. They now set the two endpoints inline instead, because Simkl’s discovery document was subsequently published and describes V2. The flow they perform is unchanged and the endpoints are the same ones the other snippets use, but that specific edit has not itself been re-driven end to end. If you hit a problem with one of them, the raw HTTP reference at the bottom of the page is the ground truth.
Every library here needs the same thing: the two endpoint URLs and your credentials. Nothing on this page requires discovery, and for V1 you should not use it — see the warning above. The libraries worth a second look are the three that prefer to discover: openid-client v6, oauth4webapi and Spring Security. Left to their defaults they will fetch a metadata document and configure themselves from it, which for a V1 app is exactly the wrong outcome. Their snippets below set the endpoints inline instead, which is a one-line difference and removes a network call from your startup path.

The wire format

Success response:
The PKCE variant swaps client_secret for code_verifier.

Python authlib


Python requests-oauthlib


Python httpx-oauth


Node openid-client v6


Node oauth4webapi


Node simple-oauth2


Node passport-oauth2


Node @badgateway/oauth2-client


Java Nimbus OAuth 2.0 SDK


Java Spring Security OAuth2 Client

Set authorization-uri and token-uri directly rather than issuer-uri, as above — this is the one place a V1 app must not take the shortcut. issuer-uri resolves, and it resolves to V2: Spring reads /.well-known/oauth-authorization-server, configures itself for /oauth2/*, and your V1 client_id is then rejected with invalid_client. Default client_secret_basic works either way.

Java Google OAuth Client for Java


Java scribejava-core


Go golang.org/x/oauth2


PHP league/oauth2-client


Raw HTTP


Other OAuth libraries (inferred from RFC compliance)

These libraries aren’t in our live test harness, so the status below is read from each library’s source/docs — not from a captured request to api.simkl.com. Most wrap one of the live-tested libraries above; the rest follow the same RFC defaults Simkl now accepts. If you hit a library not on this list, the sanity check is one HTTP capture: confirm the token POST hits https://api.simkl.com/oauth/token, sends client_id / code / redirect_uri / grant_type (and client_secret either in the body or in Authorization: Basic), and see what comes back. If the request looks RFC-shaped and you still hit an error, let us know — we’d appreciate the capture so we can promote the library to the live matrix.

See also

OAuth 2.0 walkthrough

Confidential (server-side) flow.

Public PKCE walkthrough

Mobile / SPA / desktop flow without client_secret.

PIN flow

TV / console / CLI flow with a 5-character code.