# emailvalidation documentation > emailvalidation validates and verifies email addresses, returning deliverability, syntax, MX, disposable and free-provider signals over a simple JSON REST API. Authenticate every request with your API key via the `apikey` query parameter or request header. Base URL: https://api.emailvalidation.io OpenAPI specification: https://emailvalidation.io/docs/openapi.yaml --- Source: https://emailvalidation.io/docs # emailvalidation.io API Documentation Use the emailvalidation.io API to retrieve information about any email address and seamlessly integrate it into your product using one of our many SDKs or other pre-built integrations. Building with an AI assistant? The full API is available as a machine-readable [OpenAPI 3.1 specification](https://emailvalidation.io/docs/openapi.yaml), and the documentation is published as [llms.txt](https://emailvalidation.io/docs/llms.txt) / [llms-full.txt](https://emailvalidation.io/docs/llms-full.txt). There is also a hosted [MCP server](https://emailvalidation.io/docs/mcp) at `https://api.emailvalidation.io/mcp` that AI agents can connect to directly. ## Getting started To get started, you have to register an API key [here](https://app.emailvalidation.io/register). Then, follow our quickstart guide or continue reading our documentation and integrate emailvalidation.io, using our HTTP API and dedicated client SDKs. Ultimately, [upgrade your plan](https://app.emailvalidation.io/subscription) to access all data & endpoints. --- Source: https://emailvalidation.io/docs/authentication # Authentication You'll need to authenticate your requests to access any of the endpoints in the emailvalidation.io API. In this guide, we'll look at how authentication works. emailvalidation.io offers two ways to authenticate your API requests: API key as `GET` parameter, or via request header. **MULTIPLE API KEYS** While our free plan only allows one API key at a time, our [paid plans](https://app.emailvalidation.io/subscription) offer multiple API keys. By using separate keys for different use cases you can track individual usage and make key rotations affect only certain parts of your application. ## GET query parameter You can pass your API key along with every request by adding it as a query parameter `apikey` **WARNING** This method could expose your API key in access logs and such. Sending the API key via a header parameter as specified below circumvents this problem. ```bash {{ title: 'Example request with authentication via get request' }} curl "https://api.emailvalidation.io/v1/status?apikey=YOUR-API-KEY" ``` Please don't commit your emailvalidation.io password to GitHub! ## HTTP Header The recommended way to authenticate with the emailvalidation.io API through a HTTP request header: ```bash {{ title: 'Example request with authentication via header' }} curl "https://api.emailvalidation.io/v1/status" \ -H "apikey: YOUR-API-KEY" ``` Always keep your token safe and reset it if you suspect it has been compromised. ## Using an SDK If you use one of our official SDKs, you won't have to worry about any of the above — fetch your access token from the [emailvalidation.io dashboard](https://app.emailvalidation.io/dashboard) and the client library will take care of the rest. All the client libraries use header authentication behind the scenes. --- Source: https://emailvalidation.io/docs/info # Email Information Endpoint On this page, we’ll dive into the email information endpoint you can use to retrieve information about any email address in order to verify & validate it. --- ## Validate Email Address This validation endpoint provides provides information about any email address. ### Required attributes - **email** (string): The email address you want to check ### Optional attributes - **catch_all** (boolean): If set to 1 we check if the email domain is a catch-all enabled domain (Only available in paid plans) Available in plans >= small ```bash {{title: 'cURL'}} curl -G https://api.emailvalidation.io/v1/info?email=support@emailvalidation.io \ -H "apikey: YOUR-API-KEY" ``` ```js import Emailvalidation from '@everapi/emailvalidation-js' let info = await client.info('support@emailvalidation.io',{ catch_all: 0 }) console.log(info) ``` ```python import emailvalidationio client = emailvalidationio.Client('YOUR-API-KEY') result = client.validate('support@emailvalidation.io') print(result) ``` ```php $emailvalidation = new \Emailvalidation\EmailvalidationClient('YOUR-API-KEY') var_dump($emailvalidation->validate('support@emailvalidation.io')); ``` ```json {{title: 'Full Response'}} { "email": "support@emailvalidation.io", "user": "support", "tag": "", "domain": "emailvalidation.io", "smtp_check": true, "mx_found": true, "did_you_mean": "", "role": true, "disposable": false, "score": 0.64, "state": "deliverable", "reason": "valid_mailbox", "free": false, "format_valid": true, "catch_all": null } ``` --- ## State / Reason This is the main indicator for deliverability of email addresses. The `state` is the deliverability and the `reason` is the reason why it is in this state. ```json { ... "state": "deliverable", "reason": "valid_mailbox", ... } ``` ### Possible states/reasons | state | Description | | ----------- | ----------- | | `deliverable` | The email address can receive emails | | `undeliverable` | The email address can not receive emails | | `risky` | The email address can possible receive emails but it is not certain if they are read my a person or actually really received | | `unkown` | We can not check the email address if it is able to receive emails | | reason | resulting state | Description | | ----------- | ----------- | ----------- | | `valid_mailbox` | `deliverable` | The email address has avalid mailbox behind and is able to receive emails | | | | `invalid_mx` | `undeliverable` | The MX entries stored in the domains DNS either do not exist or not valid | | `invalid_format` | `undeliverable` | The format of the email address is not valid | | `invalid_smtp` | `undeliverable` | The SMTP server did not respond correctly | | `invalid_mailbox` | `undeliverable` | The email address was refused by the SMTP server | | | | `low_deliverability` | `risky` | Indicates that the possibility that a person reads the email is low | | `low_quality` | `risky` | Indicates that the email address is used by multiple people | | | | `no_connect` | `unkown` | We could not connect to the SMTP server | | `unexpected_error` | `unkown` | An unexpected error occured | | `timeout` | `unkown` | The connection to the SMTP server timed out | | `unavailable_smtp` | `unkown` | | ## User / Tag / Domain These fields provide you with a simple way to look at the singular parts of an email address ```json { ... "user": "support", "tag": "mytag", "domain": "emailvalidation.io", ... } ``` ## MX Check The Simple Mail Transfer Protocol (SMTP), which is the very same protocol we all use to move emails on and across networks, is used by the emailvalidation.io API to verify email addresses. By determining whether the requested domain is set up to accept email, our system starts the process of real-time email verification. Here is where the MX-Records check in the API is useful. The mx found response object of the API will inform you if MX-Records for the specified domain have been located. ```json { ... "mx_found": true, ... } ``` ## "Did you mean" Check In the "did you mean" object of the API result set, the emailvalidation.io API will propose a different email address if a potential misspelling or mistake in the requested email address's domain portion is identified. Please be aware that the email address in the did you mean object is just a recommendation and has no bearing on the other API response objects. ```json { ... "did_you_mean": "support@emailvalidation.io", ... } ``` ## Catch-All Detection Available in plans >= small One SMTP check is not the end of the real-time verification procedure used by the emailvalidation.io API. A catch-all detection mechanism has been created since many email servers are set up to catch (accept) all incoming mail traffic, independent of the local component of the requested email address. This functionality is disabled by default due to the significant negative impact it has on the API's response time. However, you can enable catch-all detection by adding the request URL's catch all option and setting it to `1`. Depending on whether the requested email address is discovered to be a part of a catch-all mailbox, the catch all JSON object in the API response will either return true or false. ```json { ... "catch_all": true, ... } ``` Please take note that the catch-all JSON response object will return null if the catch-all parameter of the API is not active. ## Disposable Check If the requested email address is discovered to be utilizing a disposable email service like mailinator.com or trashmail.com, the API will also return a disposable JSON object with the values true or false. ```json { ... "disposable": true, ... } ``` ### Services for Disposable Emails A disposable email service enables users to anonymously create temporary email identities that are often used only once for tasks like activating accounts or getting passwords and expire after a set amount of time. Many of these email services don't require users to register, therefore the inbox of these one-time email accounts is made available to the public. We strongly advise against adding these email addresses to your recipient list. ## Free Email Provider Check The emailvalidation.io API can recognize free email services like Gmail, GMX or Yahoo since it is connected to a regularly updated database that lists all available email providers. The free JSON object in the API response will either return true or false depending on whether the given email address is discovered to be utilizing a free service. ```json { ... "free": true, ... } ``` Even while free email addresses are typically included in recipient lists, it might make sense for some email campaigns to separate them out and only deliver to addresses with a specific domain. ## Role Check Determining whether the requested email address is a role email address is another step in the emailvalidation.io email verification procedure. A role email is an address that often refers to a function rather than a person or name (for example, "support" or "postmaster"). Due to the low open rates of this sort of email address, it could occasionally be undesirable when sending email campaigns. Example: If the requested email is a role address, the role JSON object in the API response will return `true`; otherwise, it will return `false`. ```json { ... "role": true, ... } ``` ## Quality Score The API will return a numeric Quality Score ranging from 0 (Bad) to 1 (Good), reflecting the quality and deliverability of the given email address, to complete the emailvalidation.io validation & verification procedure. Based on a system that gets smarter with each email address validated, this Quality Score is determined for each requested email address. ```json { ... "score": 0.64, ... } ``` It is impossible to draw clear distinctions between recipients who are "worth sending to" and recipients who are "not worth sending to" because the validity of the numeric quality score depends heavily on the sort of email approach you are making. However, the following rules seem reasonable to us: ### For transactional email: | Score | Quality | | ----------- | ----------- | | 1.00-0.65 | Perfect | | 0.64-0.33 | Medium | | 0.32-0.00 | Poor | ### For marketing email: | Score | Quality | | ----------- | ----------- | | 1.00-0.80 | Perfect | | 0.79-0.49 | Medium | | 0.48-0.00 | Poor | Please be advised that when deciding whether or not to send an email to an address, the Quality Score should only be used as a guide. --- Source: https://emailvalidation.io/docs/mcp 'Connect AI agents to the emailvalidation API through our hosted MCP (Model Context Protocol) server.' # MCP Server emailvalidation ships a hosted [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server, so AI agents and assistants can call the API as native tools — no SDK or glue code required. ``` https://api.emailvalidation.io/mcp ``` The endpoint speaks the streamable HTTP transport. Listing the available tools works without authentication; executing a tool requires your API key, sent as the `apikey` header. You can [get a free API key here](https://app.emailvalidation.io/register). ## Connect Using Claude Code: ```bash claude mcp add --transport http emailvalidation https://api.emailvalidation.io/mcp --header "apikey: YOUR_API_KEY" ``` Or add the server to any MCP-capable client (Claude Desktop, Cursor, VS Code, ...): ```json { "mcpServers": { "emailvalidation": { "url": "https://api.emailvalidation.io/mcp", "headers": { "apikey": "YOUR_API_KEY" } } } } ``` ## Available tools The tools are generated from the same [OpenAPI specification](https://emailvalidation.io/docs/openapi.yaml) that describes the REST API, so they always match the documented endpoints, parameters and responses. | Tool | Endpoint | Description | |---|---|---| | `getInfo` | `GET /v1/info` | Validate an email address | | `getStatus` | `GET /v1/status` | Account quota status | ## Quotas and errors Tool calls are metered exactly like REST requests: they consume your plan quota and return the same status codes and error responses (`401`, `422`, `429`, ...). If a call fails, the tool result contains the API's error message including hints on how to proceed. --- Source: https://emailvalidation.io/docs/quickstart # Quickstart This guide will get you all set up and ready to use the emailvalidation.io API. We'll cover how to get started using one of our API clients and how to make your first API request. We'll also look at where to go next to find all the information you need to take full advantage of our powerful REST API. Before you can make requests to the emailvalidation.io API, you will need to grab your API key from your dashboard. You find it under [App » Dashboard](https://app.emailvalidation.io/dashboard). ## Choose your client Before making your first API request, you need to pick which API client you will use. In addition to cURL HTTP requests, emailvalidation.io offers [clients](/sdks) for JavaScript, Python, PHP and many more programming langauges. In the following example, you can see how to install each client. ```bash {{ title: 'cURL' }} # cURL is most likely already installed on your machine curl --version ``` ```bash {{ language: 'js' }} # Install the emailvalidation JavaScript SDK npm install @everapi/emailvalidation-js --save ``` ```bash {{ language: 'python' }} # Install the emailvalidation Python SDK pip install emailvalidationcom ``` ```bash {{ language: 'php' }} # Install the emailvalidation PHP SDK composer require everapi/emailvalidation-php ``` ## Making your first API request After picking your preferred client, you are ready to make your first call to the emailvalidation API. Below, you can see how to send a `GET` request to the `/info` endpoint to get the latest information an email address. ```bash {{ title: 'cURL' }} curl -G https://api.emailvalidation.io/v1/info?email=john@doe.com \ -H "apikey: YOUR-API-KEY" ``` ```js import Emailvalidation from '@everapi/emailvalidation-js' const client = new Emailvalidation('YOUR-API-KEY') client.info('john@doe.com', { catch_all: 0 }).then(response => { console.log(response); }); ``` ```python import emailvalidationcom client = emailvalidationcom.Client('YOUR-API-KEY') info = client.validate('john@doe.com') print(info) ``` ```php $emailvalidation = new \Emailvalidation\EmailvalidationClient('YOUR-API-KEY'); var_dump($emailvalidation->validate('john@doe.at')); ``` ## What's next? Great, you're now set up with an API client and have made your first request to the API. Here are a few links that might be handy as you venture further into the emailvalidation API: - [Grab your API key from the emailvalidation dashboard](#) - [Learn about the different error messages in emailvalidation](/testing) --- Source: https://emailvalidation.io/docs/rate-limit # Rate Limit & Quotas You can use a certain number of requests per month, defined by your plan. Once you go over this quota, the API returns a `429` HTTP status code, and you either need to upgrade your plan or wait until the end of the month. We enforce a minute rate limit for specific plans. If you exceed this, the API returns a `429` HTTP status code. You then have to wait until the end of the minute to make more requests. Not every request counts towards your monthly request volume. Not every request counts Only successful calls count against your quota. Any error on our side or validation errors (e.g., wrong parameter) will NOT count against your quota or rate limit. ## Response Headers We attach specific headers to tell you your current monthly/minute quota and how much you have remaining in the period. ```json lines X-RateLimit-Limit-Quota-Minute: 10 X-RateLimit-Limit-Quota-Month: 300 X-RateLimit-Remaining-Quota-Minute: 5 X-RateLimit-Remaining-Quota-Month: 199 ``` --- Source: https://emailvalidation.io/docs/sdks # SDKs The recommended way to interact with the emailvalidation API is by using one of our official SDKs. Today, emailvalidation offers fine-tuned JavaScript, Ruby, PHP, Python, and Go libraries to make your life easier and give you the best experience when consuming the API. --- Source: https://emailvalidation.io/docs/status # Status Endpoint The status endpoint returns information about your current quota. Requests to this endpoint do not count against your quota or rate limit. --- ## Check API Status This status endpoint returns information about your current quota. ### Response Properties - **quotas** (object): Contains information about your request quota. ```bash {{title: 'cURL'}} curl -G https://api.emailvalidation.io/v1/status \ -H "apikey: YOUR-API-KEY" ``` ```js import Emailvalidation from '@everapi/emailvalidation-js' const client = new Emailvalidation('YOUR-API-KEY') let status = await client.status() console.log(status) ``` ```python import emailvalidationio client = emailvalidationio.Client('YOUR-API-KEY') result = client.status() print(result) ``` ```php $client = new \Emailvalidation\EmailvalidationClient('YOUR-API-KEY'); $client->status(); ``` ```json {{title: 'Response'}} { "account_id": 313373133731337, "quotas": { "month": { "total": 300, "used": 72, "remaining": 229 }, "grace": { "total": 0, "used": 0, "remaining": 0 } } } ``` --- Source: https://emailvalidation.io/docs/status-codes # Request Status Codes You can tell if your request was successful by checking the status code when receiving an API response. If a response comes back unsuccessful, you can use the error type and error message to figure out what has gone wrong and do some rudimentary debugging (before contacting support). A successful request will be returned with status code `200`. Before reaching out to support with an error, please be aware that 99% of all reported errors are, in fact, user errors. Therefore, please carefully check your code before contacting Protocol support. --- ## Status codes Here is a list of the different categories of status codes returned by the emailvalidation.io API. Use these to understand if a request was successful. A 200 status code indicates a successful response. A 403 status code indicates that you are not allowed to use this endpoint, [please upgrade your plan](https://app.emailvalidation.io/subscription). A 404 status code indicates that a requested endpoint does not exist. A validation error has occured. A 429 status code indicates that you have hit your rate limit or your monthly limit. For more requests [please upgrade your plan](https://app.emailvalidation.io/subscription). A 500 status code indicates a internal server error - let us know: support@emailvalidation.io --- --- Source: https://emailvalidation.io/docs/testing # Testing Available in plans >= medium This page includes test inputs and other information to make sure your test environment works before deploying to production. ### Sandbox API Keys An API request sent with a sandbox api key is automatically identified as a request in sandbox mode. All request with sandbox keys will respond with dummy data. Requests done with sandbox keys do not count against your quota. Please note that the requests are still shown in the graph on the dashboard. You can select only your live key if you want to filter them out. ### Test email addresses You can choose any domain. The deciding part is the part before the @. #### State / Reason | Email Address | State | Reason | | ----------- | ----------- | ----------- | | deliverable@example.com + all other email addresses | `deliverable` | `valid_mailbox` | | | | undeliverable@example.com undeliverable+mailbox@example.com | `undeliverable` | `valid_mailbox` | | undeliverable+mx@example.com | `undeliverable` | `invalid_mx` | | undeliverable+format@example.com | `undeliverable` | `invalid_format` | | | | risky@example.com risky+quality@example.com | `risky` | `low_quality` | | risky+deliverability@example.com | `risky` | `low_deliverability` | | | | unknown@example.com unknown+smtp@example.com | `unknown` | `unavailable_smtp` | | unknown+timeout@example.com | `unknown` | `timeout` | | unknown+error@example.com | `unknown` | `unexpected_error` | | unknown+noconnect@example.com | `unknown` | `no_connect` | #### Special Cases | Email Address | Response | | ----------- | ----------- | | catch-all@example.com & `catch_all=1` in URL | `"catch_all": true` | | role@example.com | `"role": true` | | disposable@example.com | `"disposable": true` | | free@example.com | `"free": true` |