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.
Schemas
Section titled “Schemas”OAuthClientResponse
Section titled “OAuthClientResponse”Returned by all endpoints except create. Does not include the client secret.
| Field | Type | Description |
|---|---|---|
id | UUID | Internal record identifier |
client_id | UUID | Public-facing OAuth client ID (used in token requests) |
name | string | Display name for the client application |
scopes | string[] | Granted OAuth scope strings |
tenant_id | UUID | null | Owning tenant UUID (multi-tenant isolation) |
created_by | UUID | null | Admin user UUID who created the record |
enabled | boolean | Whether the client can authenticate |
rate_limit_tier | string | Rate-limit policy: standard, premium, or unlimited |
token_lifetime_seconds | integer | Access token TTL in seconds (max: 86400) |
created_at | datetime | ISO 8601 creation timestamp |
last_used | datetime | null | Timestamp of most recent token issuance |
OAuthClientCreateResponse
Section titled “OAuthClientCreateResponse”Extends OAuthClientResponse with the plaintext secret — returned only at creation time.
| Field | Type | Description |
|---|---|---|
client_secret | string | Plaintext client secret. Store immediately — not retrievable again. |
| (all OAuthClientResponse fields) |
OAuthClientRotateSecretResponse
Section titled “OAuthClientRotateSecretResponse”Returned by the secret rotation endpoint.
| Field | Type | Description |
|---|---|---|
client_id | UUID | Public-facing client ID |
new_client_secret | string | New plaintext secret. Store immediately — not retrievable again. |
grace_period_seconds | integer | Seconds the old secret remains valid after rotation |
previous_secret_expires_at | datetime | When the old secret will be rejected |
Endpoints
Section titled “Endpoints”List OAuth clients
Section titled “List OAuth clients”GET /api/admin/oauth-clients/
Returns a paginated list of all registered OAuth M2M clients.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number (1-based) |
page_size | integer | 20 | Records per page (1–200) |
enabled | boolean | — | Filter by enabled status |
tenant_id | UUID | — | Filter by tenant |
Request:
GET /api/admin/oauth-clients/?enabled=trueAuthorization: Bearer arb_live_your-admin-keyResponse (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}Create an OAuth client
Section titled “Create an OAuth client”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:
| Field | Required | Default | Description |
|---|---|---|---|
name | Yes | — | Display name (1–255 characters) |
scopes | No | [] | List of OAuth scope strings to grant |
tenant_id | No | null | Tenant UUID for multi-tenant isolation |
rate_limit_tier | No | standard | standard, premium, or unlimited |
token_lifetime_seconds | No | 3600 | Token TTL in seconds (1–86400) |
Request:
POST /api/admin/oauth-clients/Authorization: Bearer arb_live_your-admin-keyContent-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 an OAuth client
Section titled “Get an OAuth client”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" }Update an OAuth client
Section titled “Update an OAuth client”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:
PATCH /api/admin/oauth-clients/a1b2c3d4-e5f6-7890-abcd-ef1234567890Authorization: Bearer arb_live_your-admin-keyContent-Type: application/json
{ "enabled": false }Update scopes:
PATCH /api/admin/oauth-clients/a1b2c3d4-e5f6-7890-abcd-ef1234567890Authorization: Bearer arb_live_your-admin-keyContent-Type: application/json
{ "scopes": ["chat:write", "audit:read", "dlp:read"], "rate_limit_tier": "premium"}Response (200): Returns the updated OAuthClientResponse object.
Delete an OAuth client
Section titled “Delete an OAuth client”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
Rotate client secret
Section titled “Rotate client secret”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:
POST /api/admin/oauth-clients/a1b2c3d4-e5f6-7890-abcd-ef1234567890/rotate-secretAuthorization: Bearer arb_live_your-admin-keyResponse (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:
- Call
POST /rotate-secretand copy thenew_client_secret. - Update your application’s secret store with the new value.
- Deploy the updated application configuration.
- Verify the application successfully authenticates with the new secret.
- The old secret automatically expires at
previous_secret_expires_at.
Rate limit tiers
Section titled “Rate limit tiers”| Tier | Description |
|---|---|
standard | Default rate limits — suitable for most automation workloads |
premium | Higher rate limits — for high-throughput integrations |
unlimited | No rate limits — use only for trusted internal services |
Contact your Arbitex administrator to understand the specific request-per-second limits for each tier.
Scope reference
Section titled “Scope reference”Common scopes granted to M2M clients:
| Scope | Description |
|---|---|
chat:write | Submit AI requests via /api/chat/completions |
audit:read | Read audit log entries |
dlp:read | Read DLP configuration |
groups:read | Read group memberships |
groups:write | Create and update groups |
Scopes are enforced by the OAuthScopeEnforcer when OAUTH_SCOPE_ENFORCEMENT=true. See OAuth scope enforcement guide.
Usage example: token issuance
Section titled “Usage example: token issuance”After creating a client, obtain an access token using the client credentials grant:
POST https://api.arbitex.ai/oauth/tokenContent-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=a1b2c3d4-e5f6-7890-abcd-ef1234567890&client_secret=Xk4mPz9rJqNv...&scope=chat:writeResponse:
{ "access_token": "eyJ...", "token_type": "bearer", "expires_in": 3600, "scope": "chat:write"}Use the access_token in subsequent API requests:
POST https://api.arbitex.ai/api/chat/completionsAuthorization: Bearer eyJ...See also
Section titled “See also”- OAuth M2M API guide — client credentials flow, token endpoint, and integration examples
- OAuth scope enforcement guide — scope-based access control configuration
- API keys reference — alternative authentication for human users and simple integrations
- RS256 JWT tokens guide — token validation and JWKS key rotation