Authentication

Bearer tokens, modes and installation context.

Base URL:

https://api.spuke.com/v1/app

Every request carries an installation access token:

curl "https://api.spuke.com/v1/app/v1/payments?limit=10" \
  -H "Authorization: Bearer spk_at_live_…"

The token identifies the app and the merchant. There is no merchant id parameter — you cannot address a merchant that has not installed you.

Getting a token

Tokens come from the OAuth flow at install time (authorization_code, PKCE supported) and are renewed with the refresh_token grant. See Installs & OAuth.

Property Value
Access token spk_at_live_… / spk_at_test_…, valid 1 hour (expires_in: 3600)
Refresh token spk_rt_live_… / spk_rt_test_…, single use and rotating — store the new one on every refresh
Mode Baked into the token, cannot be switched
Scopes Exactly what the merchant approved
Reissue Issuing a new access token revokes the installation's previous access tokens

Because refresh tokens rotate, refreshing twice with the same token invalidates the installation's tokens — serialise your refresh calls.

Failure modes

Status error.type Do this
401 invalid_token Refresh, then retry once
403 insufficient_scope Request the scope in a new version; do not retry
403 installation_suspended Back off, retry later, keep data
404 not_found Object does not exist for this merchant
404 unknown_endpoint Path typo or unsupported resource
405 method_not_allowed v1 is read-only; only GET
429 rate_limit_exceeded Honour Retry-After

Error bodies are uniform:

{ "error": { "type": "insufficient_scope", "message": "Missing required scope: payments:read" } }

Server-side only

The client secret and refresh tokens must never reach a browser or a mobile binary. Public clients use PKCE and keep only the short-lived access token.