---
title: API
description: Current internal deploy API routes used by the CLI.
---

# 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:

```txt
https://deploy.wgw.lol
```

The CLI can use another API with:

```sh
WGW_API_URL=https://deploy.example.com npx wgw-deploy
```

## Authentication

`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.

## Routes

| 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`.

## Create project

```http
POST /projects
content-type: application/json
```

```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.

## Prepare deploy

```http
POST /projects/:projectSlug/prepare
authorization: Bearer <apiToken>
content-type: application/json
```

```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.

## Complete deploy

```http
POST /projects/:projectSlug/deploy
authorization: Bearer <apiToken>
content-type: application/json
```

```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.

## Domains

Assign a domain:

```http
POST /projects/:projectSlug/domains
authorization: Bearer <apiToken>
content-type: application/json
```

```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:

```http
DELETE /projects/:projectSlug/domains
authorization: Bearer <apiToken>
content-type: application/json
```

```json
{
  "projectHash": "<64 hex chars>",
  "anonFingerprint": "<64 hex chars>"
}
```

This resets the project to its generated domain.

## Delete project

```http
DELETE /projects/:projectSlug
authorization: Bearer <apiToken>
content-type: application/json
```

```json
{
  "projectHash": "<64 hex chars>",
  "anonFingerprint": "<64 hex chars>"
}
```

The response is:

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

## Errors

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

Expired projects return:

```json
{
  "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.
