How this works

deploy.registermysite.com already checks domains, provisions email, and deploys HTML. The expanded Worker adds a catalog without removing those routes. Health JSON at the root stays the same.

Preserved paths

  • GET / and /health — same JSON as today
  • POST /api/domain-check
  • POST /api/projects/:id/provision-and-deploy
  • GET /api/projects/:id/provision-status/:requestId
  • POST /api/projects/:id/deploy — HTML to an existing hostname

Catalog paths

  • GET /catalog — public program list
  • GET /catalog/:id — one program
  • POST /deploy — one catalog program onto a subdomain

POST /deploy

{
  "program": "live-chat",
  "workerName": "rms-live-chat",
  "subdomain": "chat-rooms",
  "env": { "ROOM_TITLE": "Support" },
  "config": { "roomTitle": "Support" }
}

Success returns liveUrl, workerName, hostname, bindings, and nextSteps. Unknown program ids are rejected. Optional Authorization: Bearer if DEPLOY_API_KEY is set on the Worker.

Frontend call

const { programs } = await fetch(base + "/catalog").then(r => r.json());

await fetch(base + "/deploy", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    program: "live-chat",
    subdomain: "chat-rooms",
    config: { roomTitle: "Support" }
  })
});

What deploy provisions

Catalog programs can declare KV, D1, R2, Workers AI, and text secrets. The orchestrator creates or reuses those resources, uploads the Worker, and attaches subdomain.ZONE_NAME via Workers custom domains. It never creates a new zone.

HTML path stays intact

POST /api/projects/:id/deploy still publishes raw HTML to an existing hostname. Catalog program html-page is the same serving Worker, but it lands on a subdomain of the account apex (registermysite.com) through POST /deploy.

Add a program

Add a template under orchestrator-worker/src/templates (or point source at GitHub / URL / R2), append an entry to CATALOG in catalog.ts, redeploy the Worker. Only listed ids are accepted.