Skip to content

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

bash
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)

json
{
  "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

bash
curl https://api.tenor.run/manage/orgs \
  -H "Authorization: Bearer tk_admin_abc123"

Response (200 OK)

json
{
  "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

bash
curl https://api.tenor.run/manage/orgs/org_20260215_001 \
  -H "Authorization: Bearer tk_admin_abc123"

Response (200 OK)

json
{
  "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

bash
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)

json
{
  "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

bash
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)

json
{
  "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

PermissionDescription
evaluateCan call the evaluate endpoint and action space endpoint
executeCan execute flows and operations
simulateCan run simulations (dry-run)
manageCan manage deployments and persona mappings for this org
adminFull 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

bash
curl https://api.tenor.run/manage/orgs/org_20260215_001/api-keys \
  -H "Authorization: Bearer tk_admin_abc123"

Response (200 OK)

json
{
  "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

bash
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.

bash
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)

json
{
  "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)

json
{
  "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

bash
curl https://api.tenor.run/manage/orgs/org_20260215_001/deployments \
  -H "Authorization: Bearer tk_admin_abc123"

Response (200 OK)

json
{
  "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.

bash
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)

json
{
  "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

TypeFormatExample
API KeyDirect token prefix"tk_live_agent_key"
Role claimrole: prefix"role:escrow-admin"
JWT subjectsub: prefix"sub:user_123"
Emailemail: prefix"email:agent@acme.com"
Groupgroup: prefix"group:finance-team"

The executor resolves persona in this order:

  1. Check if the API key has explicit persona_bindings (set at key creation)
  2. Check the deployment's persona_map for a matching identity
  3. 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

bash
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)

json
{
  "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

bash
curl "https://api.tenor.run/manage/orgs/org_20260215_001/usage" \
  -H "Authorization: Bearer tk_admin_abc123"

Response (200 OK)

json
{
  "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

bash
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)

json
{
  "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

bash
curl "https://api.tenor.run/manage/orgs/org_20260215_001/usage/by-contract" \
  -H "Authorization: Bearer tk_admin_abc123"

Response (200 OK)

json
{
  "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
    }
  ]
}