Skip to main content
POST
/
oauth
/
token
curl -X POST https://api.simkl.com/oauth/token \ -H "Content-Type: application/json" \ -d '{ "code": "AUTHORIZATION_CODE", "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "redirect_uri": "https://yourdomain.com/oauth.html", "grant_type": "authorization_code" }'
{
  "access_token": "YOUR_ACCESS_TOKEN",
  "token_type": "bearer",
  "scope": "public"
}

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.

Authorizations

simkl-api-key
string
header
default:YOUR_CLIENT_ID
required

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.

Headers

User-Agent
string
required

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).

Query Parameters

client_id
string
required

Your client_id from your Simkl developer settings. Required on every request.

app-name
string
required

Short, lowercase identifier for your app (e.g. plex-scrobbler, kodi-bridge). Helps Simkl identify which apps are using the API.

app-version
string
required

Your app's current version (e.g. 1.0, 2.4.1). Helps Simkl debug issues you report.

Body

application/json

Body for POST /oauth/token. Send grant_type=authorization_code plus the code you received at redirect_uri. Either client_secret (standard flow) or code_verifier (PKCE) must be present.

code
string
required

Authorization code returned to your redirect_uri.

client_id
string
required

Your application's client_id.

client_secret
string
required

Your application's client_secret. Confidential flow only — mutually exclusive with code_verifier. Public clients (mobile / SPA / desktop) MUST NOT embed this value in shipped code; use the PKCE flow instead.

redirect_uri
string<uri>
required

URL where the user was sent back with the code. Required on the confidential flow. On PKCE, required only if you sent one to /oauth/authorize. When sent, must match a URL registered for the app byte-for-byte (scheme, host, port, path, trailing slash, casing).

Example:

"https://yourdomain.com/oauth.html"

grant_type
enum<string>
default:authorization_code
required
Available options:
authorization_code
code_verifier
string

PKCE code verifier (43–128 unreserved characters). Required on the PKCE flow — mutually exclusive with client_secret. Send the original verifier; Simkl re-derives the SHA-256 challenge and matches it against the code_challenge you sent on /oauth/authorize. On mismatch the response is 401 secret_error with "PKCE verification failed" in the message field.

Response

Valid code will generate you the access_token

Successful response from POST /oauth/token. Carries access_token, token_type: bearer, scope: public, and expires_in: 157680000 (5 years). Notable omission vs RFC 6749 §5.1: no refresh_token — Simkl tokens are long-lived but not refreshable. A 401 on a subsequent authenticated call means the user revoked the app; re-run OAuth.

access_token
string
required

Long-lived bearer token. Save it securely; there is no refresh-token equivalent.

Example:

"abc123def456"

token_type
string
required

Always bearer (lowercase, despite RFC 6750's canonical Bearer capitalization). Use case-insensitive matching when comparing.

Example:

"bearer"

scope
enum<string>
required

Currently always public. Simkl does not have a scope system — tokens implicitly grant all permissions the user has approved for the app. The scope field is a placeholder kept for compatibility with OAuth 2.0 token-response shape; ignore its value.

Available options:
public
Example:

"public"

expires_in
integer
required

Token lifetime in seconds (RFC 6749 §5.1). Always 157680000 (about 5 years). The value is effectively infinite for practical session lengths — Simkl tokens remain valid until the user revokes the app from Connected Apps settings. There is no refresh_token; if a 401 arrives before this lifetime expires, the user revoked your app — re-run the OAuth flow.

Example:

157680000