Authentication
Exchange your API credentials for a bearer token using the OAuth 2.0 client-credentials flow. All premote API requests require a valid token in the Authorization header.
1. Request a bearer token
Send your credentials to POST /auth/token. Full schema in the API Reference.
curl -X POST BASEURL/auth/token \
-H 'Content-Type: application/json' \
-d '{
"client_id": "prm_live_8f3c2a1b",
"client_secret": "prm_secret_d4e5f6a7b8c9"
}'const res = await fetch('BASEURL/auth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: 'prm_live_8f3c2a1b',
client_secret: 'prm_secret_d4e5f6a7b8c9',
}),
})
const { access_token } = await res.json()A successful call returns 201 Created with the token:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}access_token— the JWT to send on every request.token_type— alwaysBearer.expires_in— seconds until the token expires: 3600 (one hour). Use it to schedule a refresh rather than waiting for a401.
2. Authenticate your requests
Send the token in the Authorization header as a Bearer token on every subsequent request:
curl BASEURL/users/list \
-H 'Authorization: Bearer <access_token>'await fetch('BASEURL/users/list', {
headers: { Authorization: `Bearer ${access_token}` },
})3. Token lifetime & errors
Tokens are valid for one hour (expires_in: 3600). Don't cache one for the life of your process: on a 401 Unauthorized, request a fresh token from POST /auth/token and retry the call once. Treat a second consecutive 401 as a credentials problem, not an expiry.
Revoking a credential in the dashboard invalidates its tokens within 30 seconds.
Invalid credentials return 401:
{
"message": "Invalid api credentials"
}4. Rate limits
| Requests | Limit |
|---|---|
POST /auth/token | 30 per minute per IP address |
| Calls made with an API token | 600 per minute per credential |
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Over the limit, the API answers 429 Too Many Requests with a Retry-After header in seconds — wait that long before retrying.
5. Request IDs
Every response, errors included, carries an X-Request-Id header. Quote it when you contact support — it lets us find your exact request in our logs.
To link our records to your own request log, send your own X-Request-Id on the request: up to 128 characters from A-Z a-z 0-9 . _ : -. A valid value is echoed back unchanged; a missing or invalid one is replaced with a generated UUID.
curl BASEURL/users/list \
-H 'Authorization: Bearer <access_token>' \
-H 'X-Request-Id: acme-sync-2026-10-06-0042'Responses produced by the API gateway itself — a gateway timeout, for example — do not carry the header.
Keep credentials and tokens server-sideNever embed your client secret or bearer tokens in browser or mobile clients. Always request tokens from a backend you control.
Next steps
- Create a trip via the API — the end-to-end happy path that starts from the token you just obtained.
Updated 3 days ago
