Runner API
The HTTPS protocol remote runners use to pull and report jobs (/api/runner/v1).
Remote runners talk to the control plane over HTTPS only. You don't call this API yourself; it is
documented so security reviewers and platform teams know exactly what crosses the boundary. Schemas
live in packages/jobs/src/protocol.ts.
| Endpoint | Auth | What it does |
|---|---|---|
POST /api/runner/v1/enroll | runner token qrt_… | Registers the runner (name, slots, version). |
POST /api/runner/v1/heartbeat | runner token | Every 30 s. A runner silent for 5 minutes has its running jobs errored out. |
POST /api/runner/v1/jobs/next | runner token | Long poll (up to ~25 s) for a queued self-hosted job of the runner's own workspace. |
POST /api/runner/v1/jobs/{id}/claim | runner token | Atomic claim: returns the job spec and a per-job token qjt_…. A job runs exactly once. |
POST /api/runner/v1/jobs/{id}/events | job token | Streams steps and findings. |
POST /api/runner/v1/jobs/{id}/complete | job token | Final status and summary. Idempotent. |
The job spec
The prompt, target, limits, egress policy, only the secrets the prompt references, and model
credentials (the workspace's BYOK key for BYOK runs; null for managed runs, which use the runner's own
env key). It is never logged or cached.
Guarantees
- Runner tokens are stored as SHA-256 hashes and compared in constant time; rotating or deleting a runner makes the old token fail immediately (401).
- Job tokens are HMAC-signed, bound to the worker, runner and workspace, and expire after the run's budget plus 15 minutes.
- Bodies are size-capped (16 KB; 512 KB for events; 1 MB for complete) and validated; validation errors name paths, never values.
- Endpoints are rate-limited per runner, job and IP.
- Usage minutes come from the control plane's claim and complete timestamps, never from the runner.