Multi-agent DAG orchestration, purpose-built for enterprise engineering teams Learn more →

API reference

Last updated 2026-05-19·10 min read
Pre-beta APICendriix is in design-partner preview. Routes below match api.example.com/v1 as of May 2026. Auth uses a Cognito JWT Bearer token; workspace scope comes from the token, there is no X-Cendriix-Workspace header. Rate limits are enforced globally (intake: 5 req/min). Plan-tier tables are roadmap.

The Cendriix REST API lets you trigger runs, query run state, manage agents and policies, and stream audit events, all from your own tooling.

Authentication

Authenticated requests use a Bearer JWT from Cognito (via POST /auth/login or the app). Workspace context is embedded in the token.

bash
curl https://api.example.com/v1/runs \
  -H "Authorization: Bearer <cognito-jwt>"

API keys are created via POST /api-keys but middleware currently expects JWT auth in preview, check release notes before automating with keys alone.

Token securityTokens are shown only once at creation time. Store them in a secrets manager, not in source code or environment files committed to version control.

Base URL and rate limits

All requests go to:

bash
https://api.example.com/v1
PlanRequests / minuteRequests / day
Starter605 000
Growth300100 000
EnterpriseUnlimitedUnlimited

Rate-limit state is returned in every response: X-RateLimit-Remaining andX-RateLimit-Reset (Unix seconds). HTTP 429 is returned when the limit is exceeded.

POST /runs

Trigger a new workflow run.

POST/runs

Request body

FieldTypeRequiredDescription
workflowstringYesWorkflow slug (e.g. ship-from-ticket).
ticketstringNoJira / Linear ticket key.
envstringNopreview, staging, or production.
modelstringNoLLM override (e.g. claude-opus-4-5).
dry_runbooleanNoIf true, plan without executing side effects.
metadataobjectNoArbitrary key-value pairs stored on the run.
bash
curl -X POST https://api.example.com/v1/runs \
  -H "Authorization: Bearer <token>" \
  -H "X-Cendriix-Workspace: acme-prod" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow": "ship-from-ticket",
    "ticket":   "JIRA-3421",
    "env":      "preview"
  }'

Response

json
{
  "id":         "run_a1b2c3d4",
  "workflow":   "ship-from-ticket",
  "status":     "queued",
  "ticket":     "JIRA-3421",
  "env":        "preview",
  "created_at": "2026-05-19T09:00:00Z",
  "cost_usd":   0
}

GET /runs/:id

Retrieve the current state and cost of a run.

GET/runs/:id
bash
curl https://api.example.com/v1/runs/run_a1b2c3d4 \
  -H "Authorization: Bearer <token>" \
  -H "X-Cendriix-Workspace: acme-prod"

Response

json
{
  "id":         "run_a1b2c3d4",
  "workflow":   "ship-from-ticket",
  "status":     "awaiting_approval",
  "ticket":     "JIRA-3421",
  "env":        "preview",
  "preview_url": "https://preview-jira-3421.acme.cendriix.ai",
  "cost_usd":   0.24,
  "steps": [
    { "name": "orchestrator", "status": "done",     "duration_ms": 11000 },
    { "name": "dev",          "status": "done",     "duration_ms": 161000 },
    { "name": "sre",          "status": "done",     "duration_ms": 72000 },
    { "name": "qa",           "status": "done",     "duration_ms": 45000 },
    { "name": "approval_gate","status": "awaiting", "duration_ms": null }
  ],
  "created_at": "2026-05-19T09:00:00Z",
  "updated_at": "2026-05-19T09:04:49Z"
}

POST /runs/:id/approve

Approve a paused run at an approval gate.

POST/runs/:id/approve
FieldTypeDescription
notestringOptional human-readable note stored in the audit log.
bash
curl -X POST https://api.example.com/v1/runs/run_a1b2c3d4/approve \
  -H "Authorization: Bearer <token>" \
  -H "X-Cendriix-Workspace: acme-prod" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Looks good, ship it." }'

Response

json
{
  "id":     "run_a1b2c3d4",
  "status": "running"
}

POST /runs/:id/cancel

Cancel a queued or running run. Cancellation is immediate and non-reversible.

POST/runs/:id/cancel
bash
curl -X POST https://api.example.com/v1/runs/run_a1b2c3d4/cancel \
  -H "Authorization: Bearer <token>" \
  -H "X-Cendriix-Workspace: acme-prod"

Response

json
{
  "id":     "run_a1b2c3d4",
  "status": "cancelled"
}

GET /agents

List all agents available in the workspace (built-in and custom).

GET/agents
bash
curl https://api.example.com/v1/agents \
  -H "Authorization: Bearer <token>" \
  -H "X-Cendriix-Workspace: acme-prod"

Response

json
{
  "agents": [
    { "id": "agent_orchestrator", "name": "Orchestrator", "kind": "built-in", "model": "claude-sonnet-4-5" },
    { "id": "agent_dev",          "name": "Dev",          "kind": "built-in", "model": "claude-sonnet-4-5" },
    { "id": "agent_sre",          "name": "SRE",          "kind": "built-in", "model": "claude-sonnet-4-5" },
    { "id": "agent_qa",           "name": "QA",           "kind": "built-in", "model": "claude-haiku-4-5"  },
    { "id": "agent_cus_f3a9",     "name": "Legal review", "kind": "custom",   "model": "claude-opus-4-5"  }
  ]
}

Security policy API

Manage guardrails via the security module (not POST /policies).

GET/security/policy
PUT/security/policy
POST/security/policy/rules
bash
curl https://api.example.com/v1/security/policy \
  -H "Authorization: Bearer <token>"

GET /audit/logs

Query audit events. Supports cursor-based pagination.

GET/audit/logs

Verify chain integrity with GET /audit/verify.

Query paramDescription
sinceISO 8601 start timestamp (inclusive).
untilISO 8601 end timestamp. Defaults to now.
actorFilter by actor email or service account ID.
eventEvent type filter (e.g. run.approved).
limitPage size (max 200, default 50).
cursorPagination cursor from previous response.
bash
curl "https://api.example.com/v1/audit/logs?since=2026-05-01&limit=50" \
  -H "Authorization: Bearer <token>"

Response

json
{
  "events": [
    {
      "id":        "evt_001",
      "event":     "run.approved",
      "actor":     "alice@acme.com",
      "run_id":    "run_a1b2c3d4",
      "note":      "Looks good.",
      "timestamp": "2026-05-19T09:06:00Z"
    }
  ],
  "next_cursor": "eyJpZCI6ImV2dF8wMDEifQ"
}

Errors

All errors use standard HTTP status codes and a consistent JSON body:

json
{
  "error": {
    "code":    "run_not_found",
    "message": "Run run_xxxxxxxx was not found in workspace acme-prod.",
    "status":  404
  }
}
StatusCodeMeaning
400invalid_requestMalformed request body or missing required field.
401unauthorizedMissing or invalid Bearer token.
403forbiddenToken lacks the required permission scope.
404not_foundResource does not exist or is not visible to this token.
409conflictState conflict (e.g. approving a run that is not awaiting approval).
429rate_limitedRate limit exceeded. Retry after X-RateLimit-Reset.
500internal_errorUnexpected server error. Contact support with the request ID.
Request IDsEvery response includes an X-Request-Id header. Include this ID when contacting support, it lets us trace the exact request in our logs.