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#
| Token | Prefix | Lifetime | Purpose |
|---|---|---|---|
| Access token | ost_ | 15 minutes | Authenticate API requests |
| Refresh token | osr_ | 30 days | Get new access tokens |
| Authorization code | osc_ | 5 minutes | One-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"]
}Refresh tokens are rotated. Each time you refresh, you get a new refresh token. The old one is invalidated. Always store the latest refresh token from the response.
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_restrictederror 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