Skip to content
View Markdown

Bulk Validation

Validate multiple email addresses and domains in a single request. Entries can be mixed in any order; DISIFY infers each entry's type. Per-request limits depend on your tier (10,000 anonymous → 100,000 on Pro — see Authentication).

Endpoints

GET/api/email/{emails}/mass
POST/api/email

GET request

Pass comma-separated emails, domains, or both directly in the URL with the /mass suffix:

bash
curl "https://disify.com/api/email/[email protected],example.org,[email protected]/mass"

POST request

Send the bulk parameter alongside comma-, space-, or newline-separated entries:

bash
curl -X POST https://disify.com/api/email \
     -d "bulk=true" \
     --data-urlencode "[email protected],example.org,[email protected]"
python
import requests

response = requests.post("https://disify.com/api/email", data={
    "bulk": True,
    "email": "[email protected],example.org,[email protected]"
})
print(response.json())
php
$ch = curl_init("https://disify.com/api/email");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([
    "bulk"  => true,
    "email" => "[email protected],example.org,[email protected]"
]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);

$data = json_decode($response, true);

These snippets show request encoding. Add the timeout and HTTP checks shown in the Quick Start, and handle both response shapes below.

POST parameters

ParameterTypeDescription
bulkbooleanRequired. Set to true to enable bulk mode.
emailstringComma-, space-, or newline-separated emails and domains. Entries containing @ are treated as emails; all others are treated as domains.
domainstringAlternative parameter for domain-only or mixed input. Type inference still happens per entry.
jsonbooleanOptional. When set, a synchronous response is wrapped as { "session", "stats", "results" } — where stats is the summary object below and results maps each submitted entry to its validation result — so you don't need a second call to /api/view/{session}. Queued responses do not include this map.

Send bulk=1 to enable bulk mode and json=1 for the optional result map; omit flags you do not need. The features parameter is ignored for bulk requests. Core checks run for every entry; spam_trap also runs when included in your tier. Use single checks for explicitly requested premium features.

Bulk response

json
{
  "total": 3,
  "unique": 3,
  "invalid_format": 0,
  "invalid_dns": 0,
  "disposable": 1,
  "valid": 2,
  "session": "371ef6badf1e11510ced33107ab44bf5"
}

Bulk response fields

FieldTypeDescription
totalintTotal number of entries submitted (before de-duplication)
uniqueintCount of distinct entries after de-duplication — this is what counts against your per-request limit. Includes invalid and disposable entries, not just valid ones.
invalid_formatintCount of entries with invalid format
invalid_dnsintCount of non-disposable, valid-format entries with dns: false, including inconclusive DNS results
disposableintCount of entries detected as disposable
validintCount of valid, non-disposable email or domain entries — these are what /api/view/{session} returns
sessionstringSession hash to retrieve valid results

Retrieving results

GET/api/view/{session}

After a bulk validation, use the session hash to retrieve the valid emails and domains. The response body is plain text — one valid entry per line by default. Poll from the submitting backend: access is tied to the originating IP, or the submitting account when a job record is available.

bash
curl https://disify.com/api/view/d117271ce938bf91bc718f6cfb7954de

Optional suffixes

SuffixEffect
/downloadForces a file download (Content-Disposition: inline; filename="valid_list.txt", application/octet-stream).
/separator (also /separate, /comma)Returns results comma-separated on a single line instead of newline-separated.

Suffixes can be combined in any order:

bash
# Comma-separated + download
curl https://disify.com/api/view/d117271ce938bf91bc718f6cfb7954de/separator/download

Want per-entry results?

Pass json=1 on the initial bulk submit. The results map is included only if that request finishes synchronously. Queued jobs do not provide per-entry verdict maps.

Sessions expire after 15 minutes

Session results are temporary and expire after 15 minutes. Retrieve and store your results promptly after bulk validation.

Synchronous and asynchronous jobs

Bulk requests of 100 or fewer unique entries attempt synchronous processing. If the processing time budget is exhausted, the complete batch is queued instead. Larger batches are queued immediately. Always handle both response shapes, even when requesting json=1 or submitting a small batch. A queued request returns HTTP 200 with a pending response:

json
{
  "session": "d117271ce938bf91bc718f6cfb7954de",
  "status": "pending",
  "email_count": 8000,
  "estimated_seconds": 32
}

Poll GET /api/view/{session} for progress. While still running, the same endpoint returns JSON with a status of pending, processing, or failed:

json
{
  "session": "d117271ce938bf91bc718f6cfb7954de",
  "status": "processing",
  "email_count": 8000,
  "processed_count": 3200
}

The email_count field name is retained for API compatibility and counts all unique email and domain entries in the job.

When complete, the endpoint normally returns the plain-text valid list (with the suffix options above), without a JSON status field. A completed job without a result file can return JSON summary statistics with status: "completed" instead. Inspect the response content type before parsing. If you configured a webhook on your account, you'll also receive a bulk.completed event with the final stats.

One async job at a time

Only one async job per client account (or IP, for anonymous users) may run at a time. Anonymous users must also let a cooldown elapse between jobs — the number of seconds to wait is returned in the 429 error message. Retry after that interval.

Errors

Bulk requests can fail before validation starts. Each returns a JSON { "error": "..." } body with the matching status code:

CodeWhenExample message
413Bulk input exceeds 2,000,000 bytesBulk input is too large.
422More unique addresses than your tier's per-request limitMaximum 10,000 unique emails allowed. Tried to load 12,500.
429An async job is already running, or you're inside the anonymous cooldownYou already have a bulk job in progress. Wait for it to complete before submitting another. / Please wait {n} seconds before submitting another bulk job.
503The async queue, shared storage, or bounded processing buffer is temporarily unavailableService temporarily unavailable / Service is busy. Please try again in a few minutes.

See Error Handling for the full list of API status codes.

Free disposable email detection API · Terms · Privacy