# Deployments

A deployment is one try to put a version of a service live: a build (for a GitHub service), then a start and a health check. If it works, it goes live and the one before it stops. If it fails, the one before it stays live.

The examples use `API=https://dudbox.com/api/v1` and `AUTH="Authorization: Bearer $DUDBOX_TOKEN"`.

## The deployment object

```json
{
  "id": 44,
  "service": "acme/shop",
  "status": "live",
  "done": true,
  "error": null,
  "trigger": "git",
  "created_at": "2026-11-04T09:30:00Z",
  "finished_at": "2026-11-04T09:31:12Z",
  "commit": { "sha": "9f2c…", "message": "Fix the cart", "branch": "main", "author": "rook", "repo": "acme/shop" },
  "rollback_of": null,
  "can_rollback": true
}
```

- `status`: `queued`, `building` and `starting` are in progress. `live`: it serves traffic now. `failed`: the build or the health check failed. `superseded`: it was live, then a newer one replaced it. `cancelled`: stopped before it went live.
- `done`: `true` when the status will not change any more. Wait for this.
- `error`: one line on why it failed. The build log has the rest.
- `commit`: `null` for a one-click app.
- `can_rollback`: its image is still kept, so a rollback to it needs no build.

### `GET /api/v1/services/{project}/{service}/deployments`

The newest 20 deployments of a service, newest first: `{"deployments": [Deployment, …]}`.

### `POST /api/v1/services/{project}/{service}/redeploy`

Starts the live version again, with the current env vars and no build. A one-click app pulls its image again. Use it after you change env vars.

```sh
curl -s -X POST $API/services/acme/shop/redeploy -H "$AUTH"
```

Answer: `201` with the new deployment. A service that was never built gets `400`.

### `POST /api/v1/services/{project}/{service}/deploy`

For a GitHub service: builds and deploys the newest commit of its branch now. A push does this by itself; use this when you do not want to wait or push.

Answer: `201` with the new deployment. A service without a repo gets `400`.

### `POST /api/v1/services/{project}/{service}/rollback`

Makes an older deployment live again, with no build. With no body, it goes to the deployment before the live one. With `{"to": 41}`, it goes to deployment 41. Only deployments with `"can_rollback": true` work.

```sh
curl -s -X POST $API/services/acme/shop/rollback -H "$AUTH" -H 'content-type: application/json' -d '{"to": 41}'
```

Answer: `201` with the new deployment (its `rollback_of` is 41).

### `GET /api/v1/deployments/{id}`

One deployment. With `?wait=N` (at most 300), the answer waits until the deployment is done or N seconds pass, then gives its status. This is the best way to wait for a deploy:

```sh
curl -s "$API/deployments/44?wait=300" -H "$AUTH"
```

If `done` is still `false` after the wait, call it again.

### `GET /api/v1/deployments/{id}/log`

The build and start log, as text in JSON:

```json
{ "deployment_id": 44, "log": "building with railpack…\n…", "offset": 18234, "done": true }
```

To get only new text, pass the last `offset` back: `GET .../log?offset=18234`. Secret env values are masked in the log.

### `GET /api/v1/deployments/{id}/events`

The deployment live, as server-sent events, until it is done:

- `deployment`: the deployment object, at the start and on each status change.
- `log`: new log text, as a JSON string.
- `end`: the final status, as a JSON string. Then the stream closes.

```sh
curl -sN $API/deployments/44/events -H "$AUTH"
```

```text
event: deployment
data: {"id":44,"service":"acme/shop","status":"building","done":false,…}

event: log
data: "installing packages\n"

event: end
data: "live"
```

`?offset=N` skips the first N characters of the log.

### `POST /api/v1/deployments/{id}/cancel`

Stops a deployment that is still `queued`, `building` or `starting`. The live one stays.

Answer: `200` with the deployment (now `cancelled`). A deployment that is done gets `409`.
