Every feature. Same pricing. From your stack.

A clean REST API for single address verification, bulk jobs, catch-all resolution, and domain pattern lookup. Authenticate with an API key. Pay only for confirmed results, same as the dashboard.

Authentication

One header. Every request.

Generate an API key from your dashboard. Keys use the ak_ prefix. Pass it as a Bearer token on every request.

Authorization: Bearer ak_your_key_here

API keys are for programmatic access only. Account management, billing, and key generation require dashboard authentication.

Single verification

One address. One result.

Request
curl -X POST https://api.filtrat.io/v1/verify/email \
  -H "Authorization: Bearer ak_your_key" \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]"}'

Response — confirmed deliverable:

Response · 200
{
  "email": "[email protected]",
  "status": "verified",
  "confidence": 98,
  "syntax_valid": true,
  "disposable": false,
  "role_account": false,
  "domain_intelligence": {
    "mx_provider": "Google Workspace",
    "gateway": null,
    "real_provider": "Google Workspace",
    "catch_all": false,
    "spf": "v=spf1 include:_spf.google.com ~all",
    "dmarc": "v=DMARC1; p=reject; rua=mailto:[email protected]"
  },
  "catchall_resolved": null,
  "is_cached": false,
  "credits_used": 0.5,
  "credits_remaining": 9847.5
}

Response — catch-all detected (free):

Response · 200
{
  "email": "[email protected]",
  "status": "catchall",
  "confidence": 62,
  "syntax_valid": true,
  "disposable": false,
  "role_account": false,
  "domain_intelligence": {
    "mx_provider": "Google Workspace",
    "catch_all": true
  },
  "catchall_resolved": null,
  "is_cached": false,
  "credits_used": 0,
  "credits_remaining": 9847.5
}

To resolve a catch-all in the same call, add resolve_catchall: true. Costs 3 credits if confirmed, nothing if unresolvable:

Request · resolve catch-all
curl -X POST https://api.filtrat.io/v1/verify/email \
  -H "Authorization: Bearer ak_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "resolve_catchall": true
  }'
Response · 200
{
  "email": "[email protected]",
  "status": "verified",
  "confidence": 98,
  "domain_intelligence": {
    "catch_all": true
  },
  "catchall_resolved": true,
  "is_cached": false,
  "credits_used": 3.0,
  "credits_remaining": 9844.5
}

Bulk verification

Submit a list. Poll until complete. Retrieve results.

1

Create the job

Upload a CSV file or submit an array of addresses. The job starts immediately and returns a job_id.

File upload
curl -X POST https://api.filtrat.io/v1/bulk/jobs \
  -H "Authorization: Bearer ak_your_key" \
  -F "[email protected]"

Or with a JSON array:

JSON array
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": [
      "[email protected]",
      "[email protected]",
      "[email protected]"
    ]
  }'
Response · 202 Accepted
{
  "job_id": "d4f7a2b1-8c3e-4f5a-9b2d-1e3f5a7b9c1d",
  "file_name": "contacts.csv",
  "total": 10000,
  "queued": 10000,
  "status": "pending",
  "credits_estimated": 5000.0,
  "credits_remaining": 9847.5
}
2

Poll for status

Request
curl https://api.filtrat.io/v1/bulk/jobs/{job_id} \
  -H "Authorization: Bearer ak_your_key"
Response · processing
{
  "job_id": "d4f7a2b1-8c3e-4f5a-9b2d-1e3f5a7b9c1d",
  "file_name": "contacts.csv",
  "total": 10000,
  "processed": 6847,
  "verified": 4203,
  "invalid": 1244,
  "catchall": 987,
  "unknown": 413,
  "skipped": 0,
  "status": "running",
  "auto_resolve_catchall": false
}
Response · completed
{
  "job_id": "d4f7a2b1-8c3e-4f5a-9b2d-1e3f5a7b9c1d",
  "file_name": "contacts.csv",
  "total": 10000,
  "processed": 10000,
  "verified": 6200,
  "invalid": 1800,
  "catchall": 1400,
  "unknown": 600,
  "skipped": 0,
  "status": "completed",
  "auto_resolve_catchall": false
}

Poll status until it returns completed or failed. Recommended interval: 2–5s for small jobs, 10–30s for large ones.

3

Retrieve results

Filter by result type before fetching:

Request · paginated rows
curl "https://api.filtrat.io/v1/bulk/jobs/{job_id}/rows\
?status=verified&offset=0&limit=100" \
  -H "Authorization: Bearer ak_your_key"
Response · 200
{
  "items": [
    {
      "id": "row_a1b2c3d4",
      "index": 0,
      "email": "[email protected]",
      "domain": "snowplow.io",
      "status": "verified",
      "reason": "Mailbox exists",
      "mx_provider": "Google Workspace",
      "role": false,
      "disposable": false,
      "suggested_email": null
    }
  ],
  "total": 10000,
  "filtered_total": 6200,
  "next_offset": 100
}

Or export as CSV:

CSV export
curl "https://api.filtrat.io/v1/bulk/jobs/{job_id}/export\
?status=verified" \
  -H "Authorization: Bearer ak_your_key" \
  -o deliverable_results.csv
4

Resolve catch-all addresses

Resolve all catch-alls
curl -X POST \
  https://api.filtrat.io/v1/bulk/jobs/{job_id}/resolve-catchalls \
  -H "Authorization: Bearer ak_your_key"

Or resolve specific emails:

Resolve selection
curl -X POST \
  https://api.filtrat.io/v1/bulk/jobs/{job_id}/resolve-catchalls \
  -H "Authorization: Bearer ak_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "emails": [
      "[email protected]",
      "[email protected]"
    ]
  }'

Only emails with catch-all status are queued. Non-catch-all emails are skipped:

Response · 202 Accepted
{
  "queued": 2,
  "skipped": 0,
  "message": "Queued 2 catch-all emails for resolution.",
  "credits_estimated": 6.0,
  "credits_remaining": 9841.5
}

Resolution runs asynchronously. Poll the job again to track progress.

More endpoints

Everything else available via API.

Domain pattern lookup

POST /v1/domain-intelligence/lookup

7 credits per domain · Cached domains free. Returns naming conventions with usage percentages.

Domain inspection

POST /v1/domain-intelligence/inspect

Always free. Returns MX provider, catch-all status, SPF, DMARC, gateway detection.

Billing status

GET /v1/billing/status

Returns plan and PAYG credit balances, subscription status, and current period.

API key management

GET /v1/api-keys
POST /v1/api-keys
DELETE /v1/api-keys/{key_id}

List, create, and revoke keys. Session auth only — keys cannot create keys.

Limits & pricing

Rate limits and credit costs.

Rate limits

Single verify30 req/min
Bulk job creation5 req/min
Job polling60 req/min
Pattern lookup10 req/min
Domain inspect20 req/min
CSV export10 req/min

Credit costs

Confirmed deliverable0.5 credits
Confirmed bounce0.5 credits
Catch-all resolution3 credits
Pattern lookup7 credits / domain
Domain inspectfree
Catch-all detectionfree
Uncertain / riskyfree
Cached results (180 days)free

Credits are deducted per result, not per request. Every response that deducts credits returns credits_used and credits_remaining.

Full documentation

Every endpoint, every parameter, every response field.

View API docs

200 free credits. No card.