---
title: "Create contacts"
method: POST
path: "/v1/contacts"
tags: ["Contacts"]
---

# Create contacts

`POST /v1/contacts`

## Request

- Base URL: `https://api.automatedclientacquisition.com`
- URL: `https://api.automatedclientacquisition.com/v1/contacts`
- Auth: HTTP bearer

Creates CRM contacts in bulk, scoped to your organization. Deduplicates on
email by default — both against contacts already in your CRM and within the
submitted batch.

Every field on a contact is optional, but a contact needs something to be
named by. When `display_name` is omitted it is derived from first + last
name, then company, then email. A contact with none of those returns `400`,
and rejects the whole batch rather than writing part of it.

> **Deduplicated contacts are not returned.** Skipped rows are counted in
> `skipped` but their IDs are absent from `contact_ids`. If you chain straight
> into list membership, existing contacts silently drop out of the flow — look
> them up by email instead when re-syncing a source.

Contacts without an email are always inserted, dedupe or not. A source with
blank emails will duplicate on every run.

## Request body

- object
  - `contacts` ContactInput[], required: Contact objects. A request over 1000 is rejected outright, not truncated.
    - `display_name` string: Derived when omitted.
    - `first_name` string: Used for personalization tokens in sequences.
    - `last_name` string
    - `primary_email` string: The dedupe key. Contacts without one are always inserted.
    - `primary_phone` string: E.164 recommended.
    - `primary_linkedin_url` string: Full profile URL.
    - `company` string
    - `company_website` string: Domain or full URL.
    - `job_title` string: Used by ICP scoring.
    - `city` string
    - `state` string
    - `country` string: Used by geography filters.
    - `tags` string[]: Applied on create.
    - `custom_fields` object: Arbitrary JSON, available as merge variables in sequences.
    - `pipeline_id` string, uuid: Place directly into a CRM pipeline.
    - `stage_id` string, uuid: Place directly into a pipeline stage.
    - `owner_user_id` string, uuid: Assign an owner.
    - `source` string: Per-contact attribution, overriding the request default.
  - `dedupe_on_email` boolean: Skip contacts whose email already exists in the organization.
  - `source` string: Attribution applied to rows without their own `source`.
  - `log_activity` boolean: Write a `contact_created` activity row per contact.

## Response `200`

Contacts processed.

- object
  - `success` boolean
  - `created` integer: Contacts inserted.
  - `skipped` integer: Contacts skipped as duplicates.
  - `total_submitted` integer
  - `contact_ids` string[]: IDs of created contacts only — skipped duplicates are absent.

## Other responses

- `400`: Malformed or invalid body. Do not retry — it will fail identically.
- `401`: Missing, invalid or revoked token.
- `500`: Something broke on our side. Safe to retry with backoff.

---

[API](https://skmtc.dev/automatedclientacquisition/apis/aca-api.md) · [All operations](https://skmtc.dev/automatedclientacquisition/apis/aca-api/llms.txt) · [OpenAPI document](https://skmtc.dev/automatedclientacquisition/apis/aca-api/revisions/8f3e3b141311?raw)
