Skip to content

API

The deploy API is internal and unstable. It exists for the npx wgw-deploy CLI, not as a versioned public API.

The hosted base URL is:

https://deploy.wgw.lol

The CLI can use another API with:

Terminal window
WGW_API_URL=https://deploy.example.com npx wgw-deploy

POST /projects creates a project and returns an apiToken once. Project-specific routes require:

  • Authorization: Bearer <apiToken>
  • projectHash in the JSON body
  • anonFingerprint in the JSON body

The server stores a hash of the API token, not the raw token.

Method Path Purpose
GET /health Health check.
GET /healthz Health check.
POST /projects Create a project and return project metadata plus a one-time API token.
POST /projects/:projectSlug/prepare Prepare a deploy, create an upload session, and return Cloudflare upload buckets.
POST /projects/:projectSlug/deploy Complete a prepared deploy and publish the static Worker update.
POST /projects/:projectSlug/domains Assign a generated or external domain.
DELETE /projects/:projectSlug/domains Reset a project back to its generated domain.
DELETE /projects/:projectSlug Delete the project metadata and remove it from the published manifest.
OPTIONS Any route CORS preflight.

Unknown /projects routes return 405. Other unknown routes return 404.

POST /projects
content-type: application/json
{
"projectHash": "<64 hex chars>",
"anonFingerprint": "<64 hex chars>"
}

The response includes public project metadata and apiToken. Store the token locally and treat it as a project credential.

POST /projects/:projectSlug/prepare
authorization: Bearer <apiToken>
content-type: application/json
{
"projectHash": "<64 hex chars>",
"anonFingerprint": "<64 hex chars>",
"manifest": {
"/project-slug/index.html": {
"hash": "<asset hash>",
"size": 1234
}
}
}

The response includes:

  • deployId
  • accountId
  • revisionId
  • uploadJwt
  • buckets
  • project
  • urls

The CLI uploads requested asset buckets directly to Cloudflare Workers Assets using the returned upload JWT. The deploy preparation record expires after 1 hour.

POST /projects/:projectSlug/deploy
authorization: Bearer <apiToken>
content-type: application/json
{
"projectHash": "<64 hex chars>",
"anonFingerprint": "<64 hex chars>",
"deployId": "<deploy id>",
"completionJwt": "<cloudflare completion jwt>"
}

The response includes the final revisionId, productionUrl, revisionUrl, and public project metadata.

Assign a domain:

POST /projects/:projectSlug/domains
authorization: Bearer <apiToken>
content-type: application/json
{
"projectHash": "<64 hex chars>",
"anonFingerprint": "<64 hex chars>",
"domain": "preview.example.com"
}

The response includes domain.hostname and domain.cnameTarget. For hosted wgw.lol, the CNAME target is cname.wgw.lol.

Delete the assigned domain:

DELETE /projects/:projectSlug/domains
authorization: Bearer <apiToken>
content-type: application/json
{
"projectHash": "<64 hex chars>",
"anonFingerprint": "<64 hex chars>"
}

This resets the project to its generated domain.

DELETE /projects/:projectSlug
authorization: Bearer <apiToken>
content-type: application/json
{
"projectHash": "<64 hex chars>",
"anonFingerprint": "<64 hex chars>"
}

The response is:

{
"projectSlug": "<project slug>",
"deleted": true
}

Errors are JSON and use either a string error or an object with code and message.

Expired projects return:

{
"error": {
"code": "PROJECT_EXPIRED",
"message": "project expired"
}
}

Other common failures include bad bearer tokens, ownership mismatch, invalid project hashes, invalid anonymous fingerprints, method-not-allowed responses, and Cloudflare API failures.