# Deployments

A deployment says that one product runs in one environment, at which URL and which version. Test runs target a deployment, and vault pulls read the secrets of one.

## The Deployment object

One product running in one environment.

### Attributes

- `id` (string, required): Unique ID of the deployment.
- `product` (object, required): The product that is deployed.
  - `id` (string, required): Unique ID of the product.
  - `slug` (string, required): Lowercase letters, digits and hyphens, unique in the workspace, such as storefront.
  - `name` (string, required): The product's display name.
  - `type` (string, one of: `website`, `api`, `cli`, `mobile_app`, `desktop_app`, `agent`, required): What kind of software the product is.
  - `archived` (boolean, required): Whether the product is archived.
- `environment` (object, required): The environment it is deployed to.
  - `id` (string, required): Unique ID of the environment.
  - `slug` (string, required): Lowercase letters, digits and hyphens, unique in the workspace, such as staging.
  - `name` (string, required): The environment's display name.
  - `class` (string, one of: `production`, `non-production`, required): Production holds real customer data; everything else is non-production.
  - `emoji` (nullable string, required): One emoji shown beside the environment's name, or null.
  - `archived` (boolean, required): Whether the environment is archived.
- `baseUrl` (nullable string, required): The http(s) URL where the product answers in this environment. Required for website and API products.
- `fixtureUrl` (nullable string, required): The deployment's Fixture API, which test runs call to create and delete test data, or null when it has none.
- `version` (nullable string, required): The build that is running, such as a git SHA, or null when unknown.
- `versionUpdatedAt` (nullable string, required): When `version` last changed, as an ISO 8601 timestamp.
- `active` (boolean, required): False while the product or the environment is archived.
- `createdAt` (string, required): When it was created, as an ISO 8601 timestamp.
- `updatedAt` (string, required): When it last changed, as an ISO 8601 timestamp.

### Example

```json
{
  "id": "Dp3FkR8wNv2T",
  "product": {
    "id": "Pr4GtY9sLm3B",
    "slug": "storefront",
    "name": "Storefront",
    "type": "website",
    "archived": false
  },
  "environment": {
    "id": "En8RqZ2vKp5D",
    "slug": "staging",
    "name": "Staging",
    "class": "non-production",
    "emoji": "🧪",
    "archived": false
  },
  "baseUrl": "https://staging.acme.dev",
  "fixtureUrl": "https://staging.acme.dev/fixtures",
  "version": "9f2c41e",
  "versionUpdatedAt": "2026-10-14T09:05:12.000Z",
  "active": true,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z"
}
```

## List deployments

`GET /v1/workspaces/{slug}/deployments`

Returns the workspace's deployments, optionally for one product or one environment.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `product` (string, in query): Only deployments of this product, by slug or ID.
- `environment` (string, in query): Only deployments to this environment, by slug or ID.
- `archived` (string, one of: `exclude`, `include`, `only`, in query): Whether to include deployments whose product or environment is archived. Defaults to exclude.

### Returns

Returns an object with these fields. The status is 200.

- `deployments` (array of objects, required): The deployments, sorted by product name and then environment name. See [the Deployment object](https://docs.qa.clankership.net/api/deployments/object.md).
  - `id` (string, required): Unique ID of the deployment.
  - `product` (object, required): The product that is deployed.
    - `id` (string, required): Unique ID of the product.
    - `slug` (string, required): Lowercase letters, digits and hyphens, unique in the workspace, such as storefront.
    - `name` (string, required): The product's display name.
    - `type` (string, one of: `website`, `api`, `cli`, `mobile_app`, `desktop_app`, `agent`, required): What kind of software the product is.
    - `archived` (boolean, required): Whether the product is archived.
  - `environment` (object, required): The environment it is deployed to.
    - `id` (string, required): Unique ID of the environment.
    - `slug` (string, required): Lowercase letters, digits and hyphens, unique in the workspace, such as staging.
    - `name` (string, required): The environment's display name.
    - `class` (string, one of: `production`, `non-production`, required): Production holds real customer data; everything else is non-production.
    - `emoji` (nullable string, required): One emoji shown beside the environment's name, or null.
    - `archived` (boolean, required): Whether the environment is archived.
  - `baseUrl` (nullable string, required): The http(s) URL where the product answers in this environment. Required for website and API products.
  - `fixtureUrl` (nullable string, required): The deployment's Fixture API, which test runs call to create and delete test data, or null when it has none.
  - `version` (nullable string, required): The build that is running, such as a git SHA, or null when unknown.
  - `versionUpdatedAt` (nullable string, required): When `version` last changed, as an ISO 8601 timestamp.
  - `active` (boolean, required): False while the product or the environment is archived.
  - `createdAt` (string, required): When it was created, as an ISO 8601 timestamp.
  - `updatedAt` (string, required): When it last changed, as an ISO 8601 timestamp.

### Request

```bash
curl https://api.qa.clankership.net/v1/workspaces/{slug}/deployments \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Response

```json
{
  "deployments": [
    {
      "id": "Dp3FkR8wNv2T",
      "product": {
        "id": "Pr4GtY9sLm3B",
        "slug": "storefront",
        "name": "Storefront",
        "type": "website",
        "archived": false
      },
      "environment": {
        "id": "En8RqZ2vKp5D",
        "slug": "staging",
        "name": "Staging",
        "class": "non-production",
        "emoji": "🧪",
        "archived": false
      },
      "baseUrl": "https://staging.acme.dev",
      "fixtureUrl": "https://staging.acme.dev/fixtures",
      "version": "9f2c41e",
      "versionUpdatedAt": "2026-10-14T09:05:12.000Z",
      "active": true,
      "createdAt": "2026-10-01T16:20:00.000Z",
      "updatedAt": "2026-10-14T09:05:12.000Z"
    }
  ]
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Create a deployment

`POST /v1/workspaces/{slug}/deployments`

Records that a product runs in an environment. A product has at most one deployment per environment.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `product` (string, required): The product to deploy, by slug or ID.
- `environment` (string, required): The environment to deploy it to, by slug or ID.
- `baseUrl` (nullable string): The http(s) URL where the product answers. Required for website and API products.
- `fixtureUrl` (nullable string): The http(s) URL of the deployment's Fixture API, which test runs call to create and delete test data.
- `version` (nullable string): The build that is running, such as a git SHA.

### Returns

Returns the [Deployment](https://docs.qa.clankership.net/api/deployments/object.md) object. The status is 201.

### Request

```bash
curl -X POST https://api.qa.clankership.net/v1/workspaces/{slug}/deployments \
  -H "Authorization: Bearer $CLANKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "product": "storefront",
    "environment": "staging",
    "baseUrl": "https://staging.acme.dev",
    "fixtureUrl": "https://staging.acme.dev/fixtures",
    "version": "9f2c41e"
  }'
```

### Response

```json
{
  "id": "Dp3FkR8wNv2T",
  "product": {
    "id": "Pr4GtY9sLm3B",
    "slug": "storefront",
    "name": "Storefront",
    "type": "website",
    "archived": false
  },
  "environment": {
    "id": "En8RqZ2vKp5D",
    "slug": "staging",
    "name": "Staging",
    "class": "non-production",
    "emoji": "🧪",
    "archived": false
  },
  "baseUrl": "https://staging.acme.dev",
  "fixtureUrl": "https://staging.acme.dev/fixtures",
  "version": "9f2c41e",
  "versionUpdatedAt": "2026-10-14T09:05:12.000Z",
  "active": true,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z"
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Get a deployment

`GET /v1/workspaces/{slug}/deployments/{product}/{environment}`

Returns the deployment of one product to one environment.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `product` (string, in path, required): The product's slug or ID, such as storefront.
- `environment` (string, in path, required): The environment's slug or ID, such as staging.

### Returns

Returns the [Deployment](https://docs.qa.clankership.net/api/deployments/object.md) object. The status is 200.

### Request

```bash
curl https://api.qa.clankership.net/v1/workspaces/{slug}/deployments/{product}/{environment} \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Response

```json
{
  "id": "Dp3FkR8wNv2T",
  "product": {
    "id": "Pr4GtY9sLm3B",
    "slug": "storefront",
    "name": "Storefront",
    "type": "website",
    "archived": false
  },
  "environment": {
    "id": "En8RqZ2vKp5D",
    "slug": "staging",
    "name": "Staging",
    "class": "non-production",
    "emoji": "🧪",
    "archived": false
  },
  "baseUrl": "https://staging.acme.dev",
  "fixtureUrl": "https://staging.acme.dev/fixtures",
  "version": "9f2c41e",
  "versionUpdatedAt": "2026-10-14T09:05:12.000Z",
  "active": true,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z"
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Update a deployment

`PATCH /v1/workspaces/{slug}/deployments/{product}/{environment}`

Changes only the fields sent. Send `version` after each deploy to record what is running.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `product` (string, in path, required): The product's slug or ID, such as storefront.
- `environment` (string, in path, required): The environment's slug or ID, such as staging.
- `baseUrl` (nullable string): The http(s) URL where the product answers. `null` clears it for products that do not need one.
- `fixtureUrl` (nullable string): The http(s) URL of the deployment's Fixture API. `null` clears it.
- `version` (nullable string): The build that is running, such as a git SHA. `null` clears it.

### Returns

Returns the [Deployment](https://docs.qa.clankership.net/api/deployments/object.md) object. The status is 200.

### Request

```bash
curl -X PATCH https://api.qa.clankership.net/v1/workspaces/{slug}/deployments/{product}/{environment} \
  -H "Authorization: Bearer $CLANKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "version": "4b7e0d2"
  }'
```

### Response

```json
{
  "id": "Dp3FkR8wNv2T",
  "product": {
    "id": "Pr4GtY9sLm3B",
    "slug": "storefront",
    "name": "Storefront",
    "type": "website",
    "archived": false
  },
  "environment": {
    "id": "En8RqZ2vKp5D",
    "slug": "staging",
    "name": "Staging",
    "class": "non-production",
    "emoji": "🧪",
    "archived": false
  },
  "baseUrl": "https://staging.acme.dev",
  "fixtureUrl": "https://staging.acme.dev/fixtures",
  "version": "9f2c41e",
  "versionUpdatedAt": "2026-10-14T09:05:12.000Z",
  "active": true,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z"
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Delete a deployment

`DELETE /v1/workspaces/{slug}/deployments/{product}/{environment}`

Removes the deployment. Its secret values are kept and return if the product is deployed to the environment again.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `product` (string, in path, required): The product's slug or ID, such as storefront.
- `environment` (string, in path, required): The environment's slug or ID, such as staging.

### Returns

Returns no content. The status is 204.

### Request

```bash
curl -X DELETE https://api.qa.clankership.net/v1/workspaces/{slug}/deployments/{product}/{environment} \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.
