Platform admin API
This page documents platform administration API endpoints served by the Platform at https://platform.arbitex.ai. All endpoints require a Platform admin role Bearer JWT unless otherwise noted.
Content categories API
Section titled “Content categories API”CRUD operations and statistics for the content category taxonomy. Content categories classify conversation topics using keyword-based matching, enabling policy rules based on content domain.
Base URL: https://platform.arbitex.ai
Authentication: Authorization: Bearer <platform-admin-jwt>
For the full guide, see Content Categories. For detailed schemas with curl examples, see API reference — batch 43.
Category object
Section titled “Category object”| Field | Type | Description |
|---|---|---|
id |
UUID | Category identifier |
slug |
string | Dot-notation identifier (e.g., legal.contracts). Must match ^[a-z][a-z0-9_.]*$. |
parent_slug |
string or null | Parent domain slug (e.g., legal). Null for top-level domains. |
name |
string | Human-readable display name |
description |
string or null | Description of the category |
keywords |
array of string | Keyword list for L1 classification matching |
enabled |
boolean | Whether this category is active for classification |
org_id |
UUID or null | Null for global builtins; non-null for org-scoped overrides |
created_at |
datetime | ISO 8601 creation timestamp |
updated_at |
datetime | ISO 8601 last-update timestamp |
Endpoint summary
Section titled “Endpoint summary”| Method | Path | Description |
|---|---|---|
GET |
/api/v1/admin/content-categories |
List categories with optional filters |
POST |
/api/v1/admin/content-categories |
Create a custom category |
GET |
/api/v1/admin/content-categories/{slug} |
Get a single category by slug |
PUT |
/api/v1/admin/content-categories/{slug} |
Update a category |
DELETE |
/api/v1/admin/content-categories/{slug} |
Soft-delete builtin or hard-delete custom |
GET |
/api/v1/admin/content-categories/stats |
Keyword counts and enabled status per category |
List categories
Section titled “List categories”GET /api/v1/admin/content-categoriesReturns categories with optional filters. When org_id is provided, global categories are merged with org-scoped overrides (org row shadows global for the same slug).
Query parameters
| Parameter | Type | Description |
|---|---|---|
enabled |
boolean | Filter by enabled state |
parent |
string | Exact match on parent_slug |
org_id |
UUID | Merge global + org overrides for this org |
limit |
integer | Results per page (default 100, max 1000) |
offset |
integer | Pagination offset |
Request
curl "https://platform.arbitex.ai/api/v1/admin/content-categories?parent=legal&enabled=true" \ -H "Authorization: Bearer $ADMIN_TOKEN"Response 200 OK
{ "categories": [ { "id": "a1b2c3d4-0000-0000-0000-000000000001", "slug": "legal.contracts", "parent_slug": "legal", "name": "Contract Drafting", "description": "NDA, SOW, MSA drafting and review", "keywords": ["NDA", "non-disclosure agreement", "SOW", "statement of work", "MSA"], "enabled": true, "org_id": null, "created_at": "2026-03-14T00:00:00Z", "updated_at": "2026-03-14T00:00:00Z" } ], "total": 4}Create a custom category
Section titled “Create a custom category”POST /api/v1/admin/content-categoriesRequest body
| Field | Type | Required | Description |
|---|---|---|---|
slug |
string | Yes | Dot-notation identifier (^[a-z][a-z0-9_.]*$, max 100 chars) |
parent_slug |
string | No | Must reference an existing global domain |
name |
string | Yes | Display name (max 255 chars) |
description |
string | No | Long-form description |
keywords |
array of string | No | Keyword list for matching (default []) |
org_id |
UUID | No | Null for global; non-null for org-scoped |
Response 201 Created — returns category object.
| Status | Description |
|---|---|
404 |
parent_slug does not exist in global taxonomy |
409 |
Category with same (slug, org_id) already exists |
422 |
Invalid slug format |
Get a category
Section titled “Get a category”GET /api/v1/admin/content-categories/{slug}Path parameters: slug — dot-notation category slug.
Query parameters: org_id (UUID, optional) — fetch org-scoped override instead of global row.
Response 200 OK — returns category object. 404 if not found.
Update a category
Section titled “Update a category”PUT /api/v1/admin/content-categories/{slug}All request body fields are optional. Only provided fields are applied.
Builtin protection: On global rows (org_id IS NULL), only keywords and enabled are writable. Attempting to set name or description returns 422.
| Status | Description |
|---|---|
200 |
Updated successfully |
404 |
Category not found |
422 |
Attempted to modify immutable fields on a builtin |
Delete a category
Section titled “Delete a category”DELETE /api/v1/admin/content-categories/{slug}Behavior differs by row type:
- Builtin (
org_id IS NULL): soft-delete (setsenabled=false), returns200with updated body - Custom (
org_id IS NOT NULL): hard-delete, returns204 No Content
| Status | Description |
|---|---|
200 |
Builtin soft-deleted |
204 |
Custom category hard-deleted |
404 |
Category not found |
Category statistics
Section titled “Category statistics”GET /api/v1/admin/content-categories/statsReturns keyword count and enabled state for all global categories. No query parameters.
Response 200 OK
{ "total": 32, "stats": [ { "category_slug": "adult", "keyword_count": 3, "enabled": true }, { "category_slug": "adult.explicit", "keyword_count": 5, "enabled": true }, { "category_slug": "legal", "keyword_count": 6, "enabled": true } ]}Analytics dashboard API
Section titled “Analytics dashboard API”Summary metrics and breakdown endpoints for the platform admin analytics dashboard. All endpoints in this group are served by the Platform and require a Platform admin role Bearer JWT.
Base URL: https://platform.arbitex.ai
Authentication: Authorization: Bearer <platform-admin-jwt>
Endpoint summary
Section titled “Endpoint summary”| Method | Path | Description |
|---|---|---|
GET |
/api/v1/admin/analytics/summary |
High-level usage and security metrics |
GET |
/api/v1/admin/analytics/dlp-breakdown |
DLP event breakdown by entity type |
GET |
/api/v1/admin/analytics/top-users |
Top users by token consumption |
GET |
/api/v1/admin/analytics/model-usage |
Per-model usage breakdown |
Analytics summary
Section titled “Analytics summary”GET /api/v1/admin/analytics/summaryReturns high-level metrics for the specified time period, suitable for a top-of-dashboard summary view.
Query parameters
| Parameter | Type | Description |
|---|---|---|
period |
string | Time window: 24h, 7d, or 30d (default 24h) |
Request
curl "https://platform.arbitex.ai/api/v1/admin/analytics/summary?period=7d" \ -H "Authorization: Bearer eyJ..."Response 200 OK
| Field | Type | Description |
|---|---|---|
period |
string | The requested time window |
total_requests |
integer | Total API requests processed |
total_tokens |
integer | Total tokens consumed (input + output) |
active_users |
integer | Distinct users who made at least one request |
active_conversations |
integer | Distinct conversation sessions started |
dlp_triggers |
integer | Total DLP rule matches |
policy_blocks |
integer | Requests blocked by policy enforcement |
avg_latency_ms |
number | Average end-to-end request latency in milliseconds |
{ "period": "7d", "total_requests": 284931, "total_tokens": 91204840, "active_users": 1204, "active_conversations": 18742, "dlp_triggers": 3287, "policy_blocks": 512, "avg_latency_ms": 342.7}DLP event breakdown
Section titled “DLP event breakdown”GET /api/v1/admin/analytics/dlp-breakdownReturns DLP match counts broken down by entity type, with percentage share and trend data. Used to identify which entity types are generating the most DLP activity.
Query parameters
| Parameter | Type | Description |
|---|---|---|
period |
string | Time window: 24h, 7d, or 30d (default 30d) |
severity |
string | Filter by severity level: low, medium, high, critical |
Request
curl "https://platform.arbitex.ai/api/v1/admin/analytics/dlp-breakdown?period=30d&severity=high" \ -H "Authorization: Bearer eyJ..."Response 200 OK
{ "period": "30d", "generated_at": "2026-03-14T10:00:00Z", "items": [ { "entity_type": "US_SSN", "count": 1842, "percentage": 31.2, "trend": "up" }, { "entity_type": "CREDIT_CARD_NUMBER", "count": 1104, "percentage": 18.7, "trend": "stable" }, { "entity_type": "EMAIL_ADDRESS", "count": 873, "percentage": 14.8, "trend": "down" } ], "total_events": 5903}| Field | Type | Description |
|---|---|---|
items[].entity_type |
string | DLP entity type identifier |
items[].count |
integer | Number of DLP match events for this entity type |
items[].percentage |
number | Percentage of total DLP events |
items[].trend |
string | up, down, or stable vs. prior equivalent period |
total_events |
integer | Total DLP events in the period |
Top users by consumption
Section titled “Top users by consumption”GET /api/v1/admin/analytics/top-usersReturns the users with the highest token consumption for the specified period. Results are ordered by total_tokens descending.
Query parameters
| Parameter | Type | Description |
|---|---|---|
period |
string | Time window: 24h, 7d, or 30d (default 30d) |
limit |
integer | Number of users to return (default 10, max 100) |
Request
curl "https://platform.arbitex.ai/api/v1/admin/analytics/top-users?period=30d&limit=10" \ -H "Authorization: Bearer eyJ..."Response 200 OK
{ "period": "30d", "items": [ { "user_id": "usr_01HZ_ALICE", "total_tokens": 4820341, "request_count": 9204, "last_active": "2026-03-14T09:48:00Z" }, { "user_id": "usr_01HZ_BOB", "total_tokens": 3104892, "request_count": 6701, "last_active": "2026-03-14T08:15:00Z" } ]}| Field | Type | Description |
|---|---|---|
items[].user_id |
string | User UUID |
items[].email |
string | User email address |
items[].total_tokens |
integer | Total tokens consumed in the period |
items[].request_count |
integer | Total API requests in the period |
items[].last_active |
datetime | ISO 8601 timestamp of the most recent request |
Model usage breakdown
Section titled “Model usage breakdown”GET /api/v1/admin/analytics/model-usageReturns per-model usage statistics for the specified period, including token counts, request volume, latency, and error rate. Used to understand provider distribution and identify underperforming models.
Query parameters
| Parameter | Type | Description |
|---|---|---|
period |
string | Time window: 24h, 7d, or 30d (default 30d) |
provider |
string | Filter by provider name (e.g. openai, anthropic) |
Request
curl "https://platform.arbitex.ai/api/v1/admin/analytics/model-usage?period=7d&provider=anthropic" \ -H "Authorization: Bearer eyJ..."Response 200 OK
{ "period": "7d", "items": [ { "model_id": "claude-sonnet-4-6", "provider": "anthropic", "total_tokens": 28401920, "input_tokens": 19084201, "output_tokens": 9317719, "request_count": 47203, "avg_latency_ms": 318.4, "error_rate": 0.0021 }, { "model_id": "claude-opus-4-6", "provider": "anthropic", "total_tokens": 8204103, "input_tokens": 5841920, "output_tokens": 2362183, "request_count": 9841, "avg_latency_ms": 710.2, "error_rate": 0.0008 } ]}| Field | Type | Description |
|---|---|---|
items[].model_id |
string | Model identifier as used in API calls |
items[].provider |
string | Provider name |
items[].total_tokens |
integer | Total tokens consumed (input + output) |
items[].input_tokens |
integer | Input tokens consumed |
items[].output_tokens |
integer | Output tokens generated |
items[].request_count |
integer | Total requests routed to this model |
items[].avg_latency_ms |
number | Average end-to-end latency in milliseconds |
items[].error_rate |
number | Fraction of requests that returned an error (0.0–1.0) |
System configuration API
Section titled “System configuration API”Typed configuration key management for platform-wide settings. Configuration keys control DLP behavior, session handling, rate limits, and other platform parameters. All changes are recorded with the modifying user and timestamp.
Base URL: https://platform.arbitex.ai
Authentication: Authorization: Bearer <platform-admin-jwt>
Configuration types
Section titled “Configuration types”| Type | Description | Example value |
|---|---|---|
string |
Arbitrary text value | "redacted" |
integer |
Whole number | 1000 |
boolean |
true or false |
true |
json |
Arbitrary JSON object or array | {"key": "value"} |
duration |
Go duration string | "15m", "2h", "30s" |
Configuration object
Section titled “Configuration object”| Field | Type | Description |
|---|---|---|
key |
string | Dot-separated configuration key (e.g. dlp.scan_timeout) |
value |
any | Current value; type depends on the key’s declared type |
type |
string | Declared type: string, integer, boolean, json, or duration |
description |
string | Description of the key’s purpose and effect |
default_value |
any | Factory default value |
last_modified |
datetime | null | ISO 8601 timestamp of the most recent write; null if never modified |
modified_by |
string | null | Email of the user who last modified the key; null if never modified |
Endpoint summary
Section titled “Endpoint summary”| Method | Path | Description |
|---|---|---|
GET |
/api/v1/admin/config |
List all configuration keys |
GET |
/api/v1/admin/config/{key} |
Get a single configuration key |
PUT |
/api/v1/admin/config/{key} |
Update a configuration key |
POST |
/api/v1/admin/config/validate |
Dry-run validation without applying changes |
List configuration keys
Section titled “List configuration keys”GET /api/v1/admin/configReturns all configuration keys and their current values. Use the prefix query parameter to scope results to a specific subsystem.
Query parameters
| Parameter | Type | Description |
|---|---|---|
prefix |
string | Filter keys by dot-notation prefix (e.g. dlp., session., ratelimit.) |
Request
curl "https://platform.arbitex.ai/api/v1/admin/config?prefix=dlp." \ -H "Authorization: Bearer eyJ..."Response 200 OK
[ { "key": "dlp.scan_timeout", "value": "5s", "type": "duration", "description": "Maximum time allowed for a single DLP scan before the request is failed-open or failed-closed per dlp.fail_mode.", "default_value": "5s", "last_modified": null, "modified_by": null }, { "key": "dlp.fail_mode", "value": "closed", "type": "string", "description": "Behavior when a DLP scan times out or errors. 'closed' blocks the request; 'open' allows it through.", "default_value": "closed", "last_modified": "2026-02-10T14:22:00Z", }, { "key": "dlp.max_body_bytes", "value": 262144, "type": "integer", "description": "Maximum request body size in bytes submitted for DLP scanning. Bodies exceeding this limit are truncated.", "default_value": 262144, "last_modified": null, "modified_by": null }]Get a configuration key
Section titled “Get a configuration key”GET /api/v1/admin/config/{key}Returns a single configuration key and its current value.
Path parameters
| Parameter | Description |
|---|---|
key |
Dot-separated configuration key (e.g. dlp.fail_mode) |
Request
curl "https://platform.arbitex.ai/api/v1/admin/config/dlp.fail_mode" \ -H "Authorization: Bearer eyJ..."Response 200 OK
{ "key": "dlp.fail_mode", "value": "closed", "type": "string", "description": "Behavior when a DLP scan times out or errors. 'closed' blocks the request; 'open' allows it through.", "default_value": "closed", "last_modified": "2026-02-10T14:22:00Z",}Error responses
| Status | Description |
|---|---|
404 |
Unknown configuration key |
Update a configuration key
Section titled “Update a configuration key”PUT /api/v1/admin/config/{key}Updates the value of a configuration key. The value is validated against the key’s declared type before being applied. Updates are applied immediately and take effect on the next request processed by the platform.
Path parameters
| Parameter | Description |
|---|---|
key |
Dot-separated configuration key |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
value |
any | Yes | New value for the key. Must match the key’s declared type. |
Request
curl -X PUT "https://platform.arbitex.ai/api/v1/admin/config/dlp.scan_timeout" \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{ "value": "10s" }'Response 200 OK
{ "key": "dlp.scan_timeout", "value": "10s", "type": "duration", "description": "Maximum time allowed for a single DLP scan before the request is failed-open or failed-closed per dlp.fail_mode.", "default_value": "5s", "last_modified": "2026-03-14T10:00:00Z",}Error responses
| Status | Description |
|---|---|
404 |
Unknown configuration key |
422 |
Value does not match the key’s declared type, or fails range/constraint validation |
Validate a configuration value
Section titled “Validate a configuration value”POST /api/v1/admin/config/validatePerforms a dry-run validation of a proposed key-value pair. Type checking and constraint validation are applied but no state is modified. Use this endpoint before applying a change in automation pipelines.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
key |
string | Yes | Configuration key to validate against |
value |
any | Yes | Proposed value to validate |
Request
curl -X POST "https://platform.arbitex.ai/api/v1/admin/config/validate" \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{ "key": "dlp.scan_timeout", "value": "not-a-duration" }'Response 200 OK
{ "valid": false, "errors": [ "value 'not-a-duration' is not a valid duration string; expected format like '5s', '1m30s', or '2h'" ]}A valid value returns:
{ "valid": true, "errors": []}| Field | Type | Description |
|---|---|---|
valid |
boolean | true if the value passes all type and constraint checks |
errors |
array of string | Human-readable validation error messages; empty when valid is true |
Error responses
| Status | Description |
|---|---|
404 |
Unknown configuration key — validation cannot be performed |
See also
Section titled “See also”- Admin operations API reference — configuration import and restore, webhook management, software updates, and MRM model registry
- DLP API reference — DLP rule management and scan endpoints
- Policy engine API reference — policy rule and bundle management
- Usage API reference — token usage, quotas, and billing data