Anymail finder API
Anymail finder is built with reliability in mind. In over two years of operation it suffered only minor downtime, none of which affected the API, which is completely separate.
The API provides access to the complete Anymail finder database, our validator, and our email guesser.
You can find your API key in your account settings.
Differences from the website
The current version of our API will provide the same results you will get in our web app.
- Pricing: On Anymail finder, you never pay for the same query twice, regardless of your billing period. The only exception to this are:
- email verifications, which are charged every time you perform them, regardless of the result;
- employee name lookups, which are charged every time you perform them, if we find at least one employee.
- Speed: The API performs all requests in real time, so while the load time might be a bit slow, you won’t have to check back for a result. It can take several seconds for the server to respond, so you should set a high timeout within your application (at least 60 seconds).
API Status
You can make a request to our GET /status
endpoint to check the status of the API.
In your logic, any 503 response should be treated the same way & retried after a few seconds.
To check the status of the API, make a request to:
https://api.anymailfinder.com/status
If the API is healthy, the following response will be returned.
{"healthy": true}
If the API is currently experiencing issues, the following error will be returned. Any response with a status code other than 200 - OK should be interpreted as the API having downtime.
{"healthy": false}
Authentication
All requests except the GET /status
endpoint require authentication. To authenticate, you’ll need to set an Authorization
header with the API key you find in your settings as value.
For example, if your API key is secret_key_123
you will want to add a Authorization
header with value Bearer secret_key_123
A failed authentication will return this error:
{"error": "not_authorized","error_explained": "Please make sure you are authenticating this request correctly.","success": false}
If you run out of credits, this error will be returned:
{"error": "upgrade_needed","status": "You will need to upgrade your account at https://app.anymailfinder.com/purchase","success": false}
Rate limits
Our API does not have rate limits. We aim to process queries as fast as possible and will scale up our back-end resources when more request come in.
To accomplish this we have implemented an internal queue system that makes sure requests are served fast and that priority is given to smaller accounts. Your request can be in this queue for up to 1 minute. Do not terminate / restart the request, as this will put you at the back of the queue.
When a large number of requests comes in and we are unable to meet the demand quickly enough, we’ll be returning a 503 response. Whenever you encounter this, you are encouraged to retry the request after a few seconds.
When we are unable to serve your request quickly enough, the following error will be returned:
{"error": "server_busy","error_explained": "Our server is currently under heavy load, please slow down."}
Webhooks
Our API looks for emails in real time, which means that responses can be slow. You can run multiple requests in parallel, but that could mean running multiple workers on your server and using lots of resources.
Using webhooks, you can make a request to Anymail finder and receive a webhook callback when the result is ready.
To use webhooks, make a request to any of the endpoints below, and add a X-Webhook-Url
header with the URL you want us to send the result to. Webhooks are only available for POST
endpoints.
It is reccomended you do not use webhooks in situations where you need the result immediately (e.g. when a user is waiting for the result), but rather when you are processing data in the background.
To perform a request with webhooks, you will need to add a X-Webhook-Url
header with the URL you want us to send the result to.
https://api.anymailfinder.com/v5.0/search/person.jsonX-Webhook-Url: https://requestbin.io/example
{"domain": "hundo.io","full_name": "Joe d'Elia"}
Response
If our server has accepted your webhook request, our response will have a 202 status code, and the body will contain the ID of the request.
Field | Type | Description |
---|---|---|
request_id | String (uuid) | A unique ID used to identify the request and the webhook. |
webhook_url | String | The URL we’ll be sending the webhook to. |
If the request fails validation, authentication, or hits a rate limit, you will receive the regular error response right away. In that case, you will not receive any webhook callbacks.
If we have accepted the webhook, the response will look like this:
{"request_id": "2602fcf5-030a-4686-a9ae-f4108256223b","webhook_url": "https://requestbin.io/example"}
If the request fails validation, we will return the error right away and not deliver it as a webhook.
{"error": "bad_request","error_explained": "Please provide a valid full_name","success": false}
Webhook callback
We will send the response as a POST
request to the URL you specified. The request will contain a JSON body with the same format as the response you would get if you had made a normal request, as well as the following headers.
Header | Type | Description |
---|---|---|
X-Webhook-Url | String | The webhook URL we are sending this request to |
X-Request-Id | String (uuid) | The ID of the request (same as the one from the first response) |
X-Response-Status | Integer | The status code of the response. This will be 200 if the request was successful. |
Retry strategy
If for whatever reason your server does not respond with a status code between 200 and 299, or it times out (we wait 30 seconds), we will retry the webhook every approximately 10 minutes over the course of two hours.
Checking how many searches you have left
If you’d like to know how many credits you have left, you can make a request to our GET /v5.0/meta/account.json
endpoint.
To check how many searches you have left on your account, make a request to:
https://api.anymailfinder.com/v5.0/meta/account.json
Response
Field | Type | Description |
---|---|---|
credits_left | Integer | How many credits are left |
credits_total | Integer | Total number of credits initially available to you |
credits_used_not_verified | Integer | Number of requests that would have used a credit but were free because only partially verified |
credits_used_verified | Integer | Number of credits used for fully verified emails |
This will return a JSON response that looks like this:
{"credits_left": 1000,"credits_total": 5000,"credits_used_not_verified": 1000,"credits_used_verified": 3000,"success": true}
Find someone’s email
Use our POST /v5.0/search/person.json
endpoint to find an individual’s email.
Parameters
Field | Type | Description |
---|---|---|
full_name | String | The full name of the person to search |
first_name | String | The first name of the person to search |
last_name | String | The last name of the person to search |
domain | String | The domain to search the email at |
company_name | String | The name of the company to search the email at |
country_code | String | The country code (e.g. US ) to target the company name conversion in. |
You must provide either a domain
or a company_name
. Providing a domain
will yield better results than a company_name
.
You must provide either a full_name
, or both a first_name
and a last_name
.
The request will return one of the following responses.
To perform an email search of a specific person, make the following request:
https://api.anymailfinder.com/v5.0/search/person.json
{"domain": "hundo.io","full_name": "Joe d'Elia"}
Successful search
Successful searches will cost one credit, taken from your Anymail finder balance.
Field | Description |
---|---|
input | Your original input |
results.email | The most likely email for the person |
results.validation | Either valid or unknown depending on whether we could confirm with the server. |
results.alternatives | An array of other possible emails. |
A successful response will look like this:
{"input": {"company_name": null,"country_code": null,"domain": "hundo.io","first_name": null,"full_name": "Joe d'Elia","last_name": null},"results": {"alternatives": ["joedelia@hundo.io"],"email": "joed@hundo.io","validation": "valid"},"success": true}
Errors
One of the following errors might be returned by the server. You will not be charged any credits if you incur an error.
Error code | Error string | Description |
---|---|---|
400 | bad_request | The field specified in field is not correct / you haven’t provided one |
404 | no_result | We could not find an email |
404 | domain_not_found | We could not find a domain from the company name provided |
404 | domain_records_not_found | The domain does not have valid email hosting |
451 | blacklisted | We are not allowed to return this email because its owner has asked us to remove it from our database. |
An error from the endpoint will generally look like this:
{"error": "no_result","error_explained": "We could not find an email for this person. Sorry.","input": {"company_name": null,"country_code": null,"domain": "hundo.io","first_name": null,"full_name": "Mark d'Elia","last_name": null},"success": false}
Finding all emails at a company
You can pull up the most popular emails at a particular company with our POST /v5.0/search/company.json
endpoint.
Parameters
A domain
or a company_name
is required.
Field | Type | Description |
---|---|---|
domain | String | The domain to search the emails at |
company_name | String | The company name to search the emails at |
The request will return one of the following responses.
To retrieve a list of emails at a company, use the following endpoint:
https://api.anymailfinder.com/v5.0/search/company.json
{"domain": "hundo.io"}
Successful search
Successful searches will cost one credit, taken from your Anymail finder balance.
Field | Description |
---|---|
input | Your original input |
results.emails | An array of emails at the company |
results.validation | Either valid or unknown depending on whether we could confirm with the server. |
results.totalCount | The total number of emails in our database at the searched company. Refining the search by adding a person name will show these results. |
A successful response looks like this:
{"input": {"company_name": null,"country_code": null,"domain": "hundo.io"},"results": {"emails": ["joedelia@hundo.io","cameronjames@hundo.io"],"totalCount": 4,"validation": "valid"},"success": true}
Errors
One of the following errors might be returned by the server. You will not be charged any credits if you incur an error.
Error code | Error string | Description |
---|---|---|
400 | bad_request | The field specified in field is not correct / you haven’t provided one |
404 | no_result | We could not find any emails |
404 | domain_not_found | We could not find a domain from the company name provided |
404 | domain_records_not_found | The domain does not have valid email hosting |
451 | blacklisted | We are not allowed to return this email because its owner has asked us to remove it from our database. |
An error response will generally look like this:
{"input": {"company_name": null,"country_code": null,"domain": "hundo.io"},"results": {"emails": ["joedelia@hundo.io","cameronjames@hundo.io"],"validation": "valid"},"success": true}
Listing a company’s employees
If you want to find a list of employees at a company you can use our POST /v5.0/search/employees.json
endpoint. A credit will be charged each time there is at least one result.
Parameters
A domain
or a company_name
is required, as well as a preferred_title
Field | Type | Description |
---|---|---|
domain | String | The domain to search the employees |
company_name | String | The company name to search the employees |
preferred_title | String | The target job title to look for |
country_code | String | The country code (e.g. US ) to target the search in |
The request will return one of the following responses.
To retrieve a list of employees at a company, use the following endpoint:
https://api.anymailfinder.com/v5.0/search/employees.json
{"company_name": "Upscope","domain": "upscope.io","preferred_title": "CTO"}
Successful search
Successful searches will cost one credit, taken from your Anymail finder balance.
Field | Description |
---|---|
input | Your original input |
company_name_used | The company name used to search for employees (in case it was converted from a domain) |
employees[].company | The name of the company for the employee (can vary slightly from the search name) |
employees[].linkedin_url | If available, the URL of the employee’s linkedin account |
employees[].name | The name of the employee |
employees[].title | The job title of the employee |
A successful response looks like this:
{"company_name_used": "upscope","employees": [{"company": "Upscope","linkedin_url": "https://uk.linkedin.com/in/thejoedelia","name": "Joe d'Elia","title": "Co-Founder"}],"input": {"company_name": "upscope","country_code": null,"domain": "upscope.io","preferred_title": "CTO"},"success": true}
Errors
One of the following errors might be returned by the server. You will not be charged any credits if you incur an error.
Error code | Error string | Description |
---|---|---|
400 | bad_request | The field specified in field is not correct / you haven’t provided one |
404 | no_result | We could not find any employees |
404 | company_name_not_found | We could not convert the domain into a valid company name |
451 | blacklisted | We are not allowed to return this employee because they have removed themselves from our database. |
An error response will generally look like this:
{"error": "company_name_not_found","error_explained": "We could not find the correct company name","success": false}
Validating an email
You can use our POST /v5.0/validate.json
Parameters
Field | Type | Description |
---|---|---|
email | String | The email to validate |
To validate an email, make the following request
https://api.anymailfinder.com/v5.0/validate.json
{"email": "jo@hundo.io"}
Response
A successful response will contain a validation
field with either valid
, invalid
or unknown
if the validation was inconclusive.
A credit will be charged regardless of the outcome.
A successful response will look like this:
{"input": {"email": "jo@hundo.io"},"success": true,"validation": "invalid"}
Errors
A full list of possible errors follows.
Error code | Error string | Description |
---|---|---|
400 | bad_request | The email to validate is missing. |
An error response looks like this:
{"error": "bad_request","error_explained": "Please enter a valid email","field": "email","input": {"email": null},"success": false}