{
  "info": {
    "_postman_id": "e0c05399-aaf0-41d3-a622-0734056539a2",
    "name": "email-validation.org API",
    "description": "REST API of email-validation.org. Send your API key in the `Authorization` header as a bearer token\n(or in `X-Api-Key`); keys in URLs are refused. Requests and responses are JSON (UTF-8), except bulk\nuploads (CSV or plain text) and result downloads (CSV).\n\nResults use five statuses (`valid`, `invalid`, `catch_all`, `unknown`, `disposable`), each with a reason and a\nrecommended action: spam traps and frequent complainers are `valid` with the action `remove`. `unknown` results\nnever cost a credit, and neither do errors.\n\nRate limits: up to 500 requests per second per account after a purchase (20 before),\nand up to 500 requests per second from one IP address (IPv6: one /48), counted per Cloudflare data center.\nRequests from Cloudflare Workers, which all share one address, count toward the per-IP limit only without a key.\nAfter 20 requests with an invalid key in a minute, an IP address's further invalid keys get 429 for up to a minute; valid keys keep working, on the global and the EU server alike.\nOver a limit: `429 rate_limited` with `Retry-After`, never charged.\n\nA method a path does not list here (for example `GET /v1/bulk` or `PUT /v1/validate`) answers\n`405 invalid_request` with an `Allow` header naming the methods the path takes. Nothing is charged.\n\nEU data residency: validated and stored in the EU. Send the same requests to https://api-eu.email-validation.org (the second server), where\n`/v1/validate` takes the address in a POST body only. An account with EU-only processing gets\n`403 forbidden` on https://api.email-validation.org. See https://email-validation.org/docs/eu-data-residency/.\n\nGuides and examples: https://email-validation.org/docs/\n\nPick the environment \"email-validation.org (US)\" or \"(EU)\" and paste your API key into its `apiKey` value. Generated from the OpenAPI document 1.0.0 (https://api.email-validation.org/openapi.json).",
    "version": "1.0.0",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "id": "fa467cf4-5ef7-4bb4-ac2a-de0f0abb4126",
      "name": "Validation",
      "description": "Check single addresses.",
      "item": [
        {
          "id": "c3b4926d-276e-49a9-a048-0575482cf7b5",
          "name": "Validate an email address (query string)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "https://api.email-validation.org/v1/validate?email=accepted@sandbox.email-validation.org",
              "protocol": "https",
              "host": ["api", "email-validation", "org"],
              "path": ["v1", "validate"],
              "query": [
                {
                  "key": "email",
                  "value": "accepted@sandbox.email-validation.org",
                  "description": "The address to check. Prefer `POST` so addresses stay out of URLs."
                },
                {
                  "key": "ip_address",
                  "value": "",
                  "description": "Optional IP address the person used when they gave you the address.",
                  "disabled": true
                },
                {
                  "key": "timeout",
                  "value": "10",
                  "description": "Seconds you are willing to wait (5–15).",
                  "disabled": true
                },
                {
                  "key": "fresh",
                  "value": "false",
                  "description": "Set `true` to check the address again even when it was checked in the last 12 months. By default a definite result from such a check can be returned instead; it costs 1 credit like a new check. A definite new result is stored only when no earlier result is; it never replaces or removes a stored one.",
                  "disabled": true
                }
              ]
            },
            "description": "Checks one address and returns its status, reason and recommended action.\n\n- Costs 1 credit, except results with status `unknown` (free) and answers to malformed or sandbox addresses (free).\n- Waits up to `timeout` seconds (default 10). Set your HTTP client timeout a few seconds higher.\n- The result can come from a check of the same address made in the last 12 months (`processed_at` is when this answer was produced). Results with status `unknown` are always checked again. Send `fresh=true` to check again anyway.\n- Paid accounts may send up to 500 requests per second; accounts without a purchase up to 20. Every IP address may send up to 500 API requests per second; requests from Cloudflare Workers, which all share one address, count toward it only without a key.\n- Test for free with `<reason>@sandbox.email-validation.org` addresses: https://email-validation.org/docs/test-addresses/\n\nThis form puts the address in the URL. Prefer `POST`. The EU endpoint (https://api-eu.email-validation.org) does not accept it: it answers `400 invalid_request` (\"On the EU endpoint, send the address in a POST body, never in the URL.\")."
          },
          "response": [
            {
              "name": "Valid (sandbox address, free)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.email-validation.org/v1/validate?email=accepted@sandbox.email-validation.org",
                  "protocol": "https",
                  "host": ["api", "email-validation", "org"],
                  "path": ["v1", "validate"],
                  "query": [
                    {
                      "key": "email",
                      "value": "accepted@sandbox.email-validation.org",
                      "description": "The address to check. Prefer `POST` so addresses stay out of URLs."
                    },
                    {
                      "key": "ip_address",
                      "value": "",
                      "description": "Optional IP address the person used when they gave you the address.",
                      "disabled": true
                    },
                    {
                      "key": "timeout",
                      "value": "10",
                      "description": "Seconds you are willing to wait (5–15).",
                      "disabled": true
                    },
                    {
                      "key": "fresh",
                      "value": "false",
                      "description": "Set `true` to check the address again even when it was checked in the last 12 months. By default a definite result from such a check can be returned instead; it costs 1 credit like a new check. A definite new result is stored only when no earlier result is; it never replaces or removes a stored one.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"accepted@sandbox.email-validation.org\",\n  \"status\": \"valid\",\n  \"reason\": \"accepted\",\n  \"action\": \"send\",\n  \"account\": \"accepted\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": false,\n  \"role_account\": false,\n  \"disposable\": false,\n  \"catch_all_domain\": false,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Catch-all: the domain accepts every address (sandbox, free)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.email-validation.org/v1/validate?email=accepted@sandbox.email-validation.org",
                  "protocol": "https",
                  "host": ["api", "email-validation", "org"],
                  "path": ["v1", "validate"],
                  "query": [
                    {
                      "key": "email",
                      "value": "accepted@sandbox.email-validation.org",
                      "description": "The address to check. Prefer `POST` so addresses stay out of URLs."
                    },
                    {
                      "key": "ip_address",
                      "value": "",
                      "description": "Optional IP address the person used when they gave you the address.",
                      "disabled": true
                    },
                    {
                      "key": "timeout",
                      "value": "10",
                      "description": "Seconds you are willing to wait (5–15).",
                      "disabled": true
                    },
                    {
                      "key": "fresh",
                      "value": "false",
                      "description": "Set `true` to check the address again even when it was checked in the last 12 months. By default a definite result from such a check can be returned instead; it costs 1 credit like a new check. A definite new result is stored only when no earlier result is; it never replaces or removes a stored one.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"catch_all@sandbox.email-validation.org\",\n  \"status\": \"catch_all\",\n  \"reason\": \"catch_all\",\n  \"action\": \"send_with_caution\",\n  \"account\": \"catch_all\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": false,\n  \"role_account\": false,\n  \"disposable\": false,\n  \"catch_all_domain\": true,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Disposable: a throwaway inbox (sandbox, free)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.email-validation.org/v1/validate?email=accepted@sandbox.email-validation.org",
                  "protocol": "https",
                  "host": ["api", "email-validation", "org"],
                  "path": ["v1", "validate"],
                  "query": [
                    {
                      "key": "email",
                      "value": "accepted@sandbox.email-validation.org",
                      "description": "The address to check. Prefer `POST` so addresses stay out of URLs."
                    },
                    {
                      "key": "ip_address",
                      "value": "",
                      "description": "Optional IP address the person used when they gave you the address.",
                      "disabled": true
                    },
                    {
                      "key": "timeout",
                      "value": "10",
                      "description": "Seconds you are willing to wait (5–15).",
                      "disabled": true
                    },
                    {
                      "key": "fresh",
                      "value": "false",
                      "description": "Set `true` to check the address again even when it was checked in the last 12 months. By default a definite result from such a check can be returned instead; it costs 1 credit like a new check. A definite new result is stored only when no earlier result is; it never replaces or removes a stored one.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"disposable@sandbox.email-validation.org\",\n  \"status\": \"disposable\",\n  \"reason\": \"disposable\",\n  \"action\": \"remove\",\n  \"account\": \"disposable\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": false,\n  \"role_account\": false,\n  \"disposable\": true,\n  \"catch_all_domain\": false,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Valid with a warning: a spam trap, action remove (sandbox, free)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.email-validation.org/v1/validate?email=accepted@sandbox.email-validation.org",
                  "protocol": "https",
                  "host": ["api", "email-validation", "org"],
                  "path": ["v1", "validate"],
                  "query": [
                    {
                      "key": "email",
                      "value": "accepted@sandbox.email-validation.org",
                      "description": "The address to check. Prefer `POST` so addresses stay out of URLs."
                    },
                    {
                      "key": "ip_address",
                      "value": "",
                      "description": "Optional IP address the person used when they gave you the address.",
                      "disabled": true
                    },
                    {
                      "key": "timeout",
                      "value": "10",
                      "description": "Seconds you are willing to wait (5–15).",
                      "disabled": true
                    },
                    {
                      "key": "fresh",
                      "value": "false",
                      "description": "Set `true` to check the address again even when it was checked in the last 12 months. By default a definite result from such a check can be returned instead; it costs 1 credit like a new check. A definite new result is stored only when no earlier result is; it never replaces or removes a stored one.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"spamtrap@sandbox.email-validation.org\",\n  \"status\": \"valid\",\n  \"reason\": \"spamtrap\",\n  \"action\": \"remove\",\n  \"account\": \"spamtrap\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": false,\n  \"role_account\": false,\n  \"disposable\": false,\n  \"catch_all_domain\": false,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Invalid: likely typo (sandbox, free)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.email-validation.org/v1/validate?email=accepted@sandbox.email-validation.org",
                  "protocol": "https",
                  "host": ["api", "email-validation", "org"],
                  "path": ["v1", "validate"],
                  "query": [
                    {
                      "key": "email",
                      "value": "accepted@sandbox.email-validation.org",
                      "description": "The address to check. Prefer `POST` so addresses stay out of URLs."
                    },
                    {
                      "key": "ip_address",
                      "value": "",
                      "description": "Optional IP address the person used when they gave you the address.",
                      "disabled": true
                    },
                    {
                      "key": "timeout",
                      "value": "10",
                      "description": "Seconds you are willing to wait (5–15).",
                      "disabled": true
                    },
                    {
                      "key": "fresh",
                      "value": "false",
                      "description": "Set `true` to check the address again even when it was checked in the last 12 months. By default a definite result from such a check can be returned instead; it costs 1 credit like a new check. A definite new result is stored only when no earlier result is; it never replaces or removes a stored one.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"likely_typo@sandbox.email-validation.org\",\n  \"status\": \"invalid\",\n  \"reason\": \"likely_typo\",\n  \"action\": \"remove\",\n  \"account\": \"likely_typo\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": \"accepted@sandbox.email-validation.org\",\n  \"free_email\": false,\n  \"role_account\": null,\n  \"disposable\": null,\n  \"catch_all_domain\": null,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Unknown: timed out (sandbox, free)",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "https://api.email-validation.org/v1/validate?email=accepted@sandbox.email-validation.org",
                  "protocol": "https",
                  "host": ["api", "email-validation", "org"],
                  "path": ["v1", "validate"],
                  "query": [
                    {
                      "key": "email",
                      "value": "accepted@sandbox.email-validation.org",
                      "description": "The address to check. Prefer `POST` so addresses stay out of URLs."
                    },
                    {
                      "key": "ip_address",
                      "value": "",
                      "description": "Optional IP address the person used when they gave you the address.",
                      "disabled": true
                    },
                    {
                      "key": "timeout",
                      "value": "10",
                      "description": "Seconds you are willing to wait (5–15).",
                      "disabled": true
                    },
                    {
                      "key": "fresh",
                      "value": "false",
                      "description": "Set `true` to check the address again even when it was checked in the last 12 months. By default a definite result from such a check can be returned instead; it costs 1 credit like a new check. A definite new result is stored only when no earlier result is; it never replaces or removes a stored one.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"timeout@sandbox.email-validation.org\",\n  \"status\": \"unknown\",\n  \"reason\": \"timeout\",\n  \"action\": \"retry_later\",\n  \"account\": \"timeout\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": null,\n  \"role_account\": null,\n  \"disposable\": null,\n  \"catch_all_domain\": null,\n  \"mx_found\": null,\n  \"mx_record\": null,\n  \"smtp_provider\": null,\n  \"domain_age_days\": null,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            }
          ]
        },
        {
          "id": "fd43a8af-6622-4524-a97d-abe893b37739",
          "name": "Validate an email address",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"email\": \"accepted@sandbox.email-validation.org\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/validate",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "validate"]
            },
            "description": "Checks one address and returns its status, reason and recommended action.\n\n- Costs 1 credit, except results with status `unknown` (free) and answers to malformed or sandbox addresses (free).\n- Waits up to `timeout` seconds (default 10). Set your HTTP client timeout a few seconds higher.\n- The result can come from a check of the same address made in the last 12 months (`processed_at` is when this answer was produced). Results with status `unknown` are always checked again. Send `fresh=true` to check again anyway.\n- Paid accounts may send up to 500 requests per second; accounts without a purchase up to 20. Every IP address may send up to 500 API requests per second; requests from Cloudflare Workers, which all share one address, count toward it only without a key.\n- Test for free with `<reason>@sandbox.email-validation.org` addresses: https://email-validation.org/docs/test-addresses/\n\nThe body (JSON or form data) is at most 4 KB (`413` above) and must arrive within 2 seconds (`400` otherwise)."
          },
          "response": [
            {
              "name": "Valid (sandbox address, free)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"accepted@sandbox.email-validation.org\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/validate",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "validate"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"accepted@sandbox.email-validation.org\",\n  \"status\": \"valid\",\n  \"reason\": \"accepted\",\n  \"action\": \"send\",\n  \"account\": \"accepted\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": false,\n  \"role_account\": false,\n  \"disposable\": false,\n  \"catch_all_domain\": false,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Catch-all: the domain accepts every address (sandbox, free)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"accepted@sandbox.email-validation.org\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/validate",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "validate"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"catch_all@sandbox.email-validation.org\",\n  \"status\": \"catch_all\",\n  \"reason\": \"catch_all\",\n  \"action\": \"send_with_caution\",\n  \"account\": \"catch_all\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": false,\n  \"role_account\": false,\n  \"disposable\": false,\n  \"catch_all_domain\": true,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Disposable: a throwaway inbox (sandbox, free)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"accepted@sandbox.email-validation.org\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/validate",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "validate"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"disposable@sandbox.email-validation.org\",\n  \"status\": \"disposable\",\n  \"reason\": \"disposable\",\n  \"action\": \"remove\",\n  \"account\": \"disposable\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": false,\n  \"role_account\": false,\n  \"disposable\": true,\n  \"catch_all_domain\": false,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Valid with a warning: a spam trap, action remove (sandbox, free)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"accepted@sandbox.email-validation.org\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/validate",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "validate"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"spamtrap@sandbox.email-validation.org\",\n  \"status\": \"valid\",\n  \"reason\": \"spamtrap\",\n  \"action\": \"remove\",\n  \"account\": \"spamtrap\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": false,\n  \"role_account\": false,\n  \"disposable\": false,\n  \"catch_all_domain\": false,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Invalid: likely typo (sandbox, free)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"accepted@sandbox.email-validation.org\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/validate",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "validate"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"likely_typo@sandbox.email-validation.org\",\n  \"status\": \"invalid\",\n  \"reason\": \"likely_typo\",\n  \"action\": \"remove\",\n  \"account\": \"likely_typo\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": \"accepted@sandbox.email-validation.org\",\n  \"free_email\": false,\n  \"role_account\": null,\n  \"disposable\": null,\n  \"catch_all_domain\": null,\n  \"mx_found\": true,\n  \"mx_record\": \"mx.sandbox.email-validation.org\",\n  \"smtp_provider\": \"other\",\n  \"domain_age_days\": 3650,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            },
            {
              "name": "Unknown: timed out (sandbox, free)",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"email\": \"accepted@sandbox.email-validation.org\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/validate",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "validate"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"email\": \"timeout@sandbox.email-validation.org\",\n  \"status\": \"unknown\",\n  \"reason\": \"timeout\",\n  \"action\": \"retry_later\",\n  \"account\": \"timeout\",\n  \"domain\": \"sandbox.email-validation.org\",\n  \"did_you_mean\": null,\n  \"free_email\": null,\n  \"role_account\": null,\n  \"disposable\": null,\n  \"catch_all_domain\": null,\n  \"mx_found\": null,\n  \"mx_record\": null,\n  \"smtp_provider\": null,\n  \"domain_age_days\": null,\n  \"processed_at\": \"2026-10-20T09:30:00.000Z\",\n  \"credits_used\": 0,\n  \"request_id\": \"req_7Hq2LmX9cV4bN8tR1zK6wD\"\n}"
            }
          ]
        }
      ]
    },
    {
      "id": "a844954f-d2be-47a7-acd3-39e79512eba3",
      "name": "Account",
      "description": "Credits and usage.",
      "item": [
        {
          "id": "fea68390-5bcb-46e9-a104-084152f66cd7",
          "name": "Get your credit balance",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/credits",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "credits"]
            },
            "description": "Returns the spendable balance, any debt, credits still being applied, and the credit lots with their expiry dates. Needs the `account:read` scope."
          },
          "response": [
            {
              "name": "Your credits.",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/credits",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "credits"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"balance\": 24350,\n  \"debt\": 0,\n  \"pending\": 0,\n  \"lots\": [\n    {\n      \"remaining\": 850,\n      \"expires_at\": \"2027-03-14T12:00:00.000Z\"\n    },\n    {\n      \"remaining\": 23500,\n      \"expires_at\": \"2028-09-30T08:15:00.000Z\"\n    }\n  ]\n}"
            }
          ]
        },
        {
          "id": "901f8479-eaea-42cb-a1de-8aa917f8287b",
          "name": "Get credit usage by day or by key",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/usage",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "usage"],
              "query": [
                {
                  "key": "from",
                  "value": "",
                  "description": "First day (UTC, `YYYY-MM-DD`), no earlier than 89 days before today: usage covers the last 90 days. Defaults to the start of the 90-day range that ends on `to`.",
                  "disabled": true
                },
                {
                  "key": "to",
                  "value": "",
                  "description": "Last day (UTC). Defaults to today. The whole window must lie within the last 90 days (today included); an earlier day is a `400`.",
                  "disabled": true
                },
                {
                  "key": "group_by",
                  "value": "day",
                  "description": "Group the usage by day or by API key.",
                  "disabled": true
                }
              ]
            },
            "description": "Credit usage for any window within the last 90 days. Daily credit totals come from the credit ledger and are exact; the split by status (API, MCP, dashboard and bulk results) is compiled from request records and is approximate (it can lag by up to an hour). `totals` are always the whole account; with `group_by=key` the items cover only credits spent through an API key. Needs the `account:read` scope."
          },
          "response": [
            {
              "name": "Grouped by day",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/usage",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "usage"],
                  "query": [
                    {
                      "key": "from",
                      "value": "",
                      "description": "First day (UTC, `YYYY-MM-DD`), no earlier than 89 days before today: usage covers the last 90 days. Defaults to the start of the 90-day range that ends on `to`.",
                      "disabled": true
                    },
                    {
                      "key": "to",
                      "value": "",
                      "description": "Last day (UTC). Defaults to today. The whole window must lie within the last 90 days (today included); an earlier day is a `400`.",
                      "disabled": true
                    },
                    {
                      "key": "group_by",
                      "value": "day",
                      "description": "Group the usage by day or by API key.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"from\": \"2026-10-19\",\n  \"to\": \"2026-10-20\",\n  \"group_by\": \"day\",\n  \"totals\": {\n    \"credits_used\": 1212,\n    \"by_status\": {\n      \"valid\": 1040,\n      \"invalid\": 121,\n      \"catch_all\": 42,\n      \"unknown\": 31,\n      \"disposable\": 9\n    }\n  },\n  \"items\": [\n    {\n      \"date\": \"2026-10-19\",\n      \"credits_used\": 640,\n      \"by_status\": {\n        \"valid\": 552,\n        \"invalid\": 61,\n        \"catch_all\": 22,\n        \"unknown\": 17,\n        \"disposable\": 5\n      }\n    },\n    {\n      \"date\": \"2026-10-20\",\n      \"credits_used\": 572,\n      \"by_status\": {\n        \"valid\": 488,\n        \"invalid\": 60,\n        \"catch_all\": 20,\n        \"unknown\": 14,\n        \"disposable\": 4\n      }\n    }\n  ]\n}"
            },
            {
              "name": "Grouped by API key",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/usage",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "usage"],
                  "query": [
                    {
                      "key": "from",
                      "value": "",
                      "description": "First day (UTC, `YYYY-MM-DD`), no earlier than 89 days before today: usage covers the last 90 days. Defaults to the start of the 90-day range that ends on `to`.",
                      "disabled": true
                    },
                    {
                      "key": "to",
                      "value": "",
                      "description": "Last day (UTC). Defaults to today. The whole window must lie within the last 90 days (today included); an earlier day is a `400`.",
                      "disabled": true
                    },
                    {
                      "key": "group_by",
                      "value": "day",
                      "description": "Group the usage by day or by API key.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"from\": \"2026-10-19\",\n  \"to\": \"2026-10-20\",\n  \"group_by\": \"key\",\n  \"totals\": {\n    \"credits_used\": 1212,\n    \"by_status\": {\n      \"valid\": 1040,\n      \"invalid\": 121,\n      \"catch_all\": 42,\n      \"unknown\": 31,\n      \"disposable\": 9\n    }\n  },\n  \"items\": [\n    {\n      \"key_id\": \"key_5Dt1RmZ8vK3qP7xL2nH6sC\",\n      \"name\": \"Production server\",\n      \"last4\": \"x7Qa\",\n      \"credits_used\": 1212\n    }\n  ]\n}"
            }
          ]
        }
      ]
    },
    {
      "id": "5907f1d1-a28b-4ffb-a1c0-c209b8c63904",
      "name": "Bulk jobs",
      "description": "Check lists of up to 1,000,000 rows.\n\nDocumentation: https://email-validation.org/docs/api/bulk/",
      "item": [
        {
          "id": "f379733f-59c0-4991-aba0-14f8f118c889",
          "name": "Create a bulk job",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"emails\": [\n    \"accepted@sandbox.email-validation.org\",\n    \"catch_all@sandbox.email-validation.org\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/v1/bulk",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "bulk"],
              "query": [
                {
                  "key": "column",
                  "value": "",
                  "description": "The column that holds the addresses: a 1-based index (up to 512) or the header name. When omitted we detect it.",
                  "disabled": true
                },
                {
                  "key": "has_header",
                  "value": "",
                  "description": "Whether the first row is a header. When omitted we detect it.",
                  "disabled": true
                },
                {
                  "key": "start",
                  "value": "true",
                  "description": "Start checking as soon as the file has been analyzed. Set `false` to review the cost first and call the start endpoint later.",
                  "disabled": true
                },
                {
                  "key": "webhook_endpoint_id",
                  "value": "",
                  "description": "Id of a webhook endpoint registered in the dashboard. We notify it when the job finishes, even if it did not subscribe to `bulk.completed` / `bulk.failed`.",
                  "disabled": true
                }
              ]
            },
            "description": "Uploads a list and creates a job. Send either a CSV or plain-text file (one address per line) as the raw body with `Content-Type: text/csv` or `text/plain` (up to 100 MB and 1,000,000 rows), or a JSON body `{\"emails\": [...]}` with up to 100,000 addresses. `Content-Length` is required.  The job starts in `analyzing`: we read the file, remove duplicates and answer malformed addresses for free. Then it either starts on its own (`start=true`, the default) or waits in `ready` until you start it. Credits are held for every unique address that needs a check when the job starts, and anything not used is returned when it ends. Files and results are deleted 30 days after upload (results of a list that finishes in its last day are kept for 7 days after it finishes). Needs a key with the `bulk` scope.  Quotas: an account without a purchase may have at most 2 lists that are `analyzing` or `ready` (jobs that start on their own count while they are analyzed); another upload is a `409 conflict` until one starts or is canceled. Stored lists may take up to 2 GB without a purchase and 20 GB with one; an upload over the quota is a `413 payload_too_large`."
          },
          "response": [
            {
              "name": "Job created and being analyzed.",
              "originalRequest": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"emails\": [\n    \"accepted@sandbox.email-validation.org\",\n    \"catch_all@sandbox.email-validation.org\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": {
                  "raw": "{{baseUrl}}/v1/bulk",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "bulk"],
                  "query": [
                    {
                      "key": "column",
                      "value": "",
                      "description": "The column that holds the addresses: a 1-based index (up to 512) or the header name. When omitted we detect it.",
                      "disabled": true
                    },
                    {
                      "key": "has_header",
                      "value": "",
                      "description": "Whether the first row is a header. When omitted we detect it.",
                      "disabled": true
                    },
                    {
                      "key": "start",
                      "value": "true",
                      "description": "Start checking as soon as the file has been analyzed. Set `false` to review the cost first and call the start endpoint later.",
                      "disabled": true
                    },
                    {
                      "key": "webhook_endpoint_id",
                      "value": "",
                      "description": "Id of a webhook endpoint registered in the dashboard. We notify it when the job finishes, even if it did not subscribe to `bulk.completed` / `bulk.failed`.",
                      "disabled": true
                    }
                  ]
                }
              },
              "status": "Accepted",
              "code": 202,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"id\": \"job_3Fv8QpL2xM7nC1rT9kW4yB\",\n  \"status\": \"analyzing\",\n  \"filename\": \"newsletter-2026-11.csv\",\n  \"total_rows\": null,\n  \"unique_emails\": null,\n  \"duplicates\": null,\n  \"syntax_invalid\": null,\n  \"local_answered\": null,\n  \"processed\": 0,\n  \"credits_reserved\": 0,\n  \"credits_charged\": 0,\n  \"counts\": {},\n  \"error_code\": null,\n  \"webhook_endpoint_id\": null,\n  \"created_at\": \"2026-10-20T09:30:00.000Z\",\n  \"started_at\": null,\n  \"finished_at\": null,\n  \"expires_at\": \"2026-11-19T09:30:00.000Z\"\n}"
            }
          ],
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// Keeps the new job id for the other bulk requests (collection variable jobId).",
                  "if (pm.response.code === 202) {",
                  "  pm.collectionVariables.set('jobId', pm.response.json().id);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "id": "282d79a3-8047-4702-a45c-5bdeb3f14108",
          "name": "Get a bulk job",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/bulk/:id",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "bulk", ":id"],
              "variable": [
                {
                  "key": "id",
                  "value": "{{jobId}}",
                  "description": "Bulk job id."
                }
              ]
            },
            "description": "Returns the job with its progress and counts. Poll every few seconds, or use a webhook."
          },
          "response": [
            {
              "name": "The job.",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/bulk/:id",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "bulk", ":id"],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{jobId}}",
                      "description": "Bulk job id."
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"id\": \"job_3Fv8QpL2xM7nC1rT9kW4yB\",\n  \"status\": \"completed\",\n  \"filename\": \"newsletter-2026-11.csv\",\n  \"total_rows\": 12480,\n  \"unique_emails\": 12102,\n  \"duplicates\": 378,\n  \"syntax_invalid\": 41,\n  \"local_answered\": 41,\n  \"processed\": 12102,\n  \"credits_reserved\": 12061,\n  \"credits_charged\": 11874,\n  \"counts\": {\n    \"valid\": 10447,\n    \"invalid\": 977,\n    \"catch_all\": 401,\n    \"unknown\": 187,\n    \"disposable\": 90\n  },\n  \"error_code\": null,\n  \"webhook_endpoint_id\": \"whk_9Lp4XcV2nB7mQ1tR6zK3wF\",\n  \"created_at\": \"2026-10-20T09:30:00.000Z\",\n  \"started_at\": \"2026-10-20T09:30:41.000Z\",\n  \"finished_at\": \"2026-10-20T09:52:07.000Z\",\n  \"expires_at\": \"2026-11-19T09:30:00.000Z\"\n}"
            }
          ]
        },
        {
          "id": "bfa7443a-40e0-4d17-aa0b-220a62d05025",
          "name": "Cancel a bulk job",
          "request": {
            "method": "DELETE",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/bulk/:id",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "bulk", ":id"],
              "variable": [
                {
                  "key": "id",
                  "value": "{{jobId}}",
                  "description": "Bulk job id."
                }
              ]
            },
            "description": "Cancels the job. Work in flight finishes (`cancelling`), then the job becomes `cancelled`, unused credits are returned and its files are deleted. Canceling a finished job is a `conflict`."
          },
          "response": [
            {
              "name": "The job after the cancel request.",
              "originalRequest": {
                "method": "DELETE",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/bulk/:id",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "bulk", ":id"],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{jobId}}",
                      "description": "Bulk job id."
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"id\": \"job_3Fv8QpL2xM7nC1rT9kW4yB\",\n  \"status\": \"cancelling\",\n  \"filename\": \"newsletter-2026-11.csv\",\n  \"total_rows\": 12480,\n  \"unique_emails\": 12102,\n  \"duplicates\": 378,\n  \"syntax_invalid\": 41,\n  \"local_answered\": 41,\n  \"processed\": 4120,\n  \"credits_reserved\": 12061,\n  \"credits_charged\": 4031,\n  \"counts\": {\n    \"valid\": 3570,\n    \"invalid\": 331,\n    \"catch_all\": 110,\n    \"unknown\": 89,\n    \"disposable\": 20\n  },\n  \"error_code\": null,\n  \"webhook_endpoint_id\": \"whk_9Lp4XcV2nB7mQ1tR6zK3wF\",\n  \"created_at\": \"2026-10-20T09:30:00.000Z\",\n  \"started_at\": \"2026-10-20T09:30:41.000Z\",\n  \"finished_at\": null,\n  \"expires_at\": \"2026-11-19T09:30:00.000Z\"\n}"
            }
          ]
        },
        {
          "id": "736a12f4-3c40-453e-aacf-89f153cbbd57",
          "name": "Start a bulk job",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/bulk/:id/start",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "bulk", ":id", "start"],
              "variable": [
                {
                  "key": "id",
                  "value": "{{jobId}}",
                  "description": "Bulk job id."
                }
              ]
            },
            "description": "Starts a job that is `ready`. Credits for every unique address that needs a check are held now and count toward the daily credit cap of the API key that starts it. Answers `insufficient_credits` when the balance is too low and `key_daily_cap` (429) when the job would pass the key's daily cap (the job stays `ready` either way)."
          },
          "response": [
            {
              "name": "The started job.",
              "originalRequest": {
                "method": "POST",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/bulk/:id/start",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "bulk", ":id", "start"],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{jobId}}",
                      "description": "Bulk job id."
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"id\": \"job_3Fv8QpL2xM7nC1rT9kW4yB\",\n  \"status\": \"queued\",\n  \"filename\": \"newsletter-2026-11.csv\",\n  \"total_rows\": 12480,\n  \"unique_emails\": 12102,\n  \"duplicates\": 378,\n  \"syntax_invalid\": 41,\n  \"local_answered\": 41,\n  \"processed\": 0,\n  \"credits_reserved\": 12061,\n  \"credits_charged\": 0,\n  \"counts\": {},\n  \"error_code\": null,\n  \"webhook_endpoint_id\": \"whk_9Lp4XcV2nB7mQ1tR6zK3wF\",\n  \"created_at\": \"2026-10-20T09:30:00.000Z\",\n  \"started_at\": \"2026-10-20T09:30:41.000Z\",\n  \"finished_at\": null,\n  \"expires_at\": \"2026-11-19T09:30:00.000Z\"\n}"
            }
          ]
        },
        {
          "id": "2dbfc7d7-7e00-4a0c-ae8a-69f0b5d894e6",
          "name": "Download bulk results (CSV)",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Range",
                "value": "bytes=0-1048575",
                "description": "Byte range of a stored result file, to resume an interrupted download. Honored only with `columns=original` and either `filter=all` (with or without `escape_formulas`) or a single status of `valid`, `invalid` or `unknown` with `escape_formulas=false`: those answers carry `Accept-Ranges: bytes` and a `206`. Other answers carry `Accept-Ranges: none` and ignore the header (`200`, the whole file).",
                "disabled": true
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/v1/bulk/:id/results",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "bulk", ":id", "results"],
              "query": [
                {
                  "key": "filter",
                  "value": "all",
                  "description": "`all`, one status, or a comma-separated list of statuses (for example `valid,catch_all`). The old name `risky` is still accepted and stands for `catch_all,disposable`, and so are `deliverable` (`valid`) and `undeliverable` (`invalid`); any other value is refused.",
                  "disabled": true
                },
                {
                  "key": "columns",
                  "value": "original",
                  "description": "`original` keeps every column of your file; `email_only` returns the address and our columns.",
                  "disabled": true
                },
                {
                  "key": "escape_formulas",
                  "value": "true",
                  "description": "Prefix cells from your file that start with `=`, `+`, `-` or `@` (also after a comma, semicolon, tab or line break inside a cell, for spreadsheets set to another list separator) so spreadsheets do not run them as formulas. Our own columns and the address column are always escaped.",
                  "disabled": true
                }
              ],
              "variable": [
                {
                  "key": "id",
                  "value": "{{jobId}}",
                  "description": "Bulk job id."
                }
              ]
            },
            "description": "Streams the results of a `completed` job as CSV (UTF-8). Our columns are appended to yours in this order: `ev_status`, `ev_reason`, `ev_action`, `ev_free_email`, `ev_role_account`, `ev_disposable`, `ev_catch_all_domain`, `ev_did_you_mean`, `ev_mx_found`, `ev_mx_record`, `ev_smtp_provider`, `ev_domain_age_days`. Rows that repeat an address get the same result. To resume a download with `Range`, request `columns=original` with `filter=all` (the default, with or without `escape_formulas`) or with a single status and `escape_formulas=false`, and check for `206`."
          },
          "response": [
            {
              "name": "The CSV file.",
              "originalRequest": {
                "method": "GET",
                "header": [
                  {
                    "key": "Range",
                    "value": "bytes=0-1048575",
                    "description": "Byte range of a stored result file, to resume an interrupted download. Honored only with `columns=original` and either `filter=all` (with or without `escape_formulas`) or a single status of `valid`, `invalid` or `unknown` with `escape_formulas=false`: those answers carry `Accept-Ranges: bytes` and a `206`. Other answers carry `Accept-Ranges: none` and ignore the header (`200`, the whole file).",
                    "disabled": true
                  }
                ],
                "url": {
                  "raw": "{{baseUrl}}/v1/bulk/:id/results",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "bulk", ":id", "results"],
                  "query": [
                    {
                      "key": "filter",
                      "value": "all",
                      "description": "`all`, one status, or a comma-separated list of statuses (for example `valid,catch_all`). The old name `risky` is still accepted and stands for `catch_all,disposable`, and so are `deliverable` (`valid`) and `undeliverable` (`invalid`); any other value is refused.",
                      "disabled": true
                    },
                    {
                      "key": "columns",
                      "value": "original",
                      "description": "`original` keeps every column of your file; `email_only` returns the address and our columns.",
                      "disabled": true
                    },
                    {
                      "key": "escape_formulas",
                      "value": "true",
                      "description": "Prefix cells from your file that start with `=`, `+`, `-` or `@` (also after a comma, semicolon, tab or line break inside a cell, for spreadsheets set to another list separator) so spreadsheets do not run them as formulas. Our own columns and the address column are always escaped.",
                      "disabled": true
                    }
                  ],
                  "variable": [
                    {
                      "key": "id",
                      "value": "{{jobId}}",
                      "description": "Bulk job id."
                    }
                  ]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "text",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "text/csv"
                }
              ],
              "body": "email,first_name,ev_status,ev_reason,ev_action,ev_free_email,ev_role_account,ev_disposable,ev_catch_all_domain,ev_did_you_mean,ev_mx_found,ev_mx_record,ev_smtp_provider,ev_domain_age_days\naccepted@sandbox.email-validation.org,Ana,valid,accepted,send,false,false,false,false,,true,mx.sandbox.email-validation.org,other,\ncatch_all@sandbox.email-validation.org,Ben,catch_all,catch_all,send_with_caution,false,false,false,true,,true,mx.sandbox.email-validation.org,other,\n"
            }
          ]
        }
      ]
    },
    {
      "id": "d152d1d3-0691-499e-ab96-ef1d5086c8fe",
      "name": "Service",
      "description": "Service status, the latency test and this document.",
      "item": [
        {
          "id": "54b6c050-8ffd-4833-ab8e-55a262e7592d",
          "name": "Get service status",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/status",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "status"]
            },
            "description": "Public status of each component. No key needed. Updated every minute; answers may be up to 30 seconds old. When no status information is available the answer is `503` with `Retry-After: 60`."
          },
          "response": [
            {
              "name": "Current status.",
              "originalRequest": {
                "method": "GET",
                "header": [],
                "url": {
                  "raw": "{{baseUrl}}/v1/status",
                  "host": ["{{baseUrl}}"],
                  "path": ["v1", "status"]
                }
              },
              "status": "OK",
              "code": 200,
              "_postman_previewlanguage": "json",
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"status\": \"operational\",\n  \"components\": {\n    \"website\": \"operational\",\n    \"api\": \"operational\",\n    \"bulk\": \"operational\",\n    \"sign_in\": \"operational\",\n    \"payments\": \"operational\",\n    \"support\": \"operational\"\n  },\n  \"updated_at\": \"2026-10-20T09:30:00.000Z\"\n}"
            }
          ]
        },
        {
          "id": "f699e749-219c-4934-ad9f-8f630be51ffd",
          "name": "Latency test (for our website)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/v1/latency",
              "host": ["{{baseUrl}}"],
              "path": ["v1", "latency"]
            },
            "description": "Measures how fast our API answers from the result cache, for the latency page on our website: it looks one fixed test address (on a reserved domain) up in the result cache, exactly as a check of a stored address does, and returns its status with the time spent in our API.\n\n- No key, no credits, no parameters: any query string is refused (`400`). It never checks an address and never returns anything about any other address.\n- It answers our website (https://email-validation.org) only: a browser request from another website (by `Origin` or `Sec-Fetch-Site`) gets `403`, and CORS allows our website only.\n- Limited to 20 requests per 10 seconds per IP address (`429` with `Retry-After`).\n- `503` with `Retry-After: 60` while the test answer is not in the cache.\n- The measurements of our once-a-minute monitor: `GET https://email-validation.org/api/public/latency`."
          },
          "response": []
        },
        {
          "id": "80a8ed20-a514-4101-a8f1-2a7747afe8d4",
          "name": "Get this OpenAPI document",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/openapi.json",
              "host": ["{{baseUrl}}"],
              "path": ["openapi.json"]
            },
            "description": "This document as JSON. The same document is served as YAML at `/openapi.yaml`."
          },
          "response": []
        },
        {
          "id": "af21d1a2-e557-4f63-a0dc-156d984d3fc5",
          "name": "Get this OpenAPI document as YAML",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/openapi.yaml",
              "host": ["{{baseUrl}}"],
              "path": ["openapi.yaml"]
            },
            "description": "This document as YAML, the same content as `/openapi.json`."
          },
          "response": []
        }
      ]
    },
    {
      "id": "3c55f821-10f6-4940-a1cf-dc7efe0e9232",
      "name": "MCP",
      "description": "Model Context Protocol endpoint for AI agents.\n\nDocumentation: https://email-validation.org/docs/mcp/",
      "item": [
        {
          "id": "d01453d0-93d9-4dce-aefc-864ce6b15293",
          "name": "MCP event stream (not offered)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/mcp",
              "host": ["{{baseUrl}}"],
              "path": ["mcp"]
            },
            "description": "The server is stateless and does not open server-initiated streams, so `GET` answers 405. The key is checked first: without a valid key the answer is 401 (or 400 for a key in the URL)."
          },
          "response": []
        },
        {
          "id": "85839f4f-3f87-4040-ab60-18cd4e32e756",
          "name": "MCP endpoint (Streamable HTTP)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/mcp",
              "host": ["{{baseUrl}}"],
              "path": ["mcp"]
            },
            "description": "Model Context Protocol endpoint for AI agents and MCP clients (stateless Streamable HTTP, JSON-RPC 2.0). Tools: `validate_email`, `get_credits`, `create_bulk_job` (up to 10,000 addresses inline) and `get_bulk_job`. Authenticate with the same API key as the REST API; tool calls use the same credits, limits and rules. A message is at most 4 MB (`413` above). Setup: https://email-validation.org/docs/mcp/"
          },
          "response": []
        }
      ]
    },
    {
      "id": "bb947d20-9cc9-4203-a3b3-b96fbaca90c6",
      "name": "A2A",
      "description": "Agent2Agent (A2A) protocol endpoint and agent card for AI agents.\n\nDocumentation: https://email-validation.org/docs/ai-agents/",
      "item": [
        {
          "id": "c1075ff8-fc9a-4daf-a4c8-ca6a0977b25e",
          "name": "A2A endpoint (POST only)",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/a2a",
              "host": ["{{baseUrl}}"],
              "path": ["a2a"]
            },
            "description": "The endpoint takes JSON-RPC requests with `POST`; `GET` answers 405."
          },
          "response": []
        },
        {
          "id": "581f3e3d-c2c5-45d0-a070-e6fda685e3bb",
          "name": "A2A endpoint (JSON-RPC 2.0)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              },
              {
                "key": "A2A-Version",
                "value": "1.0",
                "description": "A2A protocol version (Major.Minor). No header means 0.3.",
                "disabled": true
              }
            ],
            "url": {
              "raw": "{{baseUrl}}/a2a",
              "host": ["{{baseUrl}}"],
              "path": ["a2a"]
            },
            "description": "Agent2Agent protocol endpoint (A2A 1.0 JSON-RPC binding; send the header `A2A-Version: 1.0`, or no header for A2A 0.3). Skills: `validate_email` (one address per message, in a text part or a data part `{\"email\": …}`; the result comes back as a data part of a completed task) and `get_credits`. Authenticate with the same API key as the REST API; a validation uses the same credits, limits and rules as `POST /v1/validate`. Tasks finish inside the request and are not stored. JSON-RPC errors use the A2A codes (for example -32602 invalid parameters); throttling and outages are answered with HTTP 429 and 503 and `Retry-After`, like the REST API. Agent card: https://api.email-validation.org/.well-known/agent-card.json. Guide: https://email-validation.org/docs/ai-agents/"
          },
          "response": []
        },
        {
          "id": "a97a46fe-d13c-46f5-a431-d06d40b760ba",
          "name": "Get the A2A agent card",
          "request": {
            "auth": {
              "type": "noauth"
            },
            "method": "GET",
            "header": [],
            "url": {
              "raw": "https://api.email-validation.org/.well-known/agent-card.json",
              "protocol": "https",
              "host": ["api", "email-validation", "org"],
              "path": [".well-known", "agent-card.json"]
            },
            "description": "The A2A agent card: endpoint, protocol versions, the bearer key scheme and the skills. No key needed. The same card is published at https://email-validation.org/.well-known/agent-card.json. The EU endpoint serves no agent card."
          },
          "response": []
        }
      ]
    }
  ],
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{apiKey}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "baseUrl",
      "value": "https://api.email-validation.org",
      "type": "string"
    },
    {
      "key": "jobId",
      "value": "",
      "type": "string"
    }
  ]
}
