Skip to content

Create Contacts

POST
/contacts

Create a contact, optionally adding it to a list.

The contact is created independent of any list. When list_id is provided, the contact is added to that list AFTER it is created; when omitted, the contact is created standalone. A company is resolved and attached from company_domain when supplied.

Duplicate handling: when the submitted work_email / linkedin_url (or the deterministic identity hash) already matches an existing contact, the handler does NOT overwrite it — it writes nothing and skips the list_id linkage. This endpoint mirrors the in-app create and responds 409 Conflict with the matched contact_id and a field_diff under detail (rather than a misleading 201 success). The 409 is NOT cached under the Idempotency-Key, so a later create of the same identity is re-evaluated fresh.

Supports optional Stripe-style idempotency via the Idempotency-Key header — a safe retry of the same key replays the first SUCCESSFUL response (flagged Idempotent-Replay: true) rather than creating duplicate contacts.

Authorizations

Parameters

Header Parameters

Idempotency-Key
Any of:
string

Optional. Retrying a create with the same key returns the first response instead of creating a duplicate (cached 24h). Omit for the existing non-idempotent behavior.

X-Target-Org-Id
Any of:
string

Request Body required

Request body for creating contacts.

object
city
Any of:
string
company_domain
Any of:
string
company_id
Any of:
integer
country
Any of:
string
create_missing_fields

When true, custom_fields keys that match no existing column are created as NEW custom columns (list-scoped when list_id is set) and then written.

boolean
custom_fields
Any of:
object
key
additional properties
Any of:
string
direct_phone
Any of:
string
first_name
Any of:
string
job_department
Any of:
string
job_title
Any of:
string
last_name
Any of:
string
linkedin_url
Any of:
string
list_id
Any of:
integer
mobile_phone
Any of:
string
personal_emails
Any of:
string
seniority_level
Any of:
string
state
Any of:
string
work_email
Any of:
string

Responses

201

Successful Response

object
data
required
object
company_attached
boolean
contact_id
Any of:
integer
count
required
integer
custom_fields

How a write path handled the request’s custom (dynamic) column keys.

Shared by every Developer API write surface that accepts custom columns (POST /contacts, PUT /contacts/assert[/batch], PUT /companies/assert[/batch]).

Every field defaults to empty, so a client that ignores this object sees no behavioural change. It exists because these keys were previously dropped with NO caller-visible signal — the only trace was a server-side logger.warning in append_to_audience.

object
created

Caller keys for which a NEW custom column was created by this request.

Array<string>
ignored

Caller keys that matched no custom column and were NOT written. Create the column first (POST /fields) or pass create_missing_fields=true.

Array<string>
written

Caller keys that resolved to a custom column and were written.

Array<string>
merged
boolean
status
required
string
validation_errors
Array<string>
pagination
Any of:
object
has_next
required

Whether there are more pages

boolean
limit
required

Items per page

integer
next_cursor
Any of:
string
page
required

Current page number (1-indexed)

integer
total
required

Total number of items

integer

422

Validation Error

object
detail
Array<object>
object
loc
required
Array
msg
required
string
type
required
string