API
Runner HTTP API reference — auth, per-resource routes, statuses, and the JSON-RPC mirror.
Base: the runner listens on 127.0.0.1:8080 in-container; Caddy serves it at api.<domain>. All routes below are prefixed with that host unless noted.
Auth
| Credential | Sent as | Used for |
|---|---|---|
RUNNER_TOKEN |
Authorization: Bearer <token> (or x-runner-token / x-host-token / x-agent-token fallback) |
Runner API, control UI server calls |
| Profile API key | Git Basic git:<key> |
git push / git fetch on smart-HTTP remotes |
| Collaborator role | Assigned per app | view = fetch only, push = create + fast-forward, admin = anything |
curl -H "Authorization: Bearer $RUNNER_TOKEN" https://api.<domain>/v1/apps
The control UI uses the bearer token server-side; browsers never see it. Git smart-HTTP verifies the API key via the UI’s /internal/git-auth and enforces the collaborator role per slug. Unknown slugs 404 at auth.
Public (no credential): /health, /ready, /v1/git/*, /v1/edge/*.
/v1/edge/* is internal edge plumbing (fallback page, TLS ask gate, wake hop) — public and credential-less by design; not a client API.
Apps
| Method | Route | Notes |
|---|---|---|
GET / POST |
/v1/apps |
List; create (quota-checked, see Limits) |
GET / PATCH / DELETE |
/v1/apps/{id} |
PATCH sets desired_state: running|stopped |
POST |
/v1/apps/{id}/rename |
Renames the app; rotates scoped credentials once a provider exists (none today — see Tenancy) |
POST |
/v1/apps/{id}/sleep |
Parks the app; next request wakes it |
Deploys
| Method | Route | Notes |
|---|---|---|
GET |
/v1/apps/{id}/deploys |
Deploy history |
GET |
/v1/apps/{id}/deploys/stream |
SSE stream of deploys |
GET |
/v1/apps/{id}/deploys/{deploy_id}/log |
Build/deploy log |
POST |
/v1/apps/{id}/rollback |
Redeploys a previous deploy; wakes asleep apps first |
POST |
/v1/apps/{id}/git-remote |
Remote URL info for the app’s repo |
Env
| Method | Route | Notes |
|---|---|---|
GET / POST |
/v1/apps/{id}/env |
List; set (triggers redeploy flow) |
DELETE |
/v1/apps/{id}/env/{name} |
Removes one var |
Domains
| Method | Route | Notes |
|---|---|---|
GET / POST |
/v1/apps/{id}/domains |
List; attach a custom hostname |
DELETE |
/v1/apps/{id}/domains/{hostname} |
Detaches the hostname |
Source
| Method | Route | Notes |
|---|---|---|
GET |
/v1/apps/{id}/tree |
File tree at tip |
GET |
/v1/apps/{id}/blob/{*path} |
File contents |
GET |
/v1/apps/{id}/diff |
Working diff |
POST |
/v1/apps/{id}/source/commit |
Browser-edit commit (validated paths + message + author email); wakes asleep apps |
Storage
| Method | Route | Notes |
|---|---|---|
GET |
/v1/apps/{id}/storage |
Storage overview |
GET |
/v1/apps/{id}/storage/d1/{database_id} |
Query a D1 database |
POST |
/v1/apps/{id}/storage/d1/{database_id}/write |
Execute a D1 write |
GET |
/v1/apps/{id}/storage/do/{class_name} |
Durable Object contents |
GET |
/v1/apps/{id}/storage/r2/{bucket} |
List bucket keys |
GET / DELETE |
/v1/apps/{id}/storage/r2/{bucket}/object |
Read / delete one object |
GET |
/v1/apps/{id}/storage/r2/{bucket}/raw |
Raw object bytes |
Metrics and telemetry
| Method | Route | Notes |
|---|---|---|
GET |
/v1/apps/{id}/metrics?hours=24 |
Minute buckets (14-day prune) |
GET |
/v1/apps/{id}/metrics/version |
Schema/watermark version |
GET |
/v1/apps/{id}/devices |
Device breakdown (tailed from Caddy access log) |
GET |
/v1/apps/{id}/paths |
Path breakdown |
GET |
/v1/apps/{id}/refs |
Referrer breakdown |
GET |
/v1/apps/{id}/spans?hours=1 |
On-demand spans |
GET |
/v1/apps/{id}/logs |
App logs |
GET |
/v1/apps/{id}/logs/stream |
SSE log stream |
Events
| Method | Route | Notes |
|---|---|---|
GET / POST |
/v1/apps/{id}/events |
List; log an event |
GET |
/v1/apps/{id}/events/stream |
SSE event stream |
GET |
/v1/apps/{id}/events/channels |
Known channels |
POST |
/v1/apps/{id}/identify |
Identify a user |
GET |
/v1/apps/{id}/users/{user_id}/props |
Stored user props |
GET / POST |
/v1/apps/{id}/insights |
List; set an insight |
Admin
| Method | Route | Notes |
|---|---|---|
GET |
/v1/admin/stats |
Fleet-wide stats |
POST |
/v1/admin/snapshot |
Writes the state snapshot to the bucket |
Git smart-HTTP
Stock Git protocol; no git-remote-s3 on clients. Push to main to deploy.
| Method | Route | Notes |
|---|---|---|
GET |
/v1/git/{slug}/info/refs |
Advertisement (view suffices) |
POST |
/v1/git/{slug}/git-upload-pack |
Fetch (view suffices) |
POST |
/v1/git/{slug}/git-receive-pack |
Push (push = create + fast-forward; admin = anything) |
git remote add noite https://git:<key>@git.<domain>/<slug>
git push noite main
RPC mirror
POST /rpc is a JSON-RPC mirror of the REST routes (same auth, same effects). Prefer REST; use /rpc only where batching calls matters.
Statuses
| Code | Meaning |
|---|---|
401 |
Missing or wrong bearer token / API key |
404 |
Unknown app, slug, deploy, or key |
409 |
Domain already taken; conflicting sleep/wake transition |
503 |
Fleet shedding load (+ Retry-After) or failed wake |