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)
To proactively revoke access from your side, stop using the tokens and discard them. There is no explicit revocation endpoint at this time.

All Set? Let's Start Automating
- Image, PDF and Video Generation via API
- Canva like editor with AI and smart features
- No-Code Integrations (Zapier, Make, n8n etc.)
- Embed Orshot Studio in your app
- Start Free. No credit card required. Cancel anytime.