> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vertracloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Add Application Domain

> Adds a custom domain to a published application, without redeploying it, with optional www, port, path prefix and redirect.

Adds a custom domain to the application and answers `201 Created` with the new domain. The application is not
restarted or redeployed. The domain starts as `pending` until its DNS records resolve; read them with
[Domain DNS Records](/api-reference/endpoint/apps/domains/dns). Requires the `apps:write` scope when called with an API key.

By default the call also creates the automatic companion: `www.example.com` when you add `example.com`, or
`example.com` when you add `www.example.com`. The companion redirects to the domain you added with a `308`, and it
**does not count** toward your plan's domain limit. For any other subdomain (`app.example.com`) there is no companion.

**id** `string` *required*

The application ID. The application must be published on the web (it needs a `*.vertraweb.app` subdomain).

**workspace\_id** `string`

If the application belongs to a workspace, the workspace's ID. Required for workspace members acting on an application they don't own.

**hostname** `string` *required*

The domain to add (e.g., `example.com` or `api.example.com`), between 1 and 253 characters. It is stored in
lowercase. Send the bare hostname: a scheme, a path or a port is rejected with `INVALID_CUSTOM_DOMAIN_FORMAT`.
Domains that belong to Vertra Cloud are rejected with `FORBIDDEN_DOMAIN`.

**www** `boolean` (default: true)

Whether to create the automatic `www` (or root) companion. Send `false` to add only the hostname you sent. It has no
effect on subdomains other than `www`, and it is ignored when `redirect_to` is set.

**port** `integer` (default: 80)

The port of the application that serves this domain, an integer from `1` to `65535`. An application can serve its
domains on up to **5 different ports besides `80`**; a sixth answers `DOMAIN_PORT_LIMIT_REACHED`. A domain that only
redirects does not use a port.

**path\_prefix** `string`

A literal path added in front of every request the domain forwards to the application: with `/api`, a request for
`https://api.example.com/users` reaches the application as `/api/users`. It must start with `/`, must not end with
`/`, is up to 128 characters, and may only contain letters, digits, `.`, `_`, `~` and `-` between slashes
(e.g., `/api` or `/v1/api`). Recommended for APIs: a site must be built to run under that path, including its assets
and its own redirects.

**redirect\_to** `string`

The ID of another domain of the same application. The new domain then redirects every request to that domain,
keeping the path and the query string, instead of serving the application. The target must not redirect itself.

**redirect\_status** `integer` (default: 308)

The HTTP status of the redirect: `301`, `302`, `307` or `308`. Only used together with `redirect_to`. `301` and `308`
are permanent; `302` and `307` are temporary. `307` and `308` keep the request method; `301` and `302` may turn a
`POST` into a `GET`.

### Response

**response** `APIApplicationDomain[]`

The domain you added first, followed by its companion when one was created. Each item has the fields described in
[List Application Domains](/api-reference/endpoint/apps/domains/list#response).

```json Response (201) theme={null}
{
  "response": [
    {
      "id": "7b8f5e0a-3c1d-4e52-9a47-0d6e2c1f9b34",
      "hostname": "example.com",
      "apex": true,
      "companion_of": null,
      "redirect_to": null,
      "redirect_status": 308,
      "path_prefix": null,
      "port": 80,
      "status": "pending",
      "ssl_status": "pending",
      "created_at": "2026-10-21T14:02:11.000Z"
    },
    {
      "id": "c2a9d4f1-86b0-4a37-b5e8-1f3d7a9c0e62",
      "hostname": "www.example.com",
      "apex": false,
      "companion_of": "7b8f5e0a-3c1d-4e52-9a47-0d6e2c1f9b34",
      "redirect_to": "7b8f5e0a-3c1d-4e52-9a47-0d6e2c1f9b34",
      "redirect_status": 308,
      "path_prefix": null,
      "port": 80,
      "status": "pending",
      "ssl_status": "pending",
      "created_at": "2026-10-21T14:02:11.000Z"
    }
  ]
}
```

> [!NOTE]
>
> Custom domains start at the **Intermediary** plan (1 domain per application) and grow with the Enterprise tier. The
> automatic companion never counts. The limits per plan are in [Plans and limits](/plans-and-limits#how-many-custom-domains-and-ports-does-each-plan-allow).
> Unpublishing the application removes all of its domains. Removing a domain, by hand, by unpublishing or by the
> automatic cleanup, never changes your DNS: delete its `CNAME` and `TXT` records yourself, as explained in
> [Remove Application Domain](/api-reference/endpoint/apps/domains/delete).

### Error Responses

**code** `string`

The error code indicating the reason for the failure. Possible values:

* `VALIDATION_ERROR`: The path parameter or the body failed validation, for example an unknown field or a wrong type (`400`). The response also carries `message` and `path`.
* `INVALID_CUSTOM_DOMAIN_FORMAT`: `hostname` is not a valid public hostname (`400`).
* `FORBIDDEN_DOMAIN`: The domain is reserved and cannot be added (`400`).
* `INVALID_DOMAIN_PORT`: `port` is not an integer from 1 to 65535 (`400`).
* `INVALID_PATH_PREFIX`: `path_prefix` does not follow the format above (`400`).
* `INVALID_REDIRECT_TARGET`: `redirect_to` is not a domain of this application, is not `active`, or the target redirects itself (`400`).
* `APP_NOT_PUBLISHED`: The application is not published on the web; publish it first with [Publish Application on the Web](/api-reference/endpoint/apps/network/publish) (`400`).
* `UNAUTHORIZED`: The request is not authenticated (`401`).
* `USER_NOT_FOUND`: The authenticated user could not be resolved (`401`).
* `ACCESS_DENIED`: The user does not have permission to act on the application (`403`).
* `API_KEY_SCOPE_DENIED`: The API key does not have the `apps:write` scope (`403`).
* `PLAN_REQUIRED`: The application's owner has no active plan (`403`).
* `PLAN_DOES_NOT_SUPPORT_CUSTOM_DOMAIN`: The owner's plan does not include custom domains (`403`).
* `DOMAIN_LIMIT_REACHED`: The application already has as many domains as the plan allows (`403`). `details.limit` carries the limit.
* `DOMAIN_PORT_LIMIT_REACHED`: The application already serves domains on 5 ports besides `80` (`403`). `details.limit` carries the limit.
* `APP_NOT_FOUND`: The specified application does not exist (`404`).
* `DOMAIN_ALREADY_IN_USE`: The hostname is already attached to an application (`409`).
* `RATE_LIMIT_EXCEEDED`: The route's budget was reached (`429`).
* `CUSTOM_DOMAIN_REGISTRATION_FAILED`: The domain could not be registered right now; retry later (`502`).
* `INTERNAL_SERVER_ERROR`: Unexpected failure (`500`).

```json Error Response (403) theme={null}
{
  "code": "DOMAIN_LIMIT_REACHED",
  "details": { "limit": 1 }
}
```

```json Error Response (409) theme={null}
{
  "code": "DOMAIN_ALREADY_IN_USE"
}
```

> [!NOTE]
>
> This route has its own budget of 10 requests per minute. See [Rate Limiting](/api-reference/introduction#how-is-the-api-rate-limited).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.