---
title: "Create new contact"
description: "Create a new contact with duplicate checking and comprehensive data validation"
---

> Documentation Index
> Fetch the complete documentation index at: https://developer.channelautomations.com/llms.txt
> Use this file to discover all available pages before exploring further.

Path: Channel Automation API › Contacts

`POST /api/contacts`

Create a new contact with duplicate checking and comprehensive data validation

## Authentication

- `ApiKeyAuth`, apiKey, in header, header `X-API-Key`, format `API_KEY`

## Request body

_Required._

- `workspace_id` (`post/api/contacts.workspace_id`; string, required) — Workspace ID for data isolation
- `firstname` (`post/api/contacts.firstname`; string, required) — Contact's first name
  - maxLength 100; example `"John"`
- `lastname` (`post/api/contacts.lastname`; string, required) — Contact's last name
  - maxLength 100; example `"Doe"`
- `phone_number` (`post/api/contacts.phone_number`; string, required) — Contact's phone number in E.164 format
  - pattern `^\+[1-9]\d{1,14}$`; example `"+1234567890"`
- `email` (`post/api/contacts.email`; string, optional) — Contact's email address
  - format `email`; example `"john.doe@example.com"`
- `lead_status` (`post/api/contacts.lead_status`; string, optional) — Initial lead status
  - example `"new"`
- `lead_source` (`post/api/contacts.lead_source`; string, optional) — Source of the lead
  - example `"website_form"`
- `product` (`post/api/contacts.product`; string, optional) — Product of interest
  - example `"premium_plan"`
- `address` (`post/api/contacts.address`; string, optional) — Street address
  - maxLength 255
- `city` (`post/api/contacts.city`; string, optional) — City
  - maxLength 100
- `state` (`post/api/contacts.state`; string, optional) — State or province
  - maxLength 50
- `zip` (`post/api/contacts.zip`; string, optional) — ZIP or postal code
  - maxLength 20
- `notes` (`post/api/contacts.notes`; string, optional) — Additional notes about the contact
  - maxLength 1000
- `tags` (`post/api/contacts.tags`; array<string>, optional) — Array of tags to associate with contact
  - example `["vip","enterprise"]`
- `priority` (`post/api/contacts.priority`; string, optional) — Contact priority level
  - one of `"low"`, `"medium"`, `"high"`, `"urgent"`; default `"medium"`
- `opt_in_through` (`post/api/contacts.opt_in_through`; string, optional) — How contact opted in for communications
  - default `"api"`
- `follow_up_date` (`post/api/contacts.follow_up_date`; string, optional) — Follow-up date (YYYY-MM-DD)
  - format `date`

## Example requests

### Basic contact creation

```json
{
  "workspace_id": "15213",
  "firstname": "John",
  "lastname": "Doe",
  "phone_number": "+1234567890",
  "email": "john.doe@example.com",
  "lead_status": "new",
  "lead_source": "website"
}
```

### Detailed contact with all fields

```json
{
  "workspace_id": "123e4567-e89b-12d3-a456-426614174000",
  "firstname": "Jane",
  "lastname": "Smith",
  "phone_number": "+1987654321",
  "email": "jane.smith@example.com",
  "lead_status": "qualified",
  "lead_source": "referral",
  "product": "enterprise_plan",
  "address": "456 Oak Avenue",
  "city": "San Francisco",
  "state": "CA",
  "zip": "94102",
  "notes": "Interested in enterprise features",
  "tags": [
    "enterprise",
    "high-value"
  ],
  "priority": "high",
  "follow_up_date": "2024-02-15"
}
```

## Code samples

### cURL

```bash
curl --request POST \
  --url https://api.channelautomation.com/api/contacts \
  --header 'Content-Type: application/json' \
  --header 'X-API-Key: <X-API-Key>' \
  --data '
{
  "workspace_id": "15213",
  "firstname": "John",
  "lastname": "Doe",
  "phone_number": "+1234567890",
  "email": "john.doe@example.com",
  "lead_status": "new",
  "lead_source": "website"
}
'
```

### TypeScript

```typescript
const url = 'https://api.channelautomation.com/api/contacts';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json', 'X-API-Key': '<X-API-Key>'},
  body: JSON.stringify({
    workspace_id: '15213',
    firstname: 'John',
    lastname: 'Doe',
    phone_number: '+1234567890',
    email: 'john.doe@example.com',
    lead_status: 'new',
    lead_source: 'website'
  })
};

fetch(url, options)
  .then(res => res.json())
  .then(json => console.log(json))
  .catch(err => console.error(err));
```

### Python

```python
import requests

url = "https://api.channelautomation.com/api/contacts"

payload = {
    "workspace_id": "15213",
    "firstname": "John",
    "lastname": "Doe",
    "phone_number": "+1234567890",
    "email": "john.doe@example.com",
    "lead_status": "new",
    "lead_source": "website"
}
headers = {
    "Content-Type": "application/json",
    "X-API-Key": "<X-API-Key>"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
```

## Responses

### 201

Contact created successfully

#### Example

```json
{
  "success": true,
  "contact": {
    "id": "string",
    "workspace_id": "string",
    "firstname": "John",
    "lastname": "Doe",
    "name": "John Doe",
    "phone_number": "+1234567890",
    "email": "john.doe@example.com",
    "lead_status": "qualified",
    "lead_source": "website",
    "product": "premium_plan",
    "address": "123 Main St",
    "city": "New York",
    "state": "NY",
    "zip": "10001",
    "notes": "string",
    "tags": [
      "vip",
      "enterprise"
    ],
    "priority": "high",
    "opt_in_through": "api",
    "conversation_status": "active",
    "last_message_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "updated_at": "2019-08-24T14:15:22Z",
    "follow_up_date": "2019-08-24",
    "webhook_name": "string",
    "firstName": "string",
    "lastName": "string",
    "phone": "string",
    "workspaceId": "string",
    "status": "string"
  },
  "message": "Contact created successfully",
  "duplicate_check": {
    "checked": true,
    "found_duplicates": true,
    "duplicate_contacts": [
      {
        "id": "string",
        "workspace_id": "string",
        "firstname": "John",
        "lastname": "Doe",
        "name": "John Doe",
        "phone_number": "+1234567890",
        "email": "john.doe@example.com",
        "lead_status": "qualified",
        "lead_source": "website",
        "product": "premium_plan",
        "address": "123 Main St",
        "city": "New York",
        "state": "NY",
        "zip": "10001",
        "notes": "string",
        "tags": [
          "vip",
          "enterprise"
        ],
        "priority": "high",
        "opt_in_through": "api",
        "conversation_status": "active",
        "last_message_at": "2019-08-24T14:15:22Z",
        "created_at": "2019-08-24T14:15:22Z",
        "updated_at": "2019-08-24T14:15:22Z",
        "follow_up_date": "2019-08-24",
        "webhook_name": "string",
        "firstName": "string",
        "lastName": "string",
        "phone": "string",
        "workspaceId": "string",
        "status": "string"
      }
    ]
  }
}
```

- `success` (`post/api/contacts.response.201.success`; boolean, optional)
  - example `true`
- `contact` (`post/api/contacts.response.201.contact`; object, optional)
  - `firstName` (`post/api/contacts.response.201.contact.firstName`; string, required) — The contact's first name
  - `phone` (`post/api/contacts.response.201.contact.phone`; string, required) — The contact's phone number
  - `workspaceId` (`post/api/contacts.response.201.contact.workspaceId`; string, required) — The workspace ID this contact belongs to
  - `id` (`post/api/contacts.response.201.contact.id`; string, optional) — The auto-generated ID of the contact
  - `workspace_id` (`post/api/contacts.response.201.contact.workspace_id`; string, optional) — Workspace ID
  - `firstname` (`post/api/contacts.response.201.contact.firstname`; string, optional) — Contact's first name
    - example `"John"`
  - `lastname` (`post/api/contacts.response.201.contact.lastname`; string, optional) — Contact's last name
    - example `"Doe"`
  - `name` (`post/api/contacts.response.201.contact.name`; string, optional) — Full name (auto-generated from firstname + lastname)
    - example `"John Doe"`
  - `phone_number` (`post/api/contacts.response.201.contact.phone_number`; string, optional) — Contact's phone number in E.164 format
    - example `"+1234567890"`
  - `email` (`post/api/contacts.response.201.contact.email`; string, optional) — The contact's email
    - format `email`; example `"john.doe@example.com"`
  - `lead_status` (`post/api/contacts.response.201.contact.lead_status`; string, optional) — Current lead status
    - example `"qualified"`
  - `lead_source` (`post/api/contacts.response.201.contact.lead_source`; string, optional) — Source of the lead
    - example `"website"`
  - `product` (`post/api/contacts.response.201.contact.product`; string, optional) — Product of interest
    - example `"premium_plan"`
  - `address` (`post/api/contacts.response.201.contact.address`; string, optional) — Street address
    - example `"123 Main St"`
  - `city` (`post/api/contacts.response.201.contact.city`; string, optional) — City
    - example `"New York"`
  - `state` (`post/api/contacts.response.201.contact.state`; string, optional) — State or province
    - example `"NY"`
  - `zip` (`post/api/contacts.response.201.contact.zip`; string, optional) — ZIP or postal code
    - example `"10001"`
  - `notes` (`post/api/contacts.response.201.contact.notes`; string, optional) — Additional notes about the contact
  - `tags` (`post/api/contacts.response.201.contact.tags`; array<string>, optional) — Array of tags associated with contact
    - example `["vip","enterprise"]`
  - `priority` (`post/api/contacts.response.201.contact.priority`; string, optional) — Contact priority level
    - one of `"low"`, `"medium"`, `"high"`, `"urgent"`; example `"high"`
  - `opt_in_through` (`post/api/contacts.response.201.contact.opt_in_through`; string, optional) — How contact opted in for communications
    - example `"api"`
  - `conversation_status` (`post/api/contacts.response.201.contact.conversation_status`; string, optional) — Current conversation status
    - example `"active"`
  - `last_message_at` (`post/api/contacts.response.201.contact.last_message_at`; string, optional) — Timestamp of last message
    - format `date-time`
  - `created_at` (`post/api/contacts.response.201.contact.created_at`; string, optional) — The date the contact was created
    - format `date-time`
  - `updated_at` (`post/api/contacts.response.201.contact.updated_at`; string, optional) — The date the contact was last updated
    - format `date-time`
  - `follow_up_date` (`post/api/contacts.response.201.contact.follow_up_date`; string, optional) — Follow-up date
    - format `date`
  - `webhook_name` (`post/api/contacts.response.201.contact.webhook_name`; string, optional) — Name of webhook that created this contact
  - `lastName` (`post/api/contacts.response.201.contact.lastName`; string, optional) — The contact's last name
  - `status` (`post/api/contacts.response.201.contact.status`; string, optional) — The contact's status
- `message` (`post/api/contacts.response.201.message`; string, optional)
  - example `"Contact created successfully"`
- `duplicate_check` (`post/api/contacts.response.201.duplicate_check`; object, optional)
  - `checked` (`post/api/contacts.response.201.duplicate_check.checked`; boolean, optional) — Whether duplicate checking was performed
  - `found_duplicates` (`post/api/contacts.response.201.duplicate_check.found_duplicates`; boolean, optional) — Whether duplicates were found
  - `duplicate_contacts` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts`; array<object>, optional) — Array of potential duplicate contacts
    - `firstName` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.firstName`; string, required) — The contact's first name
    - `phone` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.phone`; string, required) — The contact's phone number
    - `workspaceId` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.workspaceId`; string, required) — The workspace ID this contact belongs to
    - `id` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.id`; string, optional) — The auto-generated ID of the contact
    - `workspace_id` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.workspace_id`; string, optional) — Workspace ID
    - `firstname` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.firstname`; string, optional) — Contact's first name
      - example `"John"`
    - `lastname` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.lastname`; string, optional) — Contact's last name
      - example `"Doe"`
    - `name` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.name`; string, optional) — Full name (auto-generated from firstname + lastname)
      - example `"John Doe"`
    - `phone_number` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.phone_number`; string, optional) — Contact's phone number in E.164 format
      - example `"+1234567890"`
    - `email` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.email`; string, optional) — The contact's email
      - format `email`; example `"john.doe@example.com"`
    - `lead_status` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.lead_status`; string, optional) — Current lead status
      - example `"qualified"`
    - `lead_source` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.lead_source`; string, optional) — Source of the lead
      - example `"website"`
    - `product` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.product`; string, optional) — Product of interest
      - example `"premium_plan"`
    - `address` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.address`; string, optional) — Street address
      - example `"123 Main St"`
    - `city` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.city`; string, optional) — City
      - example `"New York"`
    - `state` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.state`; string, optional) — State or province
      - example `"NY"`
    - `zip` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.zip`; string, optional) — ZIP or postal code
      - example `"10001"`
    - `notes` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.notes`; string, optional) — Additional notes about the contact
    - `tags` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.tags`; array<string>, optional) — Array of tags associated with contact
      - example `["vip","enterprise"]`
    - `priority` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.priority`; string, optional) — Contact priority level
      - one of `"low"`, `"medium"`, `"high"`, `"urgent"`; example `"high"`
    - `opt_in_through` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.opt_in_through`; string, optional) — How contact opted in for communications
      - example `"api"`
    - `conversation_status` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.conversation_status`; string, optional) — Current conversation status
      - example `"active"`
    - `last_message_at` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.last_message_at`; string, optional) — Timestamp of last message
      - format `date-time`
    - `created_at` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.created_at`; string, optional) — The date the contact was created
      - format `date-time`
    - `updated_at` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.updated_at`; string, optional) — The date the contact was last updated
      - format `date-time`
    - `follow_up_date` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.follow_up_date`; string, optional) — Follow-up date
      - format `date`
    - `webhook_name` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.webhook_name`; string, optional) — Name of webhook that created this contact
    - `lastName` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.lastName`; string, optional) — The contact's last name
    - `status` (`post/api/contacts.response.201.duplicate_check.duplicate_contacts.status`; string, optional) — The contact's status

### 400

Validation error or duplicate contact

#### Example

```json
{
  "success": false,
  "error": "Contact with this phone number already exists",
  "existing_contact": {
    "id": "string",
    "workspace_id": "string",
    "firstname": "John",
    "lastname": "Doe",
    "name": "John Doe",
    "phone_number": "+1234567890",
    "email": "john.doe@example.com",
    "lead_status": "qualified",
    "lead_source": "website",
    "product": "premium_plan",
    "address": "123 Main St",
    "city": "New York",
    "state": "NY",
    "zip": "10001",
    "notes": "string",
    "tags": [
      "vip",
      "enterprise"
    ],
    "priority": "high",
    "opt_in_through": "api",
    "conversation_status": "active",
    "last_message_at": "2019-08-24T14:15:22Z",
    "created_at": "2019-08-24T14:15:22Z",
    "updated_at": "2019-08-24T14:15:22Z",
    "follow_up_date": "2019-08-24",
    "webhook_name": "string",
    "firstName": "string",
    "lastName": "string",
    "phone": "string",
    "workspaceId": "string",
    "status": "string"
  },
  "validation_errors": [
    "string"
  ]
}
```

- `success` (`post/api/contacts.response.400.success`; boolean, optional)
  - example `false`
- `error` (`post/api/contacts.response.400.error`; string, optional)
  - example `"Contact with this phone number already exists"`
- `existing_contact` (`post/api/contacts.response.400.existing_contact`; object, optional)
  - `firstName` (`post/api/contacts.response.400.existing_contact.firstName`; string, required) — The contact's first name
  - `phone` (`post/api/contacts.response.400.existing_contact.phone`; string, required) — The contact's phone number
  - `workspaceId` (`post/api/contacts.response.400.existing_contact.workspaceId`; string, required) — The workspace ID this contact belongs to
  - `id` (`post/api/contacts.response.400.existing_contact.id`; string, optional) — The auto-generated ID of the contact
  - `workspace_id` (`post/api/contacts.response.400.existing_contact.workspace_id`; string, optional) — Workspace ID
  - `firstname` (`post/api/contacts.response.400.existing_contact.firstname`; string, optional) — Contact's first name
    - example `"John"`
  - `lastname` (`post/api/contacts.response.400.existing_contact.lastname`; string, optional) — Contact's last name
    - example `"Doe"`
  - `name` (`post/api/contacts.response.400.existing_contact.name`; string, optional) — Full name (auto-generated from firstname + lastname)
    - example `"John Doe"`
  - `phone_number` (`post/api/contacts.response.400.existing_contact.phone_number`; string, optional) — Contact's phone number in E.164 format
    - example `"+1234567890"`
  - `email` (`post/api/contacts.response.400.existing_contact.email`; string, optional) — The contact's email
    - format `email`; example `"john.doe@example.com"`
  - `lead_status` (`post/api/contacts.response.400.existing_contact.lead_status`; string, optional) — Current lead status
    - example `"qualified"`
  - `lead_source` (`post/api/contacts.response.400.existing_contact.lead_source`; string, optional) — Source of the lead
    - example `"website"`
  - `product` (`post/api/contacts.response.400.existing_contact.product`; string, optional) — Product of interest
    - example `"premium_plan"`
  - `address` (`post/api/contacts.response.400.existing_contact.address`; string, optional) — Street address
    - example `"123 Main St"`
  - `city` (`post/api/contacts.response.400.existing_contact.city`; string, optional) — City
    - example `"New York"`
  - `state` (`post/api/contacts.response.400.existing_contact.state`; string, optional) — State or province
    - example `"NY"`
  - `zip` (`post/api/contacts.response.400.existing_contact.zip`; string, optional) — ZIP or postal code
    - example `"10001"`
  - `notes` (`post/api/contacts.response.400.existing_contact.notes`; string, optional) — Additional notes about the contact
  - `tags` (`post/api/contacts.response.400.existing_contact.tags`; array<string>, optional) — Array of tags associated with contact
    - example `["vip","enterprise"]`
  - `priority` (`post/api/contacts.response.400.existing_contact.priority`; string, optional) — Contact priority level
    - one of `"low"`, `"medium"`, `"high"`, `"urgent"`; example `"high"`
  - `opt_in_through` (`post/api/contacts.response.400.existing_contact.opt_in_through`; string, optional) — How contact opted in for communications
    - example `"api"`
  - `conversation_status` (`post/api/contacts.response.400.existing_contact.conversation_status`; string, optional) — Current conversation status
    - example `"active"`
  - `last_message_at` (`post/api/contacts.response.400.existing_contact.last_message_at`; string, optional) — Timestamp of last message
    - format `date-time`
  - `created_at` (`post/api/contacts.response.400.existing_contact.created_at`; string, optional) — The date the contact was created
    - format `date-time`
  - `updated_at` (`post/api/contacts.response.400.existing_contact.updated_at`; string, optional) — The date the contact was last updated
    - format `date-time`
  - `follow_up_date` (`post/api/contacts.response.400.existing_contact.follow_up_date`; string, optional) — Follow-up date
    - format `date`
  - `webhook_name` (`post/api/contacts.response.400.existing_contact.webhook_name`; string, optional) — Name of webhook that created this contact
  - `lastName` (`post/api/contacts.response.400.existing_contact.lastName`; string, optional) — The contact's last name
  - `status` (`post/api/contacts.response.400.existing_contact.status`; string, optional) — The contact's status
- `validation_errors` (`post/api/contacts.response.400.validation_errors`; array<string>, optional)

### 401

Authentication required

#### Example

```json
{
  "error": "Authentication required",
  "success": false
}
```

- `error` (`post/api/contacts.response.401.error`; string, optional)
  - example `"Authentication required"`
- `success` (`post/api/contacts.response.401.success`; boolean, optional)
  - example `false`

### 500

Internal server error

#### Example

```json
{
  "error": "Internal server error",
  "details": "string",
  "success": false
}
```

- `error` (`post/api/contacts.response.500.error`; string, optional)
  - example `"Internal server error"`
- `details` (`post/api/contacts.response.500.details`; string, optional)
- `success` (`post/api/contacts.response.500.success`; boolean, optional)
  - example `false`


Source: https://developer.channelautomations.com/api/post-api-contacts/index.md
