API overview
The Orunbase API is a JSON REST API served at https://api.orunbase.com. Every endpoint lives under the /v1 path prefix, accepts and returns application/json, and wraps responses in a consistent envelope so clients can handle success, errors, and pagination the same way everywhere.
curl https://api.orunbase.com/v1/organizations/ws_a1b2c3d4/projects \
-H "Authorization: Bearer $ORUN_CLOUD_TOKEN"
Versioning
All routes are prefixed with /v1. Breaking changes ship under a new version prefix; additive changes (new fields, new endpoints) may appear within /v1 at any time — clients should ignore unknown response fields.
Response envelopes
Successful responses wrap the payload in data and carry request metadata in meta:
{
"data": { "id": "proj_9f8e7d6c", "name": "checkout-api" },
"meta": { "requestId": "req_5f2d1c0b9a8e7f6d5c4b3a21", "cursor": null }
}
meta.requestId— the id of this request; echo it in support tickets.meta.cursor— continuation token on list endpoints;nullmeans no more pages. See Pagination.
Errors use a single envelope with a stable machine-readable code:
{
"error": {
"code": "not_found",
"message": "Route not found: /v1/organizations/org_1a2b3c/nope",
"details": {},
"requestId": "req_5f2d1c0b9a8e7f6d5c4b3a21"
}
}
See Errors for the full code table.
Tenancy in the path
Most resources are scoped to a workspace and addressed as /v1/organizations/{ref}/… — organizations is the API's canonical name for what the product calls a workspace. The {ref} segment accepts three spellings, all resolved at the edge before routing:
| Ref form | Example | Notes |
|---|---|---|
| Opaque id | org_1f6a3c9e… | Canonical; zero-overhead pass-through |
| Workspace ID | ws_a1b2c3d4 | Durable, immutable public id |
| Slug | acme-prod | Mutable vanity label |
A ws_ ref or slug that does not resolve returns 404 not_found — the request is never forwarded with an unresolvable reference.
/v1/workspaces/* is an accepted alias that rewrites to /v1/organizations/* before routing, so both spellings serve identical resources. API examples in these docs use the canonical /v1/organizations/… paths.
Request ids
Every response carries a request id — in meta.requestId on success and error.requestId on failure. Supply your own with the x-request-id header (1–128 characters, letters/digits/_/-) to correlate with your logs; otherwise the edge generates a req_… value. The SDK sends a generated req_<uuid> automatically and accepts a requestId per-request option.
Health
GET /health is unauthenticated and returns service status:
{
"status": "ok",
"service": "api-edge",
"environment": "production",
"checks": { "database": { "configured": true, "reachable": true } }
}
status is ok or degraded (degraded returns HTTP 503).
Request headers
| Header | Direction | Purpose |
|---|---|---|
Authorization: Bearer <token> | request | Credential — session token, API key, CLI JWT, or workflow token. See Authentication |
Content-Type: application/json | request | Required on requests with a body |
Idempotency-Key | request | Caller-owned replay key for unsafe methods. See Idempotency |
x-request-id | both | Trace id; echoed in meta.requestId / error.requestId |
X-RateLimit-Limit/Remaining/Reset-{org,identity} | response | Per-scope rate-limit state. See Rate limits |
Retry-After | response | Seconds to wait, on 429 responses |
x-saas-replay-source: edge-idempotency | response | Present when the response is an idempotent replay |
Resource groups
| Group | Reference |
|---|---|
| Workspaces (organizations) | Organizations |
| Members & invitations | Members and invitations |
| Teams | Teams |
| API keys | API keys |
| Projects & environments | Projects and environments |
| Configuration & secrets | Config |
| Audit log | Audit |
| Usage & quotas | Usage |
| Billing | Billing |
| Outbound webhooks | Webhooks |
| Notification preferences | Notifications |
| Integrations (GitHub) | Integrations |
| State plane | State |