Authentication
Exchange client credentials for an access token
POST /api/v1/oauth2/token
Send the form as application/x-www-form-urlencoded. HTTP Basic with client_id:client_secret is accepted too, and so is a JSON body with the same three fields.
The answer is a bearer token that lasts 24 hours. Cache it and re-use it until a 401 says it expired, then mint another. Revoking the credentials under Settings › Integrations invalidates every token issued from them at once.
Request body
application/x-www-form-urlencoded, shaped as TokenRequest.
| Field | Type | Description |
|---|---|---|
| grant_type required | "client_credentials" | Always client_credentials. |
| client_id required | string | The client ID from Settings › Integrations, e.g. qc_… |
| client_secret required | string | The secret shown once when the credentials were created, e.g. qs_… |
Response
200 { }
Errors
Every failure is { error, message }; see Errors. A missing or expired bearer is a 401 on every endpoint
but the token exchange.
| Status | error | When |
|---|---|---|
| 400 | invalid_request | client_id or client_secret missing, or a body that is neither form-encoded nor JSON. |
| 400 | unsupported_grant_type | Anything but grant_type=client_credentials. |
| 401 | invalid_client | Unknown client id, wrong secret, or credentials that were revoked. |
Notes
- The response carries Cache-Control: no-store and Pragma: no-cache, as the RFC asks. Cache the token in your own process, not in an HTTP cache.
- Tokens are per credential set. A second set for a second system gets its own tokens, and revoking one leaves the other untouched.