Export the results
GET /v1/bulk-verifications/{jobId}/items?limit=100Rows come back in row_index order, one page at a time. limit defaults
to 100 and can be raised to 1000.
Response
Section titled “Response”{ "emails": [ { "row_index": 0, "submitted_email": "a@example.com", "normalized_email": "a@example.com", "result": { "email": "a@example.com", "normalized_email": "a@example.com", "verdict": "deliverable", "sub_status": "mailbox_exists", "quality_score": 95, "confidence": 92, "signals": { "syntax": "pass", "domain": "pass", "mx": "pass", "smtp": "pass", "catch_all": "pass", "role_account": "pass", "disposable": "pass", "dnsbl": "pass", "toxic": "pass", "greylisting": "pass" }, "verified_at": "2026-09-05T06:35:01.000Z" } }, { "row_index": 1, "submitted_email": "B@Example.com", "normalized_email": "b@example.com", "result": null } ], "next_cursor": "1"}result is the same object a
single verification returns,
or null for a row that has not finished yet.
Pagination
Section titled “Pagination”When next_cursor is a string, there are more rows: pass it
back as ?cursor= on the next call. It is null on the last page.
curl "https://api.tryverifyemail.com/v1/bulk-verifications/$JOB_ID/items?limit=1000&cursor=$CURSOR" \ -H "Authorization: Bearer sk_your_api_key"const rows = [];let cursor = null;do { const url = new URL(`${BASE}/${jobId}/items`); url.searchParams.set("limit", "1000"); if (cursor) url.searchParams.set("cursor", cursor); const page = await (await fetch(url, { headers })).json(); rows.push(...page.emails); cursor = page.next_cursor;} while (cursor);rows, cursor = [], Nonewhile True: params = {"limit": 1000, **({"cursor": cursor} if cursor else {})} page = requests.get(f"{BASE}/{job_id}/items", headers=HEADERS, params=params).json() rows.extend(page["emails"]) cursor = page["next_cursor"] if cursor is None: breakSee also
Section titled “See also”- Poll progress — the previous step
- The result object — every field under
result - Bulk jobs — overview