# Check availability

> Check whether one domain, or up to 30 at once, is available and what it would cost.

## POST /api/v1/domains/search

Is this domain available, and what would it cost? Costs 1 quota point, and the answer is cached for 10 seconds per account. Together with `bulk-search` it is limited to 2 calls per second — see [Rate limits](https://www.domainnameapi.com/docs/getting-started/rate-limits/).

**Request**

```json
{
  "domainName": "apiname.com"
}
```

**Response — 200, available domain**

```json
{
  "success": true,
  "code": "1000",
  "reason": null,
  "operationMessage": null,
  "info": {
    "domainName": "apiname.com",
    "tld": "com",
    "status": "AVAILABLE",
    "reason": null,
    "isPremium": false,
    "isDocumentRequired": false,
    "price": 11.40,
    "currency": "USD",
    "period": 1
  }
}
```

**Response — 200, taken domain**

```json
{
  "success": true,
  "code": "2302",
  "reason": "Domain exists",
  "info": {
    "domainName": "apiname.com",
    "tld": "com",
    "status": "NOTAVAILABLE",
    "reason": "Domain exists",
    "isPremium": false,
    "isDocumentRequired": false,
    "price": 11.40,
    "currency": "USD",
    "period": 1
  }
}
```

:::note[`success: true` does not mean "available"]
`success` describes the *lookup*, not the domain. A successful lookup of a registered domain returns `success: true` with `info.status: "NOTAVAILABLE"`. **Read `info.status`**.
:::

**info.status values**

| Value | Meaning and what to do |
| --- | --- |
| `AVAILABLE` | Registrable now. Proceed to register. |
| `NOTAVAILABLE` | Taken. It may still be transferable — check with `/transfers/check`. |
| `UNSUPPORTEDTLD` | We do not sell this extension. Do not retry. |
| `INVALIDDOMAINNAME` | The name is syntactically invalid. |
| `ERROR` | The registry lookup failed. Retry after a short pause. |
| `NONE` | No result returned. |

**Fields that change your flow**

| Field | What it means for you |
| --- | --- |
| `price` | Your selling price for the **shortest** registration term this TLD offers — not necessarily one year. Check `period`. |
| `isPremium` | Registry-priced premium name. `price` is the registry quote with your margin applied, and **you can only register, renew or transfer it for one year**. |
| `isDocumentRequired` | Registration will not complete until you upload documents. Plan the [document flow](https://www.domainnameapi.com/docs/domains/documents/) before selling this domain. |

**Errors**

| Code | Meaning and fix |
| --- | --- |
| `DnaValidationError` | `domainName` empty. |
| `Dna.DomainService:Domain:10005` | Invalid domain name. |
| `Dna.DomainService:Domain:10004` | We do not sell this extension. |
| `Dna.DomainService:Domain:10017` | Registry search temporarily unavailable. Retry. |
| `Dna.DomainService:Price:10001` | No price configured for this extension. Open a ticket. |

## POST /api/v1/domains/bulk-search

Up to **30** domains in one call. Use this for search-result pages and extension suggestions.

**Request — a JSON array, not an object**

```json
[
  { "domainName": "apiname.com" },
  { "domainName": "apiname.net" },
  { "domainName": "apiname.org" },
  { "domainName": "apiname.com.tr" }
]
```

**Response — 200**

```json
{
  "success": true,
  "code": "1000",
  "reason": null,
  "operationMessage": null,
  "infos": [
    { "domainName": "apiname.com", "tld": "com", "status": "NOTAVAILABLE",
      "isPremium": false, "isDocumentRequired": false,
      "price": 11.40, "currency": "USD", "period": 1 },
    { "domainName": "apiname.net", "tld": "net", "status": "AVAILABLE",
      "isPremium": false, "isDocumentRequired": false,
      "price": 13.20, "currency": "USD", "period": 1 },
    { "domainName": "apiname.org", "tld": "org", "status": "AVAILABLE",
      "isPremium": false, "isDocumentRequired": false,
      "price": 12.80, "currency": "USD", "period": 1 }
  ]
}
```

:::danger[Two traps in this response]
1. **`infos` can be shorter than your request.** In the example above four domains were asked about and three came back — `apiname.com.tr` was dropped. Entries are skipped silently when the name is invalid, the extension is unknown, or no price is configured. **Match results back by `infos[].domainName`, never by array index.** Anything missing should be treated as "unknown", not "available".
2. **The top-level `success`, `code`, `reason` and `operationMessage` are not per-domain.** They reflect the last entry processed. Ignore them and read `infos[]`.
:::

:::note[Cost]
This costs **10 points**, not 1 — it is a bulk write-weight operation. Even so, 30 domains in one `bulk-search` (10 points) is three times cheaper than 30 separate `search` calls (30 points), as well as far faster.
:::

**Errors**

| Code | Meaning and fix |
| --- | --- |
| `Dna.Domainservice:Domain:10036` | More than 30 domains. Split into batches of 30. |
