# Email list (batch)

`POST /v1/email/batch` · **1 credit per address** (+5 each with `verify_mailbox`)

Use it to clean an existing list or to check a CSV import. Each address gets exactly the same result as [`/v1/email/check`](/docs/email-check), in the order you sent them.

## Request

| Field | Type | Required | Description |
|---|---|---|---|
| `emails` | array of strings | yes | 1 to 100 addresses. |
| `verify_mailbox` | boolean | no | Verify each mailbox over SMTP. Default `false`. |

```bash [curl]
curl https://veqen-app.com/v1/email/batch \
  -H "Authorization: Bearer $VEQEN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["ana@gmail.com", "bot@mailinator.com", "sales@acme.com"]}'
```

```python [Python]
import requests


def clean(addresses, key):
    keep = []
    for start in range(0, len(addresses), 100):
        chunk = addresses[start : start + 100]
        r = requests.post(
            "https://veqen-app.com/v1/email/batch",
            headers={"Authorization": f"Bearer {key}"},
            json={"emails": chunk},
            timeout=60,
        )
        r.raise_for_status()
        for item in r.json()["results"]:
            if item["risk"]["verdict"] != "refuse":
                keep.append(item.get("normalized") or item["email"])
    return keep
```

```javascript [JavaScript]
const res = await fetch("https://veqen-app.com/v1/email/batch", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.VEQEN_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ emails: ["ana@gmail.com", "bot@mailinator.com"] }),
});
const { results } = await res.json();
const keep = results.filter((r) => r.risk.verdict !== "refuse");
```

## Response

```json
{
  "count": 3,
  "results": [
    { "email": "ana@gmail.com", "disposable": false, "risk": { "score": 0, "verdict": "admit", "...": "..." } },
    { "email": "bot@mailinator.com", "disposable": true, "risk": { "score": 90, "verdict": "refuse", "...": "..." } },
    { "email": "sales@acme.com", "role_account": true, "risk": { "score": 15, "verdict": "admit", "...": "..." } }
  ]
}
```

Your balance must cover the whole batch before it runs (the number of addresses × the cost per address). Otherwise you get `insufficient_credits` and nothing is charged.
