Skip to main content

API Tokens

Endpoints for managing API tokens for programmatic access.

A token row pairs a type with optional entity scoping. The type must be a registered token driver; each driver's authorize() decides which routes the token may call, so an entity-scoped token (e.g. a dataset token) only works against that entity's surfaces. The default type, api, is the general-purpose token. Other in-tree types include report, dataset, query, visual, datasource, assistant, app_view (App external links), and webhook (App inbound webhooks).

The token string itself is the key field: a JWT signed with the tenant's token secret, computed at response time and never stored. Any full read of the row (create response, list, single GET) re-derives it, so it can be retrieved again later; rotating the tenant token secret invalidates every key at once.

GET /api/tokens

List API tokens with optional filtering.

Authentication: Required

Query Parameters:

ParameterTypeDescription
reportIdstringFilter by Report ID
datasourceIdstringFilter by Datasource ID
assistantIdstringFilter by Assistant ID
visualIdstringFilter by visual ID
datasetIdstringFilter by Dataset ID
queryIdstringFilter by query ID
appIdstringFilter by App ID
usernamestringFilter by username
List tokensGET /api/tokens
Filterable by the resource FKs (appId, datasetId, reportId, ...) to scope to one entity.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/tokens"
}
},
"start": 0,
"count": 1,
"total": 1,
"_embedded": {
"inf:token": [
{
"_links": {
"self": {
"href": "https://informer.example.com/api/tokens/00000000-0000-4000-8000-000000000001"
},
"inf:token-type": {
"href": "https://informer.example.com/api/token-types/api"
}
},
"permissions": {
"edit": true,
"delete": true
},
"id": "00000000-0000-4000-8000-000000000001",
"type": "api",
"readOnly": false,
"notes": "CI integration",
"restrict": null,
"host": null,
"cidr": null,
"data": null,
"requests": 0,
"blocked": 0,
"lastAccessedAt": null,
"expiresAt": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"username": "admin",
"reportId": null,
"queryId": null,
"visualId": null,
"datasourceId": null,
"datasetId": null,
"appId": null,
"assistantId": null,
"oauthClientId": null,
"user": {
"permissions": {
"changeDomain": true,
"changeProfile": true,
"changePassword": false,
"delete": true,
"edit": true,
"reassign": true,
"superuser": true,
"enable": true,
"changeTheme": true,
"lock": true,
"setGlobalPermissions": true,
"manageLogin": false
},
"displayName": "acme Administrator",
"email": null
},
"assistant": null,
"oauthClient": null,
"key": "eyJhbGciOiJIUzI1NiJ9.example-token-1.signature"
}
]
}
}
Captured from the API examples test suite; ids and timestamps are normalized.

POST /api/tokens

Create a new API token. The token is owned by the calling user (username is set from the session).

Authentication: Required

Permission: tokens:create

Request Body:

FieldTypeRequiredDescription
typestringNoToken type (default api); must be a registered token driver
notesstringNoToken description or notes
readOnlybooleanNoRestrict to GETs and read-only-marked routes (default: false)
restrictstringNoNetwork restriction: host or cidr
hoststringNoAllowed hostname (if restrict: 'host')
cidrstringNoCIDR range (if restrict: 'cidr')
reportId / datasetId / queryId / visualId / datasourceId / assistantId / appIdstringPer typeThe entity the token is scoped to; the matching driver validates which FK it requires
dataobjectNoDriver-specific data (e.g. roles for app_view links)
Create an API tokenPOST /api/tokens
The key is a signed JWT computed at response time and never stored; fetch the token again to re-derive it. readOnly true restricts the token to GETs.
Request body
{
"type": "api",
"notes": "CI integration",
"readOnly": false
}
Response · 201
{
"_links": {
"self": {
"href": "https://informer.example.com/api/tokens/00000000-0000-4000-8000-000000000001"
},
"inf:token-type": {
"href": "https://informer.example.com/api/token-types/api"
}
},
"permissions": {
"edit": true,
"delete": true
},
"id": "00000000-0000-4000-8000-000000000001",
"type": "api",
"readOnly": false,
"notes": "CI integration",
"restrict": null,
"host": null,
"cidr": null,
"data": null,
"requests": 0,
"blocked": 0,
"lastAccessedAt": null,
"expiresAt": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"username": "admin",
"reportId": null,
"queryId": null,
"visualId": null,
"datasourceId": null,
"datasetId": null,
"appId": null,
"assistantId": null,
"oauthClientId": null,
"user": {
"permissions": {
"changeDomain": true,
"changeProfile": true,
"changePassword": false,
"delete": true,
"edit": true,
"reassign": true,
"superuser": true,
"enable": true,
"changeTheme": true,
"lock": true,
"setGlobalPermissions": true,
"manageLogin": false
},
"displayName": "acme Administrator",
"email": null
},
"assistant": null,
"oauthClient": null,
"key": "eyJhbGciOiJIUzI1NiJ9.example-token-1.signature"
}
Captured from the API examples test suite; ids and timestamps are normalized.

Status: 201 Created with a Location header pointing at the new token.


GET /api/tokens/{id}

Retrieve a specific API token, including its re-derived key.

Authentication: Required (read access: your own tokens, or superuser)

Response: the same shape as a list entry above.


PUT /api/tokens/{id}

Update an API token's metadata. Only notes, data, readOnly, restrict, host, and cidr are accepted; everything else is stripped (the type and entity scoping are fixed at creation).

Authentication: Required

Update a tokenPUT /api/tokens/00000000-0000-4000-8000-000000000001
Notes and network restrictions are editable in place; the key stays valid.
Request body
{
"notes": "CI integration (rotated owner)"
}
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/tokens/00000000-0000-4000-8000-000000000001"
},
"inf:token-type": {
"href": "https://informer.example.com/api/token-types/api"
}
},
"permissions": {
"edit": true,
"delete": true
},
"id": "00000000-0000-4000-8000-000000000001",
"type": "api",
"readOnly": false,
"notes": "CI integration (rotated owner)",
"restrict": null,
"host": null,
"cidr": null,
"data": null,
"requests": 0,
"blocked": 0,
"lastAccessedAt": null,
"expiresAt": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"username": "admin",
"reportId": null,
"queryId": null,
"visualId": null,
"datasourceId": null,
"datasetId": null,
"appId": null,
"assistantId": null,
"oauthClientId": null,
"user": {
"permissions": {
"changeDomain": true,
"changeProfile": true,
"changePassword": false,
"delete": true,
"edit": true,
"reassign": true,
"superuser": true,
"enable": true,
"changeTheme": true,
"lock": true,
"setGlobalPermissions": true,
"manageLogin": false
},
"displayName": "acme Administrator",
"email": null
},
"assistant": null,
"oauthClient": null,
"key": "eyJhbGciOiJIUzI1NiJ9.example-token-1.signature"
}
Captured from the API examples test suite; ids and timestamps are normalized.

DELETE /api/tokens/{id}

Revoke an API token.

Authentication: Required

Revoke a tokenDELETE /api/tokens/00000000-0000-4000-8000-000000000001
Deleting the row invalidates the key immediately.
Response · 200 · no body
Captured from the API examples test suite; ids and timestamps are normalized.
Permanent Revocation

Deleting a token immediately revokes access. This cannot be undone. Any requests using the token will fail with 401 Unauthorized.


GET /api/token-types

List the registered token types (the same registry the type field validates against), for the token-creation UI.

Authentication: Required


GET /api/token-types/{id}

Get details for a specific token type.

Authentication: Required


GET /api/token-templates

Get token templates for UI generation.

Authentication: Required

Response:

Array of token template objects with field definitions.