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

# Sync contacts in real time

> Push signups from your website, app, or CRM into Mailercloud lists as they happen.

Three endpoints cover almost every sync scenario:

| Scenario                                       | Endpoint                                                                    |
| ---------------------------------------------- | --------------------------------------------------------------------------- |
| New signup on your site                        | [`POST /contacts`](/api-reference/contacts/create-contact)                  |
| Might already exist (form resubmits, CRM sync) | [`POST /contacts/upsert`](/api-reference/contacts/create-or-update-contact) |
| Bulk import (migrations, nightly sync)         | [`POST /contacts/batch`](/api-reference/contacts/create-batch-contact)      |

## Real-time: one contact per event

Call this from your signup handler, checkout flow, or form webhook (e.g. a Wix or WordPress form):

```bash theme={null}
curl --request POST \
  --url https://cloudapi.mailercloud.com/v1/contacts \
  --header 'Authorization: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "email": "jane@example.com",
    "first_name": "Jane",
    "list_id": "YOUR_LIST_ID",
    "tags": ["signup-website"]
  }'
```

<Tip>
  Use `tags` to record where the contact came from — you can segment and trigger automations on tags later.
</Tip>

## Idempotent sync: upsert

If the same email may be submitted more than once, use **upsert** instead — it creates the contact if new, updates it if it exists, and won't fail on duplicates.

## Bulk: batch create

For imports, send up to a full batch in one call with `contacts` (array) and `list_id`. For very large one-time migrations, consider the CSV import wizard in the app instead — it includes field mapping and validation.

## Custom fields

Contacts accept a `custom_fields` object keyed by your account's custom-field IDs. List your fields via the app under **Audience → Custom fields**, or see [Custom Properties](/api-reference/custom-properties) to manage them via API.
