Token Management

Refresh, introspect, and manage OAuth tokens


After a user authorizes your app, you receive an access token and (optionally) a refresh token. Here's how to manage them.

Token Types#

TokenPrefixLifetimePurpose
Access tokenost_15 minutesAuthenticate API requests
Refresh tokenosr_30 daysGet new access tokens
Authorization codeosc_5 minutesOne-time use, exchanged for tokens

Using Access Tokens#

Include the access token in the Authorization header of every API request:

curl https://api.orshot.com/v1/templates \
  -H "Authorization: Bearer ost_your_access_token"

Refreshing Tokens#

Access tokens expire after 15 minutes. Use the refresh token to get a new one without re-prompting the user:

curl -X POST https://api.orshot.com/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "refresh_token": "osr_your_refresh_token"
  }'

Response:

{
  "access_token": "ost_new_access_token",
  "refresh_token": "osr_new_refresh_token",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "workspace:read render:generate",
  "user_id": "user-uuid",
  "workspace_ids": ["workspace-uuid-1"]
}

Token Introspection#

Check whether a token is still valid and see its metadata:

curl -X POST https://api.orshot.com/v1/oauth/introspect \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "token": "ost_token_to_check"
  }'

Active token response:

{
  "active": true,
  "scope": "workspace:read render:generate",
  "client_id": "your-client-id",
  "user_id": "user-uuid",
  "workspace_ids": ["workspace-uuid-1"],
  "exp": 1714500000
}

Expired or revoked token:

{
  "active": false
}

Best Practices#

Handle token expiry gracefully#

Don't wait for a 401 response to refresh. Check the expires_in value and refresh proactively:

function isTokenExpiringSoon(expiresAt, bufferSeconds = 60) {
  return Date.now() / 1000 > expiresAt - bufferSeconds;
}

Store tokens securely#

  • Server-side apps: Store tokens in an encrypted database or secrets manager
  • Desktop apps: Use the OS keychain (macOS Keychain, Windows Credential Manager)
  • CLI tools: Store in a local config file with restricted file permissions (chmod 600)
  • Never store tokens in localStorage, cookies without httpOnly, or source code

Handle refresh failures#

If a refresh request fails, the user needs to re-authorize:

async function getValidToken(storedTokens) {
  if (!isTokenExpiringSoon(storedTokens.expiresAt)) {
    return storedTokens.accessToken;
  }

  try {
    const response = await refreshToken(storedTokens.refreshToken);
    // Map OAuth response (snake_case) to your stored format
    const newTokens = {
      accessToken: response.access_token,
      refreshToken: response.refresh_token,
      expiresAt: Date.now() / 1000 + response.expires_in,
    };
    await saveTokens(newTokens);
    return newTokens.accessToken;
  } catch (err) {
    // Refresh failed — re-authorize
    throw new Error("Re-authorization required");
  }
}

Token Revocation#

Tokens are automatically revoked when:

  • The user removes your app's access from their Orshot settings
  • The user removes a workspace from your app's grant (only tokens for that workspace)
  • Your app's OAuth client is disabled
  • A refresh token is replaced during rotation (the old one is invalidated)

Sandbox Restrictions#

If an app is in development mode (not yet published), tokens are restricted at the API level:

  • Only tokens belonging to the app owner or test users will work
  • API calls from other users return a sandbox_restricted error with HTTP 403
  • This applies even if a token was issued while the app was published — switching an app back to private immediately enforces sandbox restrictions on existing tokens
{
  "error": "This app is in development mode. Only the developer or approved test users can make API calls.",
  "code": "sandbox_restricted"
}

To proactively revoke access from your side, stop using the tokens and discard them. There is no explicit revocation endpoint at this time.

Ready to automate?

Start rendering images, PDFs and videos from your templates in under 2 minutes. Free plan, no credit card.

Get your API key
  • Image, PDF and video generation via API
  • Visual editor with AI and smart layouts
  • Zapier, Make, MCP and 50+ integrations
  • White-label embed for your own app
  • 60 free renders — no credit card required