Skip to content

REST API

Base URL: http://<cellpd>:8790/v1

Full machine contract: cellp/api/openapi.yaml in the repo. This page is the operator map.

Auth

http
Authorization: Bearer <token>
TokenEndpoints
CELLP_DEPLOY_TOKENPOST /projects/{id}/versions only
CELLP_ADMIN_TOKENEverything else — list/get versions, poll deploy status, promote, bindings, Dashboard

If deploy and admin tokens differ, CI must use admin (or a second credential) to GET …/versions/{id} while polling; deploy token alone cannot read version status.

Details: Auth.

Health & runtime

REST paths below are under /v1. Prometheus metrics are not under /v1:

MethodPathAuthNotes
GET/v1/healthnoneLiveness
GET/v1/health/deepnoneRegistry, store, queue; 503 if overloaded (queue_full)
GEThttp://<cellpd>:8790/metricsnonePrometheus (cellpd root, no /v1 prefix)
GET/v1/runtime/routesadminActive upstream summary

Projects

MethodPathAuth
GET/projectsadmin
POST/projectsadmin
GET/projects/{projectID}admin

Query GET /projects: limit (default 50, max 200), cursor for pagination.

GET /projects/{projectID}: optional include=versions with limit for an embedded first page.

POST body: { "id": "my-shop", "git_remote": "optional" }.

Response includes prod_version_id, prod_url when production is set.

Versions

MethodPathAuthNotes
GET/projects/{p}/versionsadminlimit, cursor, optional status filter
POST/projects/{p}/versionsdeploy202 — async deploy
GET/projects/{p}/versions/{v}adminStatus, preview_url, prod_url, parent, …
DELETE/projects/{p}/versions/{v}adminDestroy (irreversible)
GET PUT/projects/{p}/versions/{v}/envadminWorker env overrides
POST…/promoteadminProduction cutover (202)
POST…/archive …/wakeadminProcess lifecycle
POST…/pin …/unpinadminIdle protection

POST /versions body

json
{
  "id": "pr-42-abc",
  "parent_version_id": "v-staging-seed",
  "git_ref": "pr-42",
  "git_sha": "abc123",
  "artifact_digest": "sha256:…",
  "env": { "FEATURE": "1" }
}
  • id optional — server generates v-YYYYMMDDHHMMSS if omitted.
  • artifact_uri in client JSON is ignored; cellpd builds s3://{CELLP_ARTIFACTS_BUCKET}/{project}/{version}/.
  • Upload artifacts to that prefix before or immediately after POST (orchestrator fetches from object storage).

POST /versions responses

CodeMeaning
202Accepted — body includes id, status, preview_url, poll_url
422Invalid fork (e.g. parenting live production for a PR)
503Deploy queue full (queue_full, pending_jobs, queue_max)

Poll GET …/versions/{id} until status is ready or failed. You may see deploy_ready transiently only with the default-off CELLP_ELASTIC_RUNTIME internal scaffold; keep polling until ready.

CELLP_ELASTIC_RUNTIME is an unsupported internal E1–E5 scaffold, not an operator feature. It provides no remote HTTP+mTLS Node Agent, real celld lifecycle management, Scheduler/complete 0→N scaling, or production-readiness.

Version status values

StatusMeaning
pendingCreated, queued
fetchingPulling artifact
branchingoffshoot / D1 / KV / R2 / Queue branch
preparingImport / seed
deployingcelld deploy
deploy_readyArtifact and bindings prepared; may appear only when elastic serving (CELLP_ELASTIC_RUNTIME) is enabled—qualification before ready. Poll until ready for deploy success; do not treat deploy_ready as the public CD terminal state.
readyServes preview Host (external deploy success terminal state)
failedDeploy error — see error field
archivedProcess stopped; data retained
drainingTransient during promote
destroyedRemoved

GET /versions/{v} fields (snapshot semantics)

FieldMeaning
parent_version_idWhen set, this version branched data (D1/KV/R2/Queue) from that parent at deploy time. The child does not see parent writes after the fork cut. null = root version.
ready_atWhen the version became ready.
preview_urlOutward Gateway URL for preview Host (scheme/host from ingress config).

Concepts: Preview · Promote.

Gateway (not /v1)

User traffic hits cellpd Gateway on port 8787 (default). Routing is by HTTP Host (Preview & production):

RoleHost pattern
Preview{version}.{project}.{baseDomain}
Production{project}.{baseDomain}

Configure CELLP_INGRESS_BASE_DOMAIN, GATEWAY_URL, and public schemes on cellpd. Dev setup: repo dev/INGRESS-HOST.md. Path selectors http://gateway:8787/{project}/ and /{project}/{version}/ are deprecated.

WebSockets: The gateway forwards Upgrade: websocket to celld (RFC 6455). Use the same Host rules as HTTP. TLS terminates at your outer proxy, not inside cellpd.

bash
curl -H "Host: demo-app.ingress.local" http://127.0.0.1:8787/health
curl -sS -H "Authorization: Bearer $ADMIN_TOKEN" \
  "$CELLP_URL/projects/demo-app/versions/v1" | jq .preview_url

Bindings & data

Prefix: /projects/{p}/versions/{v} — all admin.

AreaPaths
ManifestGET /bindings
D1GET /database, /database/tables, /database/tables/{table}/rows, POST /database/query
KVGET /kv, /kv/{ns}, /kv/{ns}/keys, `GET
Queues/queues, /queues/{name}, GET /peek, POST /pause /resume /redrive /purge
WorkflowsGET /workflows, GET /workflows/{name}/instances (read-only)

curl: first version smoke

bash
export CELLP_URL=http://127.0.0.1:8790/v1
export TOKEN=dev-local-token

curl -sS "$CELLP_URL/health"
curl -sS -H "Authorization: Bearer $TOKEN" "$CELLP_URL/projects"
curl -sS -H "Authorization: Bearer $TOKEN" \
  "$CELLP_URL/projects/commerce-store/versions/v1"

Use preview_url / prod_url from the API for Gateway checks (Host routing, not /v1).

Self-hosted Workers control plane. Not affiliated with Cloudflare or Vercel.