Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/apollo-api-documentation-contacts-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no email required.
A second provider on the same verified email joins the account you already have.
openapi: 3.1.0
info:
title: Apollo API — Contacts
summary: Programmatic access to Apollo's sales intelligence and engagement platform — data enrichment, prospect and company
search, and go-to-market workflow management.
description: 'The Apollo API provides programmatic access to [Apollo](https://www.apollo.io/), the all-in-one sales intelligence
and engagement platform. Use it to enrich people and company data (individually or in bulk), search Apollo''s database
of over 240 million contacts and 30 million companies, and manage accounts, contacts, deals, sequences, tasks, calls,
and conversations in your go-to-market workflows.
## Base URL
All API requests are made to `https://api.apollo.io/api/v1`.
## Authentication
- **Apollo users** authenticate with an API key passed in the `x-api-key` request header. See [Create API Keys](https://docs.apollo.io/docs/create-api-key).
- **Apollo partners** building integrations on behalf of mutual users authenticate with the [OAuth 2.0 authorization flow](https://docs.apollo.io/docs/use-oauth-20-authorization-flow-to-access-apollo-user-information-partners).
## Rate limits & credits
Rate limits and credit consumption depend on your [Apollo pricing plan](https://docs.apollo.io/docs/api-pricing). Check
your current limits and usage with the [View API Usage Stats and Rate Limits](https://docs.apollo.io/reference/view-api-usage-stats)
endpoint. For more details, see [Rate Limits](https://docs.apollo.io/reference/rate-limits) and the [API FAQs](https://docs.apollo.io/docs/apollo-api-faqs).
New to the API? Start with the [Apollo API overview](https://docs.apollo.io/reference/apollo-api).'
termsOfService: https://www.apollo.io/terms/api
contact:
name: Apollo API Support
url: https://docs.apollo.io/
version: '1.0'
servers:
- url: https://api.apollo.io/api/v1
tags:
- name: Contacts
description: Create, update, and search the people your team saves in Apollo.
security:
- apiKey: []
- bearerAuth: []
components:
securitySchemes:
apiKey:
type: apiKey
in: header
name: x-api-key
description: '[Recommended] API key, passed in the `x-api-key` request header.
See [Create API Keys](https://docs.apollo.io/docs/create-api-key).'
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
description: 'OAuth 2.0 access token, used by Apollo partners building integrations.
See the [OAuth 2.0 authorization flow](https://docs.apollo.io/docs/use-oauth-20-authorization-flow-to-access-apollo-user-information-partners).'
paths:
/contacts:
post:
summary: Create a Contact
description: '## Endpoint essentials
**API key access:** `api/v1/contacts/create` or `Master API key`
**OAuth scopes:** `contact_write`
**Credit usage:** `0 credits` — [Learn more about API pricing and credits](https://docs.apollo.io/docs/api-pricing).
<a href="https://knowledge.apollo.io/hc/en-us/articles/5995459280525-View-and-Edit-Contacts" target="_blank">Contacts</a>
are people saved in Apollo.<br><br>Use the Create a Contact endpoint to add a new contact to your team''s Apollo account.<br><br>By
default, Apollo doesn''t apply deduplication processes when you create a new contact via API. If your entry has the
same name, email address, or other details as an existing contact, Apollo creates a new contact instead of updating
the existing contact. To enable deduplication and prevent duplicate contacts, set the <code>run_dedupe</code> parameter
to <code>true</code>. <br><br>To update an existing contact, use the <a href="https://docs.apollo.io/reference/update-a-contact">Update
a Contact endpoint</a> instead.
### What `run_dedupe` actually does
Setting `run_dedupe` to `true` does more than suppress a duplicate. On a match, Apollo **updates that existing contact
in place** with your request''s values and returns it. The response looks like a creation, but the `id` belongs to
the pre-existing contact — so treating every `200` as "a new contact was created" doesn''t hold once `run_dedupe`
is on.
**How Apollo picks the match.** It checks these in order and stops at the first hit, so a match isn''t necessarily
on email:
1. `id`, if you send one.
2. CRM identifiers: `salesforce_lead_id`, `salesforce_contact_id`, `hubspot_vid`, or a previously merged CRM ID.
3. `person_id`.
4. `email` — compared against the contact''s primary email **and** any additional emails stored on it.
5. `first_name` plus `last_name` (or a full name) with a matching company, where the company matches on email domain,
`organization_id`, or `organization_name`.
Because of step 5, a contact can be matched and updated even when the email you send differs from the stored one.
**What the update writes.** It''s a field-level overwrite of the values you send, not a merge that prefers existing
data:
* Fields you **send** overwrite the stored values, with no warning and no record of the previous value.
* Fields you **omit** are left untouched, so you don''t need to resend the whole record.
* An **empty value clears the field** rather than being ignored.
* The contact''s `email` can itself be overwritten when the match came from a CRM ID, `person_id`, or name-plus-company.
`email_status` isn''t re-verified, so it can keep reading `verified` while describing the previous address.
* Protected once set: `person_id`, `salesforce_lead_id`, and `salesforce_contact_id`. LinkedIn-sourced photos won''t
replace an existing `photo_url`.
**Recommended handling.** To add records without changing existing ones, leave `run_dedupe` off (the default) and
reconcile duplicates yourself. To upsert, set it to `true` and send the complete set of fields you want the contact
to end up with, since omitted fields keep their old values. To edit a known contact, prefer [Update a Contact](https://docs.apollo.io/reference/update-a-contact)
with its `id` — explicit, with no matching involved.
[Bulk Create Contacts](https://docs.apollo.io/reference/bulk-create-contacts) differs: matched contacts are returned
in `existing_contacts` **without** being modified.'
tags:
- Contacts
operationId: create-a-contact
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
first_name:
type: string
description: 'The first name of the contact you want to create. Example: `Tim`'
last_name:
type: string
description: 'The last name of the contact you want to create. Example: `Zheng`'
organization_name:
type: string
description: 'The name of the contact''s employer (company). Example: `apollo`'
title:
type: string
description: 'The current job title that the contact holds. Example: `senior research analyst`'
account_id:
type: string
description: 'The Apollo ID for the account. Example: `63f53afe4ceeca00016bdd2f`'
email:
type: string
description: 'The email address of the contact. Example: `example@email.com`'
website_url:
type: string
description: 'The corporate website URL. Example: `https://www.apollo.io/`'
label_names:
type: array
description: Lists to which the contact belongs.
items:
type: string
contact_stage_id:
type: string
description: 'The Apollo ID for the contact stage. Example: `6095a710bd01d100a506d4ae`'
present_raw_address:
type: string
description: 'The personal location for the contact. Example: `Atlanta, United States`'
direct_phone:
type: string
description: 'The primary phone number. Example: `555-555-0133`'
corporate_phone:
type: string
description: 'The work/office phone number. Example: `+44 7700 900852`'
mobile_phone:
type: string
description: 'The mobile phone number. Example: `555-555-0133`'
home_phone:
type: string
description: 'The home phone number. Example: `555-555-0133`'
other_phone:
type: string
description: 'Alternative phone number. Example: `555-555-0133`'
typed_custom_fields:
type: object
description: "Add information to <a href=\"https://knowledge.apollo.io/hc/en-us/articles/4412498825869-Create-Custom-Contact-Fields\"\
\ target=\"_blank\">custom fields</a> in Apollo. <br><br><b>Your custom fields are unique to your team's\
\ Apollo account. This means that the examples in this documentation may not work for your testing purposes.</b>\
\ <br><br>To utilize this parameter successfully, call the <a href=\"https://docs.apollo.io/reference/get-a-list-of-all-custom-fields\"\
>Get a List of All Custom Fields</a> endpoint and identify the `id` value for the custom field, as well\
\ as the appropriate data type. For example, if a custom field accepts picklist entries, you need to pass\
\ the accompanying `id` value for the picklist entry that you want to use as the input value. <br><br><b>Example</b>:\
\ When the <a href=\"https://docs.apollo.io/reference/get-a-list-of-all-custom-fields\">Get a List of\
\ All Custom Fields</a> endpoint returns an `id` of field: \n * `\"60c39ed82bd02f01154c470a\"` (datetime)\
\ \n \n\n then the value passed should be: \n\n `{\"60c39ed82bd02f01154c470a\": \"2025-08-07\"}`"
additionalProperties:
type: string
example:
60c39ed82bd02f01154c470a: '2025-08-07'
run_dedupe:
type: boolean
description: 'Set to `true` to match against your existing contacts instead of always creating a new one.
The default value is `false`. <br><br>When a match is found, Apollo **updates that existing contact in
place** with the values you sent and returns it — the `id` in the response belongs to the pre-existing
contact, not a new record. Fields you send overwrite the stored values, fields you omit are left untouched,
and sending an empty value clears the field. <br><br>Matching is checked in order: `id`, CRM identifiers,
`person_id`, `email` (against the contact''s primary and additional emails), then name plus company. Because
of the last rule, a contact can be matched and updated even when the email differs. <br><br>When deduplication
is enabled, performance may be slightly impacted due to the additional matching checks. See the endpoint
description for full details.'
default: false
examples:
Create contact without deduplication:
summary: Create a new contact without deduplication (default behavior)
value:
first_name: John
last_name: Smith
email: john.smith@example.com
organization_name: Example Corp
title: Software Engineer
Create contact with deduplication:
summary: Create a new contact with deduplication enabled
value:
first_name: Jane
last_name: Doe
email: jane.doe@example.com
organization_name: Example Corp
title: Product Manager
run_dedupe: true
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value:
contact:
contact_roles: []
id: 66e34b81740c50074e3d1bd4
first_name: Fyodor
last_name: Dostoevsky
name: Fyodor Dostoevsky
linkedin_url: null
title: Chief Fiction Writer
contact_stage_id: 6095a710bd01d100a506d4ae
owner_id: 60affe7d6e270a00f5db6fe4
creator_id: 60affe7d6e270a00f5db6fe4
person_id: null
email_needs_tickling: null
organization_name: Apollo.io
source: api
original_source: api
organization_id: 5e66b6381e05b4008c8331b8
headline: null
photo_url: null
present_raw_address: St. Petersburg, Russia
linkedin_uid: null
extrapolated_email_confidence: null
salesforce_id: null
salesforce_lead_id: null
salesforce_contact_id: null
salesforce_account_id: null
crm_owner_id: null
created_at: '2024-09-12T20:13:53.207Z'
emailer_campaign_ids: []
direct_dial_status: null
direct_dial_enrichment_failed_at: null
email_status: verified
email_source: null
account_id: 63f53afe4ceeca00016bdd2f
last_activity_date: null
hubspot_vid: null
hubspot_company_id: null
crm_id: null
sanitized_phone: '+15555550149'
merged_crm_ids: null
updated_at: '2024-09-12T20:13:53.331Z'
queued_for_crm_push: true
suggested_from_rule_engine_config_id: null
email_unsubscribed: null
label_ids:
- 66e34b81740c50074e3d1bd0
- 66e34b81740c50074e3d1bd1
- 66e34b81740c50074e3d1bd2
- 66e34b81740c50074e3d1bd3
has_pending_email_arcgate_request: false
has_email_arcgate_request: false
existence_level: full
email: fyodo@apollo.io
email_from_customer: true
custom_field_errors: {}
crm_record_url: null
email_status_unavailable_reason: null
email_true_status: User Managed
updated_email_true_status: true
contact_rule_config_statuses: []
source_display_name: Created from API
twitter_url: null
contact_campaign_statuses: []
contact_emails: []
next_contact_id: null
time_zone: Asia/Krasnoyarsk
city: Saint Petersburg
state: Saint Petersburg
country: Russia
show_intent: false
phone_numbers:
- raw_number: 555-555-0149
sanitized_number: '+15555550149'
type: work_direct
position: 0
status: no_status
dnc_status: null
dnc_other_info: null
dialer_flags: null
account_phone_note: null
free_domain: false
is_likely_to_engage: false
email_domain_catchall: false
typed_custom_fields:
5b75f1c11dc2727d43ae3bb9: test
5c4296857f799409361890ea: test2
labels:
- id: 66e34b81740c50074e3d1bd2
modality: contacts
cached_count: 0
name: typewriter
created_at: '2024-09-12T20:13:53.119Z'
updated_at: '2024-09-12T20:13:53.279Z'
user_id: 60affe7d6e270a00f5db6fe4
- id: 66e34b81740c50074e3d1bd1
modality: contacts
cached_count: 0
name: fiction
created_at: '2024-09-12T20:13:53.107Z'
updated_at: '2024-09-12T20:13:53.258Z'
user_id: 60affe7d6e270a00f5db6fe4
- id: 66e34b81740c50074e3d1bd0
modality: contacts
cached_count: 0
name: writer
created_at: '2024-09-12T20:13:53.093Z'
updated_at: '2024-09-12T20:13:53.308Z'
user_id: 60affe7d6e270a00f5db6fe4
- id: 66e34b81740c50074e3d1bd3
modality: contacts
cached_count: 0
name: microsoft word
created_at: '2024-09-12T20:13:53.132Z'
updated_at: '2024-09-12T20:13:53.313Z'
user_id: 60affe7d6e270a00f5db6fe4
Deduplication-Result:
summary: Contact creation with deduplication enabled - existing contact found
value:
contact:
contact_roles: []
id: 66e34b81740c50074e3d1bd4
first_name: Jane
last_name: Doe
name: Jane Doe
linkedin_url: null
title: Product Manager
contact_stage_id: 6095a710bd01d100a506d4ae
owner_id: 60affe7d6e270a00f5db6fe4
creator_id: 60affe7d6e270a00f5db6fe4
person_id: null
email_needs_tickling: null
organization_name: Example Corp
source: api
original_source: api
organization_id: 5e66b6381e05b4008c8331b8
headline: null
photo_url: null
present_raw_address: null
linkedin_uid: null
extrapolated_email_confidence: null
salesforce_id: null
salesforce_lead_id: null
salesforce_contact_id: null
salesforce_account_id: null
crm_owner_id: null
created_at: '2024-09-12T20:13:53.207Z'
emailer_campaign_ids: []
direct_dial_status: null
direct_dial_enrichment_failed_at: null
email_status: verified
email_source: null
account_id: 63f53afe4ceeca00016bdd2f
last_activity_date: null
hubspot_vid: null
hubspot_company_id: null
crm_id: null
sanitized_phone: null
merged_crm_ids: null
updated_at: '2024-09-12T20:13:53.331Z'
queued_for_crm_push: false
suggested_from_rule_engine_config_id: null
email_unsubscribed: null
label_ids: []
has_pending_email_arcgate_request: false
has_email_arcgate_request: false
existence_level: full
email: jane.doe@example.com
email_from_customer: true
custom_field_errors: {}
crm_record_url: null
email_status_unavailable_reason: null
email_true_status: User Managed
updated_email_true_status: true
contact_rule_config_statuses: []
source_display_name: Created from API
twitter_url: null
contact_campaign_statuses: []
contact_emails: []
next_contact_id: null
time_zone: null
city: null
state: null
country: null
show_intent: false
phone_numbers: []
account_phone_note: null
free_domain: false
is_likely_to_engage: false
email_domain_catchall: false
typed_custom_fields: {}
labels: []
dedupe_result:
found_existing: true
match_reason: email_match
existing_contact_id: 66e34b81740c50074e3d1bd4
schema:
type: object
properties:
contact:
type: object
properties:
contact_roles:
type: array
id:
type: string
example: 66e34b81740c50074e3d1bd4
first_name:
type: string
example: Fyodor
last_name:
type: string
example: Dostoevsky
name:
type: string
example: Fyodor Dostoevsky
linkedin_url: {}
title:
type: string
example: Chief Fiction Writer
contact_stage_id:
type: string
example: 6095a710bd01d100a506d4ae
owner_id:
type: string
example: 60affe7d6e270a00f5db6fe4
creator_id:
type: string
example: 60affe7d6e270a00f5db6fe4
person_id: {}
email_needs_tickling: {}
organization_name:
type: string
example: Apollo.io
source:
type: string
example: api
original_source:
type: string
example: api
organization_id:
type: string
example: 5e66b6381e05b4008c8331b8
headline: {}
photo_url: {}
present_raw_address:
type: string
example: St. Petersburg, Russia
linkedin_uid: {}
extrapolated_email_confidence:
type: number
nullable: true
salesforce_id: {}
salesforce_lead_id: {}
salesforce_contact_id: {}
salesforce_account_id: {}
crm_owner_id: {}
created_at:
type: string
example: '2024-09-12T20:13:53.207Z'
emailer_campaign_ids:
type: array
direct_dial_status: {}
direct_dial_enrichment_failed_at: {}
email_status:
type: string
example: verified
email_source: {}
account_id:
type: string
example: 63f53afe4ceeca00016bdd2f
last_activity_date: {}
hubspot_vid: {}
hubspot_company_id: {}
crm_id: {}
sanitized_phone:
type: string
example: '+15555550149'
merged_crm_ids: {}
updated_at:
type: string
example: '2024-09-12T20:13:53.331Z'
queued_for_crm_push:
type: boolean
example: true
default: true
suggested_from_rule_engine_config_id: {}
email_unsubscribed: {}
label_ids:
type: array
items:
type: string
example: 66e34b81740c50074e3d1bd0
has_pending_email_arcgate_request:
type: boolean
example: false
default: true
has_email_arcgate_request:
type: boolean
example: false
default: true
existence_level:
type: string
example: full
email:
type: string
example: fyodo@apollo.io
email_from_customer:
type: boolean
example: true
default: true
typed_custom_fields:
type: object
properties: {}
custom_field_errors:
type: object
properties: {}
crm_record_url: {}
email_status_unavailable_reason: {}
email_true_status:
type: string
example: User Managed
updated_email_true_status:
type: boolean
example: true
default: true
contact_rule_config_statuses:
type: array
source_display_name:
type: string
example: Created from API
twitter_url: {}
contact_campaign_statuses:
type: array
description: Array of campaign statuses for the contact, showing their participation in various email
sequences
items:
type: object
description: Contact campaign status object representing the contact's current state in a specific
email sequence
properties:
id:
type: string
description: Unique identifier for this contact campaign status record
example: 68782af181c7f0002159df25
emailer_campaign_id:
type: string
description: ID of the email sequence (emailer campaign) this status belongs to
example: 66e9e215ece19801b219997f
send_email_from_user_id:
type: string
description: ID of the user who is sending emails for this contact in the sequence
example: 66302798d03b9601c7934ebf
inactive_reason:
type: string
nullable: true
description: Reason why the contact is inactive in this sequence, if applicable
example: Sequence inactive
status:
type: string
description: Current status of the contact in this email sequence
enum:
- active
- failed
- paused
- finished
example: paused
added_at:
type: string
format: date-time
description: Timestamp when the contact was added to this sequence
example: '2025-07-16T22:42:57.372+00:00'
added_by_user_id:
type: string
description: ID of the user who added this contact to the sequence
example: 60affe7d6e270a00f5db6fe4
finished_at:
type: string
format: date-time
nullable: true
description: Timestamp when the contact finished/completed the sequence
example: null
paused_at:
type: string
format: date-time
nullable: true
description: Timestamp when the contact was paused in the sequence
example: null
auto_unpause_at:
type: string
format: date-time
nullable: true
description: Scheduled timestamp for automatically unpausing the contact
example: null
send_email_from_email_address:
type: string
nullable: true
description: Specific email address used to send emails to this contact
example: test.marcus.hale@apollomail.io
send_email_from_email_account_id:
type: string
description: ID of the email account used to send emails to this contact
example: 6633baaece5fbd01c791d7ca
manually_set_unpause:
type: boolean
nullable: true
description: Whether the unpause was manually set by a user
example: null
failure_reason:
type: string
nullable: true
description: Specific reason for failure if status is 'failed'
enum:
- hard_bounced
- spam_blocked
- bounced
- past_date_failure
example: null
current_step_id:
type: string
nullable: true
description: ID of the current step in the sequence that the contact is on
example: null
# --- truncated at 32 KB (198 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/apollo-api-documentation/refs/heads/main/openapi/apollo-api-documentation-contacts-api-openapi.yml