Authentication – requesting and using access tokens¶
Every call to the REST API needs an access token. This page describes how a calling system requests a token, how it sends it, how long it is valid and which errors can occur. It is intended for the people who build the calling system.
How an administrator creates the API access, its client ID and client secrets is described in API access and credentials. This page does not repeat it.
1. At a glance¶
| Method | OAuth 2.0 client credentials (RFC 6749, section 4.4) |
| Token endpoint | POST /api/oauth/token |
| Credentials | Client ID and client secret of an API access |
| Token type | Bearer, sent as Authorization: Bearer <token> |
| Validity | 3600 seconds by default (ApiAuthentication:AccessTokenLifetimeInSeconds) |
| Runs as | The user assigned to the API access |
| Refresh tokens | None – request a new token when the old one has expired |
Summary¶
- One request with client ID and secret returns a token; the token is then sent with every call.
- Every token opens an API session of the assigned user and takes a license for that user (unless the user already has one or has a license-free role).
- A token stops working when it expires, when its session is revoked, when the user is locked, and when the client secret it was requested with is removed or the API access is deleted.
2. Requesting a token¶
POST /api/oauth/token
| Item | Value |
|---|---|
| Content type | application/x-www-form-urlencoded (a JSON body is rejected with 415) |
grant_type |
client_credentials – exactly in this spelling |
client_id |
The client ID of the API access |
client_secret |
A client secret of the API access |
| Token needed | No |
The client ID and secret can be sent in the form body or as HTTP basic authentication
(Authorization: Basic <base64 of client_id:client_secret>). Basic authentication is used only
when the body contains neither client_id nor client_secret.
Example – credentials in the body¶
curl -X POST https://nexxcite.example.com/api/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=Zx8nQ2vLr5TfK1wE" \
-d "client_secret=<CLIENT_SECRET>"
Example – basic authentication¶
curl -X POST https://nexxcite.example.com/api/oauth/token \
-u "Zx8nQ2vLr5TfK1wE:<CLIENT_SECRET>" \
-d "grant_type=client_credentials"
Response – 200 OK¶
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
| Property | Meaning |
|---|---|
access_token |
The token. Treat it like a password. |
token_type |
Always Bearer |
expires_in |
Validity in seconds |
The response carries Cache-Control: no-store, so proxies and browsers do not keep it.
3. Errors of the token endpoint¶
Errors follow RFC 6749, section 5.2: a JSON object with error and error_description.
{
"error": "invalid_client",
"error_description": "Unknown client_id or invalid client_secret."
}
| HTTP status | error |
Cause | What to do |
|---|---|---|---|
| 400 | unsupported_grant_type |
grant_type missing or not client_credentials |
Send grant_type=client_credentials |
| 400 | invalid_request |
Client ID or client secret missing | Send both, in the body or as basic authentication |
| 400 | temporarily_unavailable |
All licenses are in use | Try again later |
| 401 | invalid_client |
Unknown client ID; wrong secret; secret outside its "Valid From" / "Valid To"; no user assigned to the API access; user locked or deleted | Check the credentials with the administrator |
| 415 | – | The body is not a form (for example JSON) | Send application/x-www-form-urlencoded |
| 500 | server_error |
No valid signing key is configured on the server – the REST API sign-in is switched off | Operator: set ApiAuthentication:SigningKey |
| 503 | license_invalid |
The installation has no valid license | Administrator: enter a valid license key |
For security reasons, the answer does not tell an unknown client ID from a wrong secret.
4. Using the token¶
Send the token with every request to /api/v1/...:
curl https://nexxcite.example.com/api/v1/records/6a1f0c52-3d4e-4b8a-9c71-2f5e8d0b4a13/9b7e2d41-0c5a-4f36-8e12-7d3a6b9c0f58 \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
A request without a valid token is answered with 401 Unauthorized and an empty body. The
header WWW-Authenticate contains Bearer, and – when a token was sent – error="invalid_token".
| Situation | Result |
|---|---|
No Authorization header |
401 |
| Token expired (a tolerance of 30 seconds applies) | 401 |
| Session of the token revoked under "User Sessions" | 401, immediately, on every server |
| User of the API access locked or deleted | 401, immediately |
| Signing key changed or removed on the server | 401 for all tokens issued before |
| Client secret the token was requested with removed, or API access deleted | 401, immediately, on every server – as soon as the change is published |
Recommended token handling¶
- Request a token and keep it in memory together with its expiry time (
expires_in). - Use it for all calls until shortly before it expires.
- Request a new token when it is about to expire, or when a call returns
401– then repeat that call once.
Do not request a new token for every call: every token creates a new API session and is counted in "User Sessions" until it expires.
5. Sessions and licenses¶
Every token creates an API session of the assigned user:
| Where | What you see |
|---|---|
| Admin Studio → Access → Authenticated Users | The user, tagged "API" |
| "User Sessions" | One entry per token, with the name of the API access |
| Situation | Effect |
|---|---|
| A token is issued | The user takes a license – unless they already have one or have a license-free role |
| All licenses are in use | No token: 400 temporarily_unavailable |
| The token expires | The session ends; the license is released at the latest about 5 minutes later |
| The installation loses its valid license | All API requests return 503 license_invalid |
| The server restarts | Valid tokens stay valid; with several servers, every server accepts the tokens of the others |
Expired API sessions of a user are removed when that user requests the next token. Details on licenses: Licensing.
6. Tokens for the signed-in user¶
An action can also obtain a token for the user who is currently signed in, with the system function
CurrentUserApiAccessToken – for example to hand it to another system that then calls the REST API
on behalf of this user. Such a token works exactly like one from the token endpoint. See
API access and credentials, section 5.
7. Security notes¶
For the calling system
- Keep the client secret and tokens secret. Store them in a secure store, never in source code, logs or URLs.
- Use HTTPS only.
- Use one API access per system, so that you can cut off one system without affecting others.
For administrators
- To cut off a system at once, remove its secret or delete the API access. Tokens requested with that secret stop working as soon as the change is published. The open API sessions stay listed in "User Sessions" until they expire; revoke them there to release the license earlier.
- Keep the token lifetime moderate. A token is valid for its whole lifetime unless it is cut off as described above.
- The token endpoint has no limit on the number of requests. Client secrets are long random values and cannot be guessed in practice.
8. Limitations¶
- Only the client credentials method is supported. Authorization code, password and refresh tokens are not offered.
- A token carries no scopes. It always has all permissions of the assigned user.
- Two-factor authentication does not apply to the API.