Authentication
Every request authenticates with a Bearer token — either a business API key or a user access token.
Two token types
- Business API key — a long-lived key bound to one business, generated in the dashboard. Use it for server-to-server integrations (your dispatch system, a website, a booking widget on your own server).
-
User access token — a short-lived token obtained by logging in
with
POST /api/v1/auth/login. It acts as a person and can reach every business that person can access. This is what the Destination Tools mobile apps (operator and driver) use.
Both are sent the same way, and every endpoint accepts either unless noted otherwise
(the /api/v1/auth/* and /api/v1/me* endpoints are user-token only).
Sending your token
Send the token in the Authorization header on every request.
Requests without a valid token receive a 401 response.
Header
Authorization: Bearer YOUR_API_KEY
401 Response
{
"error": {
"type": "unauthorized",
"message": "Missing API key."
},
"meta": { "request_id": "req_1a2b3c4d5e6f7a8b" }
}
Generating and revoking keys
Manage keys in the dashboard under Settings → Integration. You can create multiple keys and give each a label so you can tell your integrations apart. Each key shows when it was created and last used.
- Create a key per integration or environment (e.g. staging vs production).
- Revoke a key by deleting it — the change takes effect immediately.
User login & refresh tokens
POST /api/v1/auth/login exchanges an email and password for an
access token (a 15-minute JWT) and a refresh token
(valid 30 days). When the access token expires, exchange the refresh token at
POST /api/v1/auth/refresh for a new pair.
Refresh tokens rotate: each refresh invalidates the token you
presented and returns a new one. Reusing an already-rotated refresh token is treated
as theft and revokes the whole session — the user must log in again.
POST /api/v1/auth/logout revokes the session immediately.
Native Google Sign-In is supported via POST /api/v1/auth/google with a Google ID token.
Login
POST /api/v1/auth/login
{ "email": "[email protected]", "password": "•••", "device_name": "Pixel 9" }
{
"data": {
"token_type": "Bearer",
"access_token": "eyJ0eXAiOiJKV1Qi...",
"expires_in": 900,
"refresh_token": "rt_9f2c4e...",
"user": { "id": 42, "email": "[email protected]", "account_type": "A" },
"businesses": [ { "business_id": 7, "business_name": "Executive Transfers" } ]
}
}
Choosing the business
A user may have access to several transport businesses. Select the one to act on with
the X-Business-Id header (any id from GET /api/v1/me/businesses).
With access to exactly one business the header can be omitted. Without it, and with
several businesses available, requests receive a 422 business_required
error listing the choices.
Request
GET /api/v1/trips
Authorization: Bearer eyJ0eXAiOiJKV1Qi...
X-Business-Id: 7
Scope
An API key is bound to the business that created it; a user token is bound to the
businesses the user can access. Every endpoint is automatically scoped to the acting
business — you can only read and write your own trips, cars, drivers and customers.
Requests for another business's resources return 404, and selecting a
business the user cannot access returns 403.
Transport security
All requests must use HTTPS. Requests over plain HTTP are not supported. Never embed a business API key in client-side code (a browser app or mobile binary) where end users could extract it — call the API from your server. Mobile and desktop apps should use the user login flow instead: tokens are per-person, short-lived and revocable.