OrkStageOrkStage

REST API overview

How the OrkStage Control API v1 works. Base path, API keys and sessions, the CSRF header, errors, pagination, correlation ids, idempotency and rate limits.

The Control API is the only way into the platform, and the console uses it too. The base path is /api/v1. A running API serves an OpenAPI UI at /api/docs and the OpenAPI document at /api/docs-json. The API reference in these docs is generated from that document.

Authentication

Send an API key as a bearer token. You need no cookie and no CSRF header.

curl https://orkstage.example.com/api/v1/me \
  -H "Authorization: Bearer ork_live_7f3a9c21_…"

A key reaches only the endpoints that declare a scope. Endpoints without a scope, such as API key management, answer 403 API_KEY_NOT_ALLOWED to a key.

GET /me returns the caller, their memberships and the authorization rules. When you call it with an API key, it also returns apiKey: { id, name, prefix, scopes }.

Errors

Error responses never contain stack traces. They all have this shape:

{
  "error": {
    "code": "INSTANCE_BUSY",
    "message": "Instance is DEPLOYING; wait for the current operation to finish.",
    "requestId": "req-1a2b",
    "correlationId": "c0ffee00-…",
    "details": {}
  }
}
StatusTypical codes
400VALIDATION_ERROR, with the failing fields in details
422Domain rules: TEMPLATE_INVALID, UNSAFE_WEBHOOK_URL, INVALID_REPORT, ROLE_TOO_HIGH
401UNAUTHENTICATED, INVALID_API_KEY
402ENTERPRISE_REQUIRED (an Enterprise feature and no license that covers it)
403CSRF_REJECTED, API_KEY_NOT_ALLOWED, API_KEY_SCOPE, missing permission
404Not found, including records of other tenants
409INSTANCE_BUSY, VERSION_EXISTS, ALREADY_CONVERTED, TEMPLATE_EXISTS
429Rate limited
501SCANNER_UNAVAILABLE (the API was built without the IaC scan engine)

Correlation ids

Send x-correlation-id to tie your logs to ours. Every response carries x-correlation-id and x-request-id. The correlation id follows the request into deployments, OpenTofu runs, audit events and webhook deliveries, so quote it when you report a problem.

Pagination

List endpoints that can grow use cursors and return the newest items first:

GET /api/v1/deployments?limit=25&cursor=<id>
{ "items": [ … ], "nextCursor": "b7c1…" }

Pass nextCursor as cursor until it is null.

Long running operations

Deploy and destroy return 202 Accepted with a deployment summary. The work never runs inside the request. Follow its progress with these endpoints:

GET /api/v1/deployments/:id
GET /api/v1/deployments/:id/events?after=<eventId>   # poll every 1–2 s

You can also subscribe to webhooks for deployment.succeeded, deployment.failed and deployment.awaiting_approval.

Idempotency

Deployments are keyed by tenant, instance and a hash of the desired state. While an instance has an operation in progress, further deploy or destroy requests get 409 INSTANCE_BUSY, and the worker never recreates resources that have already converged. The API accepts an Idempotency-Key header but ignores it for now.

Tenancy

Reads of tenant records are filtered by the caller's memberships, and every write is checked against the record loaded from the database. The API never trusts a tenantId in a request on its own.

Rate limits

Limits are counted per client IP address and per endpoint, over a 60 second window. An endpoint accepts 600 requests per minute from one client unless it has a lower limit:

EndpointRequests per minute
Development login10
OIDC login and callback20 each
Deploy10
Destroy5
Cloud target validation10
Template version publishing10
API key creation20
Import creation20
Webhook creation20
Webhook test10

GET /healthz and GET /readyz have no limit. A 429 response means wait and retry with backoff.

Endpoint map

AreaEndpoints
HealthGET /healthz, GET /readyz
AuthGET /auth/providers, OIDC login and callback, POST /auth/logout, GET /me
Tenants and their limitsGET/POST /tenants, GET/PATCH /tenants/:id
TemplatesGET/POST /templates, GET /templates/:id, versions, validate, publish, clone
Catalog and targetsGET /applications, GET /cloud/providers, GET/POST /cloud/targets, validate, capabilities
Instanceslist, create, get, update, preview, deploy, upgrade, destroy, deployments, logs, metrics
Deploymentslist, get, events, approve, cancel, retry
Operationsoverview, status page, notifications, audit, incidents
Integrationsapi-keys, webhooks, POST /templates/validate, PUT /applications/:name, POST /applications/:name/versions, imports
License and EnterpriseGET /license, GET /audit/export (Enterprise)

Request and response shapes are defined in the platform's contracts package. The generated API reference lists every operation.

On this page