curl --request GET \
--url https://api.simkl.com/oauth/pin \
--header 'User-Agent: <user-agent>' \
--header 'simkl-api-key: <api-key>'{
"result": "OK",
"device_code": "DEVICE_CODE",
"user_code": "5G6JAH",
"verification_uri": "https://simkl.com/pin",
"verification_url": "https://simkl.com/pin",
"expires_in": 900,
"interval": 5
}Step 1 of the PIN flow (also called the device flow). Best for TVs, consoles, smart watches, CLI tools — anywhere typing a URL is hard. You don’t need client_secret for this flow.
The response contains a 5-character user_code to display, a verification_uri for the user to visit, an expires_in lifetime (15 minutes), and an interval you must respect when polling (5 seconds).
| Param | Required | Notes |
|---|---|---|
client_id | yes | Sent as ?client_id=… URL query parameter. The simkl-api-key header is also accepted but the URL-parameter form is preferred. |
redirect | no | URL the simkl.com/pin page sends the user to after they approve. Must match a URL pre-registered in your app’s developer settings. Mostly relevant for browser-extension and web-flavoured PIN integrations. |
device_code response fieldThe response includes a device_code field whose value is the literal string "DEVICE_CODE" — it’s a placeholder kept for compatibility with the OAuth 2.0 Device Authorization Grant response shape. Clients only need user_code (what you display, and what you poll on). You can ignore device_code entirely.
Not the RFC 8628 device flow. Simkl’s PIN flow is conceptually similar to RFC 8628 (OAuth Device Authorization Grant) but the wire format differs in several spots:
device_code is a hardcoded placeholder, not a real opaque token.GET /oauth/pin/{user_code} instead of POST /oauth/token with grant_type=urn:ietf:params:oauth:grant-type:device_code.{"result": "KO", "message": "Authorization pending"} instead of 400 + {"error": "authorization_pending"}.Generic device-flow libraries (e.g. openid-client device-flow extension) won’t work out of the box. Either write a custom client for the wire format above, or follow the PIN flow walkthrough which uses the documented endpoints directly.
Device authorization for TVs, consoles, smart watches, and CLI tools — show a 5-character code, the user enters it at simkl.com/pin, the app polls for the access token.
curl --request GET \
--url https://api.simkl.com/oauth/pin \
--header 'User-Agent: <user-agent>' \
--header 'simkl-api-key: <api-key>'{
"result": "OK",
"device_code": "DEVICE_CODE",
"user_code": "5G6JAH",
"verification_uri": "https://simkl.com/pin",
"verification_url": "https://simkl.com/pin",
"expires_in": 900,
"interval": 5
}Documentation Index
Fetch the complete documentation index at: https://api.simkl.org/llms.txt
Use this file to discover all available pages before exploring further.
Optional alias for the client_id query parameter. Simkl accepts your client_id either as the simkl-api-key request header or as the ?client_id=… query parameter — pick one. The query-parameter form is preferred because it makes the request fully self-describing in URL form.
Descriptive identifier for your app, ideally name/version. Examples: PlexMediaServer/1.43.1.10540, kodi-simkl/0.9.2, MyApp/2.4.1 (https://myapp.com).
Your client_id from your Simkl developer settings. Required on every request.
URL the simkl.com/pin page sends the user to after they approve the connection. Must match a URL pre-registered in your app settings. Optional — most PIN-flow clients (TVs, consoles, CLIs) don't need this since the user authorizes on a separate device and the app polls for the result.
Short, lowercase identifier for your app (e.g. plex-scrobbler, kodi-bridge). Helps Simkl identify which apps are using the API.
Your app's current version (e.g. 1.0, 2.4.1). Helps Simkl debug issues you report.
OK
Step 1 response from GET /oauth/pin. Display user_code, point the user at verification_uri, and poll GET /oauth/pin/{user_code} every interval seconds until expires_in elapses.
"OK"
"5G6JAH"
Where the user enters user_code. RFC 8628 §3.2 spelling. Read this field.
"https://simkl.com/pin"
Alias for verification_uri — same value, kept for back-compat. New code should read verification_uri.
"https://simkl.com/pin"
900
5
Was this page helpful?