Single checks answer in the same response. Anything with many rows runs in the background as a job: bulk verification, bulk email finding, LinkedIn captures, AI enrichment and ICP scoring.
They all work the same way:
- Start the job. The response comes back straight away with the job's
id(job_idfor bulk jobs). - Poll the job every 5–10 seconds until its
statusis a finished one. - Read its rows, or export them as CSV.
Example: verify a list
Start the job:
curl -X POST https://api.filtrat.io/v1/bulk/jobs/from-list \
-H "Authorization: Bearer ak_your_key" \
-H "Content-Type: application/json" \
-d '{"emails": ["jane@acme.com", "john@globex.com"], "auto_resolve_catchall": false}'Poll it with the job_id from the response:
curl https://api.filtrat.io/v1/bulk/jobs/JOB_ID \
-H "Authorization: Bearer ak_your_key"When status is completed, read the rows (filter by status if you only want some):
curl "https://api.filtrat.io/v1/bulk/jobs/JOB_ID/rows?status=verified" \
-H "Authorization: Bearer ak_your_key"Or download everything, with any columns you uploaded, from GET /v1/bulk/jobs/JOB_ID/export.
Bulk email finding works the same with /v1/bulk-finder/jobs/.... Send contacts, each with a name and a domain, plus company_name and linkedin_url when you have them.
Job statuses
Anything not in the middle column is final: stop polling.
| Job | Still working | Finished |
|---|---|---|
| Bulk verification, bulk finder | queued, pending, running | completed, stopped, failed |
| Captures | pending, running, paused | completed, completed_with_issues, cancelled, failed |
| AI enrichment | pending, running | completed, completed_with_issues, cancelled, failed |
| ICP scoring | pending, running, paused | done, cancelled, failed |
Stopped and paused jobs
- A bulk job that runs out of credits ends as
stopped. Top up, then call its resume endpoint (POST /v1/bulk/jobs/{job_id}/resume-resolveorPOST /v1/bulk-finder/jobs/{job_id}/resume). Rows already done keep their results. - A capture
pausedby a LinkedIn limit, the account's daily cap or low credits continues by itself. You don't need to do anything. See A capture stopped or paused. completed_with_issuesmeans most rows finished but some couldn't be done. The job's counts say how many.
Safe retries
Network calls fail sometimes. Captures and bulk verification jobs are safe to retry if you send an Idempotency-Key header with a value unique to that action (a UUID works):
curl -X POST https://api.filtrat.io/v1/bulk/jobs/from-list \
-H "Authorization: Bearer ak_your_key" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3f6c2a4e-8d1b-4b7e-9a0c-5e2f1d7c9b10" \
-d '{"emails": ["jane@acme.com"]}'Sending the same request with the same key returns the job the first call started instead of starting a second one. Without a key, an identical capture request sent within a few minutes is treated as the same capture.
Tips
- Poll every 5–10 seconds. Polling faster doesn't make a job finish sooner and uses up your rate limit.
- Large exports are easier as CSV than paging through rows.
- Every job you start from the API also appears in the app, so you can watch its progress there.