The management API controls your Tenor platform resources: organizations, API keys, deployments, and persona mappings. All management endpoints live under https://api.tenor.run/manage/ and require an admin-scoped API key.
Base URL: https://api.tenor.run/manage
Organizations
POST /manage/orgs — Create Organization
curl -X POST https://api.tenor.run/manage/orgs \
-H "Authorization: Bearer tk_admin_abc123" \
-H "Content-Type: application/json" \
-d '{
"name": "acme",
"display_name": "Acme Corporation",
"billing_email": "billing@acme.com",
"plan": "pro"
}'Response (201 Created)
{
"org_id": "org_20260215_001",
"name": "acme",
"display_name": "Acme Corporation",
"billing_email": "billing@acme.com",
"plan": "pro",
"created_at": "2026-02-15T10:00:00Z",
"environments": ["test", "production"],
"api_keys": []
}GET /manage/orgs — List Organizations
curl https://api.tenor.run/manage/orgs \
-H "Authorization: Bearer tk_admin_abc123"Response (200 OK)
{
"organizations": [
{
"org_id": "org_20260215_001",
"name": "acme",
"display_name": "Acme Corporation",
"plan": "pro",
"created_at": "2026-02-15T10:00:00Z",
"active_deployments": 3,
"total_evaluations_mtd": 14523
}
]
}GET /manage/orgs/{org_id} — Get Organization Details
curl https://api.tenor.run/manage/orgs/org_20260215_001 \
-H "Authorization: Bearer tk_admin_abc123"Response (200 OK)
{
"org_id": "org_20260215_001",
"name": "acme",
"display_name": "Acme Corporation",
"billing_email": "billing@acme.com",
"plan": "pro",
"created_at": "2026-02-15T10:00:00Z",
"environments": ["test", "production"],
"active_deployments": 3,
"api_key_count": 5,
"usage_mtd": {
"evaluations": 14523,
"flow_executions": 3201,
"simulations": 892,
"entity_instances_peak": 4500,
"storage_bytes": 52428800
}
}PATCH /manage/orgs/{org_id} — Update Organization
curl -X PATCH https://api.tenor.run/manage/orgs/org_20260215_001 \
-H "Authorization: Bearer tk_admin_abc123" \
-H "Content-Type: application/json" \
-d '{
"display_name": "Acme Corp International",
"billing_email": "finance@acme.com"
}'Response (200 OK)
{
"org_id": "org_20260215_001",
"name": "acme",
"display_name": "Acme Corp International",
"billing_email": "finance@acme.com",
"plan": "pro",
"updated_at": "2026-02-15T11:00:00Z"
}API Keys
POST /manage/orgs/{org_id}/api-keys — Create API Key
curl -X POST https://api.tenor.run/manage/orgs/org_20260215_001/api-keys \
-H "Authorization: Bearer tk_admin_abc123" \
-H "Content-Type: application/json" \
-d '{
"name": "Production Agent Key",
"environment": "production",
"permissions": ["evaluate", "execute"],
"persona_bindings": ["escrow_agent"],
"expires_at": "2027-02-15T00:00:00Z"
}'Response (201 Created)
{
"key_id": "key_20260215_001",
"name": "Production Agent Key",
"token": "tk_live_9f4a2b3c4d5e6f7a8b9c0d1e2f3a4b5c",
"environment": "production",
"permissions": ["evaluate", "execute"],
"persona_bindings": ["escrow_agent"],
"created_at": "2026-02-15T10:30:00Z",
"expires_at": "2027-02-15T00:00:00Z"
}:::caution The token field is returned only once at creation time. Store it securely. It cannot be retrieved again. :::
Available Permissions
| Permission | Description |
|---|---|
evaluate | Can call the evaluate endpoint and action space endpoint |
execute | Can execute flows and operations |
simulate | Can run simulations (dry-run) |
manage | Can manage deployments and persona mappings for this org |
admin | Full access including API key management and org settings |
Permissions are additive. A key with ["evaluate", "execute"] can evaluate and execute but cannot manage deployments or create other keys.
GET /manage/orgs/{org_id}/api-keys — List API Keys
curl https://api.tenor.run/manage/orgs/org_20260215_001/api-keys \
-H "Authorization: Bearer tk_admin_abc123"Response (200 OK)
{
"api_keys": [
{
"key_id": "key_20260215_001",
"name": "Production Agent Key",
"environment": "production",
"permissions": ["evaluate", "execute"],
"persona_bindings": ["escrow_agent"],
"created_at": "2026-02-15T10:30:00Z",
"expires_at": "2027-02-15T00:00:00Z",
"last_used_at": "2026-02-15T14:22:00Z"
},
{
"key_id": "key_20260215_002",
"name": "Test Key",
"environment": "test",
"permissions": ["evaluate", "simulate"],
"persona_bindings": [],
"created_at": "2026-02-15T10:00:00Z",
"expires_at": null,
"last_used_at": "2026-02-15T13:05:00Z"
}
]
}DELETE /manage/orgs/{org_id}/api-keys/{key_id} — Revoke API Key
curl -X DELETE https://api.tenor.run/manage/orgs/org_20260215_001/api-keys/key_20260215_001 \
-H "Authorization: Bearer tk_admin_abc123"Response (204 No Content)
Revoked keys are immediately invalid. Any in-flight requests using the key will fail with 401 Unauthorized.
Deployments
POST /manage/orgs/{org_id}/deployments — Create Deployment
Deployments are typically created via tenor deploy, but can also be created directly via the management API.
curl -X POST https://api.tenor.run/manage/orgs/org_20260215_001/deployments \
-H "Authorization: Bearer tk_admin_abc123" \
-H "Content-Type: application/json" \
-d '{
"contract_name": "escrow",
"environment": "production",
"artifact": "<base64-encoded compiled contract>",
"contract_hash": "sha256:9f4a2b...",
"source_hash": "sha256:1a2b3c..."
}'Response (201 Created)
{
"deployment_id": "dep_20260215_001",
"org": "acme",
"contract_name": "escrow",
"environment": "production",
"contract_hash": "sha256:9f4a2b...",
"source_hash": "sha256:1a2b3c...",
"status": "active",
"created_at": "2026-02-15T10:30:00Z",
"endpoint": "https://api.tenor.run/acme/escrow",
"static_checks": {
"S1": "pass", "S2": "pass", "S3": "pass", "S4": "pass",
"S5": "pass", "S6": "pass", "S7": "pass", "S8": "pass"
}
}If any static check fails, the deployment is rejected:
Response (422 Unprocessable Entity)
{
"error": "deployment_rejected",
"code": 422,
"message": "Contract failed static analysis",
"static_checks": {
"S1": "pass", "S2": "pass", "S3": "pass", "S4": "pass",
"S5": "pass", "S6": "pass", "S7": "fail", "S8": "pass"
},
"failures": [
{
"check": "S7",
"name": "Stratum Acyclicity",
"message": "Rule 'check_eligibility' at stratum 1 references verdict 'special_override' at stratum 1. Cross-stratum reference must be strictly lower."
}
]
}GET /manage/orgs/{org_id}/deployments — List Deployments
curl https://api.tenor.run/manage/orgs/org_20260215_001/deployments \
-H "Authorization: Bearer tk_admin_abc123"Response (200 OK)
{
"deployments": [
{
"deployment_id": "dep_20260215_001",
"contract_name": "escrow",
"environment": "production",
"contract_hash": "sha256:9f4a2b...",
"status": "active",
"created_at": "2026-02-15T10:30:00Z",
"evaluation_count": 14523
},
{
"deployment_id": "dep_20260210_003",
"contract_name": "escrow",
"environment": "production",
"contract_hash": "sha256:7d8e9f...",
"status": "superseded",
"created_at": "2026-02-10T08:00:00Z",
"superseded_at": "2026-02-15T10:30:00Z",
"evaluation_count": 89201
}
]
}PATCH /manage/orgs/{org_id}/deployments/{deployment_id} — Update Deployment
Update a deployment's persona mapping or deactivate it.
curl -X PATCH https://api.tenor.run/manage/orgs/org_20260215_001/deployments/dep_20260215_001 \
-H "Authorization: Bearer tk_admin_abc123" \
-H "Content-Type: application/json" \
-d '{
"persona_map": {
"escrow_agent": ["tk_live_agent_key", "role:escrow-admin"],
"buyer": ["tk_live_buyer_key"],
"seller": ["tk_live_seller_key"]
}
}'Response (200 OK)
{
"deployment_id": "dep_20260215_001",
"contract_name": "escrow",
"persona_map": {
"escrow_agent": ["tk_live_agent_key", "role:escrow-admin"],
"buyer": ["tk_live_buyer_key"],
"seller": ["tk_live_seller_key"]
},
"updated_at": "2026-02-15T11:00:00Z"
}Persona-to-Identity Mapping
Persona mappings connect external identities to contract personas. A single deployment can map identities from multiple sources:
Mapping Types
| Type | Format | Example |
|---|---|---|
| API Key | Direct token prefix | "tk_live_agent_key" |
| Role claim | role: prefix | "role:escrow-admin" |
| JWT subject | sub: prefix | "sub:user_123" |
email: prefix | "email:agent@acme.com" | |
| Group | group: prefix | "group:finance-team" |
The executor resolves persona in this order:
- Check if the API key has explicit
persona_bindings(set at key creation) - Check the deployment's
persona_mapfor a matching identity - If no match, reject with
403 Forbidden
A single identity can map to multiple personas. In that case, the persona field in the execution request disambiguates which persona is acting.
GET /manage/orgs/{org_id}/deployments/{deployment_id}/persona-map
curl https://api.tenor.run/manage/orgs/org_20260215_001/deployments/dep_20260215_001/persona-map \
-H "Authorization: Bearer tk_admin_abc123"Response (200 OK)
{
"deployment_id": "dep_20260215_001",
"persona_map": {
"escrow_agent": ["tk_live_agent_key", "role:escrow-admin"],
"buyer": ["tk_live_buyer_key", "role:customer"],
"seller": ["tk_live_seller_key", "role:merchant"]
},
"unmapped_personas": []
}If a contract persona has no identity mapping, it appears in unmapped_personas. Unmapped personas cannot execute operations until a mapping is configured.
Usage and Metering
GET /manage/orgs/{org_id}/usage — Current Period Usage
curl "https://api.tenor.run/manage/orgs/org_20260215_001/usage" \
-H "Authorization: Bearer tk_admin_abc123"Response (200 OK)
{
"org_id": "org_20260215_001",
"billing_period": {
"start": "2026-02-01T00:00:00Z",
"end": "2026-02-28T23:59:59Z"
},
"usage": {
"evaluations": {
"count": 14523,
"limit": null
},
"flow_executions": {
"count": 3201,
"limit": null
},
"simulations": {
"count": 892,
"limit": null
},
"entity_instances_peak": {
"count": 4500,
"limit": null
},
"storage_bytes": {
"count": 52428800,
"limit": 10737418240
}
},
"plan": "pro"
}For Free tier organizations, the limit fields reflect the plan caps. When a limit is reached, subsequent requests return 429 with a message indicating the plan limit.
GET /manage/orgs/{org_id}/usage/daily — Daily Breakdown
curl "https://api.tenor.run/manage/orgs/org_20260215_001/usage/daily?from=2026-02-01&to=2026-02-15" \
-H "Authorization: Bearer tk_admin_abc123"Response (200 OK)
{
"org_id": "org_20260215_001",
"period": {
"from": "2026-02-01",
"to": "2026-02-15"
},
"daily": [
{
"date": "2026-02-01",
"evaluations": 812,
"flow_executions": 198,
"simulations": 45,
"entity_instances_peak": 3200,
"storage_bytes": 48234567
},
{
"date": "2026-02-02",
"evaluations": 1023,
"flow_executions": 234,
"simulations": 67,
"entity_instances_peak": 3400,
"storage_bytes": 49012345
}
]
}GET /manage/orgs/{org_id}/usage/by-contract — Per-Contract Breakdown
curl "https://api.tenor.run/manage/orgs/org_20260215_001/usage/by-contract" \
-H "Authorization: Bearer tk_admin_abc123"Response (200 OK)
{
"org_id": "org_20260215_001",
"contracts": [
{
"contract_name": "escrow",
"deployment_id": "dep_20260215_001",
"evaluations": 10234,
"flow_executions": 2456,
"simulations": 678,
"entity_instances": 3200,
"storage_bytes": 38000000
},
{
"contract_name": "subscription",
"deployment_id": "dep_20260212_002",
"evaluations": 4289,
"flow_executions": 745,
"simulations": 214,
"entity_instances": 1300,
"storage_bytes": 14428800
}
]
}