## POST /api/v2/shared-hosting/{accountId}/domains

**Add hosting addon domain**

Provision an addon domain inside a shared-hosting account that supports cPanel control-panel domain management. Send the full hostname in `domain`; do not pass a raw domain name as `{accountId}` and do not use the retired `subdomain` field. `dir` is optional and must be a safe relative path. If this returns `account_not_eligible_cpanel`, the selected hosting account uses HostUp's legacy control panel. Use the control panel SSO link to add the domain manually, or open a support ticket using a slug from `GET /api/v2/support/departments` and ask to migrate the account to a newer cPanel-backed plan.

### Related Endpoints

- `GET /api/v2/shared-hosting/{accountId}/domains`: List hosting domains
- `DELETE /api/v2/shared-hosting/{accountId}/domains`: Remove hosting addon domain
- `GET /api/v2/shared-hosting/{accountId}`: Get shared-hosting account

### Headers

- `Accept`: application/json
- `Authorization`: Bearer YOUR_API_KEY
- Required API scopes: `write:hosting`, `console:services`
- `Content-Type`: application/json

### Parameters

- `accountId` (path, string, required): Public shared-hosting account ID. Get it from GET /api/v2/shared-hosting `data[].id`. Do not invent this value; use the exact ID returned by the referenced API response. Example: `acct_01hxa3b4c5d6e7f8g9h0j1k2m3`

### Request Body

- `domain` (string, required) Example: `shop.example.com`
- `dir` (string, optional): Relative directory under the hosting account. Must not start with `/` and must not contain `..`. Example: `public_html/shop.example.com`

### Request Examples

#### Add addon domain

```bash
curl -X POST "https://cloud.hostup.se/api/v2/shared-hosting/acct_01hxa3b4c5d6e7f8g9h0j1k2m3/domains" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "shop.example.com",
    "dir": "public_html/shop.example.com"
  }'
```

```json
{
  "domain": "shop.example.com",
  "dir": "public_html/shop.example.com"
}
```

### Response Schema

- `domain` (string, required)
- `kind` (string, required)
  Allowed values: addon
- `documentRoot` (string, required)

### Responses

#### 201 - Addon domain added.
```json
{
  "domain": "shop.example.com",
  "kind": "addon",
  "documentRoot": "public_html/shop.example.com"
}
```

#### 400 - Invalid request body, for example an invalid `domain` hostname or unsafe `dir` path.
```json
{
  "type": "https://developer.hostup.se/errors/invalid_request",
  "title": "Validation failed",
  "status": 400,
  "detail": "The request body failed validation.",
  "code": "invalid_request",
  "instance": "/api/v2/orders",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z",
  "errors": [
    {
      "pointer": "/items/0/eppCode",
      "detail": "`eppCode` is required for this transfer.",
      "code": "missing_required"
    }
  ],
  "extensions": {}
}
```

#### 401 - Unauthorized. Authentication is required.
```json
{
  "type": "https://developer.hostup.se/errors/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication is required.",
  "code": "unauthorized",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z"
}
```

#### 403 - Forbidden. The caller lacks a required scope or does not own the resource.
```json
{
  "type": "https://developer.hostup.se/errors/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "The caller lacks a required scope or does not own the resource.",
  "code": "forbidden",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z"
}
```

#### 404 - Not found. The resource does not exist or is not owned by the caller.
```json
{
  "type": "https://developer.hostup.se/errors/not_found",
  "title": "Not found",
  "status": 404,
  "detail": "The requested resource could not be found.",
  "code": "not_found",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z"
}
```

#### 409 - The hosting account is not eligible for addon-domain management through this API.
```json
{
  "type": "https://developer.hostup.se/errors/account_not_eligible_cpanel",
  "title": "Control panel action unavailable",
  "status": 409,
  "detail": "Addon domain management is only supported for hosting accounts on the cPanel control panel. This account uses HostUp's legacy control panel. Use the control panel SSO link to make the change manually, or contact support to migrate the account to a newer cPanel-backed plan.",
  "instance": "/api/v2/shared-hosting/acct_01hxa3b4c5d6e7f8g9h0j1k2m3/domains",
  "code": "account_not_eligible_cpanel"
}
```

#### 429 - Rate limited. Retry after the limit resets. 429 responses include `Retry-After` seconds plus `X-RateLimit-*` headers.
```json
{
  "type": "https://developer.hostup.se/errors/rate_limit_exceeded",
  "title": "Too many requests",
  "status": 429,
  "detail": "Too many requests. Retry after the limit resets.",
  "code": "rate_limit_exceeded",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z"
}
```

#### 500 - Internal error. Retry later or contact support if the issue persists.
```json
{
  "type": "https://developer.hostup.se/errors/internal_error",
  "title": "Internal server error",
  "status": 500,
  "detail": "An unexpected error occurred. Retry later or contact support if the issue persists.",
  "code": "internal_error",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z"
}
```
