Automate
Customer API
Runnable’s customer REST routes are same-origin dashboard APIs for authenticated users. They are useful for controlled browser or internal automation, but they are not a general public API-key surface.
Scope and authentication
Customer endpoints use the Authaz browser session and the active runnable-organization cookie.
| Requirement | Behavior |
|---|---|
| Authentication | Signed-in Authaz session; unauthenticated browser requests enter the login flow. |
| Tenant | The runnable-organization cookie selects one membership. Every resource query also filters by that organization ID. |
| Authorization | Endpoint-specific minimum role from viewer through owner. |
| Content type | JSON for structured API routes; job logs are text/plain and artifact routes return download responses. |
No customer bearer API token
/api/mcp. There is no documented long-lived customer REST API token today.Supported customer endpoints
This table is the documented customer surface. Dashboard implementation details can change; automate only endpoints whose contract is listed here.
| Method | Endpoint | Minimum role | Purpose |
|---|---|---|---|
| GET / POST | /api/organizations | Signed-in / signed-in | List memberships or create an organization. |
| POST | /api/organizations/:id/activate | Member of target | Select the active organization cookie. |
| GET / POST | /api/repositories | Viewer / Admin | List repositories or create an Entire-native repository. |
| PATCH | /api/repositories/:id/checkout | Admin | Select GitHub or a validated Entire mirror checkout. |
| POST | /api/repositories/:id/migration | Admin | Scan GitHub workflows or create a migration PR. |
| POST | /api/repositories/:id/dispatch | Member | Emit a typed repository_dispatch event. |
| POST | /api/repositories/:id/entire-webhook | Admin | Rotate the Entire relay bearer. |
| GET | /api/workflows | Viewer | List workflow definitions and diagnostics. |
| POST | /api/workflows/:id/dispatch | Member | Create a workflow_dispatch run. |
| GET | /api/runs | Viewer | Cursor-based run history. |
| POST | /api/runs/:id/cancel | Member | Idempotently cancel a run. |
| POST | /api/runs/:id/rerun | Member | Queue a full or failed-only rerun. |
| GET | /api/jobs?runId= | Viewer | List up to 200 jobs, optionally for one run. |
| GET | /api/jobs/:id/logs | Viewer | Read, range, or download the current attempt log. |
| POST | /api/jobs/:id/environment-approval | Eligible member | Approve, reject, or explicitly bypass protection. |
| GET | /api/artifacts?runId= | Viewer | List up to 200 unexpired artifact metadata rows. |
| GET | /api/artifacts/:id | Viewer | Download an unexpired artifact. |
| GET / POST / DELETE | /api/secrets and /api/secrets/:id | Admin | List write-only metadata, create/replace, or delete secrets. |
| GET / POST / DELETE | /api/variables and /api/variables/:id | Admin | List, create/replace, or delete variables. |
| GET / POST / DELETE | /api/environments and /api/environments/:id | Admin | List, upsert, or delete protected environments. |
| GET | /api/usage | Viewer | Usage events and active storage totals. |
| GET / POST | /api/billing and /api/billing/settings | Viewer / Owner | Entitlements and spend controls. |
| POST | /api/billing/checkout and /api/billing/portal | Owner | Stripe subscription and customer portal sessions. |
| GET | /api/billing/preview | Viewer | Upcoming invoice or local estimate. |
| GET / POST / DELETE | /api/mcp-tokens and /api/mcp-tokens/:id | Admin | List, issue, or revoke MCP credentials on any active plan. |
| GET / POST / DELETE | /api/integrations/slack | Admin | Read/update/test or disconnect the Slack integration. |
Pagination, limits, and byte ranges
Only run history is cursor-paginated today. Other list limits are endpoint-specific.
| Endpoint | Contract |
|---|---|
| GET /api/runs | limit defaults to 50, clamps to 1–100; pass next as before for the next page, ordered newest first. |
| GET /api/jobs | Optional runId filter; at most 200 rows; no continuation cursor. |
| GET /api/artifacts | Optional runId filter; at most 200 unexpired rows; no continuation cursor. |
| GET /api/jobs/:id/logs | Accepts Range: bytes=start-end and returns 206 + Content-Range; invalid/unsatisfiable ranges return 416. |
GET /api/runs?limit=2&before=2026-08-12T10:00:00.000Z
200 OK
{
"data": [
{
"id": "run_uuid",
"status": "completed",
"conclusion": "success",
"sourceSha": "0123456789abcdef",
"createdAt": "2026-08-12T09:42:10.000Z"
}
],
"next": "2026-08-12T09:42:10.000Z"
}Request and response conventions
Mutation endpoints return the created resource identifier or a short operation result. Input is JSON unless the endpoint is a provider callback or download.
POST /api/runs/RUN_ID/rerun
Content-Type: application/json
{ "failedOnly": true }
201 Created
{
"runId": "new_run_uuid",
"orchestration": { "started": true },
"message": "Rerun queued"
}Secrets never return a cleartext value. MCP and Entire relay credentials are returned once at creation or rotation and only a hash/prefix is stored afterward.
Idempotency and rate limits
Idempotency is operation-specific; there is no general Idempotency-Key contract for customer endpoints today.
| Operation | Guarantee |
|---|---|
| Run cancellation | Idempotent: repeating cancel does not create another run. |
| Provider delivery | GitHub signature + delivery ID and Entire repository + delivery ID deduplicate event processing. |
| Stripe webhook | Stripe event ID is persisted before lifecycle mutation. |
| Dispatch and rerun | Not generally idempotent; each accepted call can create a new run. |
| Create/replace value | The same scope/name is updated rather than duplicated, but clients should not treat a transport retry as universally safe. |
No numeric customer API rate guarantee
wait_for_run instead of rapid polling for agent workflows.Errors
Most JSON errors use a single message field. Do not branch on message text unless an endpoint explicitly documents it.
| HTTP | Meaning | Typical body |
|---|---|---|
| 400 | Malformed or semantically invalid input. | { "error": "…" } |
| 401 | Missing/invalid auth on bearer-authenticated surfaces. | { "error": "…" } |
| 403 | Membership role is below the endpoint minimum. | { "error": "This action requires the admin role." } |
| 404 | Resource absent from the active organization or expired. | { "error": "Run not found" } |
| 409 | State conflict such as ineligible approval, duplicate link, or no compatible migration candidate. | { "error": "…" } |
| 416 | Invalid or unsatisfiable log byte range. | Empty response with Content-Range when known. |
| 429 | Temporary request throttling. | Retry after the server-provided delay when present. |
| 500 | Unexpected failure; details are intentionally hidden. | { "error": "The request could not be completed." } |
Excluded internal and runner APIs
These routes are not customer APIs and are intentionally absent from the supported endpoint table.
Do not integrate with internal routes
/api/agent/*, /api/internal/*, the job-scoped /v1/agent protocol, provider OAuth callbacks, signed provider webhooks, Stripe webhooks, and Slack Events callbacks use dedicated service credentials and may change without customer compatibility guarantees.Agent credentials are scoped to one organization, job, and attempt. They can claim work and exchange lifecycle messages but cannot enumerate customer resources. Vercel Cron routes require CRON_SECRET and are deployment operations, not automation endpoints.

