Operations
Errors
Errors use the same envelope as success responses, with error.code set to 1, a human-readable message, and a stable machine-readable type.
Error shape
On failure, data is null and error carries code: 1, a human message, and a stable type you can branch on:
{
"data": null,
"error": {
"code": 1,
"message": "Token invalid or expired",
"type": "invalid_token"
}
}Error reference
| HTTP | error.type | Meaning |
|---|---|---|
| 400 | invalid_request | Validation failed (message lists the fields) |
| 401 | missing_token | No / malformed Authorization header |
| 401 | invalid_token | Token invalid or expired — get a new one |
| 401 | invalid_client | Bad client_id / client_secret |
| 403 | insufficient_scope | Token lacks the required scope |
| 403 | client_inactive | Your client has been deactivated |
| 403 | playlist_restricted | No access to that playlist |
| 404 | track_not_found / playlist_not_found | Unknown resource |
| 429 | rate_limited | Too many requests — back off and retry |
| 503 | — | Temporary outage — retry with backoff |
Recommended client behavior
- Cache the access token until ~5 minutes before
expires_in, then refresh. - On
401 invalid_token, fetch a new token once and retry the call. - On
429/503, retry with exponential backoff.
See Rate limits and Best practices.