# Contacts

A contact is a stored recipient: an email address plus whatever you know about the person behind it. Contacts are where Bird keeps your recipient data so you can group people into [audiences](/docs/guides/email/audiences) and reuse them. You manage contacts in the dashboard's **Contacts** section, with the `bird` [CLI](/docs/cli), or through the [contacts API](/docs/api/reference/list-contacts).

## Reaching contacts

Storing a contact does not send anything on its own. To email one person, send a normal message to their address with the [send API](/docs/guides/email/sending-email); the contact record keeps who they are, ready to reuse. To reach many at once, send a [batch](/docs/guides/email/sending-bulk); to build reusable groups, see [audiences](/docs/guides/email/audiences).

## The Contacts page

The [**Contacts**](https://bird.com/dashboard/w/contacts) page (**Contacts → All contacts** in the sidebar) lists everyone in your workspace, with their email, name, external ID, and creation date. Search by email address to find one, click a row to open the contact, and use the header buttons to add a single contact or import many at once. Viewing contacts needs the `email_marketing` read permission; adding, editing, and deleting need write.

![The Contacts page in the Bird dashboard, listing stored contacts by email, name, and external ID, with search and Add contact controls](/images/docs/dashboard-email-contacts.png)

## What a contact holds

Every contact has a workspace-unique email address and, optionally, a name and your own identifier for it:

| Field         | What it is                                                                                                                                                                                             |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `email`       | The address, required and unique per workspace. Bird stores it trimmed and lowercased, so `Sam@Acme.com` and `sam@acme.com` are the same contact.                                                      |
| `first_name`  | Optional given name, used to personalize a send.                                                                                                                                                       |
| `last_name`   | Optional family name.                                                                                                                                                                                  |
| `external_id` | Optional. Your own primary key for the person (a user ID from your database), unique per workspace when set. It is how you match a Bird contact back to your own records without relying on the email. |
| `data`        | Custom property values, one per registered [contact property](#contact-properties).                                                                                                                    |

Each contact also carries a Bird ID with a `con_` prefix and its created and updated timestamps. The full field contract is in the [API reference](/docs/api/reference/get-contact).

## Contact properties

Contact properties are the typed schema for the custom fields on a contact. You register a property once per workspace, and from then on every contact can carry a value for it under `data`. Registering the schema up front is what lets you personalize and segment reliably: a value is always the type you declared, not an untyped blob that varies per contact.

![The Contact properties page in the Bird dashboard, listing registered properties with their key, type, and fallback value, including one archived property marked with an Archived badge](/images/docs/dashboard-email-contact-properties.png)

Manage them on the [**Contact properties**](https://bird.com/dashboard/w/contact-properties) page, reached from the sidebar or the **Properties** button on the Contacts page. Each property has a key, a type, and an optional fallback:

- **Key** is the name you reference the value by, for example `plan_tier`. It must be lowercase and start with a letter (`^[a-z][a-z0-9_]*$`), and it is fixed once created.
- **Type** is one of `string`, `number`, or `boolean`, and it is also fixed once created. Dates have no dedicated type; store a date as a `string` (an ISO 8601 date, say). A value written to a contact must match its property's declared type.
- **Fallback value** is the default used when a contact has no value for the property, so a missing `plan_tier` can read as `free` rather than a blank.

Properties are not deleted, they are archived. Archiving a property stops new writes to its key while keeping every value already stored, and the key stays reserved so it can never be reused for a different type. Unarchive it to bring it back. This is why the type is immutable: a stored `number` must never start being read as a `string`. A workspace can register up to 200 properties, and archived properties count toward that cap because their keys stay reserved.

You can set property values wherever you edit a contact: the dashboard's contact form shows one typed input per active property, and the CLI and API take the same keys under `data`.

## Importing and syncing contacts

The dashboard import is the fastest way to load a list. From **Import** on the Contacts page, paste up to 1000 rows, one contact per line as `email, first name, last name` with only the email required. Bird matches each row to an existing contact by email and updates it, or creates it if it is new, so re-importing the same file is an upsert rather than a pile of duplicates. The result tells you how many were added, updated, and skipped.

To sync from your own database, script the CLI or call the [batch endpoint](/docs/api/reference/create-contact-batch) directly. `bird contacts create <email>` adds one; `bird contacts batch` upserts up to 1,000 in a single call, which is how you keep Bird in step with your system: one batch per run rather than one request per person.

```bash
bird contacts create alex@example.com --first-name Alex --last-name Rivera --external-id user_8412
```

Batch entries are matched by email the same way as the dashboard import, can carry custom property values, and can drop every contact in the request straight into audiences via `audience_ids`. Each entry succeeds or fails on its own, and the response reports one result per entry in submission order:

```json
{
  "data": [
    {
      "contact_id": "con_01ky7q5t51echr7mqj5c08423b",
      "email": "alex@example.com",
      "status": "updated"
    },
    {
      "contact_id": "con_01ky7q6mxdfhe86c9dqyt866pz",
      "email": "jamie@example.com",
      "status": "created"
    },
    {
      "email": "casey@example.com",
      "error": {
        "message": "A contact with this external_id already exists in this workspace.",
        "type": "conflict_error"
      },
      "status": "failed"
    }
  ]
}
```

Two defaults worth knowing for syncs. A batch merges `data` keys onto what a contact already stores (set `data_mode: "replace"` to overwrite the whole map instead), so an import that touches one attribute never wipes the others. And set your own `external_id` on each contact, so a later sync can find the same person even if their email changes.

## Deleting a contact

Deleting a contact is a hard delete: the record and its audience memberships go, and it is not recoverable. It does not touch suppressions, though. An address that unsubscribed or hard-bounced stays on your [suppression list](/docs/guides/email/suppressions) even after you delete the contact, so deleting someone never quietly makes them mailable again.

## Next steps

- [Audiences](/docs/guides/email/audiences): group contacts into reusable lists
- [Suppressions](/docs/guides/email/suppressions): the workspace list of addresses Bird will not deliver to, kept separate from your contacts
- [Batch sending](/docs/guides/email/sending-bulk): reaching many recipients today, up to 100 messages per request
- [CLI](/docs/cli): scripting contacts, properties, and audiences with the `bird` command
- [API reference](/docs/api/reference/list-contacts): full request and response schemas