Skip to content

API reference — OAuth client management

OAuth M2M (machine-to-machine) clients enable server-side applications to authenticate to Arbitex using the OAuth 2.0 client credentials grant. Each client has a client_id and client_secret pair. Secrets are generated at creation time, returned once in plaintext, and stored only as SHA-256 hashes — they cannot be retrieved after creation.

All endpoints are admin-only. Authentication: Authorization: Bearer arb_live_<admin-key>.

Base path: /api/admin/oauth-clients

For the token issuance endpoint (POST /oauth/token) used by clients at runtime, see OAuth M2M API guide.


Returned by all endpoints except create. Does not include the client secret.

FieldTypeDescription
idUUIDInternal record identifier
client_idUUIDPublic-facing OAuth client ID (used in token requests)
namestringDisplay name for the client application
scopesstring[]Granted OAuth scope strings
tenant_idUUID | nullOwning tenant UUID (multi-tenant isolation)
created_byUUID | nullAdmin user UUID who created the record
enabledbooleanWhether the client can authenticate
rate_limit_tierstringRate-limit policy: standard, premium, or unlimited
token_lifetime_secondsintegerAccess token TTL in seconds (max: 86400)
created_atdatetimeISO 8601 creation timestamp
last_useddatetime | nullTimestamp of most recent token issuance

Extends OAuthClientResponse with the plaintext secret — returned only at creation time.

FieldTypeDescription
client_secretstringPlaintext client secret. Store immediately — not retrievable again.
(all OAuthClientResponse fields)

Returned by the secret rotation endpoint.

FieldTypeDescription
client_idUUIDPublic-facing client ID
new_client_secretstringNew plaintext secret. Store immediately — not retrievable again.
grace_period_secondsintegerSeconds the old secret remains valid after rotation
previous_secret_expires_atdatetimeWhen the old secret will be rejected

GET /api/admin/oauth-clients/

Returns a paginated list of all registered OAuth M2M clients.

Query parameters:

ParameterTypeDefaultDescription
pageinteger1Page number (1-based)
page_sizeinteger20Records per page (1–200)
enabledbooleanFilter by enabled status
tenant_idUUIDFilter by tenant

Request:

Terminal window
GET /api/admin/oauth-clients/?enabled=true
Authorization: Bearer arb_live_your-admin-key

Response (200):

{
"items": [
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "CI/CD Pipeline",
"scopes": ["chat:write", "audit:read"],
"tenant_id": null,
"created_by": "7c8d9e0f-...",
"enabled": true,
"rate_limit_tier": "standard",
"token_lifetime_seconds": 3600,
"created_at": "2026-03-01T00:00:00Z",
"last_used": "2026-03-12T13:58:00Z"
}
],
"total": 4,
"page": 1,
"page_size": 20
}

POST /api/admin/oauth-clients/

Creates a new M2M client registration. Returns the client record with the plaintext secret (client_secret). The secret is not stored and cannot be retrieved again — copy it immediately.

Request body:

FieldRequiredDefaultDescription
nameYesDisplay name (1–255 characters)
scopesNo[]List of OAuth scope strings to grant
tenant_idNonullTenant UUID for multi-tenant isolation
rate_limit_tierNostandardstandard, premium, or unlimited
token_lifetime_secondsNo3600Token TTL in seconds (1–86400)

Request:

Terminal window
POST /api/admin/oauth-clients/
Authorization: Bearer arb_live_your-admin-key
Content-Type: application/json
{
"name": "CI/CD Pipeline",
"scopes": ["chat:write", "audit:read"],
"rate_limit_tier": "standard",
"token_lifetime_seconds": 3600
}

Response (201 Created):

{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"client_secret": "Xk4mPz9rJqNv...(48 chars, URL-safe base64)",
"name": "CI/CD Pipeline",
"scopes": ["chat:write", "audit:read"],
"tenant_id": null,
"created_by": "admin-uuid",
"enabled": true,
"rate_limit_tier": "standard",
"token_lifetime_seconds": 3600,
"created_at": "2026-03-12T14:00:00Z",
"last_used": null
}

Error (422 Unprocessable Entity):

{ "detail": "Invalid rate_limit_tier 'gold'. Must be one of: premium, standard, unlimited" }

GET /api/admin/oauth-clients/{client_id}

Where client_id is the public-facing OAuth client UUID (the client_id field, not id).

Response (200): Returns the OAuthClientResponse object (no secret).

Error (404 Not Found):

{ "detail": "OAuth client not found" }

PATCH /api/admin/oauth-clients/{client_id}

Partial update — only non-null fields are applied.

Updatable fields: name, scopes, enabled, rate_limit_tier, token_lifetime_seconds.

Disable a client:

Terminal window
PATCH /api/admin/oauth-clients/a1b2c3d4-e5f6-7890-abcd-ef1234567890
Authorization: Bearer arb_live_your-admin-key
Content-Type: application/json
{ "enabled": false }

Update scopes:

Terminal window
PATCH /api/admin/oauth-clients/a1b2c3d4-e5f6-7890-abcd-ef1234567890
Authorization: Bearer arb_live_your-admin-key
Content-Type: application/json
{
"scopes": ["chat:write", "audit:read", "dlp:read"],
"rate_limit_tier": "premium"
}

Response (200): Returns the updated OAuthClientResponse object.


DELETE /api/admin/oauth-clients/{client_id}

Permanently removes the client registration. Active tokens issued to this client will continue to work until they expire — delete and then revoke existing tokens if immediate termination is required.

Response: 204 No Content


POST /api/admin/oauth-clients/{client_id}/rotate-secret

Generates a new client secret. The old secret remains valid for a grace period to allow zero-downtime secret rotation in deployed applications. After the grace period, the old secret is rejected.

Request:

Terminal window
POST /api/admin/oauth-clients/a1b2c3d4-e5f6-7890-abcd-ef1234567890/rotate-secret
Authorization: Bearer arb_live_your-admin-key

Response (200):

{
"client_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"new_client_secret": "Yk7nQw2sFpMx...(48 chars, URL-safe base64)",
"grace_period_seconds": 3600,
"previous_secret_expires_at": "2026-03-12T15:00:00Z"
}

Secret rotation procedure:

  1. Call POST /rotate-secret and copy the new_client_secret.
  2. Update your application’s secret store with the new value.
  3. Deploy the updated application configuration.
  4. Verify the application successfully authenticates with the new secret.
  5. The old secret automatically expires at previous_secret_expires_at.

TierDescription
standardDefault rate limits — suitable for most automation workloads
premiumHigher rate limits — for high-throughput integrations
unlimitedNo rate limits — use only for trusted internal services

Contact your Arbitex administrator to understand the specific request-per-second limits for each tier.


Common scopes granted to M2M clients:

ScopeDescription
chat:writeSubmit AI requests via /api/chat/completions
audit:readRead audit log entries
dlp:readRead DLP configuration
groups:readRead group memberships
groups:writeCreate and update groups

Scopes are enforced by the OAuthScopeEnforcer when OAUTH_SCOPE_ENFORCEMENT=true. See OAuth scope enforcement guide.


After creating a client, obtain an access token using the client credentials grant:

Terminal window
POST https://api.arbitex.ai/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890
&client_secret=Xk4mPz9rJqNv...
&scope=chat:write

Response:

{
"access_token": "eyJ...",
"token_type": "bearer",
"expires_in": 3600,
"scope": "chat:write"
}

Use the access_token in subsequent API requests:

Terminal window
POST https://api.arbitex.ai/api/chat/completions
Authorization: Bearer eyJ...