Admin operations API
This page documents administrative API endpoints across the Platform, Cloud Portal, and Outpost services. These endpoints are intended for operators and automation tooling performing organization configuration management, event integration, software lifecycle control, observability provisioning, and model governance. Authentication requirements vary by endpoint group and are detailed in each section.
Configuration import and restore
Section titled “Configuration import and restore”These endpoints allow operators to export, import, and roll back organization DLP configuration.
Scope: Only DLP rules are included in exports and imports. Users, billing settings, and SSO configuration are explicitly out of scope and are never written or overwritten by these endpoints.
Endpoint summary
Section titled “Endpoint summary”| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/v1/orgs/{org_id}/config/export |
Admin API key | Export current DLP configuration |
POST |
/v1/orgs/{org_id}/config/import |
Org Bearer JWT | Import a configuration snapshot |
POST |
/v1/orgs/{org_id}/config/rollback |
Org Bearer JWT | Restore from the last import snapshot |
Export configuration
Section titled “Export configuration”GET /v1/orgs/{org_id}/config/exportProxies to Platform and returns the current DLP configuration as a JSON export document. The response can be saved and used as the request body for POST /v1/orgs/{org_id}/config/import.
Authentication: Admin API key (X-API-Key)
Path parameters
| Parameter | Description |
|---|---|
org_id |
Organization UUID |
Request
curl "https://cloud.arbitex.ai/v1/orgs/org_01HZ_ACME/config/export" \ -H "X-API-Key: arb_your_admin_api_key"Response 200 OK
{ "schema_version": "2.0", "exported_at": "2026-03-14T10:00:00Z", "org_id": "org_01HZ_ACME", "config": { "dlp_rules": [ { "id": "rule_01HZ_SSN", "name": "SSN Detection", "entity_types": ["US_SSN"], "action": "block", "enabled": true } ] }}Error responses
| Status | Description |
|---|---|
404 |
Organization not found |
502 |
Platform upstream error |
503 |
Platform service unavailable |
Import configuration
Section titled “Import configuration”POST /v1/orgs/{org_id}/config/importApplies a configuration snapshot to the organization. Before applying any changes, the service saves the current configuration as an import snapshot (enabling rollback). Import results report how many rules were created or updated, and list any validation errors.
Authentication: Org Bearer JWT. IDOR check is enforced — the JWT org_id claim must match the org_id path parameter.
Path parameters
| Parameter | Description |
|---|---|
org_id |
Organization UUID |
Request body — ConfigImportRequest
| Field | Type | Required | Description |
|---|---|---|---|
schema_version |
string | Yes | Must be one of: "1.0", "1.0.0", "2.0", "2.0.0" |
exported_at |
datetime | Yes | ISO 8601 timestamp from the original export |
org_id |
string | Yes | Organization UUID — must match the path parameter |
config.dlp_rules |
array | Yes | Array of DLP rule objects to import |
Request
curl -X POST "https://cloud.arbitex.ai/v1/orgs/org_01HZ_ACME/config/import" \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{ "schema_version": "2.0", "exported_at": "2026-03-14T10:00:00Z", "org_id": "org_01HZ_ACME", "config": { "dlp_rules": [ { "name": "SSN Detection", "entity_types": ["US_SSN"], "action": "block", "enabled": true } ] } }'Response 200 OK — ConfigImportResult
| Field | Type | Description |
|---|---|---|
imported_dlp_rules |
integer | Count of newly created DLP rules |
updated_dlp_rules |
integer | Count of existing DLP rules updated |
imported_policy_rules |
integer | Count of policy rules imported (if applicable) |
updated_settings |
integer | Count of settings updated |
errors |
array | Validation errors encountered; partial imports may succeed |
snapshot_saved |
boolean | Whether the pre-import snapshot was saved for rollback |
{ "imported_dlp_rules": 3, "updated_dlp_rules": 1, "imported_policy_rules": 0, "updated_settings": 0, "errors": [], "snapshot_saved": true}Error responses
| Status | Description |
|---|---|
403 |
JWT org claim does not match path org_id (IDOR check failed) |
404 |
Organization not found |
422 |
Request body validation failed (invalid schema_version, malformed rules, etc.) |
Rollback configuration
Section titled “Rollback configuration”POST /v1/orgs/{org_id}/config/rollbackRestores the organization’s DLP configuration from the snapshot saved by the most recent import operation. The snapshot is cleared after a successful rollback; a second rollback without an intervening import will fail with 400.
Authentication: Org Bearer JWT. IDOR check enforced.
Path parameters
| Parameter | Description |
|---|---|
org_id |
Organization UUID |
Request body
No request body required.
Request
curl -X POST "https://cloud.arbitex.ai/v1/orgs/org_01HZ_ACME/config/rollback" \ -H "Authorization: Bearer eyJ..."Response 200 OK — ConfigRollbackResponse
| Field | Type | Description |
|---|---|---|
success |
boolean | true if rollback completed without errors |
restored_sections |
array of string | Sections restored (e.g. ["dlp_rules"]) |
message |
string | Human-readable summary |
{ "success": true, "restored_sections": ["dlp_rules"], "message": "Configuration restored from import snapshot taken at 2026-03-14T10:00:00Z"}Error responses
| Status | Description |
|---|---|
400 |
No import snapshot available to roll back to |
403 |
JWT org claim does not match path org_id |
404 |
Organization not found |
422 |
Snapshot data failed validation on restore |
Webhook management and delivery history
Section titled “Webhook management and delivery history”All endpoints in this group required an Org Bearer JWT with an IDOR check — the JWT org_id claim must match the path org_id.
Signing: Outbound webhook requests are signed using HMAC-SHA256 computed over the request body using the webhook’s configured secret. The signature is delivered in the X-Arbitex-Signature header.
Event types
Section titled “Event types”| Event | Description |
|---|---|
new_conversation |
A new conversation session was started |
dlp_trigger |
A DLP rule fired and blocked or flagged a message |
quota_exceeded |
An organization quota threshold was crossed |
bundle_state_change |
A policy bundle transitioned state |
Endpoint summary
Section titled “Endpoint summary”| Method | Path | Description |
|---|---|---|
GET |
/v1/orgs/{org_id}/webhooks |
List webhooks with delivery statistics |
POST |
/v1/orgs/{org_id}/webhooks |
Create a webhook |
PUT |
/v1/orgs/{org_id}/webhooks/{webhook_id} |
Update a webhook |
DELETE |
/v1/orgs/{org_id}/webhooks/{webhook_id} |
Delete a webhook |
POST |
/v1/orgs/{org_id}/webhooks/{webhook_id}/test |
Send a test delivery |
GET |
/v1/orgs/{org_id}/webhooks/deliveries |
List recent delivery logs |
POST |
/v1/orgs/{org_id}/webhooks/deliveries/{delivery_id}/retry |
Retry a dead-letter delivery |
GET |
/v1/orgs/{org_id}/webhooks/{webhook_id}/health |
Probe webhook endpoint reachability |
GET |
/v1/orgs/{org_id}/webhooks/retry-policy |
Get current retry policy |
POST |
/v1/orgs/{org_id}/webhooks/retry-policy |
Update retry policy |
List webhooks
Section titled “List webhooks”GET /v1/orgs/{org_id}/webhooksReturns all configured webhooks for the organization, including delivery statistics.
Request
curl "https://cloud.arbitex.ai/v1/orgs/org_01HZ_ACME/webhooks" \ -H "Authorization: Bearer eyJ..."Response 200 OK
[ { "id": "wh_01HZ_MAIN", "org_id": "org_01HZ_ACME", "url": "https://hooks.example.com/arbitex", "events": ["dlp_trigger", "quota_exceeded"], "enabled": true, "created_at": "2026-02-01T09:00:00Z", "delivery_stats": { "delivered": 142, "failed": 3, "dead_letter": 1 } }]Create a webhook
Section titled “Create a webhook”POST /v1/orgs/{org_id}/webhooksRegisters a new webhook endpoint for the organization.
Request body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
url |
string | Yes | max 2048 chars, must be HTTPS | Destination URL for webhook deliveries |
events |
array of string | Yes | valid event type values | Event types to subscribe to |
secret |
string | No | max 256 chars | HMAC-SHA256 signing secret |
enabled |
boolean | No | defaults to true |
Whether deliveries are active |
Request
curl -X POST "https://cloud.arbitex.ai/v1/orgs/org_01HZ_ACME/webhooks" \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://hooks.example.com/arbitex", "events": ["dlp_trigger", "quota_exceeded"], "secret": "my-signing-secret" }'Response 201 Created
{ "id": "wh_01HZ_MAIN", "org_id": "org_01HZ_ACME", "url": "https://hooks.example.com/arbitex", "events": ["dlp_trigger", "quota_exceeded"], "enabled": true, "created_at": "2026-03-14T10:00:00Z"}Error responses
| Status | Description |
|---|---|
403 |
IDOR check failed |
422 |
Invalid URL, unknown event type, or constraint violation |
Update a webhook
Section titled “Update a webhook”PUT /v1/orgs/{org_id}/webhooks/{webhook_id}Updates an existing webhook. All fields are optional; only supplied fields are changed.
Path parameters
| Parameter | Description |
|---|---|
org_id |
Organization UUID |
webhook_id |
Webhook UUID |
Request body — all fields optional
| Field | Type | Constraints |
|---|---|---|
url |
string | max 2048 chars |
events |
array of string | valid event type values |
secret |
string | max 256 chars |
enabled |
boolean | — |
Error responses
| Status | Description |
|---|---|
403 |
IDOR check failed |
404 |
Webhook not found |
422 |
Validation error |
Delete a webhook
Section titled “Delete a webhook”DELETE /v1/orgs/{org_id}/webhooks/{webhook_id}Permanently removes a webhook and stops all future deliveries.
Response 204 No Content
Error responses
| Status | Description |
|---|---|
403 |
IDOR check failed |
404 |
Webhook not found |
Send a test delivery
Section titled “Send a test delivery”POST /v1/orgs/{org_id}/webhooks/{webhook_id}/testImmediately sends a test payload to the webhook URL and reports the result. Does not create a delivery log entry.
Response 200 OK
{ "status": "delivered", "status_code": 200, "response_time_ms": 142}Error responses
| Status | Description |
|---|---|
404 |
Webhook not found |
List delivery logs
Section titled “List delivery logs”GET /v1/orgs/{org_id}/webhooks/deliveriesReturns the 50 most recent delivery log entries across all webhooks for the organization.
Delivery status values
| Status | Description |
|---|---|
pending |
Queued but not yet attempted |
delivered |
Successfully acknowledged by the destination |
failed |
Attempt failed; further retries may occur per retry policy |
dead_letter |
All retry attempts exhausted; manual retry required |
Response 200 OK
[ { "id": "del_01HZ_ABC", "webhook_id": "wh_01HZ_MAIN", "event": "dlp_trigger", "status": "delivered", "attempt_count": 1, "response_code": 200, "error_message": null, "created_at": "2026-03-14T09:55:00Z", "last_attempted_at": "2026-03-14T09:55:01Z" }, { "id": "del_01HZ_DEF", "webhook_id": "wh_01HZ_MAIN", "event": "quota_exceeded", "status": "dead_letter", "attempt_count": 3, "response_code": 503, "error_message": "upstream connect error", "created_at": "2026-03-13T18:00:00Z", "last_attempted_at": "2026-03-13T18:05:00Z" }]Retry a dead-letter delivery
Section titled “Retry a dead-letter delivery”POST /v1/orgs/{org_id}/webhooks/deliveries/{delivery_id}/retryRe-queues a delivery that is in dead_letter status for a new delivery attempt. Returns 409 if the delivery is in any other status.
Response 200 OK
{ "id": "del_01HZ_DEF", "status": "pending"}Error responses
| Status | Description |
|---|---|
404 |
Delivery not found |
409 |
Delivery is not in dead_letter status |
Check webhook health
Section titled “Check webhook health”GET /v1/orgs/{org_id}/webhooks/{webhook_id}/healthPerforms an HTTP HEAD probe against the configured webhook URL and reports reachability. The probe has a 10-second timeout.
Response 200 OK
{ "reachable": true, "status_code": 200, "response_time_ms": 87}If the probe times out or the host is unreachable, reachable is false and status_code may be null.
Error responses
| Status | Description |
|---|---|
404 |
Webhook not found |
Get retry policy
Section titled “Get retry policy”GET /v1/orgs/{org_id}/webhooks/retry-policyReturns the current webhook retry policy for the organization.
Response 200 OK
{ "max_retries": 3, "backoff_base": 1, "timeout_seconds": 10}| Field | Type | Default | Description |
|---|---|---|---|
max_retries |
integer | 3 |
Maximum number of delivery attempts before dead-lettering |
backoff_base |
integer | 1 |
Base delay in seconds between retry attempts (exponential backoff) |
timeout_seconds |
integer | 10 |
Per-attempt delivery timeout in seconds |
Update retry policy
Section titled “Update retry policy”POST /v1/orgs/{org_id}/webhooks/retry-policyUpdates the webhook retry policy. All fields are required.
Request body
| Field | Type | Constraints | Description |
|---|---|---|---|
max_retries |
integer | 1–10 | Maximum delivery attempts |
backoff_base |
integer | 1–60 | Base delay in seconds |
timeout_seconds |
integer | 5–120 | Per-attempt timeout in seconds |
Request
curl -X POST "https://cloud.arbitex.ai/v1/orgs/org_01HZ_ACME/webhooks/retry-policy" \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{ "max_retries": 5, "backoff_base": 2, "timeout_seconds": 30 }'Response 200 OK
{ "max_retries": 5, "backoff_base": 2, "timeout_seconds": 30}Error responses
| Status | Description |
|---|---|
403 |
IDOR check failed |
422 |
Field value outside permitted range |
Software update check and apply (Outpost)
Section titled “Software update check and apply (Outpost)”The Outpost admin API exposes software update lifecycle management on port 8301. These endpoints allow operators to check for new Outpost releases, download and verify update bundles, and stage them for application. All endpoints require a Bearer admin key.
Base URL: http://<outpost-host>:8301
Authentication: Authorization: Bearer <admin-key>
Update status values
Section titled “Update status values”| Status | Description |
|---|---|
idle |
No update operation in progress |
checking |
Fetching release manifest from the configured release URL |
available |
A newer version has been found and is ready to download |
downloading |
Bundle download and verification in progress |
staged |
Bundle downloaded, verified, and extracted — ready for operator-initiated restart |
verify_failed |
Signature or HMAC verification of the downloaded bundle failed |
error |
A non-verification error occurred during the update process |
disabled |
SOFTWARE_UPDATE_RELEASE_URL is not set; update operations are unavailable |
Configuration environment variables
Section titled “Configuration environment variables”| Variable | Description |
|---|---|
SOFTWARE_UPDATE_RELEASE_URL |
URL of the release manifest JSON. Required to enable software updates. |
SOFTWARE_UPDATE_ED25519_KEY |
Ed25519 public key for primary bundle signature verification |
SOFTWARE_UPDATE_SIGNING_KEY |
Alias for SOFTWARE_UPDATE_ED25519_KEY |
POLICY_HMAC_KEY |
HMAC-SHA256 key used as fallback verification when Ed25519 is not configured |
UPDATE_STAGE_DIR |
Directory for extracted update bundles (default: /tmp/outpost-update-stage) |
Endpoint summary
Section titled “Endpoint summary”| Method | Path | Description |
|---|---|---|
GET |
/admin/api/updates/status |
Get current update status |
POST |
/admin/api/updates/check |
Fetch release manifest and check for new version |
POST |
/admin/api/updates/download |
Download, verify, and stage the available update bundle |
Get update status
Section titled “Get update status”GET /admin/api/updates/statusReturns the current state of the software update process, including version information and staged bundle details.
Request
curl "http://outpost.internal:8301/admin/api/updates/status" \ -H "Authorization: Bearer your-admin-key"Response 200 OK
| Field | Type | Description |
|---|---|---|
status |
string | Current update status (see status table above) |
current_version |
string | Running Outpost version |
latest_version |
string | null | Latest available version from manifest, if checked |
release_notes |
string | null | Release notes from the manifest |
download_progress |
number | null | Download progress 0–100 during downloading status |
staged_at |
datetime | null | ISO 8601 timestamp when bundle was staged |
staged_version |
string | null | Version string of the staged bundle |
staged_path |
string | null | Filesystem path of the staged bundle archive |
extracted_path |
string | null | Filesystem path of the extracted bundle |
signature_verified |
boolean | null | Whether Ed25519 or HMAC signature verification passed |
error |
string | null | Error detail when status is error or verify_failed |
{ "status": "staged", "current_version": "1.4.2", "latest_version": "1.5.0", "release_notes": "Outpost 1.5.0: improved DLP throughput, TLS 1.3 enforcement.", "download_progress": null, "staged_at": "2026-03-14T08:30:00Z", "staged_version": "1.5.0", "staged_path": "/tmp/outpost-update-stage/1.5.0/outpost-1.5.0.tar.gz", "extracted_path": "/tmp/outpost-update-stage/1.5.0/", "signature_verified": true, "error": null}Check for updates
Section titled “Check for updates”POST /admin/api/updates/checkFetches the release manifest from SOFTWARE_UPDATE_RELEASE_URL and compares the manifest version against the running version. Sets status to available if a newer version is found.
Release manifest format
The manifest JSON served at SOFTWARE_UPDATE_RELEASE_URL must conform to:
{ "version": "1.5.0", "download_url": "https://releases.arbitex.ai/outpost/outpost-1.5.0.tar.gz", "signature_url": "https://releases.arbitex.ai/outpost/outpost-1.5.0.tar.gz.sig", "release_notes": "Outpost 1.5.0: improved DLP throughput, TLS 1.3 enforcement.", "hmac_signature": "sha256=abc123..."}Request
curl -X POST "http://outpost.internal:8301/admin/api/updates/check" \ -H "Authorization: Bearer your-admin-key"Response 200 OK
{ "status": "available", "current_version": "1.4.2", "latest_version": "1.5.0", "release_notes": "Outpost 1.5.0: improved DLP throughput, TLS 1.3 enforcement."}If SOFTWARE_UPDATE_RELEASE_URL is not configured, the response returns "status": "disabled".
Download and stage update
Section titled “Download and stage update”POST /admin/api/updates/downloadDownloads the update bundle from the URL in the manifest, verifies its integrity, extracts it to UPDATE_STAGE_DIR/<version>/, and sets status to staged.
Verification priority (fail-closed)
The service applies verification in strict priority order and rejects the bundle if no configured method passes:
- Ed25519 primary — if
SOFTWARE_UPDATE_ED25519_KEYis set, downloads the.sigfile fromsignature_urland verifies the Ed25519 signature over the bundle. - HMAC-SHA256 fallback — if Ed25519 is not configured but
POLICY_HMAC_KEYis set, verifies thehmac_signaturefield from the manifest. - Reject — if neither key is configured, the download is rejected. No unverified bundle is staged.
Applying the update
There is no auto-apply mechanism. To apply a staged update, restart the Outpost container. The process will load the staged bundle from extracted_path on startup.
Air-gap environments
In air-gapped deployments, place the bundle archive (.tar.gz) and its signature file (.sig) directly in UPDATE_STAGE_DIR. The service detects the pre-staged files, runs Ed25519 verification, and extracts in place.
Request
curl -X POST "http://outpost.internal:8301/admin/api/updates/download" \ -H "Authorization: Bearer your-admin-key"Response 200 OK
{ "status": "staged", "staged_version": "1.5.0", "staged_path": "/tmp/outpost-update-stage/1.5.0/outpost-1.5.0.tar.gz", "extracted_path": "/tmp/outpost-update-stage/1.5.0/", "signature_verified": true}Error responses
| Status | Description |
|---|---|
400 |
No update available — run POST /admin/api/updates/check first |
409 |
A download is already in progress |
422 |
Bundle verification failed (verify_failed status set) |
Grafana dashboard provisioning
Section titled “Grafana dashboard provisioning”Arbitex provides pre-built Grafana dashboards for operational observability. There is no Platform API endpoint for dashboard provisioning — dashboards are static JSON files distributed with the Arbitex deployment package and are imported using Grafana’s native mechanisms.
Requirements:
- Grafana 10.0 or later
- A Prometheus datasource configured with the template variable
DS_PROMETHEUS
Available dashboards
Section titled “Available dashboards”Dashboards are located in deploy/grafana/ in the Arbitex distribution package.
| Dashboard | UID | Description |
|---|---|---|
| System Health | arbitex-system-health |
HTTP request rate, latency percentiles, error rate, active connections |
| Provider Performance | arbitex-provider-performance |
Per-provider latency, error rates, token throughput, model distribution |
| DLP Analysis | arbitex-dlp-analysis |
DLP scan latency, trigger rates, entity types, scan throughput |
| Usage and Billing | arbitex-usage-billing |
Token usage, per-model breakdown, budget utilization, rate limits |
| Security Events | arbitex-security-events |
Auth failures, rate limit rejections, mTLS failures, IP blocks, anonymous IP detections |
| Compliance Status | arbitex-compliance-status |
Policy violations, audit chain integrity, framework coverage |
Import methods
Section titled “Import methods”Grafana UI
Section titled “Grafana UI”Navigate to Dashboards → Import → Upload JSON file in the Grafana web interface. Select the JSON file from deploy/grafana/ and confirm the DS_PROMETHEUS datasource mapping.
Grafana HTTP API
Section titled “Grafana HTTP API”curl -X POST "https://grafana.example.com/api/dashboards/import" \ -H "Authorization: Bearer <grafana-admin-token>" \ -H "Content-Type: application/json" \ -d '{ "dashboard": <contents of dashboard JSON file>, "overwrite": true, "inputs": [ { "name": "DS_PROMETHEUS", "type": "datasource", "pluginId": "prometheus", "value": "Prometheus" } ] }'The Authorization header requires a Grafana admin service account token — it is not a Platform credential and cannot be substituted with an Arbitex API key.
File-based provisioning
Section titled “File-based provisioning”Place the dashboard JSON files in the Grafana provisioning directory (typically /etc/grafana/provisioning/dashboards/). Grafana picks up new or updated files on the configured provisioning interval. Refer to the Grafana provisioning documentation for directory structure and provider configuration.
Prometheus scrape configuration
Section titled “Prometheus scrape configuration”Platform exposes a metrics endpoint at GET /metrics (unauthenticated). Configure Prometheus to scrape this endpoint:
scrape_configs: - job_name: arbitex-platform static_configs: - targets: - platform.arbitex.internal:8080 metrics_path: /metrics scrape_interval: 30s scrape_timeout: 10sFor Kubernetes deployments, use a ServiceMonitor resource:
apiVersion: monitoring.coreos.com/v1kind: ServiceMonitormetadata: name: arbitex-platform namespace: monitoringspec: selector: matchLabels: app: arbitex-platform endpoints: - port: http path: /metrics interval: 30s scrapeTimeout: 10sMRM model registry
Section titled “MRM model registry”The Model Risk Management (MRM) registry tracks AI model usage across the organization for governance, validation, and regulatory compliance purposes. Served by the Platform at its admin API. Auth: Platform admin role Bearer JWT.
Regulatory context: The MRM registry supports compliance with OCC SR 11-7, Fed SR 15-18, and FDIC FIL-22-2017 model risk management guidance.
Risk tiers
Section titled “Risk tiers”| Tier | Description |
|---|---|
unclassified |
Risk level not yet assessed |
critical |
Highest organizational risk; requires full validation and documented controls |
high |
Significant risk; requires validation and approval before production use |
medium |
Moderate risk; review recommended |
low |
Minimal risk; standard monitoring applies |
Validation statuses
Section titled “Validation statuses”| Status | Description |
|---|---|
unclassified |
Validation not yet initiated |
under_review |
Active validation in progress |
approved |
Validated and approved for production use |
conditional |
Approved with documented restrictions or conditions |
deprecated |
Model is no longer approved; existing usage should be migrated |
Status transition state machine
Section titled “Status transition state machine”unclassified ──→ under_review ──→ approved │ │ └──→ unclassified (reverted)
approved ──→ deprecatedapproved ──→ conditional
conditional ──→ approvedconditional ──→ deprecated
deprecated ──→ under_review (reactivation)All status transitions are recorded as immutable ModelApprovalLog entries.
Endpoint summary
Section titled “Endpoint summary”| Method | Path | Description |
|---|---|---|
GET |
/api/v1/admin/models |
List model registry entries |
POST |
/api/v1/admin/models |
Create a registry entry |
POST |
/api/v1/admin/models/discover |
Auto-discover models from audit log |
GET |
/api/v1/admin/models/{entry_id} |
Get a registry entry |
PUT |
/api/v1/admin/models/{entry_id} |
Update a registry entry |
DELETE |
/api/v1/admin/models/{entry_id} |
Delete a registry entry |
POST |
/api/v1/admin/models/{entry_id}/status |
Record a status transition |
GET |
/api/v1/admin/models/{entry_id}/status/history |
Get status transition history |
List model registry entries
Section titled “List model registry entries”GET /api/v1/admin/modelsReturns a paginated list of model registry entries. All filter parameters are optional.
Query parameters
| Parameter | Type | Description |
|---|---|---|
risk_tier |
string | Filter by risk tier |
validation_status |
string | Filter by validation status |
provider |
string | Filter by provider name |
limit |
integer | Results per page (1–500) |
offset |
integer | Pagination offset |
Request
curl "https://platform.arbitex.ai/api/v1/admin/models?risk_tier=high&limit=50" \ -H "Authorization: Bearer eyJ..."Response 200 OK
{ "items": [ { "id": "mrm_01HZ_GPT4O", "model_id": "gpt-4o", "provider": "openai", "display_name": "GPT-4o", "risk_tier": "high", "validation_status": "approved", "description": "General purpose instruction-following model.", "approved_use_cases": ["customer-support", "internal-search"], "restrictions": { "max_context_tokens": 16384, "pii_allowed": false }, "created_at": "2026-01-15T09:00:00Z", "updated_at": "2026-02-20T14:00:00Z" } ], "total": 1, "limit": 50, "offset": 0}Create a registry entry
Section titled “Create a registry entry”POST /api/v1/admin/modelsCreates a new model registry entry. The (model_id, provider) pair must be unique.
Request body
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
model_id |
string | Yes | max 256 chars | Model identifier as used in API calls |
provider |
string | Yes | max 64 chars | Provider name (e.g. openai, anthropic) |
display_name |
string | No | — | Human-readable name |
risk_tier |
string | No | valid risk tier | Defaults to unclassified |
validation_status |
string | No | valid status | Defaults to unclassified |
owner |
string | No | — | Responsible team or individual |
description |
string | No | — | Free-text description |
approved_use_cases |
array of string | No | — | List of approved use case identifiers |
restrictions |
object | No | — | Key-value restrictions applied to this model |
Request
curl -X POST "https://platform.arbitex.ai/api/v1/admin/models" \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{ "model_id": "claude-sonnet-4-6", "provider": "anthropic", "display_name": "Claude Sonnet 4.6", "risk_tier": "high", "validation_status": "under_review", "owner": "[email protected]", "approved_use_cases": ["document-review"], "restrictions": { "pii_allowed": false } }'Response 201 Created
{ "id": "mrm_01HZ_SONNET", "model_id": "claude-sonnet-4-6", "provider": "anthropic", "display_name": "Claude Sonnet 4.6", "risk_tier": "high", "validation_status": "under_review", "description": null, "approved_use_cases": ["document-review"], "restrictions": { "pii_allowed": false }, "created_at": "2026-03-14T10:00:00Z", "updated_at": "2026-03-14T10:00:00Z"}Error responses
| Status | Description |
|---|---|
409 |
A registry entry for (model_id, provider) already exists |
422 |
Validation error (unknown risk tier, status value, or constraint exceeded) |
Auto-discover models
Section titled “Auto-discover models”POST /api/v1/admin/models/discoverScans the Platform audit log for (model_id, provider) pairs that do not yet have a registry entry and creates unclassified entries for each. This is the recommended starting point for bootstrapping the registry.
Request
curl -X POST "https://platform.arbitex.ai/api/v1/admin/models/discover" \ -H "Authorization: Bearer eyJ..."Response 200 OK
| Field | Type | Description |
|---|---|---|
discovered |
integer | Count of new registry entries created |
already_registered |
integer | Count of audit log pairs already in the registry |
entries |
array | Newly created registry entry objects |
{ "discovered": 2, "already_registered": 5, "entries": [ { "id": "mrm_01HZ_NEW1", "model_id": "gpt-4o-mini", "provider": "openai", "risk_tier": "unclassified", "validation_status": "unclassified", "created_at": "2026-03-14T10:00:00Z" } ]}Get a registry entry
Section titled “Get a registry entry”GET /api/v1/admin/models/{entry_id}Returns a single model registry entry.
Path parameters
| Parameter | Description |
|---|---|
entry_id |
Registry entry UUID |
Error responses
| Status | Description |
|---|---|
404 |
Entry not found |
Update a registry entry
Section titled “Update a registry entry”PUT /api/v1/admin/models/{entry_id}Updates a registry entry. This endpoint uses patch semantics — only supplied fields are changed. model_id and provider are immutable after creation.
Request body — all fields optional except as noted
| Field | Type | Description |
|---|---|---|
display_name |
string | Human-readable name |
risk_tier |
string | Updated risk tier |
validation_status |
string | Updated validation status — use POST /{entry_id}/status for logged transitions |
owner |
string | Responsible team or individual |
description |
string | Free-text description |
approved_use_cases |
array of string | Replaces the full list |
restrictions |
object | Replaces the full restrictions map |
Error responses
| Status | Description |
|---|---|
404 |
Entry not found |
422 |
Attempt to modify model_id or provider, or invalid field value |
Delete a registry entry
Section titled “Delete a registry entry”DELETE /api/v1/admin/models/{entry_id}Permanently removes a registry entry and its associated approval log history.
Response 204 No Content
Error responses
| Status | Description |
|---|---|
404 |
Entry not found |
Record a status transition
Section titled “Record a status transition”POST /api/v1/admin/models/{entry_id}/statusRecords a formal status transition for a registry entry. Validates the transition against the state machine and writes an immutable ModelApprovalLog entry. Use this endpoint for all audit-tracked status changes; direct field updates via PUT do not create log entries.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
status |
string | Yes | Target validation status |
reason |
string | Yes | Justification for the transition — recorded in the approval log |
Request
curl -X POST \ "https://platform.arbitex.ai/api/v1/admin/models/mrm_01HZ_SONNET/status" \ -H "Authorization: Bearer eyJ..." \ -H "Content-Type: application/json" \ -d '{ "status": "approved", "reason": "Validation complete. No high-risk findings. Approved for document-review use case." }'Response 200 OK
{ "entry": { "id": "mrm_01HZ_SONNET", "model_id": "claude-sonnet-4-6", "provider": "anthropic", "validation_status": "approved", "updated_at": "2026-03-14T11:00:00Z" }, "log": { "id": "apl_01HZ_LOG1", "entry_id": "mrm_01HZ_SONNET", "from_status": "under_review", "to_status": "approved", "reason": "Validation complete. No high-risk findings. Approved for document-review use case.", "changed_at": "2026-03-14T11:00:00Z" }}Error responses
| Status | Description |
|---|---|
404 |
Entry not found |
409 |
Entry is already in the requested status |
422 |
Transition is not permitted by the state machine |
Get status history
Section titled “Get status history”GET /api/v1/admin/models/{entry_id}/status/historyReturns the full approval log for a registry entry, ordered by changed_at descending.
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit |
integer | Results per page (1–500) |
offset |
integer | Pagination offset |
Response 200 OK
{ "items": [ { "id": "apl_01HZ_LOG1", "entry_id": "mrm_01HZ_SONNET", "from_status": "under_review", "to_status": "approved", "reason": "Validation complete. No high-risk findings. Approved for document-review use case.", "changed_at": "2026-03-14T11:00:00Z" }, { "id": "apl_01HZ_LOG0", "entry_id": "mrm_01HZ_SONNET", "from_status": "unclassified", "to_status": "under_review", "reason": "Initiating validation for document-review use case.", "changed_at": "2026-03-01T09:00:00Z" } ], "total": 2, "limit": 500, "offset": 0}Error responses
| Status | Description |
|---|---|
404 |
Entry not found |
See also
Section titled “See also”- Cloud Outpost API reference — outpost registration, heartbeat, and certificate lifecycle
- 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