# Check if emails work

`POST /api/v1/verify`

Checks each email with the mail server. "Takes any name" addresses (the server accepts everything) get a second check and come back as Probably works or Not sure. Send `emails`, `rows` with an `email` field, or a `listId`.

**Credits:** 0.1 credits per email that Works (you only pay when the email works (bad or unclear emails are free)). Rows your account already got an answer for in the last 30 days are answered again for free (`cached30d`).

## Body (JSON)

| Name | Type | Required | What it is |
| --- | --- | --- | --- |
| `listId` | integer |  | Run on a list you already have (from POST /api/v1/lists or a search) instead of `rows`. |
| `contactIds` | array of integer |  | With listId: only these rows (default: all rows of the list). up to 50,000 |
| `name` | string |  | Name of the new list (shown in the app). Default: "API <action> (<date>)". |
| `emails` | array of string |  | The emails to check (or send `rows` with an `email` field). up to 50,000 |
| `rows` | array of objects |  | up to 50,000 |
| `rows[].company` | string |  | Business name. |
| `rows[].website` | string |  | Website (any form: https://acme.com, acme.com/contact, www.acme.com). |
| `rows[].domain` | string |  | Domain, if you have it instead of a website. |
| `rows[].firstName` | string |  |  |
| `rows[].lastName` | string |  |  |
| `rows[].fullName` | string |  | Used when first and last name are not given separately. |
| `rows[].jobTitle` | string |  |  |
| `rows[].email` | string |  | The email to check (verify). |
| `rows[].phone` | string |  |  |
| `rows[].city` | string |  |  |
| `rows[].state` | string |  |  |
| `rows[].country` | string |  | Two-letter country code, e.g. US, CA, GB. |
| `rows[].address` | string |  | Business address. For US businesses it decides which state rules apply. |
| `rows[].category` | string |  |  |
| `webhookUrl` | string |  | Public https URL we POST the result to when the job is done (see the webhooks guide). |
| `webhookSecret` | string |  | Optional: sign this webhook with your own secret instead of the account signing secret. |
| `wait` | integer |  | Seconds to wait for the job to finish before answering (0–30). Handy for Zapier, Make and Clay: small jobs come back done, with results. default `0`, 0–30 |

## Example request

```bash
curl -X POST "https://moleman.io/api/v1/verify" \
  -H "Authorization: Bearer $MOLEMAN_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"emails":["sarah.miller@brightsmiledental.com","info@brightsmiledental.com"],"webhookUrl":"https://hooks.zapier.com/hooks/catch/123/abc/"}'
```

## Example answer

```json
{
  "jobId": 982,
  "listId": 378,
  "status": "queued",
  "livemode": true,
  "queued": 2,
  "skipped": [],
  "cached30d": 0,
  "maxCreditsHeld": 0.2,
  "pollUrl": "/api/v1/jobs/982"
}
```

## Errors

| Status | Code | When |
| --- | --- | --- |
| 401 | [`missing_api_key`](/docs/errors#missing_api_key) | The request has no API key. |
| 401 | [`invalid_api_key`](/docs/errors#invalid_api_key) | The API key is not one of ours (a typo, a cut-off copy, or a key from another account that was deleted). |
| 401 | [`revoked_api_key`](/docs/errors#revoked_api_key) | The API key was revoked on the API page. Revoking takes effect at once. |
| 429 | [`rate_limited`](/docs/errors#rate_limited) | More than 120 requests in one minute with this key. |
| 500 | [`server_error`](/docs/errors#server_error) | Something broke on our side. Nothing was charged for it. |
| 400 | [`invalid_request`](/docs/errors#invalid_request) | A parameter is missing, has the wrong type or is out of range. `details` lists every problem with its path. |
| 400 | [`invalid_json`](/docs/errors#invalid_json) | The body is not valid JSON. |
| 409 | [`idempotency_in_progress`](/docs/errors#idempotency_in_progress) | A request with the same Idempotency-Key is still running. |
| 422 | [`idempotency_key_reused`](/docs/errors#idempotency_key_reused) | The Idempotency-Key was already used in the last 24 hours with a different request. |
| 400 | [`no_eligible_rows`](/docs/errors#no_eligible_rows) | None of the rows can run this action (for example: no website or domain to find an email for, or no email to check). |
| 402 | [`insufficient_credits`](/docs/errors#insufficient_credits) | The account has fewer credits than this request could use at most. We hold the maximum while the job runs and give back what it does not use. |
| 404 | [`not_found`](/docs/errors#not_found) | The job or list does not exist, belongs to another account, or was deleted. |
| 400 | [`invalid_webhook_url`](/docs/errors#invalid_webhook_url) | The webhook URL is not a public https address (private networks and other schemes are refused). |
| 403 | [`wrong_key_mode`](/docs/errors#wrong_key_mode) | A test key asked for something made with a live key, or the other way round. Test and live data never mix. |
