> For the complete documentation index, see [llms.txt](https://umber.gitbook.io/umber/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://umber.gitbook.io/umber/api-reference-v2/collections/collection-deployment.md).

# Collection Deployment API

Deploying a [Virtual Collection](/umber/concepts/virtual-collections.md) puts the whole bundle of items behind one stable URL per environment. Unlike a version, a collection has no Default pointer — just Live and Offline (see [Deployment States](/umber/concepts/deployment-states.md), "Virtual Collections have no default concept at all"). This reference covers deploy (which folds in redeploy), deployment status, deployed URL, and undeploy.

{% hint style="info" %}
This is a low-level HTTP reference. For the dashboard equivalent, see [Managing Deployments](/umber/guides/managing-deployments.md).
{% endhint %}

## Base URL and authentication

```
https://api.umbercloud.io/api/v2/{domainId}/vc/{collectionId}/deployments
```

Authenticate with the same `apikey` header as the [Virtual Assets API](/umber/api-reference-v2/virtual-assets.md#base-url-and-authentication).

{% hint style="warning" %}
**The target environment for deploying is implicit, not part of the URL.** Deploy relies on the environment your `apikey` is scoped to (see [Environments](/umber/concepts/environments.md)) — there's no `envId` path segment on that call, unlike getting a deployed URL or undeploying, which both take `{envId}` explicitly in the path. If you're using a domain-wide key rather than one scoped to a specific environment, pass `envId` in the body.
{% endhint %}

## Errors

Every error is a small JSON body, same shape as [the Virtual Assets API](/umber/api-reference-v2/virtual-assets.md#errors).

| Status | Meaning                                                                                                                                                                                                                                                                                                                                                                         |
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | `collectionId` not found (used for this on every endpoint here except deployment status, which uses `404`); the collection isn't deployable, or has no items; deploy/offline requested but the collection isn't in the required state to do so; redeploy requested on a collection that isn't deployed anywhere yet; undeploy requested for an environment where it isn't Live. |
| `403`  | Missing or invalid `apikey`, or the key's environment doesn't match one explicitly requested.                                                                                                                                                                                                                                                                                   |
| `404`  | `collectionId` not found, specifically for [deployment status](#get-deployment-status).                                                                                                                                                                                                                                                                                         |
| `500`  | Missing `createdBy`/`updatedBy`, or an unexpected failure.                                                                                                                                                                                                                                                                                                                      |

***

## Deploy / take offline

`POST /api/v2/{domainId}/vc/{collectionId}/deployments`

One endpoint, two outcomes, selected by `state` in the body. Both require the collection to be deployable and have at least one item.

### Deploy Live

{% tabs %}
{% tab title="JSON" %}

```json
{ "state": "LIVE", "createdBy": "dev@acme-games.com" }
```

{% endtab %}

{% tab title="cURL" %}

```bash
curl -X POST "https://api.umbercloud.io/api/v2/acme-games/vc/season-pass-bundle/deployments" \
  -H "apikey: $ASSET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "state": "LIVE", "createdBy": "dev@acme-games.com" }'
```

{% endtab %}
{% endtabs %}

`201 Created`

```json
{ "downloadUrl": "https://assets.umbercloud.io/api/vc/acme-games/season-pass-bundle/prod" }
```

Fetching that `downloadUrl` doesn't return a file — it returns JSON with a download path for every item in the collection. See [Getting a single item's download URL](#getting-a-single-items-download-url) below.

### Take Offline

{% tabs %}
{% tab title="JSON" %}

```json
{ "state": "OFFLINE", "updatedBy": "dev@acme-games.com" }
```

{% endtab %}

{% tab title="cURL" %}

```bash
curl -X POST "https://api.umbercloud.io/api/v2/acme-games/vc/season-pass-bundle/deployments" \
  -H "apikey: $ASSET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "state": "OFFLINE", "updatedBy": "dev@acme-games.com" }'
```

{% endtab %}
{% endtabs %}

`201 Created`

```json
{ "message": "Asset collection is now OFFLINE." }
```

Requires the collection to currently be Live in the target environment. The deployment row itself isn't removed — it's kept and marked Offline, so it can be set Live again later without redeploying (see [Undeploy](#undeploy) for the alternative that does remove it).

### Redeploy every Live environment

`POST /api/v2/{domainId}/vc/{collectionId}/deployments?reconcile=true`

Re-runs the Live-deploy write for **every** environment where this collection is currently Live, at once — useful after changing the collection's items or cache settings, to push those changes everywhere without redeploying each environment by hand. `state` in the body is ignored for this call.

{% tabs %}
{% tab title="JSON" %}

```json
{ "createdBy": "dev@acme-games.com" }
```

{% endtab %}

{% tab title="cURL" %}

```bash
curl -X POST "https://api.umbercloud.io/api/v2/acme-games/vc/season-pass-bundle/deployments?reconcile=true" \
  -H "apikey: $ASSET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "createdBy": "dev@acme-games.com" }'
```

{% endtab %}
{% endtabs %}

`200 OK`

```json
{ "message": "Collection season-pass-bundle has been redeployed on 2 envs" }
```

`400` if it isn't Live in any environment yet — reconcile only refreshes environments that are already Live, it never deploys a new one.

## Get deployment status

`GET /api/v2/{domainId}/vc/{collectionId}/deployments`

A per-environment breakdown of which of the collection's items are Live, Offline, or never deployed there.

```bash
curl "https://api.umbercloud.io/api/v2/acme-games/vc/season-pass-bundle/deployments" \
  -H "apikey: $ASSET_API_KEY"
```

`200 OK`

```json
{
  "collectionId": "season-pass-bundle",
  "collectionName": "Season Pass Bundle",
  "items": [
    {
      "envId": "prod",
      "live": ["a1b2c3d4e5f6", "b2c3d4e5f6a1"],
      "offline": [],
      "undeployed": []
    },
    {
      "envId": "staging",
      "live": [],
      "offline": ["a1b2c3d4e5f6", "b2c3d4e5f6a1"],
      "undeployed": []
    }
  ]
}
```

{% hint style="warning" %}
`404` from this endpoint means either `collectionId` doesn't exist, **or** it exists but has never been deployed to any environment — those two cases aren't distinguishable from the response alone.
{% endhint %}

## Get a deployed URL

`GET /api/v2/{domainId}/vc/{collectionId}/deployments/{envId}`

```bash
curl "https://api.umbercloud.io/api/v2/acme-games/vc/season-pass-bundle/deployments/prod" \
  -H "apikey: $ASSET_API_KEY"
```

`200 OK`

```json
{ "downloadUrl": "https://adn.umbercloud.io/api/vc/acme-games/season-pass-bundle/prod" }
```

Fetching that `downloadUrl` doesn't return a file — it returns JSON with a download path for every item in the collection. See [Getting a single item's download URL](#getting-a-single-items-download-url) below.

`400` if there's no deployed URL for this `collectionId` + `envId` — which covers "never deployed here" and "deployed here, then taken Offline" identically. Use [deployment status](#get-deployment-status) if you need to tell those apart.

### Getting a single item's download URL

The collection's `downloadUrl` (above) is itself an endpoint — fetching it (a plain `GET`, no `apikey` needed unless the collection is `secured`) returns a JSON document, not a file:

```bash
curl "https://assets.umbercloud.io/api/vc/acme-games/season-pass-bundle/prod"
```

```json
{
  "downloadUrl": "/acme-games/season-pass-bundle/prod",
  "anchorAsset": {
    "assetItemId": "a1b2c3d4e5f6",
    "assetItemName": "Season Banner",
    "downloadUrl": "/acme-games/season-pass-bundle/a1b2c3d4e5f6/prod/generic",
    "targetPlatform": "generic",
    "mimetype": "image/png"
  },
  "assetItemUrls": [
    {
      "assetItemId": "a1b2c3d4e5f6",
      "assetItemName": "Season Banner",
      "downloadUrl": "/acme-games/season-pass-bundle/a1b2c3d4e5f6/prod/generic",
      "targetPlatform": "generic",
      "mimetype": "image/png"
    }
  ],
  "collectionId": "season-pass-bundle",
  "domainId": "acme-games",
  "envId": "prod",
  "secured": true,
  "localCacheControl": false,
  "localCacheMaxAge": 30,
  "targetPlatform": "generic"
}
```

`anchorAsset` is the collection's default item (see [Get a collection](/umber/api-reference-v2/collections.md#get-a-collection) → `anchorAsset`). `assetItemUrls` lists every item currently in the collection, each with its own `downloadUrl` — that's how you get a single item's URL: fetch the collection's `downloadUrl` and pick the item you want out of this array.

Every `downloadUrl` in this response is a path only, no host. To actually download a file, prefix it with the Asset Delivery Network's base URL:

```
https://adn.umbercloud.io/api/vi{downloadUrl}
```

e.g.:

```
https://adn.umbercloud.io/api/vi/acme-games/season-pass-bundle/a1b2c3d4e5f6/prod/generic
```

{% hint style="warning" %}
**This is a different service from `api.umbercloud.io`.** `adn.umbercloud.io` is the Asset Delivery Network — it streams the file itself, rather than returning JSON. If the item (or its parent collection) is `secured: true`, include the same `apikey: <key>` header used elsewhere in this reference; unsecured items need no auth.
{% endhint %}

This only resolves once the collection has actually been deployed Live to that environment.

## Undeploy

`DELETE /api/v2/{domainId}/vc/{collectionId}/deployments/{envId}`

Removes the environment's deployment record entirely, rather than marking it Offline — there's no way to make it Live again afterward except deploying it fresh.

{% tabs %}
{% tab title="JSON" %}

```json
{ "updatedBy": "dev@acme-games.com" }
```

{% endtab %}

{% tab title="cURL" %}

```bash
curl -X DELETE "https://api.umbercloud.io/api/v2/acme-games/vc/season-pass-bundle/deployments/prod" \
  -H "apikey: $ASSET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "updatedBy": "dev@acme-games.com" }'
```

{% endtab %}
{% endtabs %}

`200 OK`

```json
{ "message": "Asset collection season-pass-bundle has been undeployed." }
```

`400` if it isn't currently Live there — including if it was already taken Offline. Offline collections need this call skipped rather than retried, since Offline and "never deployed" both fail this same check.

{% hint style="info" %}
See [Deployment States](/umber/concepts/deployment-states.md) for what Live and Offline mean, and [Managing Deployments](/umber/guides/managing-deployments.md) for the equivalent dashboard actions.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://umber.gitbook.io/umber/api-reference-v2/collections/collection-deployment.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
