Exchange an API key for an access token

View as Markdown
Start here. Exchanges your CMS-issued API credential (`client_id` + `perkss_sk_live_…` secret) for a short-lived Bearer token via the OAuth 2.0 client-credentials grant (RFC 6749 §4.4). Send the fields as an `application/x-www-form-urlencoded` body, or pass the credential pair via HTTP Basic authentication instead — the form fields win when both are present. `expires_in` in the response reflects the actually minted lifetime (`ttl_seconds` clamped to [60, 86400]; default 86400 = 24h); cache the token and reuse it until then rather than exchanging per request. Every other `/api/v1` endpoint expects it as `Authorization: Bearer <access_token>`. Unlike every other endpoint, deliberate failures here use the RFC 6749 §5.2 error shape, not the standard error envelope.

Authentication

AuthorizationBasic

RFC 6749 client_secret_basic: API key id/secret as username/password — an alternative to the token-exchange form fields (the form wins when both are present). Only POST /api/v1/auth/token accepts it.

Request

This endpoint expects an object.
grant_typestringRequired

OAuth 2.0 grant type — only client_credentials is supported.

client_idstringOptional
The API key id shown in the CMS key list.
client_secretstringOptional

The API key secret (perkss_sk_live_…) shown exactly once at creation. May alternatively be sent via HTTP Basic authentication.

ttl_secondsstringOptional

Requested token lifetime in seconds, clamped to [60, 86400]. Defaults to 86400 (24h). Use short TTLs for browser-bound tokens.

Response

RFC 6749 §5.1 token response.

access_tokenstring

The Bearer token for all other /api/v1 endpoints. An opaque credential — do not parse or persist beyond its lifetime.

token_typeenum
expires_indouble

Seconds until expiry — reflects the actually minted lifetime after the ttl_seconds clamp to [60, 86400].

Errors

400
Bad Request Error
401
Unauthorized Error
429
Too Many Requests Error