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 and reuse them. You create and manage them in the Email app and from the bird CLI.
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; the contact record just keeps who they are, ready to reuse. To reach many at once, send a batch; to build reusable groups, see audiences.
The Contacts page
The Contacts page (Email → Contacts) lists everyone in your workspace, with their email, name, and external ID. 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.

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 |
|---|---|
| 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. See below. |
Each contact also carries a Bird ID with a con_ prefix and its created and updated timestamps.
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.

Manage them on the Contact properties page, reached from 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. There is no dedicated date 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 first_name reads as "there" 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.
One thing the dashboard does not do is let you type a custom value directly on a contact. Property values arrive through import or the CLI, keyed by the property names you defined here. The contact page shows them; it does not edit them field by field.
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 instead. bird contacts create <email> adds one; bird contacts batch upserts a whole file of them 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. A batch can also carry custom property values and drop the contacts straight into audiences as it creates them.
Codevoorbeeld
bird contacts create alex@example.com --first-name Alex --last-name Rivera --external-id user_8412Set 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 even after you delete the contact, so deleting someone never quietly makes them mailable again.
Next steps
- Audiences — group contacts into reusable lists
- Suppressions — the workspace list of addresses Bird will not deliver to, kept separate from your contacts
- Bulk sending — reaching many recipients today with batches
- CLI — scripting contacts, properties, and audiences with the bird command