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

# Contacts, segments, and topics

> Manage the contact list behind your broadcasts. Store contact properties, group contacts into segments, let contacts opt out of topics, and understand how the recipients of a broadcast are chosen.

A broadcast is sent to contacts. This page covers the four things that describe your list: contacts, contact properties, segments, and topics. It ends with the rules Nuntly applies to turn them into the recipients of one broadcast.

<Note>
  These resources need an API key with the `contact` permission. See [Set up Broadcast](/docs/guides/broadcast-setup#api-key-permissions).
</Note>

## Contacts

A contact is an email address that belongs to your organization.

* Nuntly stores the address trimmed and in lowercase. An organization holds at most one contact per address, and creating a duplicate fails with a `409` response.
* You cannot change the address of a contact after you create it. To use a different address, create a new contact.
* You create a contact with an email address. You set its [contact properties](#contact-properties) by updating the contact afterwards. Properties defined with a default value are applied when the contact is created.

| Operation | Request |
| - | - |
| Create a contact | `POST /contacts` |
| List contacts | `GET /contacts` |
| Retrieve a contact, with its properties | `GET /contacts/{contactId}` |
| Update the properties of a contact | `PATCH /contacts/{contactId}` |
| Delete a contact | `DELETE /contacts/{contactId}` |

The contact list does not include properties. Retrieve a contact to read them.

### Deleting a contact

Deleting a contact removes it from every future broadcast, including one that is already sending and has not reached it yet. It also removes the contact's segment memberships and topic memberships. Two records stay in place:

* The send records of broadcasts already sent to the contact stay as recorded until your [data retention](/docs/guides/data-retention) window removes them.
* An [unsubscribe](/docs/guides/broadcast-unsubscribe) and a [suppression](/docs/guides/broadcast-unsubscribe#suppression-list) for the address stay. Creating the contact again does not restore delivery to that address.

## Contact properties

A contact property is a custom field on your contacts, such as a plan or a signup source. You first define the property for your organization, then set values on contacts.

| Field | Description |
| - | - |
| `name` | Letters (either case), digits, and underscores, up to 64 characters, with at least one letter or underscore. Nuntly trims the name but keeps its letter case: `Plan` and `plan` are different properties. `id`, `email`, `createdAt`, and `updatedAt` are reserved, in any letter case. |
| `type` | `string` or `number`. |
| `description` | Optional text. |
| `defaultValue` | Optional value, applied to newly created contacts that omit the property. It must match the type and stay under 128 bytes once serialized. |

Rules for definitions:

* `name` and `type` cannot change after you create the definition. You can update `description` and `defaultValue`.
* An organization can hold up to 50 definitions.
* A default value is applied when a contact is created. Changing it later does not change existing contacts.
* You cannot delete a definition while any contact holds a value under its name.

Rules for values on a contact:

* You set values with an update of the contact, keyed by property name. Setting a key to `null` removes the value.
* When a definition exists for the name, the value must match its type. A name without a definition is accepted with the same name format rules and no type check.
* A contact holds up to 100 properties and 16 KB of serialized properties.

| Operation | Request |
| - | - |
| Create a definition | `POST /contact-properties` |
| List definitions | `GET /contact-properties` |
| Retrieve a definition | `GET /contact-properties/{propertyDefinitionId}` |
| Update a definition | `PATCH /contact-properties/{propertyDefinitionId}` |
| Delete a definition | `DELETE /contact-properties/{propertyDefinitionId}` |

<Note>
  A property's exact name and letter case are what a template references directly for personalization. See [Personalization](/docs/guides/broadcast-templates#personalization).
</Note>

## Segments

A segment is a named list of contacts that you maintain yourself. A segment has no rules. A contact is in a segment when you add it, and it stays there until you remove it.

* A segment name holds letters, numbers, spaces, and the characters `' . , & -`, up to 64 characters. Nuntly trims and lowercases the name, and names are unique within your organization. There is no rename operation.
* An organization can hold up to 25 segments.
* Adding a contact that is already a member succeeds and changes nothing. Removing a contact that is not a member returns a `404` response.
* You cannot delete a segment while a broadcast that targets it is `draft`, `scheduled`, `queued`, `sending`, or `paused`. Deleting a segment removes its memberships. Broadcasts that are `sent` or `failed` keep their segment id as recorded.

| Operation | Request |
| - | - |
| Create a segment | `POST /segments` |
| List segments | `GET /segments` |
| Retrieve a segment | `GET /segments/{segmentId}` |
| Delete a segment | `DELETE /segments/{segmentId}` |
| Add a contact to a segment | `POST /contacts/{contactId}/segments/{segmentId}` |
| Remove a contact from a segment | `DELETE /contacts/{contactId}/segments/{segmentId}` |
| Check whether a contact is in a segment | `GET /contacts/{contactId}/segments/{segmentId}` |
| List the segments of a contact | `GET /contacts/{contactId}/segments` |
| List the contacts in a segment | `GET /segments/{segmentId}/members` |

## Topics

A topic is a kind of message that contacts can opt out of, for example a product newsletter. Every contact is subscribed to every topic by default. You only record an exception, an unsubscribe, for a contact that opted out.

* Topic names follow the same rules as segment names, and an organization can hold up to 25 topics.
* You set the state of a contact for one topic to `subscribed` or `unsubscribed`. Repeating the same state changes nothing. A `subscribed` record is removed when the topic is deleted.
* You cannot delete a topic while any contact has an `unsubscribed` record for it, or while a broadcast that targets it is `draft`, `scheduled`, `queued`, `sending`, or `paused`.

Reading the topics of a contact returns one entry per topic with the effective state and where it comes from:

| Source | Meaning |
| - | - |
| `explicit` | A record that you set for this contact and topic. |
| `default` | No record exists, so the contact is subscribed. |
| `platform_opt_out` | The contact used an [unsubscribe link](/docs/guides/broadcast-unsubscribe). The state is `unsubscribed` for every topic, whatever you set. |

| Operation | Request |
| - | - |
| Create a topic | `POST /topics` |
| List topics | `GET /topics` |
| Retrieve a topic | `GET /topics/{topicId}` |
| Delete a topic | `DELETE /topics/{topicId}` |
| Set the state of a contact for a topic | `PUT /contacts/{contactId}/topics/{topicId}` |
| List the effective topic states of a contact | `GET /contacts/{contactId}/topics` |
| List the explicit records of a topic | `GET /topics/{topicId}/memberships` |

## How the recipients of a broadcast are chosen

When you send a broadcast, Nuntly builds its recipient set in this order:

1. **Base set.** All contacts of your organization, or the members of the segment named on the broadcast.
2. **Topic.** When the broadcast names a topic, contacts with an `unsubscribed` record for that topic are removed. Contacts without a record stay, because they are subscribed by default.
3. **Opt-outs and suppression.** Addresses that used an unsubscribe link, and addresses on the suppression list, are always removed. See [Unsubscribe and suppression](/docs/guides/broadcast-unsubscribe).

Nuntly fixes the contacts that can be included when the broadcast is accepted. A contact created after that moment does not join a broadcast that is already running. For a scheduled broadcast, the contacts are fixed when the schedule fires, not when you schedule it.

Segment membership, topic states, and opt-outs are read while the broadcast is being processed, in pages of contacts. A change you make while the broadcast is running applies to the pages that have not been processed yet.

A removed recipient gets no message and no send record, so it does not appear in the [recipient list](/docs/guides/broadcast-sending#recipients) of the broadcast.

## Next steps

<CardGroup cols={2}>
  <Card title="Templates" icon="file-text" href="/docs/guides/broadcast-templates">
    Write and publish the content of your broadcast
  </Card>

  <Card title="Create and send a broadcast" icon="send" href="/docs/guides/broadcast-sending">
    Choose a segment and a topic, then send
  </Card>

  <Card title="Unsubscribe and suppression" icon="mail-x" href="/docs/guides/broadcast-unsubscribe">
    How opt-outs and the suppression list affect recipients
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.