Skip to content
IRONDOME
Docs menu

API reference

Bulk checks

Check up to 100 email addresses with POST /v1/check/bulk. Request examples, ordered results and per-email usage.

On this page
HTTP
POST /v1/check/bulk

Check up to 100 emails in one request. Send the batch to https://api.irondome.dev. The service authenticates the request once and returns a result for each input address.

Request

https://api.irondome.dev/v1/check/bulk

Send your account’s Bearer key, Content-Type: application/json, and a known-length JSON body:

JSON
{
  "emails": [
    "person@example.com",
    "another@gmail.com",
    "not-an-email"
  ]
}
Requirement Limit
Batch size 1–100 strings
Body size 65,536 UTF-8 bytes, including JSON syntax
Accepted field emails only
Body framing Content-Length required

Additional fields, non-string entries, duplicate emails fields, and malformed JSON reject the entire request before classification. An invalid email string is handled individually instead.

Response

An accepted batch returns HTTP 200, including when some or all addresses have invalid syntax. Results follow the input order and use a zero-based index; emails are not echoed.

JSON
{
  "results": [
    {
      "index": 0,
      "provider": "custom",
      "valid": true,
      "disposable": false,
      "reason": "not_listed"
    },
    {
      "index": 1,
      "provider": "gmail",
      "valid": true,
      "disposable": false,
      "reason": "allowed_domain"
    },
    {
      "index": 2,
      "error": {
        "code": "invalid_email",
        "message": "Provide a syntactically valid email address."
      }
    }
  ],
  "checked": 2,
  "failed": 1
}

The classifications shown are illustrative; actual results depend on the current dataset.

Field Meaning
results One result per input position
index Position in the submitted array, starting at zero
checked Number of successfully classified addresses
failed Number of addresses that failed email validation
error Present on a failed item instead of classification fields

Successful items use the same provider, disposable, and reason fields as single checks. Use the index to match each result to your original array. HTTP 200 alone does not mean every item succeeded.

Usage and quota

Each successful item counts as one email check. This includes disposable results and repeated copies of the same address. Invalid items consume no check units. A batch with 80 successful items and 20 invalid items consumes 80 checks.

The free allowance is shared with single checks and across your organization's keys. Quota is checked when admitting the batch using asynchronous quota policy. A batch admitted near exhaustion can take recorded usage above 500; it is not trimmed to the exact remaining allowance. An already-exhausted organization receives a request-level 429 monthly_quota_exceeded.

Usage appears asynchronously in free usage or the dashboard. Billing is based on successful email items rather than the number of HTTP requests.

Examples

Terminal

Terminal
curl --fail-with-body --request POST 'https://api.irondome.dev/v1/check/bulk' \
  --header "Authorization: Bearer $IRONDOME_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{"emails":["person@example.com","another@gmail.com"]}'

Node.js REST

Use this inside your existing protected backend flow. Keep the endpoint and credential in trusted server configuration and use the same transport across batches.

JavaScript
const baseUrl = 'https://api.irondome.dev';
const apiKey = process.env.IRONDOME_API_KEY;

export async function checkEmails(emails) {
  if (!apiKey) {
    throw new Error('Configure IronDome on the server.');
  }
  if (!Array.isArray(emails) || emails.length < 1 || emails.length > 100
      || emails.some(email => typeof email !== 'string')) {
    throw new Error('Provide between 1 and 100 email strings.');
  }
  const body = JSON.stringify({ emails });
  if (Buffer.byteLength(body, 'utf8') > 65536) {
    throw new Error('Bulk request body exceeds 64 KiB.');
  }
  const response = await fetch(`${baseUrl}/v1/check/bulk`, {
    method: 'POST',
    redirect: 'error',
    headers: {
      Authorization: `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    },
    body,
    signal: AbortSignal.timeout(5000),
  });
  const result = await response.json();
  if (!response.ok) {
    const error = new Error('IronDome bulk check failed.');
    error.status = response.status;
    error.code = result.error?.code;
    error.requestId = response.headers.get('x-request-id');
    throw error;
  }
  return result;
}

This minimal REST example does not perform full response-schema validation. The SDKs also provide bulk methods; see the SDK guides for language-specific calls.

Request-level errors

Status Code Meaning
400 empty_batch The emails array is empty
400 invalid_json Malformed JSON, unexpected fields, or non-string entries
413 batch_too_large More than 100 emails
413 body_too_large Request exceeds 65,536 bytes
429 monthly_quota_exceeded Free quota policy denies the batch

Authentication, framing, and service failures use the standard error format. Request-level failures have an error object instead of results. All responses include a request ID and Cache-Control: no-store.

Large lists and retries

Split larger lists into batches of at most 100 and keep concurrency bounded. Batch checking saves repeated HTTP and authentication overhead; it does not make a user's single signup check wait for unrelated addresses.

Retain each original batch locally so indexes remain meaningful. There is no automatic server-side deduplication or idempotency key. If a response is lost, the batch may already have completed and consumed usage. Do not automatically resubmit the entire batch after an ambiguous timeout.