## GET /api/v2/shared-hosting/{accountId}/email-deliverability

**Inspect cPanel email authentication records**

Read cPanel Email Deliverability's current DKIM, SPF and DMARC validation for one domain hosted on the account. The response includes cPanel's exact required DKIM TXT owner and public value. This endpoint is strictly read-only: it does not generate DKIM keys and does not install or change DNS records. `spf.state: valid_hostup_policy` means cPanel's generated direct-IP/MailChannels comparison reports a warning while the domain uses HostUp's centralized `include:spf.hostup.se` sending policy; clients must not replace that policy with a second SPF record. The domain must belong to the cPanel account.

### Related Endpoints

- `GET /api/v2/shared-hosting/{accountId}`: Get shared-hosting account
- `PATCH /api/v2/shared-hosting/{accountId}`: Rename shared-hosting account
- `GET /api/v2/shared-hosting/{accountId}/backups`: List hosting backups

### Headers

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

### Parameters

- `domain` (query, string, required): Hosted domain whose DKIM, SPF and DMARC records should be inspected. Example: `example.com`
- `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 Example

```bash
curl -X GET "https://cloud.hostup.se/api/v2/shared-hosting/acct_01hxa3b4c5d6e7f8g9h0j1k2m3/email-deliverability?domain=example.com" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
```

### Response Schema

- `domain` (string, required) Example: `example.com`
- `readOnly` (boolean, required)
  Allowed values: true
- `source` (string, required)
  Allowed values: cpanel_emailauth
- `dkim` (object, required)
- `dkim.state` (string, required)
  Allowed values: valid, missing, invalid, unknown
- `dkim.cpanelState` (string, required) Example: `VALID`
- `dkim.name` (string, required, nullable): Nullable (may be null when not applicable). Example: `default._domainkey.example.com`
- `dkim.type` (string, required)
  Allowed values: TXT
- `dkim.requiredValue` (string, required, nullable): Nullable (may be null when not applicable). Example: `v=DKIM1; k=rsa; p=MIIBIjANBgkqh...;`
- `dkim.currentValues` (array<string>, required)
- `dkim.matchesRequired` (boolean, required)
- `dkim.error` (string, required, nullable): Nullable (may be null when not applicable).
- `spf` (object, required)
- `spf.state` (string, required)
  Allowed values: valid, valid_hostup_policy, missing, invalid, unknown
- `spf.cpanelState` (string, required) Example: `INVALID`
- `spf.name` (string, required) Example: `example.com`
- `spf.type` (string, required)
  Allowed values: TXT
- `spf.cpanelRequiredMechanisms` (string, required, nullable): Nullable (may be null when not applicable). Example: `ip4:185.113.11.23 include:relay.mailchannels.net`
- `spf.currentValues` (array<string>, required)
- `spf.sendingIp` (string, required, nullable): Nullable (may be null when not applicable). Example: `185.113.11.23`
- `spf.hostupPolicyDetected` (boolean, required)
- `spf.explanation` (string, required, nullable): Nullable (may be null when not applicable).
- `spf.error` (string, required, nullable): Nullable (may be null when not applicable).
- `dmarc` (object, required)
- `dmarc.state` (string, required)
  Allowed values: valid, valid_with_cpanel_spf_warning, missing, invalid, unknown
- `dmarc.cpanelState` (string, required) Example: `SPF_ERROR`
- `dmarc.name` (string, required) Example: `_dmarc.example.com`
- `dmarc.type` (string, required)
  Allowed values: TXT
- `dmarc.currentValue` (string, required, nullable): Nullable (may be null when not applicable). Example: `v=DMARC1; p=quarantine`
- `dmarc.explanation` (string, required, nullable): Nullable (may be null when not applicable).
- `dmarc.error` (string, required, nullable): Nullable (may be null when not applicable).
- `decision` (string, required)
  Allowed values: configured, action_required, unavailable
- `nextAction` (object, required)
- `nextAction.code` (string, required)
  Allowed values: none, publish_dkim, generate_dkim_key, review_spf, review_dmarc, retry_later
- `nextAction.message` (string, required)

### Responses

#### 200 - Current cPanel email-authentication assessment and required public records.
```json
{
  "domain": "example.com",
  "readOnly": true,
  "source": "cpanel_emailauth",
  "dkim": {
    "state": "valid",
    "cpanelState": "VALID",
    "name": "default._domainkey.example.com",
    "type": "TXT",
    "requiredValue": "v=DKIM1; k=rsa; p=MIIBIjANBgkqh...;",
    "currentValues": [
      "v=DKIM1; k=rsa; p=MIIBIjANBgkqh...;"
    ],
    "matchesRequired": true,
    "error": null
  },
  "spf": {
    "state": "valid_hostup_policy",
    "cpanelState": "INVALID",
    "name": "example.com",
    "type": "TXT",
    "cpanelRequiredMechanisms": "ip4:185.113.11.23 include:relay.mailchannels.net",
    "currentValues": [
      "v=spf1 mx include:spf.hostup.se ~all"
    ],
    "sendingIp": "185.113.11.23",
    "hostupPolicyDetected": true,
    "explanation": "cPanel reports its generated direct IP and MailChannels mechanisms as missing, but this domain uses HostUp's centralized include:spf.hostup.se policy, which intentionally covers that HostUp sending path. Do not replace it with cPanel's expanded suggestion.",
    "error": null
  },
  "dmarc": {
    "state": "valid_with_cpanel_spf_warning",
    "cpanelState": "SPF_ERROR",
    "name": "_dmarc.example.com",
    "type": "TXT",
    "currentValue": "v=DMARC1; p=quarantine",
    "explanation": "The DMARC TXT record is present. cPanel's DMARC warning is inherited from the same SPF mechanism-comparison warning, not from a missing DMARC record.",
    "error": "SPF record not valid"
  },
  "decision": "configured",
  "nextAction": {
    "code": "none",
    "message": "No DNS change is required from this cPanel Email Deliverability result."
  }
}
```

#### 400 - Invalid request. The response body is an RFC 7807 Problem Details document.
```json
{
  "type": "https://developer.hostup.se/errors/invalid_request",
  "title": "Invalid request",
  "status": 400,
  "detail": "The request body failed validation.",
  "code": "invalid_request",
  "instance": "/api/v2/resource",
  "requestId": "req_01hxa3b4c5d6e7f8g9h0j1k2m3",
  "timestamp": "2026-04-27T12:34:56.000Z",
  "errors": [
    {
      "pointer": "/items/0/domainName",
      "detail": "`domainName` is required.",
      "code": "invalid_request"
    }
  ]
}
```

#### 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 - The requested domain is not hosted on this account.

#### 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 account is not on the cPanel platform.

#### 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"
}
```

#### 502 - cPanel email-authentication validation is temporarily unavailable.
