Skip to main content

Client Management

Endpoints for creating and managing OAuth client applications, plus the client-builder catalog, bulk token revocation, and icon management.

Every /api/oauth-clients route except the flat list and the template catalog runs oauthClient.ensureOauth, which asserts the token API license feature. When the license lacks it the route answers 400 (not 403). The write routes (POST, PUT, DELETE, _revoke) additionally require Superuser.

GET /api/oauth-clients

List the tenant's OAuth clients, with optional search.

Authentication: Superuser + token API feature

Query Parameters:

ParameterTypeDefaultDescription
qstring-Search query (matches name and description)

Response:

A HAL collection under _embedded["inf:oauth-client"].

List OAuth clientsGET /api/oauth-clients
GET /api/oauth-clients is a HAL collection (db.query) of the tenant’s OAuth clients, embedded as `inf:oauth-client`. Superuser + the `token` api license feature are required. The optional `q` query param searches name and description.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/oauth-clients"
}
},
"start": 0,
"count": 4,
"total": 4,
"_embedded": {
"inf:oauth-client": [
{
"_links": {
"self": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001"
},
"inf:secrets": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/secrets"
},
"inf:oauth-client-revoke": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/_revoke"
},
"inf:icon": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/icon"
},
"oauth:authorize": {
"href": "https://informer.example.com/oauth/authorize"
},
"oauth:access_token": {
"href": "https://informer.example.com/api/oauth/access_token"
}
},
"isInformerCli": false,
"isInformerGo": false,
"permissions": {},
"id": "00000000-0000-4000-8000-000000000001",
"name": "Analytics Dashboard",
"description": "External analytics dashboard for Order Desk",
"url": "https://analytics.example.com",
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"redirect_uri": [
"https://analytics.example.com/callback"
],
"pkce": false,
"enableRefreshTokens": true,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"icon": null,
"_embedded": {
"inf:secret": []
}
},
{
"_links": {
"self": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000002"
},
"inf:secrets": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000002/secrets"
},
"inf:oauth-client-revoke": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000002/_revoke"
},
"inf:icon": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000002/icon"
},
"oauth:authorize": {
"href": "https://informer.example.com/oauth/authorize"
},
"oauth:access_token": {
"href": "https://informer.example.com/api/oauth/access_token"
}
},
"isInformerCli": false,
"isInformerGo": false,
"permissions": {},
"id": "00000000-0000-4000-8000-000000000002",
"name": "Scratch Client",
"description": null,
"url": null,
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"redirect_uri": [],
"pkce": false,
"enableRefreshTokens": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"icon": null,
"_embedded": {
"inf:secret": []
}
},
{
"_links": {
"self": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000003"
},
"inf:secrets": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000003/secrets"
},
"inf:oauth-client-revoke": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000003/_revoke"
},
"inf:icon": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000003/icon"
},
"oauth:authorize": {
"href": "https://informer.example.com/oauth/authorize"
},
"oauth:access_token": {
"href": "https://informer.example.com/api/oauth/access_token"
}
},
"isInformerCli": false,
"isInformerGo": true,
"permissions": {},
"id": "00000000-0000-4000-8000-000000000003",
"name": "Informer GO",
"description": "This enables support for the Informer GO desktop and mobile applications, allowing you to access your Informer account from your devices.",
"url": "",
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"redirect_uri": [],
"pkce": true,
"enableRefreshTokens": true,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"icon": null,
"_embedded": {
"inf:secret": []
}
},
"… 1 more items (4 total) — omitted from docs"
]
}
}
Captured from the API examples test suite; ids and timestamps are normalized.

GET /api/oauth-clients-list

Get a flat array of every client, each decorated with a resolved icon URL.

Authentication: Required (no special permission)

Response:

A plain JSON array (not a HAL collection envelope). Each entry carries an iconUrl, which is an empty string when the client has no icon. The endpoint supports ETags for efficient caching.

List OAuth clients (flat list)GET /api/oauth-clients-list
GET /api/oauth-clients-list is a flat array (not a HAL collection envelope) of every client, each decorated with a resolved `iconUrl` (empty string when the client has no icon). ETag-cacheable. Requires authentication but no special permission.
Response · 200
[
{
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000001",
"name": "Analytics Dashboard",
"description": "External analytics dashboard for Order Desk",
"url": "https://analytics.example.com",
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"redirect_uri": [
"https://analytics.example.com/callback"
],
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"pkce": false,
"enableRefreshTokens": true,
"hasIcon": false,
"iconUrl": ""
},
{
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000002",
"name": "Scratch Client",
"description": null,
"url": null,
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"redirect_uri": [],
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"pkce": false,
"enableRefreshTokens": false,
"hasIcon": false,
"iconUrl": ""
},
{
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000003",
"name": "Informer GO",
"description": "This enables support for the Informer GO desktop and mobile applications, allowing you to access your Informer account from your devices.",
"url": "",
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"redirect_uri": [],
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"pkce": true,
"enableRefreshTokens": true,
"hasIcon": false,
"iconUrl": ""
},
"… 1 more items (4 total) — omitted from docs"
]
Captured from the API examples test suite; ids and timestamps are normalized.

GET /api/oauth-client-templates

The client-builder catalog: a HAL collection of detective-discovered client templates used to pre-fill the create form.

Authentication: Required (no permission or token feature needed)

Response:

List client templatesGET /api/oauth-client-templates
GET /api/oauth-client-templates is the client-builder catalog (a HAL collection of detective-discovered templates). No permission or token feature required. The Informer CLI and Informer GO templates only appear when those clients are not already installed.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/oauth-client-templates"
}
},
"items": [
{
"detective": "00000000-0000-4000-8000-000000000001",
"id": "00000000-0000-4000-8000-000000000001:0",
"value": {
"group": "__top",
"name": "New OAuth Client",
"oauthClient": {
"enableRefreshTokens": true
}
}
},
{
"detective": "00000000-0000-4000-8000-000000000002",
"id": "00000000-0000-4000-8000-000000000002:0",
"value": {
"group": "__top",
"name": "Informer Command Line Interface",
"oauthClient": {
"name": "Informer Command Line Interface",
"description": "The Informer CLI is a command line tool that allows you to interact with your Informer account from the command line.",
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"isInformerCli": true,
"enableRefreshTokens": true
}
}
}
],
"start": 0,
"count": 2,
"total": 2
}
Captured from the API examples test suite; ids and timestamps are normalized.
Built-in templates

The Informer CLI and Informer GO templates appear only when those clients are not already installed.


POST /api/oauth-clients

Create an OAuth client application.

Authentication: Superuser + token API feature

Request Body:

FieldTypeRequiredDescription
namestringYesClient application name
descriptionstringNoDescription
urlstringNoApplication URL
redirect_uristring | string[]NoAllowed redirect URIs (no URL fragments). Defaults to []
client_idstringNoCustom client id (auto-generated 20-char hex when omitted)
pkcebooleanNoEnable PKCE (default false)
enableRefreshTokensbooleanNoIssue refresh tokens (default false)
svgstringNoInline SVG icon. Written to a File row and NOT echoed back

The payload is stripUnknown, so unrecognized fields are dropped.

Example Request:

{
"name": "Mobile App",
"description": "Companion mobile client",
"url": "https://mobile.example.com",
"redirect_uri": ["https://mobile.example.com/callback"],
"pkce": true,
"enableRefreshTokens": true
}

Response:

Responds 201 Created with the client and a Location header.

Create an OAuth clientPOST /api/oauth-clients
POST /api/oauth-clients (Superuser + `token` api feature). Payload is stripUnknown: name (required), description?, url?, redirect_uri? (string or string[], URIs without a fragment, defaults []), client_id? (auto-generated 20-hex when omitted), pkce? (default false), enableRefreshTokens? (default false), svg? (inline icon, written to a File and NOT echoed back). Responds 201 with a Location header.
Request body
{
"name": "Mobile App",
"description": "Companion mobile client",
"url": "https://mobile.example.com",
"redirect_uri": [
"https://mobile.example.com/callback"
],
"pkce": true,
"enableRefreshTokens": true
}
Response · 201
{
"_links": {
"self": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001"
},
"inf:secrets": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/secrets"
},
"inf:oauth-client-revoke": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/_revoke"
},
"inf:icon": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/icon"
},
"oauth:authorize": {
"href": "https://informer.example.com/oauth/authorize"
},
"oauth:access_token": {
"href": "https://informer.example.com/api/oauth/access_token"
}
},
"isInformerCli": false,
"isInformerGo": false,
"permissions": {},
"id": "00000000-0000-4000-8000-000000000001",
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"tenant": "acme",
"name": "Mobile App",
"description": "Companion mobile client",
"url": "https://mobile.example.com",
"redirect_uri": [
"https://mobile.example.com/callback"
],
"pkce": true,
"enableRefreshTokens": true,
"updatedAt": "2026-01-15T16:20:00.000Z",
"createdAt": "2026-01-15T16:20:00.000Z"
}
Captured from the API examples test suite; ids and timestamps are normalized.

GET /api/oauth-clients/{id}

Retrieve a single client, decorated with its active token count.

Authentication: Superuser + token API feature

Path Parameters:

ParameterTypeDescription
idstringClient UUID or client_id

Response:

The body adds a computed tokenCount (active tokens for this client). HAL links include inf:oauth-client-secrets, inf:oauth-client-revoke, inf:oauth-client-icon, and the oauth:authorize / oauth:access_token grant rels.

Get an OAuth clientGET /api/oauth-clients/00000000-0000-4000-8000-000000000001
GET /api/oauth-clients/{id} accepts a UUID or a client_id. The body is decorated with a computed `tokenCount` (active tokens for this client). HAL links include inf:secrets, inf:oauth-client-revoke, inf:icon, plus the oauth:authorize / oauth:access_token grant rels.
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001"
},
"inf:secrets": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/secrets"
},
"inf:oauth-client-revoke": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/_revoke"
},
"inf:icon": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/icon"
},
"oauth:authorize": {
"href": "https://informer.example.com/oauth/authorize"
},
"oauth:access_token": {
"href": "https://informer.example.com/api/oauth/access_token"
}
},
"isInformerCli": false,
"isInformerGo": false,
"permissions": {},
"id": "00000000-0000-4000-8000-000000000001",
"name": "Mobile App",
"description": "Companion mobile client",
"url": "https://mobile.example.com",
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"redirect_uri": [
"https://mobile.example.com/callback"
],
"pkce": true,
"enableRefreshTokens": true,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"icon": null,
"tokenCount": 0,
"_embedded": {
"inf:secret": []
}
}
Captured from the API examples test suite; ids and timestamps are normalized.

PUT /api/oauth-clients/{id}

Update a client's properties.

Authentication: Superuser + token API feature

Path Parameters:

ParameterTypeDescription
idstringClient UUID or client_id

Request Body (partial):

FieldTypeDescription
namestringClient name
descriptionstringDescription
urlstringApplication URL
redirect_uristring | string[]Allowed redirect URIs (defaults to [] when sent)
pkcebooleanPKCE support
enableRefreshTokensbooleanRefresh token support

Example Request:

{ "name": "Mobile App (Production)", "enableRefreshTokens": false }

Response:

Responds 200 with the updated client.

Update an OAuth clientPUT /api/oauth-clients/00000000-0000-4000-8000-000000000001
PUT /api/oauth-clients/{id} (Superuser + `token` api feature). Partial payload: name?, description?, url?, redirect_uri? (defaults [] when sent), pkce?, enableRefreshTokens?. Returns the updated client.
Request body
{
"name": "Mobile App (Production)",
"enableRefreshTokens": false
}
Response · 200
{
"_links": {
"self": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001"
},
"inf:secrets": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/secrets"
},
"inf:oauth-client-revoke": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/_revoke"
},
"inf:icon": {
"href": "https://informer.example.com/api/oauth-clients/00000000-0000-4000-8000-000000000001/icon"
},
"oauth:authorize": {
"href": "https://informer.example.com/oauth/authorize"
},
"oauth:access_token": {
"href": "https://informer.example.com/api/oauth/access_token"
}
},
"isInformerCli": false,
"isInformerGo": false,
"permissions": {},
"id": "00000000-0000-4000-8000-000000000001",
"name": "Mobile App (Production)",
"description": "Companion mobile client",
"url": "https://mobile.example.com",
"client_id": "1a2b3c4d5e6f7a8b9c0d",
"redirect_uri": [],
"pkce": true,
"enableRefreshTokens": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"tenant": "acme",
"icon": null,
"secrets": []
}
Captured from the API examples test suite; ids and timestamps are normalized.

POST /api/oauth-clients/{id}/_revoke

Delete every active token for a client, without deleting the client itself.

Authentication: Superuser + token API feature

Path Parameters:

ParameterTypeDescription
idstringClient UUID or client_id

Payload: empty

Response:

Responds 200 with an empty body. The tokens are deleted in a transaction; the client row is left intact.

Revoke all of a client’s tokensPOST /api/oauth-clients/00000000-0000-4000-8000-000000000001/_revoke
POST /api/oauth-clients/{id}/_revoke deletes every active Token for the client (in a transaction) without deleting the client itself. Superuser + `token` api feature. Returns 200 with an empty body.
Response · 200 · no body
Captured from the API examples test suite; ids and timestamps are normalized.

DELETE /api/oauth-clients/{id}

Delete a client and cascade-delete its secrets, icon, and tokens.

Authentication: Superuser (this route has no token-feature gate)

Path Parameters:

ParameterTypeDescription
idstringClient UUID or client_id

Response:

Responds 200 with an empty body (Informer's db.remove convention), not 204.

Delete an OAuth clientDELETE /api/oauth-clients/00000000-0000-4000-8000-000000000001
DELETE /api/oauth-clients/{id} is Superuser-only (no token-feature gate) and cascades to the client’s secrets, icon, and tokens. Returns 200 with an EMPTY body (Informer db.remove convention), NOT 204.
Response · 200 · no body
Captured from the API examples test suite; ids and timestamps are normalized.
Cascade delete

Deleting a client permanently removes all of its secrets, tokens, and active sessions.


Icon endpoints

The icon routes move image bytes rather than JSON, so they are documented here without captured examples.

GET /api/oauth-clients/{id}/icon

Stream the client's icon image (SVG, PNG, etc.). Superuser + token API feature. Answers 404 when the client has no icon.

PUT /api/oauth-clients/{id}/icon

Upload an icon. Superuser + token API feature.

FieldTypeRequiredDescription
uploadstringYesTemp upload id from the storage upload endpoint
progressstringNoUpload progress tracking id

Responds 201 Created with the file record.

DELETE /api/oauth-clients/{id}/icon

Remove the client's icon. Superuser + token API feature.