# CDN

Trigger a Comvi CDN deployment from the REST API and read the published file URL layout.

Canonical: https://comvi.io/docs/api/cdn

The CDN endpoint enqueues a deployment. Once it finishes, an app loads translations straight from the CDN with the SDK's fetch loader.

## URL layout

```
https://cdn.comvi.io/<project-token>/<namespace>/<locale>.json
https://cdn.comvi.io/<project-token>/<locale>.json
```

| Segment | Meaning |
|---------|---------|
| `<project-token>` | The project's CDN token, from **Settings → Content Deploy** |
| `<namespace>` | Namespace name, such as `common`. The `default` namespace has no folder and is served at the project root |
| `<locale>` | Locale code, such as `en` |

### `POST /v1/projects/{projectId}/cdn/deploy`

Enqueue a background job that builds the translation files and uploads them to the CDN.

Session cookie only, with the `project.manage` permission. The route never reads the `Authorization` header, and `project.manage` has no entry in the API-key scope map, so no key can trigger a deploy. For CI, publish from the dashboard or rely on project auto-deploy. Rate limit: 50 deploys per user per project per 10 minutes.

| Parameter | In | Type | Required | Meaning |
|-----------|----|------|----------|---------|
| `projectId` | path | `integer` | Yes | Project ID |

```bash
curl -X POST -b cookies.txt https://api.comvi.io/v1/projects/5/cdn/deploy
```

Returns `202 Accepted` as soon as the job is queued. The deploy runs in the background, so `filesDeployed` is `0` here.

```json
{ "success": true, "filesDeployed": 0, "message": "enqueued" }
```

| Field | Type | Meaning |
|-------|------|---------|
| `success` | `boolean` | Whether the deployment was enqueued |
| `filesDeployed` | `integer` | Files deployed, `0` when enqueued |
| `message` | `string` | Status message |

| Status and code | When |
|-----------------|------|
| `401 AUTHENTICATION_REQUIRED` | No session cookie, or the session is no longer valid. A Bearer token lands here too |
| `403 EMAIL_NOT_VERIFIED` | The signed-in user has not confirmed their email address |
| `403 FORBIDDEN` | Missing `project.manage`. A project you cannot see returns this too, not `404` |
| `422 VALIDATION_ERROR` | `projectId` is not a positive integer. `meta` carries `field`, plus `expectedType` when it is not an integer or `minimum` when it is below `1`. No `message` |
| `429 TOO_MANY_REQUESTS` | More than 50 deploy requests in 10 minutes for this user and project |

## Next steps

- [CDN in the platform](/docs/platform/cdn) to configure what gets published
- [Fetch loader](/docs/i18n/plugins/fetch-loader) to load CDN translations in an app
- [CI/CD integration](/docs/platform/recipes/ci-cd-integration) for the deployment pipeline
