# Error format

> The envelope every error uses, how validation and insufficient-balance errors look, and how to read an error code.

Every error carries the same envelope:

```json
{
  "error": {
    "code": "Dna.DomainService:Domain:10007",
    "message": "The domain name you requested could not be found. Please check and try again.",
    "details": "apiname.com was not found"
  }
}
```

| Field | Use it for |
| --- | --- |
| `code` | **Your logic.** Stable and contractual — it does not change. |
| `message` | **Showing the user.** Localised, and we reword it over time. |
| `details` | **Your logs.** Says which domain, which field, which limit. |

:::danger[Branch on `code`, never on `message`]
Messages are translated and get reworded for clarity. Code that matches on message text will break without warning. Match on `code`, log `details`, show `message`.
:::

## Validation errors

When a request fails field validation, the envelope gains a `validationErrors` array telling you exactly which fields were wrong. The `members` entry is prefixed with the contact role when the problem is in a contact, so you can map it straight onto your form.

```json
{
  "error": {
    "code": "Dna.DomainService:ValidationError",
    "message": "Validation failed. Please check the provided information.",
    "validationErrors": [
      {
        "message": "Registrant Country is required.",
        "members": ["Registrant.Country"]
      },
      {
        "message": "Admin PhoneCountryCode must contain only digits (e.g., 90). Please do not use the '+' sign.",
        "members": ["Admin.PhoneCountryCode"]
      }
    ]
  }
}
```

## Insufficient balance

Balance errors add a `data` object so you can tell the user exactly how much to top up, without a second API call.

```json
{
  "error": {
    "code": "Dna.DomainService:Deposit:10001",
    "message": "Insufficient balance",
    "details": "Your balance is insufficient to complete this transaction.",
    "data": {
      "tryBalance": 120.50,
      "usdBalance": 3.10,
      "requiredAmount": 11.40,
      "requiredAmountCurrency": "USD"
    }
  }
}
```

## Reading error codes

Codes are structured as `Service:Area:Number`. The area tells you where to look first:

- `…:Domain:` — domain operations
- `…:Contact:` — contact data
- `…:Contact:Verification:` — e-mail / ownership verification
- `…:Dns:` — name servers and glue
- `…:Dnssec:` — DNSSEC
- `…:TldAttribute:` — TLD-specific extra fields
- `…:Deposit:` — balance
- `…:Reseller:` — account state
- `ZoneClient:` — DNS records
- `Ssl:` — certificates

The full catalogue is in [Error codes](https://www.domainnameapi.com/docs/reference/errors/).

:::caution[A handful of codes carry two meanings]
For a small number of codes the same code string is used for two different conditions. The important one is `Dna.DomainService:Domain:10058`, which can mean either "the domain name mixes multiple alphabets" (your input was rejected, nothing happened) or "the domain was created at the registry but we could not record it" (**do not retry**). Where this applies the error reference says so — for those specific codes, read `message` as well as `code`.
:::
