You can enjoy our service's features with our simple JSON API. Three main calls are available:
Our API also provides you a RESTful way to manage your Hunter's resources. These are the resources you can Create, Read, Update and Delete with our API:
https://api.hunter.io/v2/
Our API is designed to be as simple to use as possible. We always use the same basic structure:
data
contains the data you requested.
meta
provides information regarding your
request.
errors
shows errors with insights regarding what
made the request fail. Learn more about the
errors responses.
{
"data": {
...
},
"meta": {
...
}
}
{
"errors": {
...
}
}
Authentication is made with a key you will have to add to every call you make to our API. This parameter is always required. We'll return an error if the key is either missing or invalid.
Your API key is what identifies your account, so make sure to keep it secret! You can at anytime generate or delete API keys on your dashboard.
Log in to get your API key.
Hunter's API uses conventional HTTP response codes to indicate the success or failure of an API request.
In case of an error, we'll return an array of errors containing information regarding what happened.
200 - OK | The request was successful. |
201 - Created | The request was successful and the resource was created. |
202 - Email Verification in progress | The Email Verification is still in progress. Feel free to make the same Verification again as often as you want, it will only count as a single request until we return the response. |
204 - No content | The request was successful and no additional content was sent. |
222 - Email Verification failed | The Email Verification failed because of an unexpected response from the remote SMTP server. This failure is outside of our control. We advise you to retry later. |
400 - Bad request | Your request was not valid. |
401 - Unauthorized | No valid API key was provided. |
403 - Forbidden | You have reached the rate limit. |
404 - Not found | The requested resource does not exist. |
422 - Unprocessable entity | Your request is valid but the creation of the resource failed. Check the errors. |
429 - Too many requests | You have reached your usage limit. Upgrade your plan if necessary. |
451 - Unavailable for legal reasons | The person behind the requested resource has asked us directly or indirectly to stop the processing of this resource. For this reason, you shouldn't process this resource yourself in any way. |
5XX - Server errors | Something went wrong on Hunter's end. |
{
"errors": [
{
"id": "wrong_params",
"code": 400,
"details": "You are missing the domain parameter"
}
]
}
One key feature of Hunter is to search all the email addresses corresponding to one website. You give one domain name and it returns all the email addresses using this domain name found on the internet.
domain
Required*
|
Domain name from which you want to find the email addresses. For example, "stripe.com". |
company
Required*
|
The company name from which you want to find the email addresses. For example, "stripe". Note that you'll get better results by supplying the domain name as we won't have to find it. If you send a request with both the domain and the company name, we'll use the domain name. It doesn't need to be in lowercase. |
limit | Specifies the max number of email addresses to return. The default is 10. |
offset | Specifies the number of email addresses to skip. The default is 0. |
type |
Get only personal or generic
email addresses.
|
seniority |
Get only email addresses for people with the selected seniority level.
The possible values are junior , senior
or executive . Several seniority levels can be
selected (delimited by a comma).
|
department |
Get only email addresses for people working in the selected
department(s). The possible values are executive ,
it , finance , management ,
sales , legal , support ,
hr , marketing or
communication . Several departments can be selected
(comma-delimited).
|
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
Each response will return up to 100 emails. Use the "offset" parameter to get all of them. A new query is counted for calls returning at least one result.
The number of sources is limited to 20 for each email address.
The
extracted_on
attribute of a source contains the date it was found for the first time, whereas the
last_seen_on
attribute contains the date it was found for the last time.
type
returns the value "personal" or "generic". A "generic" email address
is a role-based email address, like contact@hunter.io. On the
contrary, a "personal" email address is the address of someone in
the company.
confidence
is our estimation of the probability the email address returned is
correct. It depends on several criteria such as the number and
quality of sources.
On the Free plan, the results are limited to the first 10 email addresses.
If the limit
additioned to the offset
is higher
than 10, an error is returned.
The Domain Search API call is rate limited to 15 requests per second.
* You must send at least the domain name or the company name. You can also send both.
GET https://api.hunter.io/v2/domain-search?domain=intercom.io
{
"data": {
"domain": "intercom.io",
"disposable": false,
"webmail": false,
"accept_all": false,
"pattern": "{first}",
"organization": "Intercom",
"country": null,
"state": null,
"emails": [
{
"value": "ciaran@intercom.io",
"type": "personal",
"confidence": 92,
"sources": [
{
"domain": "github.com",
"uri": "http://github.com/ciaranlee",
"extracted_on": "2015-07-29",
"last_seen_on": "2017-07-01",
"still_on_page": true
},
{
"domain": "blog.intercom.io",
"uri": "http://blog.intercom.io/were-hiring-a-support-engineer/",
"extracted_on": "2015-08-29",
"last_seen_on": "2017-07-01",
"still_on_page": true
},
...
],
"first_name": "Ciaran",
"last_name": "Lee",
"position": "Support Engineer",
"seniority": "senior",
"department": "it",
"linkedin": null,
"twitter": "ciaran_lee",
"phone_number": null,
"verification": {
"date": "2019-12-06",
"status": "valid"
}
},
...
]
},
"meta": {
"results": 35,
"limit": 10,
"offset": 0,
"params": {
"domain": "intercom.io",
"company": null,
"type": null,
"seniority": null,
"department": null
}
}
}
This API endpoint generates or retrieves the most likely email address from a domain name, a first name and a last name.
domain
Required*
|
The domain name of the company, used for emails. For example, "asana.com". |
company
Required*
|
The company name from which you want to find the email addresses. For example, "stripe". Note that you'll get better results by supplying the domain name as we won't have to find it. If you send a request with both the domain and the company name, we'll use the domain name. It doesn't need to be in lowercase. |
first_name
Required**
|
The person's first name. It doesn't need to be in lowercase. |
last_name
Required**
|
The person's last name. It doesn't need to be in lowercase. |
full_name
Required**
|
The person's full name. Note that you'll get better results by supplying the person's first and last name if you can. It doesn't need to be in lowercase. |
max_duration | The maximum duration (in seconds) of the request. Setting a longer duration allows us to refine the results and provide more accurate data. It must range between 3 and 20. Defaults to 5. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
The score returned is an estimation of the probability the email generated is correct.
If we have found the retrieved email address somewhere on the web, we
display the sources here. The number of sources is limited to 20.
The
extracted_on
attribute contains the date it was found for the first time, whereas the
last_seen_on
attribute contains the date it was found for the last time.
The Email Finder API call is rate limited to 300 requests per minute, with bursts of 10 requests per second.
* You must send at least the domain name or the company name. You can also send both.
** You must send at least the first name and the last name or the full name.
GET https://api.hunter.io/v2/email-finder?domain=asana.com&first_name=Dustin&last_name=Moskovitz
GET https://api.hunter.io/v2/email-finder?company=Asana&full_name=Dustin+Moskovitz
{
"data": {
"first_name": "Dustin",
"last_name": "Moskovitz",
"email": "dustin@asana.com",
"score": 72,
"domain": "asana.com",
"accept_all": false,
"position": "CEO",
"twitter": "moskov",
"linkedin_url": "https://www.linkedin.com/in/dmoskov",
"phone_number": null,
"company": "Asana",
"sources": [
{
"domain": "blog.asana.com",
"uri": "http://blog.asana.com",
"extracted_on": "2015-09-27",
"last_seen_on": "2017-09-01",
"still_on_page": true
},
...
],
"verification": {
"date": "2020-02-16",
"status": "valid"
}
},
"meta": {
"params": {
"first_name": "Dustin",
"last_name": "Moskovitz",
"full_name": null,
"domain": "asana.com",
"company": null
}
}
}
This API endpoint allows you to verify the deliverability of an email address.
Hunter focuses on B2B. Therefore, webmails are not verified. We'll run every check but won't reach the remote SMTP server.
This endpoint is rate-limited by domain name. You can check up to
200 email addresses for a domain name every 24 hours. You can
check the number of requests remaining using the
X-RateLimit-Remaining
header.
The request will run for 20 seconds. If it was not able to provide
a response in time, we will return a 202
status code.
You will then be able to poll the same endpoint to get
the verification's result. Of course, all the requests in this case
are counted only once.
email
Required
|
The email address you want to verify. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
status
returns the status of the email address. It takes 1 out of 6 possible values:
result
returns the main status of the verification. It takes 1 out of 3 possible values:
It is deprecated; use
status
instead to get the detailed status of the email address.
score
is the deliverability score we give to the email address. For webmail
and disposable emails, we provide an arbitrary score of 50.
regexp
is true if the email address passes our regular expression.
gibberish
is true if we find this is an automatically generated email
address (for example "e65rc109q@company.com").
disposable
is true if we find this is an email address from a disposable
email service.
webmail
is true if we find this is an email from a webmail (for example
Gmail).
mx_records
is true if we find MX records exist on the domain of the given
email address.
smtp_server
is true if we connect to the SMTP server successfully.
smtp_check
is true if the email address doesn't bounce.
accept_all
is true if the SMTP server accepts all the email addresses.
It means you can have have false positives on SMTP checks.
block
is true if the SMTP server prevented us to perform the SMTP
check.
sources
If we have found the given email address somewhere on the web, we
display the sources here. The number of sources is limited to 20.
The
extracted_on
attribute contains the date it was found for the first time, whereas the
last_seen_on
attribute contains the date it was found for the last time.
The Email Verification API call is rate limited to 300 requests per minute, with bursts of 10 requests per second.
GET https://api.hunter.io/v2/email-verifier?email=patrick@stripe.com
{
"data": {
"status": "valid",
"result": "deliverable",
"_deprecation_notice": "Using result is deprecated, use status instead",
"score": 100,
"email": "patrick@stripe.com",
"regexp": true,
"gibberish": false,
"disposable": false,
"webmail": false,
"mx_records": true,
"smtp_server": true,
"smtp_check": true,
"accept_all": false,
"block": false,
"sources": [
{
"domain": "beta.paganresearch.io",
"uri": "http://beta.paganresearch.io/details/stripe",
"extracted_on": "2020-06-17",
"last_seen_on": "2020-06-17",
"still_on_page": true
},
{
"domain": "icloudnewz.blogspot.com",
"uri": "http://icloudnewz.blogspot.com/2017/11/follow-patrick-collison-mike-birbiglia.html",
"extracted_on": "2020-03-25",
"last_seen_on": "2020-06-29",
"still_on_page": true
}
]
},
"meta": {
"params": {
"email": "patrick@stripe.com"
}
}
}
This API endpoint allows you to know how many email addresses we have for one domain or for one company. It's free and doesn't require authentication.
domain
Required*
|
The domain name for which you want to know how many email addresses we have. |
company
Required*
|
The company name for which you want to know how many email addresses we have. For example, "stripe". Note that you'll get better results by supplying the domain name as we won't have to find it. If you send a request with both the domain and the company name, we'll use the domain name. It doesn't need to be in lowercase. |
type |
Get the count of only personal or generic
email addresses.
|
This call is free and doesn't require your API key. You can use it to quickly know if we can supply email addresses on a given domain or company.
* You must send at least the domain name or the company name. You can also send both.
GET https://api.hunter.io/v2/email-count?domain=stripe.com
{
"data": {
"total": 81,
"personal_emails": 65,
"generic_emails": 16,
"department": {
"executive": 10,
"it": 0,
"finance": 8,
"management": 0,
"sales": 0,
"legal": 0,
"support": 6,
"hr": 0,
"marketing": 0,
"communication": 2
},
"seniority": {
"junior": 13,
"senior": 5,
"executive": 2
}
},
"meta": {
"params": {
"domain": "stripe.com",
"company": null,
"type": null
}
}
}
This API endpoint enables you to get information regarding your Hunter account at any time. This call is free.
api_key
Required
|
One of the API keys associated with your account. |
calls
is the sum of search and verification requests made during the
current billing period. It is deprecated;
use
requests
instead to get the detailed usage per request type.
GET https://api.hunter.io/v2/account
{
"data": {
"first_name": "Antoine",
"last_name": "Finkelstein",
"email": "antoine@hunter.io",
"plan_name": "Pro",
"plan_level": 3,
"reset_date": 2021-01-25,
"team_id": 1,
"calls": {
"_deprecation_notice": "Sums the searches and the verifications, giving an unprecise look of the requests available",
"used": 18526,
"available": 20000
},
"requests": {
"searches": {
"used": 14260,
"available": 10000
},
"verifications": {
"used": 4266,
"available": 10000
}
}
}
}
Returns all the leads already saved in your account. The leads are returned in sorted order, with the most recent leads appearing first.
The leads can be filtered by attributes. Three kind of values can be given:
*
: select all the leads where the attribute has
any value.
~
: select all the leads where the attribute is
empty.
These filtering options apply for the following attributes:
email
, first_name
,
last_name
, position
,
company
, industry
,
website
, country_code
,
company_size
, source
,
twitter
, linkedin_url
,
phone_number
.
leads_list_id | Only returns the leads belonging to this list. |
Filters the leads by email. | |
first_name | Filters the leads by first name. |
last_name | Filters the leads by last name. |
position | Filters the leads by position. |
company | Filters the leads by company. |
industry | Filters the leads by industry. |
website | Filters the leads by website. |
country_code | Filters the leads by country. The country code is defined in the ISO 3166-1 alpha-2 standard. |
company_size | Filters the leads by company size. |
source | Filters the leads by source. |
Filters the leads by Twitter handle. | |
linkedin_url | Filters the leads by LinkedIn URL. |
phone_number | Filters the leads by phone number. |
sync_status |
Only returns the leads matching this synchronization status.
It can be one of the following values:
pending , error , success .
|
sending_status |
Only returns the leads matching this sending status.
It can be one of the following values:
clicked , opened , sent ,
pending , error , bounced ,
unsubscribed , replied .
|
last_activity_at |
Only returns the leads matching this last activity.
It can be one of the following values:
* (any value) or ~ (unset).
|
last_contact_at |
Only returns the leads matching this last contact date.
It can be one of the following values:
* (any value) or ~ (unset).
|
query | Only returns the leads with any attribute matching the query. |
limit | A limit on the number of leads to be returned. Limit can range between 1 and 1,000. Default is 20. |
offset | The number of leads to skip. Use this parameter to fetch all the leads. Offset can range between 0 and 100,000. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
GET https://api.hunter.io/v2/leads
{
"data": {
"leads": [
{
"id": 1,
"email": "hoon@stripe.com",
"first_name": "Jeremy",
"last_name": "Hoon",
"position": null,
"company": "Stripe",
"company_industry": null,
"company_size": null,
"confidence_score": null,
"website": "stripe.com",
"country_code": null,
"source": null,
"linkedin_url": null,
"phone_number": null,
"twitter": null,
"sync_status": null,
"notes": null,
"sending_status": null,
"last_activity_at": null,
"last_contacted_at": null,
"leads_list": {
"id": 1,
"name": "My leads list",
"leads_count": 2
}
},
{
"id": 2,
"email": "dustin@asana.com",
"first_name": "Dustin",
"last_name": "Moskovitz",
"position": "CEO",
"company": "Asana",
"company_industry": null,
"company_size": null,
"confidence_score": null,
"website": "asana.com",
"country_code": "US",
"source": null,
"linkedin_url": null,
"phone_number": null,
"twitter": "moskov",
"sync_status": null,
"notes": null,
"sending_status": null,
"last_activity_at": null,
"last_contacted_at": null,
"leads_list": {
"id": 1,
"name": "My leads list",
"leads_count": 2
}
}
}
},
"meta": {
"count": 2,
"total": 2,
"params": {
"limit": 20,
"offset": 0
}
}
}
Retrieves all the fields of a lead.
id
Required
|
Identifier of the lead. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
GET https://api.hunter.io/v2/leads/1
{
"data": {
"id": 1,
"email": "hoon@stripe.com",
"first_name": "Jeremy",
"last_name": "Hoon",
"position": null,
"company": "Stripe",
"company_industry": null,
"company_size": null,
"confidence_score": null,
"website": "stripe.com",
"country_code": null,
"source": null,
"linkedin_url": null,
"phone_number": null,
"twitter": null,
"sync_status": null,
"notes": null,
"sending_status": null,
"last_activity_at": null,
"last_contacted_at": null,
"leads_list": {
"id": 1,
"name": "My leads list",
"leads_count": 2
}
}
}
Creates a new lead. The parameters must be passed as a JSON hash.
email
Required
|
The email address of the lead. |
first_name | The first name of the leads. |
last_name | The last name of the lead. |
position | The job title of the lead. |
company | The name of the company the lead is working in. |
company_industry | The sector of the company. It can be any value, but we recommend using one of the following: Animal, Art and Entertainment, Automotive, Beauty and Fitness, Books and Litterature, Education and Career, Finance, Food and Drink, Game, Health, Hobby and Leisure, Home and Garden, Industry, Internet and Telecom, Law and Government, News, Real Estate, Science, Shopping, Sport, Technology or Travel. |
company_size | The size of the company the lead is working in. |
confidence_score | Estimation of the probability the email address returned is correct, between 0 and 100. In Hunter's products, the confidence score is the score returned by the Email Finder. |
website | The domain name of the company. |
country_code | The country of the lead. The country code is defined in the ISO 3166-1 alpha-2 standard. |
linkedin_url | The address of the public profile on LinkedIn. |
phone_number | The phone number of the lead. |
The Twitter handle of the lead. | |
notes | Some personal notes about the lead. |
source | The source where the lead has been found. |
leads_list_id | The identifier of the list the lead belongs to. If it's not specified, the lead is saved in the last list created. |
custom_attributes[slug] | The value of the custom attribute identified by its slug. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
POST https://api.hunter.io/v2/leads
{
"email": "dustin@asana.com",
"first_name": "Dustin",
"last_name": "Moskovitz",
"position": "Co-founder",
"company": "Asana",
"company_industry": "Internet and Telecom",
"company_size": "201-500 employees",
"confidence_score": 95,
"website": "asana.com",
"phone_number": "720-555-6251",
"twitter": "moskov",
"custom_attributes": {
"customer_id": "cus-1234abcd"
}
}
{
"data": {
"id": 3,
"email": "dustin@asana.com",
"first_name": "Dustin",
"last_name": "Moskovitz",
"position": "Co-founder",
"company": "Asana",
"company_industry": "Internet and Telecom",
"company_size": "201-500 employees",
"confidence_score": 95,
"website": "asana.com",
"country_code": "US",
"source": null,
"linkedin_url": null,
"phone_number": "720-555-6251",
"twitter": "moskov",
"sync_status": null,
"notes": null,
"sending_status": null,
"last_activity_at": null,
"last_contacted_at": null,
"customer_id": "cus1234-abcd",
"leads_list": {
"id": 1,
"name": "My leads list",
"leads_count": 3
}
}
}
Updates an existing lead. The updated values must be passed as a JSON hash.
The fields you can update are the same params you can give when you create a lead.
PUT https://api.hunter.io/v2/leads/1
{
"company": "Facebook"
}
Deletes an existing lead.
id
Required
| Identifier of the lead. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
DELETE https://api.hunter.io/v2/leads/1
Saving and managing leads lists in Hunter can be done entirely through the RESTful API.
Here is the list of the available methods:
All these calls are free.
Returns all the leads lists already saved in your account. The leads lists are returned in sorted order, with the most recent leads lists appearing first.
limit | A limit on the number of lists to be returned. Limit can range between 1 and 100 lists. Default is 20. |
offset | The number of lists to skip. Use this parameter to fetch all the lists. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
GET https://api.hunter.io/v2/leads_lists
{
"data": {
"leads_lists": [
{
"id": 1,
"name": "My first list",
"leads_count": 10
},
{
"id": 2,
"name": "My second list",
"leads_count": 1
},
}
},
"meta": {
"total": 2,
"params": {
"limit": 20,
"offset": 0
}
}
}
Retrieves all the fields of a leads list.
id
Required
|
Identifier of the leads list. |
limit | A limit on the number of leads to be returned. Limit can range between 1 and 100 lists. Default is 20. |
offset | The number of leads to skip. Use this parameter to fetch all the leads in the list. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
GET https://api.hunter.io/v2/leads_lists/1
{
"data": {
"name": "My leads",
"leads_count": 10,
"leads": [
{
"id": 1,
"first_name": "Jeremy",
"last_name": "Hoon",
"position": null,
"company": "Stripe",
"company_industry": null,
"company_size": null,
"email": "hoon@stripe.com",
"confidence_score": null,
"website": "https://stripe.com",
"country_code": null,
"source": null,
"linkedin_url": null,
"phone_number": null,
"twitter": null,
"sync_status": null,
"notes": null,
"sending_status": null,
"last_activity_at": null,
"last_contacted_at": null,
"leads_list_id": 1
},
...
]
},
"meta": {
"params": {
"limit": 20,
"offset": 0,
"leads_list_id": 1
}
}
}
Creates a new leads list. The parameters must be passed as a JSON hash.
name
Required
|
The name of the leads list. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
POST https://api.hunter.io/v2/leads_lists
{
"name": "My new leads list"
}
{
"data": {
"list_id": 3,
"name": "My new leads list"
}
}
Updates an existing leads list. The updated values must be passed as a JSON hash.
name
Required
|
The name of the leads list. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
PUT https://api.hunter.io/v2/leads_lists/1
{
"name": "New leads list name"
}
Deletes an existing leads list.
id
Required
| Identifier of the leads list. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
DELETE https://api.hunter.io/v2/leads_lists/1
You can interact with your campaigns programmatically. It enables
you to automate advanced use-cases and make your outreach even more
efficient.
Not all endpoints are available for public usage at the moment. If
you have a specific idea in mind that requires we open this access,
please reach out!
Here is the list of the available methods:
All these calls are free.
Returns all the campaigns in your account. The campaigns are returned in reverse-chronological order by creation date.
started | Only returns the campaigns that have been started. |
archived | Only returns campaigns that have been archived. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
GET https://api.hunter.io/v2/campaigns
{
"data": {
"campaigns": [
{
"id": 2,
"name": "January tourism CTO outreach",
"recipients_count": 39,
"editable": false,
"started": true,
"archived": false,
"paused": false
},
{
"id": 1,
"name": "Long-term customers upsell",
"recipients_count": 85,
"editable": true,
"started": true,
"archived": false,
"paused": true
}
]
},
"meta": {
"limit": "20",
"offset": "0"
}
}
Add a recipient to a campaign. The parameters must be passed as a JSON hash.
As the recipient is added, we try to associate it with one of your leads with the same email. This enables you to send personalized emails by using attributes.
Note that when adding a recipient to an active campaign, the email might be sent shortly after your API call, leaving you no time to cancel the sending in case of a mistake.
id
Required
|
Identifier of the campaign |
emails
Required
|
The recipients you want to add to the campaign. If there's
only one email, it can be supplied as a string. Otherwise, it
should be an array of up to 100 emails.
In case an email doesn't pass our validation, an error is returned, and no recipient is added. |
api_key
Required
|
Your secret API key. You can generate it in your dashboard. |
POST https://api.hunter.io/v2/campaigns/42/recipients
{
"emails": ["marcus@hunter.io", "john@hunter.io"]
}
{
"data": {
"recipients_added": 1
},
"meta": {
"params": {
"emails": ["marcus@hunter.io", "john@hunter.io"]
}
}
}