access_token. This page covers the four things you decide before writing any code, in the order you hit them.
Two of those decisions are easy to confuse, because the numbers differ:
Developer settings asks for the type. The flow is a choice you make in code. They are not the same list.
1. Pick a client type
The type is not a filing category — it is the one answer that configures the registration. Picking it decides three things at once:- Whether a
client_secretis minted at all. One type gets one; for the other two no secret is ever created, so there is nothing to leak. - Whether redirect URIs are stored. Two types require at least one; the third registers none.
- Which flows are therefore reachable. A registration with no redirect URI has nowhere for Simkl to send the user back to, so it cannot run a browser redirect.
AUTH V1 and AUTH V2 registrations are counted separately, so migrating never costs you a slot — your existing V1 apps keep working and do not use up your V2 allowance.The allowance for unverified apps is 3 on Free, 5 on PRO, 10 on VIP — per version, not combined. Verified apps do not count against it at all, and verification is free on every plan: request it from developer settings once your app is live.
2. Decide whether you need a client_secret
Only Server apps & services has one, and only because a backend can keep it. It is not a capability upgrade and unlocks nothing — the other two types are fully functional without one.
What the secret actually does
It answers one question at the token endpoint: is this request really coming from your backend? Yourclient_id is public, so on its own it proves nothing. The secret is the proof, and it is why a server app can be held to a stricter standard than an app running on a stranger’s phone.
It is deliberately not a key to anything by itself. There is no app-only grant — client_credentials returns 400 unsupported_grant_type — so a secret with no authorization code and no refresh token alongside it reaches nothing user-specific.
When you send it
Once you are registered as Server apps & services, sending the secret is not optional — it is required on every request that authenticates your app:
Two transports are accepted, and they are equivalent — pick whichever your HTTP library makes easy:
Client authentication is checked before anything else in the request. A missing or wrong secret is
401 invalid_client, and you get it regardless of what else might be wrong — so during setup, fix invalid_client first and re-read the rest of the error only after it clears.The upside: a 401 invalid_client does not consume your authorization code. The code is never reached, so you can fix the secret and retry the same one.client_id is public and safe to commit — in source, in a JS bundle, in a public repo. Under V2 it reaches nothing user-specific on its own. Only the secret and user tokens need protecting, and those are revoked automatically if they reach GitHub, private repositories included.
3. Pick a flow
OAuth flow
Web, mobile, SPA, desktop, extensions — anything that can open a browser.
Device / PIN flow
TVs, consoles, watches, CLIs — anything that can’t. 8-character code.
Any type can use the Device / PIN flow. Choose TV, devices & command line only if that is the only flow your app will ever use — if you also ship a web or mobile companion, register Mobile, desktop & browser apps and use both flows from it.
A
client_secret is not a third flow. A Server apps & services app runs the OAuth flow like everyone else — same authorize redirect, same PKCE, same code. The only difference is that the secret travels alongside the code at the token endpoint. Every access token belongs to a user who authorized it, whichever type you registered.4. Choose a scope
Full detail, including how to handle an insufficient scope at runtime, is on Scopes.
Point your app at the endpoints
Four URLs, on two different hosts. Setting them directly is a perfectly normal way to configure an app — most of our examples do exactly that:Or let the library fetch them
Simkl publishes an RFC 8414 discovery document at/.well-known/oauth-authorization-server. It carries all four URLs under the metadata names above, plus the supported auth methods, scopes and PKCE methods.
Neither approach is more correct. Hardcoding is fine and is what the rest of these docs show. Discovery is worth it when your library already speaks it — you configure one setting instead of four, and you pick up any future endpoint change without a release:
If your library asks for
/.well-known/openid-configuration, point it at OAuth 2.0 instead. Simkl is an OAuth 2.0 server, not an OpenID Connect provider, so that path returns 404 and the document lives at /.well-known/oauth-authorization-server. Libraries that walk both paths in turn — Spring Security, for one — sort this out themselves. A 404 during setup means yours does not, and needs telling.What you will be working with
See Tokens and refresh for the refresh grant, revocation, and the two refresh behaviours that surprise people.
Check one thing before you build: V2 apps must send a user token on everything except plain catalog lookups. If your app has a catalog or browsing mode that works with no signed-in user, read the V2 overview first — search in particular needs a token.
Next
OAuth flow
The browser flow end to end, with PKCE.
Device / PIN flow
Show a code, poll until the user approves.
Client libraries
What to configure in a stock OAuth library, and the three whose defaults break.
AUTH V2 overview
Discovery, anonymous limits, and the endpoint reference.
Errors
Every error code, including the two different 401s.
Scopes
The full
media:read / media:write reference.