Authentication
Available to: Developers (license type) Minimum plan: Free
TitanRDM's API uses OAuth 2.0 (via Doorkeeper) for authentication. This page explains how to obtain access tokens and use them to authenticate API requests.
Prerequisites
- An OAuth Application created in TitanRDM (see OAuth Applications)
- Your application's Client ID and Client Secret
Grant Types
TitanRDM supports two OAuth 2.0 grant types:
Client Credentials (Machine-to-Machine)
Use this for automated pipelines, ETL jobs, and services that don't act on behalf of a specific user.
When to use: - CI/CD pipelines importing or exporting data - Scheduled sync jobs - Monitoring and reporting scripts
Limitations:
- No user context — actions are not attributed to a specific user
- Some endpoints require user context (deployments, promotions) and will return 401 with a message to use Authorization Code flow instead
Authorization Code (User Context)
Use this for integrations that act on behalf of a specific user, where actions need to be attributed and permissions need to be evaluated per-user.
When to use: - Custom admin tools or dashboards - Integrations where audit trail must show which user performed the action - Deployment and promotion automation (these require a user)
Obtaining an Access Token
Client Credentials Flow
curl -X POST https://{subdomain}.app.titanrdm.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "scope=api"
You can also use HTTP Basic authentication for the client credentials:
curl -X POST https://{subdomain}.app.titanrdm.com/oauth/token \
-u "YOUR_CLIENT_ID:YOUR_CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "scope=api"
Successful response:
{
"access_token": "eyJhbGciOiJIUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 7200,
"scope": "api",
"created_at": 1700000000
}
Authorization Code Flow
- Redirect the user to the authorization endpoint:
https://{subdomain}.app.titanrdm.com/oauth/authorize?
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_REDIRECT_URI&
response_type=code&
scope=api
User grants access — they are redirected to your
redirect_uriwith acodeparameter.Exchange the code for an access token:
curl -X POST https://{subdomain}.app.titanrdm.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "code=AUTHORIZATION_CODE" \
-d "redirect_uri=YOUR_REDIRECT_URI"
Successful response:
{
"access_token": "eyJhbGciOiJIUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 7200,
"refresh_token": "abc123...",
"scope": "api",
"created_at": 1700000000
}
Using an Access Token
Include the token in the Authorization header of every API request:
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
https://{subdomain}.app.titanrdm.com/api/v1/domains
Token Expiration and Refresh
- Access tokens expire after 2 hours (7200 seconds) by default
- When using the Authorization Code flow, a refresh token is provided
- Use the refresh token to obtain a new access token without re-authenticating the user:
curl -X POST https://{subdomain}.app.titanrdm.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "refresh_token=YOUR_REFRESH_TOKEN"
For the Client Credentials flow, simply request a new token when the current one expires.
Scopes
Request specific scopes to limit what the token can do:
| Scope | Access Level |
api | Full access (parent scope) |
api:read | Read-only (GET requests) |
api:write | Create and update (POST, PATCH, PUT) |
api:delete | Delete resources (DELETE) |
api:admin | Administrative operations |
Request multiple scopes by separating with spaces:
scope=api:read api:write
Scopes are enforced per-request based on the HTTP method:
- GET / HEAD → requires api:read
- POST / PATCH / PUT → requires api:write
- DELETE → requires api:delete
The parent scope api satisfies all sub-scopes.
Tenant Context
TitanRDM is multi-tenant. The API automatically determines your account (tenant) from the OAuth application:
- Client Credentials: Tenant is set from the OAuth application's account
- Authorization Code: Tenant is set from the authenticated user's account
The API verifies that the token's application account matches the user's account. Cross-account access is not permitted.
Error Responses
| Status | Error | Cause |
401 | Invalid token | Token is expired, revoked, or malformed |
401 | Invalid resource owner | User associated with the token no longer exists |
401 | Token/user account mismatch | Token application and user belong to different accounts |
401 | Tenant context not set | Authentication failed completely |
403 | Insufficient scope. Required: api:write | Token does not have the required scope for this action |
Security Best Practices
- Never expose client secrets in client-side code, public repositories, or logs
- Use the minimum scope needed — request
api:readif you only need to read data - Store tokens securely — use environment variables or a secrets manager
- Rotate secrets periodically — use the "Regenerate Secret" feature in OAuth Applications
- Use Client Credentials for service accounts, Authorization Code for user-facing integrations
- Monitor API usage — check your account's usage dashboard for unexpected spikes
Related Pages
- OAuth Applications — creating and managing API credentials
- API Overview — general API concepts
- API Quick Start — get up and running quickly