---
title: "Create or update a contact"
description: "Creates the contact if it does not exist, otherwise updates it. The\nmatch is made on `phoneNumber` first, then `email`.\n\n`customFields` are addressed by `customFieldId`; get the ids from\n**List custom fields**. `assignedUsers` takes the login phone numbers\nof your team members.\n"
---

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

Path: Zacx Public API › Contacts

`PUT /contact/upsert`

Creates the contact if it does not exist, otherwise updates it. The
match is made on `phoneNumber` first, then `email`.

`customFields` are addressed by `customFieldId`; get the ids from
**List custom fields**. `assignedUsers` takes the login phone numbers
of your team members.

## Authentication

- `bearerAuth`, http, header `Authorization`

## Request body

- `upsertContact.name` (string, optional)
  - example `"John Doe"`
- `upsertContact.email` (string, optional)
  - format `email`; example `"john@example.com"`
- `upsertContact.phoneNumber` (string, optional) — Phone number with country code. A leading `+` is accepted.
  - example `"+11234567890"`
- `upsertContact.customFields` (array<object>, optional)
  - `upsertContact.customFields.customFieldId` (string, required) — Id from **List custom fields**.
    - format `uuid`
  - `upsertContact.customFields.value` (string, required)
- `upsertContact.tags` (array<string>, optional) — Tag names. Must already exist in the workspace.
- `upsertContact.assignedUsers` (array<string>, optional) — Login phone numbers of team members to assign.

## Example request

```json
{
  "name": "John Doe",
  "email": "john@example.com",
  "phoneNumber": "+11234567890",
  "customFields": [
    {
      "customFieldId": "7149ce0d-616c-46ca-8e09-cd00129fe947",
      "value": "field value 1"
    },
    {
      "customFieldId": "f6a3b468-3678-4c4d-bdd9-724e9f4c9fa9",
      "value": "field value 2"
    }
  ],
  "tags": [
    "VIP",
    "Premium"
  ],
  "assignedUsers": [
    "919100110151",
    "919100110152"
  ]
}
```

## Code samples

### cURL

```curl
curl --request PUT \
  --url https://api.zacx.io/v1/contact/upsert \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "name": "John Doe",
  "email": "john@example.com",
  "phoneNumber": "+11234567890",
  "customFields": [
    {
      "customFieldId": "7149ce0d-616c-46ca-8e09-cd00129fe947",
      "value": "field value 1"
    },
    {
      "customFieldId": "f6a3b468-3678-4c4d-bdd9-724e9f4c9fa9",
      "value": "field value 2"
    }
  ],
  "tags": [
    "VIP",
    "Premium"
  ],
  "assignedUsers": [
    "919100110151",
    "919100110152"
  ]
}
'
```

### TypeScript

```typescript
const url = 'https://api.zacx.io/v1/contact/upsert';
const options = {
  method: 'PUT',
  headers: {'Content-Type': 'application/json', Authorization: 'Bearer <token>'},
  body: JSON.stringify({
    name: 'John Doe',
    email: 'john@example.com',
    phoneNumber: '+11234567890',
    customFields: [
      {customFieldId: '7149ce0d-616c-46ca-8e09-cd00129fe947', value: 'field value 1'},
      {customFieldId: 'f6a3b468-3678-4c4d-bdd9-724e9f4c9fa9', value: 'field value 2'}
    ],
    tags: ['VIP', 'Premium'],
    assignedUsers: ['919100110151', '919100110152']
  })
};

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

### Python

```python
import requests

url = "https://api.zacx.io/v1/contact/upsert"

payload = {
    "name": "John Doe",
    "email": "john@example.com",
    "phoneNumber": "+11234567890",
    "customFields": [
        {
            "customFieldId": "7149ce0d-616c-46ca-8e09-cd00129fe947",
            "value": "field value 1"
        },
        {
            "customFieldId": "f6a3b468-3678-4c4d-bdd9-724e9f4c9fa9",
            "value": "field value 2"
        }
    ],
    "tags": ["VIP", "Premium"],
    "assignedUsers": ["919100110151", "919100110152"]
}
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <token>"
}

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

print(response.text)
```

## Responses

### 200

The contact after the write.

#### Example

```json
{
  "status": "success",
  "data": {
    "name": "John Doe",
    "phoneNumber": "11234567890",
    "email": "john@example.com",
    "customFields": [
      {
        "name": "Test Field",
        "value": "field value 1"
      },
      {
        "name": "Custom Field 2",
        "value": "field value 2"
      }
    ],
    "tags": [
      "VIP",
      "Premium"
    ],
    "assignedUsers": [
      "User 1",
      "User 2"
    ]
  }
}
```

- `upsertContact.response.200.status` (string, required)
- `upsertContact.response.200.data` (object, required)
  - `upsertContact.response.200.data.name` (string, optional)
  - `upsertContact.response.200.data.phoneNumber` (string, optional)
  - `upsertContact.response.200.data.email` (string, optional)
    - format `email`
  - `upsertContact.response.200.data.customFields` (array<object>, optional)
    - `upsertContact.response.200.data.customFields.name` (string, optional)
      - example `"test field"`
    - `upsertContact.response.200.data.customFields.value` (string, optional)
      - example `"custom field value"`
  - `upsertContact.response.200.data.tags` (array<string>, optional)
  - `upsertContact.response.200.data.assignedUsers` (array<string>, optional) — Display names of the assigned users.

### 400

One or more parameters are missing or invalid.

#### Example

```json
{
  "status": "error",
  "code": "VALIDATION_FAILED",
  "message": "Parameters are not valid"
}
```

- `upsertContact.response.400.status` (string, required)
- `upsertContact.response.400.code` (string, required) — Stable machine-readable error code.
- `upsertContact.response.400.message` (string, required) — Human-readable explanation.


Source: https://zacx.io/api/contact/upsert/index.md
