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

# Checking domain availabilities in bulk

> Bulk-check up to 25 candidate domains per call before you order - filter premium and unusable, debounce against the 5-minute cache.

`POST /domains/availability` accepts up to 25 domains per call and returns one row per domain - available, taken, premium, or unusable for a specific provider. The cache is fresh for **5 minutes** per domain; stale rows return `reason: "stale"` and Peeker refreshes them in the background.

## Full workflow

```bash cURL · full workflow lines theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
BASE="https://api.peeker.ai/api/partner/v1"
AUTH="Authorization: Bearer pk_test_<your-key>"

# Step 1: Bulk-check the candidates the customer typed.
#         Up to 25 per request; debounce 250-400ms client-side.
curl -X POST "$BASE/domains/availability" \
  -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{ "domains": ["acme-mail.com", "team-acme.com", "premium-domain.com"] }'

# Step 2: Filter the response - show only orderable rows in your UI.
#         (Same call; pipe through jq to demonstrate the filter shape.)
curl -sS -X POST "$BASE/domains/availability" \
  -H "$AUTH" -H 'Content-Type: application/json' \
  -d '{ "domains": ["acme-mail.com", "team-acme.com", "premium-domain.com"] }' \
  | jq '.data.domains[] | select(.available and (.usable_for // [] | index("google")))'
```

## Steps in detail

<AccordionGroup>
  <Accordion title="1. Send the batch" defaultOpen>
    Per-row fields:

    | Field        | Meaning                                                                                                           |
    | ------------ | ----------------------------------------------------------------------------------------------------------------- |
    | `available`  | `true` if you can register and order it now.                                                                      |
    | `usable_for` | Which mail providers the domain can run - `["google", "microsoft"]`, `["google"]` only, or absent if unavailable. |
    | `premium`    | `true` if the registry classifies it as premium (high cost, manual procurement only).                             |
    | `reason`     | Present only when `available: false`. Possible values: `taken`, `premium`, `invalid`, `errored`, `stale`.         |

    ```javascript 200 OK theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
    {
      "data": {
        "domains": [
          { "domain": "acme-mail.com",      "available": true,  "usable_for": ["google", "microsoft"], "premium": false },
          { "domain": "team-acme.com",      "available": false, "premium": false, "reason": "taken"   },
          { "domain": "premium-domain.com", "available": false, "premium": true,  "reason": "premium" }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="2. Filter for orderable rows">
    In your UI, present any `available: true` row that includes the customer's chosen provider in
    `usable_for`. Hide premium and stale rows or surface them as "needs manual help."
  </Accordion>

  <Accordion title="3. Debounce in your UI">
    The availability cache is fresh for **5 minutes** per domain. Stale rows return `reason: "stale"` and Peeker refreshes them in the background.

    In a search box, debounce keystrokes by 250–400 ms and batch the latest typed candidates into one call. Don't fire one request per character - a single call with 25 domains is far cheaper (and burns one rate-limit token instead of 25).
  </Accordion>

  <Accordion title="4. Premium domains aren't orderable via API">
    If a row comes back with `premium: true`, you can't place an order against it - `POST /orders` rejects it with `premium_domain_not_supported`. Surface premiums as "contact us" in your UI; partners on a manual procurement plan can email support to acquire them.

    ```json 400 premium_domain_not_supported theme={"theme":{"light":"one-light","dark":"one-dark-pro"}}
    {
      "error": {
        "code":    "premium_domain_not_supported",
        "message": "A premium domain was submitted on the standard order flow",
        "field":   "domains",
        "details": { "domains": ["premium-domain.com"] }
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## What's next

<CardGroup cols={2}>
  <Card title="Buying domains & ordering" href="/guides/buying-domains">
    Take the available domains and place an order - Peeker buys from a partner registrar.
  </Card>

  <Card title="Importing domains & ordering" href="/guides/importing-domains">
    The customer already owns domains? Import them and order on top.
  </Card>
</CardGroup>
