The Deliberate Admin REST API lets you manage policies, approvers, groups, and API keys programmatically — without editing YAML files. All admin endpoints require an API key with the appropriate scope passed in the X-Deliberate-API-Key header.
For scope definitions and role bundles see RBAC and API Key Management.
Every admin API request must include:
X-Deliberate-API-Key: dlb_ak_<your-key>
The bootstrap admin key (ADMIN_BOOTSTRAP_KEY env var) has full admin access and can be used to create scoped keys for other services.
Error responses:
| Status | Meaning |
|---|---|
| 401 | Missing or invalid API key |
| 403 | Key does not have the required scope |
| 404 | Resource not found |
| 409 | Conflict (duplicate ID) |
| 422 | Request body validation failed |
Create a new policy. Required scope: policies:write.
curl -X POST http://localhost:4000/policies \
-H "X-Deliberate-API-Key: dlb_ak_..." \
-H "Content-Type: application/json" \
-d '{
"name": "refund_approval",
"matches": {
"layout": "financial_decision"
},
"rules": [
{
"name": "auto_approve_small",
"when": "amount.value < 100",
"action": "auto_approve",
"rationale": "Below auto-approve threshold"
},
{
"name": "standard",
"when": "amount.value >= 100 and amount.value < 5000",
"approvers": { "any_of": ["finance_lead"] },
"timeout": "4h",
"on_timeout": "escalate",
"escalate_to": "finance_lead",
"notify": ["email", "slack"]
},
{
"name": "high_value",
"when": "amount.value >= 5000",
"approvers": { "all_of": ["finance_lead", "cfo"] },
"timeout": "8h",
"on_timeout": "fail",
"notify": ["email", "slack", "webhook"]
}
]
}'Response (201):
{
"name": "refund_approval",
"version": 1,
"created_at": "2026-04-23T10:00:00Z",
"updated_at": "2026-04-23T10:00:00Z"
}List all policies. Required scope: policies:read.
curl http://localhost:4000/policies \
-H "X-Deliberate-API-Key: dlb_ak_..."Response (200):
[
{
"name": "refund_approval",
"version": 2,
"rules_count": 3,
"created_at": "2026-04-23T10:00:00Z",
"updated_at": "2026-04-23T11:00:00Z"
}
]Get a policy by name. Required scope: policies:read.
curl http://localhost:4000/policies/refund_approval \
-H "X-Deliberate-API-Key: dlb_ak_..."Response (200): Full policy object including all rules.
Replace a policy. Creates a new version. Required scope: policies:write.
curl -X PUT http://localhost:4000/policies/refund_approval \
-H "X-Deliberate-API-Key: dlb_ak_..." \
-H "Content-Type: application/json" \
-d '{ ... full policy body ... }'Response (200):
{
"name": "refund_approval",
"version": 3,
"updated_at": "2026-04-23T12:00:00Z"
}Delete a policy. Required scope: policies:write. Returns HTTP 204.
curl -X DELETE http://localhost:4000/policies/refund_approval \
-H "X-Deliberate-API-Key: dlb_ak_..."Note: Deleting a policy does not affect existing pending approvals that were created under that policy.
Test a policy against a sample payload to see which rule would match. Required scope: policies:read.
curl -X POST http://localhost:4000/policies/refund_approval/test \
-H "X-Deliberate-API-Key: dlb_ak_..." \
-H "Content-Type: application/json" \
-d '{
"subject": "Refund for order #123",
"layout": "financial_decision",
"amount": { "value": 250.00, "currency": "USD" },
"customer": { "id": "C-001", "display_name": "Alice Johnson" }
}'Response (200):
{
"matched_rule": "standard",
"action": "route_to_approvers",
"approvers": {
"mode": "any_of",
"resolved": [
{ "id": "finance_lead", "email": "priya@example.com", "display_name": "Priya Sharma" }
]
},
"timeout": "4h",
"on_timeout": "escalate",
"notify": ["email", "slack"]
}If no rule matches:
{
"matched_rule": null,
"error": "No rule matched the provided payload"
}List all historical versions of a policy. Required scope: policies:read.
curl http://localhost:4000/policies/refund_approval/versions \
-H "X-Deliberate-API-Key: dlb_ak_..."Response (200):
[
{
"version": 3,
"updated_at": "2026-04-23T12:00:00Z",
"updated_by": "admin"
},
{
"version": 2,
"updated_at": "2026-04-23T11:00:00Z",
"updated_by": "operator-key"
},
{
"version": 1,
"created_at": "2026-04-23T10:00:00Z",
"created_by": "seed"
}
]Create an approver. Required scope: approvers:write.
curl -X POST http://localhost:4000/approvers \
-H "X-Deliberate-API-Key: dlb_ak_..." \
-H "Content-Type: application/json" \
-d '{
"id": "finance_lead",
"email": "priya@example.com",
"display_name": "Priya Sharma",
"out_of_office": {
"active": false,
"from": null,
"until": null,
"delegate_to": null
}
}'Response (201):
{
"id": "finance_lead",
"email": "priya@example.com",
"display_name": "Priya Sharma",
"out_of_office": { "active": false },
"created_at": "2026-04-23T10:00:00Z"
}List all approvers. Required scope: approvers:read.
curl http://localhost:4000/approvers \
-H "X-Deliberate-API-Key: dlb_ak_..."Response (200): Array of approver objects.
Get a single approver by ID. Required scope: approvers:read.
curl http://localhost:4000/approvers/finance_lead \
-H "X-Deliberate-API-Key: dlb_ak_..."Update an approver. Required scope: approvers:write.
curl -X PUT http://localhost:4000/approvers/finance_lead \
-H "X-Deliberate-API-Key: dlb_ak_..." \
-H "Content-Type: application/json" \
-d '{
"email": "priya@example.com",
"display_name": "Priya Sharma",
"out_of_office": {
"active": true,
"from": "2026-05-01",
"until": "2026-05-10",
"delegate_to": "cfo"
}
}'Response (200): Updated approver object.
Delete an approver. Required scope: approvers:write. Returns HTTP 204.
curl -X DELETE http://localhost:4000/approvers/finance_lead \
-H "X-Deliberate-API-Key: dlb_ak_..."Note: Deleting an approver does not affect pending approvals that reference them.
Create a group. Required scope: groups:write.
curl -X POST http://localhost:4000/groups \
-H "X-Deliberate-API-Key: dlb_ak_..." \
-H "Content-Type: application/json" \
-d '{
"id": "finance_team",
"display_name": "Finance Team",
"members": ["finance_lead", "cfo"]
}'Response (201):
{
"id": "finance_team",
"display_name": "Finance Team",
"members": ["finance_lead", "cfo"],
"created_at": "2026-04-23T10:00:00Z"
}List all groups. Required scope: groups:read.
curl http://localhost:4000/groups \
-H "X-Deliberate-API-Key: dlb_ak_..."Get a group by ID including resolved member details. Required scope: groups:read.
curl http://localhost:4000/groups/finance_team \
-H "X-Deliberate-API-Key: dlb_ak_..."Response (200):
{
"id": "finance_team",
"display_name": "Finance Team",
"members": [
{ "id": "finance_lead", "email": "priya@example.com", "display_name": "Priya Sharma" },
{ "id": "cfo", "email": "cfo@example.com", "display_name": "Alex Chen" }
]
}Delete a group. Required scope: groups:write. Returns HTTP 204.
curl -X DELETE http://localhost:4000/groups/finance_team \
-H "X-Deliberate-API-Key: dlb_ak_..."Create a new API key. Required scope: api_keys:write. The admin role (or the ADMIN_BOOTSTRAP_KEY) is needed to create keys with broad scopes.
curl -X POST http://localhost:4000/api-keys \
-H "X-Deliberate-API-Key: dlb_ak_..." \
-H "Content-Type: application/json" \
-d '{
"name": "refund-agent-prod",
"role": "agent",
"description": "Production key for the refund processing agent"
}'Or specify scopes directly instead of a role:
curl -X POST http://localhost:4000/api-keys \
-H "X-Deliberate-API-Key: dlb_ak_..." \
-H "Content-Type: application/json" \
-d '{
"name": "ci-readonly",
"scopes": ["policies:read", "approvers:read", "groups:read"]
}'Response (201):
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "refund-agent-prod",
"key": "dlb_ak_Xk9mT3hQw...",
"scopes": ["interrupts:write", "approvals:read"],
"description": "Production key for the refund processing agent",
"created_at": "2026-04-23T10:00:00Z"
}The key field is returned once only. Store it immediately.
Request body fields:
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Human-readable name for the key |
role |
string | no | Predefined role: agent, readonly, operator, admin |
scopes |
array | no | Explicit scope list (used if role is not provided) |
extra_scopes |
array | no | Additional scopes to add on top of a role |
description |
string | no | Notes about what this key is used for |
List all API keys. Returns metadata only — the raw key value is never returned after creation. Required scope: api_keys:read.
curl http://localhost:4000/api-keys \
-H "X-Deliberate-API-Key: dlb_ak_..."Response (200):
[
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "refund-agent-prod",
"scopes": ["interrupts:write", "approvals:read"],
"description": "Production key for the refund processing agent",
"created_at": "2026-04-23T10:00:00Z",
"last_used_at": "2026-04-23T11:30:00Z"
}
]Revoke an API key immediately. Required scope: api_keys:write. Returns HTTP 204.
curl -X DELETE http://localhost:4000/api-keys/550e8400-e29b-41d4-a716-446655440000 \
-H "X-Deliberate-API-Key: dlb_ak_..."After revocation, any request using the revoked key receives HTTP 401.