# Bulk verification

> Submit a list of addresses as an asynchronous batch, then poll for results. Quota for the full batch size is checked up front, before any items are processed.

Source: https://warmerly.com/docs/verify/bulk-verification

Submit a list of addresses as an asynchronous batch, then poll for results. Quota for the full batch size is checked up front, before any items are processed.

## Submit a batch

```text
POST /verify/bulk
```

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | No | Optional label for the batch. |
| `emails` | string[] | No | Array of addresses. |
| `text` | string | No | A pasted blob of addresses separated by whitespace, commas, or semicolons. |

Provide `emails`, `text`, or both, they're merged and de-duplicated. Addresses are trimmed and lower-cased, and anything without an `@` is dropped. A batch may contain at most 50,000 addresses. `name` is at most 120 characters.

```bash
curl https://app.warmerly.com/api/v1/verify/bulk \
  -X POST \
  -H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Q3 leads", "emails": ["jane@example.com", "john@example.com"] }'
```

```json
{
  "batch": {
    "id": "6f2c6c8e-9b1d-4e3a-9c7f-2d1e8b4a6c9e",
    "total": 2,
    "status": "processing"
  }
}
```

`201 Created` on success. Errors: `400 bad_request` (`invalid_body`, `no_valid_emails` or `batch_too_large_max_50000`), `403 channel_not_included` if your plan does not include email features, and `402 quota_exhausted` if the batch does not fit your remaining quota. The 402 `details` hold `label`, `used`, `limit`, `topUpUrl` and `upgradeUrl`, plus `topUp` when credits can cover the shortfall. Items still queued from your earlier batches count against the new one.

## Get batch status and results

```text
GET /verify/bulk/{id}
```

Returns the batch's progress and, for items that have been processed, their verification results.

```bash
curl https://app.warmerly.com/api/v1/verify/bulk/6f2c6c8e-9b1d-4e3a-9c7f-2d1e8b4a6c9e \
  -H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
```

```json
{
  "batch": {
    "id": "6f2c6c8e-9b1d-4e3a-9c7f-2d1e8b4a6c9e",
    "name": "Q3 leads",
    "status": "processing",
    "total": 2,
    "processed": 1,
    "createdAt": "2026-07-02T10:00:00.000Z",
    "completedAt": null
  },
  "items": [
    {
      "email": "jane@example.com",
      "recommendation": "Safe to send",
      "status": "valid",
      "confidence": 95,
      "reason": "mailbox_accepts"
    },
    {
      "email": "john@example.com",
      "recommendation": "Pending",
      "status": null,
      "confidence": null,
      "reason": null
    }
  ],
  "itemsTruncated": false,
  "itemsLimit": 1000
}
```

`batch.status` is `processing` or `completed`. The JSON view returns at most 1,000 `items`, in a stable order; `itemsTruncated` says whether the list was cut and `itemsLimit` is the cap (`1000`). Add `?all=1` for every item as JSON. Each item's `recommendation` is `Safe to send`, `Send with caution`, `Do not send`, `Unknown`, or `Pending` (not yet processed), a human-readable summary derived from `status`/`confidence`/`checks`. `404 not_found` if the batch doesn't exist or belongs to another user.

Pass `?format=csv` to download all results (not capped at 1,000) as a CSV file (`email,recommendation,status,confidence,reason`) instead of JSON. Items not yet processed show `pending` in the `status` column:

```bash
curl "https://app.warmerly.com/api/v1/verify/bulk/6f2c6c8e-9b1d-4e3a-9c7f-2d1e8b4a6c9e?format=csv" \
  -H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -o results.csv
```

## More from Verify

- [Verify a single email](https://warmerly.com/docs/verify/verify-a-single-email): Runs (or reuses a cached) verification for one address. Cached results are returned instantly and are not…
- [Verification history](https://warmerly.com/docs/verify/verification-history): Returns the recent single verifications (from POST /verify) recorded against your active workspace, most…
- [Send test (deliverability-grade check)](https://warmerly.com/docs/verify/send-test-deliverability-grade-check): Some addresses cannot be settled by SMTP probing alone, a catch-all domain accepts everything, so "accepted"…
