Get started

Token management

Access token lifetime, refresh rotation, revocation, and security practices.

Access tokens

Access tokens expire after 1 hour. Pass one in every resource request:

Terminal
Authorization: Bearer sndr_your_access_token
Refresh proactively at ~55 minutes rather than waiting for a 401 — this prevents failed requests during peak load.

Refreshing tokens

Refresh tokens are valid for 30 days and are rotated on every use — the old token is immediately invalidated. Always persist the new pair.

Terminal
curl -X POST 'https://api.sndr.sh/api/cranl/oauth/token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode 'client_id=sndr_your_client_id' \
  --data-urlencode 'client_secret=sndr_your_client_secret' \
  --data-urlencode 'refresh_token=sndr_your_refresh_token'
JSON
{
  "access_token":  "sndr_new_access_token",
  "token_type":    "Bearer",
  "expires_in":    3600,
  "refresh_token": "sndr_new_refresh_token",
  "scope":         "read send"
}
If the refresh token expires (30 days) or is revoked, the user must complete the OAuth flow again. Plan accordingly.

Revoking tokens

Revoke an access or refresh token immediately. Per RFC 7009, always returns 200 OK even for unknown tokens.

Terminal
curl -X POST 'https://api.sndr.sh/api/cranl/oauth/revoke' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  --data-urlencode 'token=sndr_token_to_revoke' \
  --data-urlencode 'client_id=sndr_your_client_id' \
  --data-urlencode 'client_secret=sndr_your_client_secret'

Security checklist

  • Use PKCE. Send code_challenge on authorize and code_verifier on token exchange.
  • Validate state. Reject callbacks where state does not match — it is a CSRF attack.
  • Secrets in a vault. Never expose client_secret or tokens in client-side code, logs, or version control.
  • Token exchange is server-side only. Never call /oauth/token from the browser.
  • Revoke on disconnect. Call revoke when a user disconnects your integration.
  • Handle 401 gracefully. Attempt one refresh on 401 token_expired before surfacing an error.