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": {}
}
}| Status | Typical codes |
|---|---|
| 400 | VALIDATION_ERROR, with the failing fields in details |
| 422 | Domain rules: TEMPLATE_INVALID, UNSAFE_WEBHOOK_URL, INVALID_REPORT, ROLE_TOO_HIGH |
| 401 | UNAUTHENTICATED, INVALID_API_KEY |
| 402 | ENTERPRISE_REQUIRED (an Enterprise feature and no license that covers it) |
| 403 | CSRF_REJECTED, API_KEY_NOT_ALLOWED, API_KEY_SCOPE, missing permission |
| 404 | Not found, including records of other tenants |
| 409 | INSTANCE_BUSY, VERSION_EXISTS, ALREADY_CONVERTED, TEMPLATE_EXISTS |
| 429 | Rate limited |
| 501 | SCANNER_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 sYou 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:
| Endpoint | Requests per minute |
|---|---|
| Development login | 10 |
| OIDC login and callback | 20 each |
| Deploy | 10 |
| Destroy | 5 |
| Cloud target validation | 10 |
| Template version publishing | 10 |
| API key creation | 20 |
| Import creation | 20 |
| Webhook creation | 20 |
| Webhook test | 10 |
GET /healthz and GET /readyz have no limit. A 429 response means wait and retry with backoff.
Endpoint map
| Area | Endpoints |
|---|---|
| Health | GET /healthz, GET /readyz |
| Auth | GET /auth/providers, OIDC login and callback, POST /auth/logout, GET /me |
| Tenants and their limits | GET/POST /tenants, GET/PATCH /tenants/:id |
| Templates | GET/POST /templates, GET /templates/:id, versions, validate, publish, clone |
| Catalog and targets | GET /applications, GET /cloud/providers, GET/POST /cloud/targets, validate, capabilities |
| Instances | list, create, get, update, preview, deploy, upgrade, destroy, deployments, logs, metrics |
| Deployments | list, get, events, approve, cancel, retry |
| Operations | overview, status page, notifications, audit, incidents |
| Integrations | api-keys, webhooks, POST /templates/validate, PUT /applications/:name, POST /applications/:name/versions, imports |
| License and Enterprise | GET /license, GET /audit/export (Enterprise) |
Request and response shapes are defined in the platform's contracts package. The generated
API reference lists every operation.
Template reference
The platform/v1 EnvironmentTemplate format. Metadata and tags, placement slots, variables, every resource type with defaults and limits, and examples.
API keys
Create, use, scope and revoke OrkStage API keys for CI/CD, scripts and the ork CLI. Token format, roles, the ten scopes, expiry, auditing and storage.