> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.hive.co/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.hive.co/_mcp/server.

# Contacts

## Create or update contacts

`POST /contacts/` pushes contact data to Hive. Contacts are matched by `email` or `phone_number`, so the same endpoint handles both creates and updates. Every contact pushed through the API is added to the brand's **Hive API** segment, so API-sourced contacts can be filtered and targeted in the dashboard.

**Required scope:** `contacts:write`

```json
{
    "contacts": [
        {
            "email": "jamie@example.com",
            "first_name": "Jamie",
            "last_name": "Smith",
            "phone_number": "+15195551234",
            "gender": "female",
            "birthday": "1990-05-15",
            "address": {
                "address": "123 Main Street",
                "city": "Toronto",
                "state": "Ontario",
                "country": "Canada",
                "zip": "M5V 1A1"
            },
            "is_email_opt_in": true,
            "is_sms_opt_in": false,
            "updated_at": "2026-02-10T14:30:00Z",
            "custom_properties": {
                "favorite_color": "blue",
                "membership_tier": "gold",
                "source": "partner_signup"
            }
        }
    ]
}
```

### Fields

`contacts` takes an array of 1–50 contacts. Each contact needs at least one of `email` or `phone_number`.

| Field                     | Required                         | Description                                                                                                                          |
| ------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `email`                   | One of `email` or `phone_number` | Contact email address. At most 75 characters, Latin characters only, and no symbols such as `#`, `&`, `{` or `}`.                    |
| `phone_number`            | One of `email` or `phone_number` | Phone number in E.164 format                                                                                                         |
| `updated_at`              | Yes                              | ISO 8601 timestamp of the last update in your system                                                                                 |
| `first_name`, `last_name` | No                               | 1–120 characters                                                                                                                     |
| `gender`                  | No                               | One of `male`, `female`, `non_binary`, `unknown`                                                                                     |
| `birthday`                | No                               | `YYYY-MM-DD` or an ISO 8601 datetime. Any offset is dropped, not converted.                                                          |
| `address`                 | No                               | Object with `address` (1–255 characters), `city`, `state`, `country` (1–120 characters each), `zip` (1–20 characters). All optional. |
| `is_email_opt_in`         | No                               | Boolean. Omit if unknown; explicit `null` is rejected.                                                                               |
| `is_sms_opt_in`           | No                               | Boolean. Omit if unknown; explicit `null` is rejected.                                                                               |
| `custom_properties`       | No                               | Key/value metadata (see below)                                                                                                       |

Text fields are trimmed and must be non-blank. Unknown fields are ignored.

Timestamps must be ISO 8601 strings; numeric Unix timestamps are rejected. A timestamp without a UTC offset is interpreted in the Hive site timezone (`America/Toronto`), so always include an offset (for example, `Z` or `-05:00`).

If any contact fails validation, the whole batch is rejected with `422 Unprocessable Entity` and nothing is saved. See [Errors & Status Codes](/docs/errors-status-codes).

> **Phone number format**
>
> Use E.164 format (for example, `+15195551234`), and make sure the country code and area code are
> valid.

> **Email and SMS consent time**
>
> The consent time for opt-in and opt-out decisions is set to the `updated_at` value you send.

### Custom properties

`custom_properties` is an optional JSON object of metadata for the contact, where keys are strings and values are strings or numbers. Numbers are stored as strings.

* Maximum 50 custom properties per contact.
* Keys can be up to 255 characters.
* Values can be up to 1,000 characters.
* Keys and values are trimmed and must be non-empty.
* Duplicate keys aren't allowed.

> **Info**
>
> Contacts can't be deleted through the API. This is intentional, to preserve historical ticketing
> and engagement data.

## Delete custom properties from contacts

`POST /contacts/custom-properties/delete/` removes specific custom property keys from one or more contacts.

**Required scope:** `contacts:write`

```json
{
    "contacts": [
        {
            "identifier": "jamie@example.com",
            "property_names": ["favorite_color", "membership_tier"]
        },
        {
            "identifier": "+15195551234",
            "property_names": ["source"]
        }
    ]
}
```

| Field                       | Required | Description                                                                                       |
| --------------------------- | -------- | ------------------------------------------------------------------------------------------------- |
| `contacts`                  | Yes      | Array of 1–50 contacts. Duplicate identifiers aren't allowed.                                     |
| `contacts[].identifier`     | Yes      | Email address (matched case-insensitively), or phone number in E.164 format (e.g. `+15195551234`) |
| `contacts[].property_names` | Yes      | Array of 1–50 property names to delete, each up to 255 characters                                 |

Both contact endpoints are asynchronous and return `202 Accepted`. See [How It Works](/docs/how-it-works). The delete endpoint first checks that every identifier matches an existing contact: if any don't, Hive rejects the request with `422 Unprocessable Entity` and nothing is deleted.