Contacts
A contact is one email address in a space, with a name and the attributes you choose. Contacts are unlimited on every plan.
Two spaces never share contacts. The same address in two spaces is two separate contacts, each with its own lists and history.
What a contact holds
| Field | Notes |
|---|---|
| Unique in the space. Stored in lowercase. | |
| First name, Last name | Optional, up to 120 characters each. |
| Attributes | Your own data: plan, company, signup_date… See below. |
| Lists | The lists the contact is subscribed to, with the status of each subscription. |
| Events | What the contact did in your product, sent by your app. Events API. |
| Emails | Every email sent to this contact and what happened to it. |
Kula also records the mailbox provider of each address (Google, Microsoft, Yahoo, AOL, Apple or other), read from the DNS of its domain. A company address hosted on Google Workspace counts as Google. The provider feeds the deliverability report and can be used in segments.
Attributes
- Up to 50 attributes per contact.
- Keys use lowercase letters, digits and underscores, up to 50 characters:
plan,signup_date,trial_ends_at. email,first_nameandlast_nameare reserved.- Text values are limited to 1,000 characters. Numbers, booleans and dates sent through the API keep their type, so segments can compare them (
greater_than,is_true,before…).
Use an attribute in an email with {{ contact.plan }}. All variables.
Status
The status decides whether a contact can receive marketing emails.
| Status | Meaning | How it gets there |
|---|---|---|
| Active | Can receive emails | Default |
| Unsubscribed | Left every list | Clicked "Unsubscribe from all" on the preferences page, or you unsubscribed them |
| Bounced | The address does not accept email | A permanent bounce, or three temporary bounces in a row |
| Complained | Reported one of your emails as spam | A complaint from the mailbox provider |
A bounced or complained contact stays in your space for history, but Kula refuses to subscribe it again, from a form, an import or the API. Bounces and suppressions.
Where contacts come from
The contact page shows how each contact was added:
| Source | Added by |
|---|---|
| Signup form | A visitor who filled one of your signup forms |
| API | Your app, through the contacts API |
| Import | A CSV import or the bulk import API |
| Dashboard | A member, with Add contact |
| AI assistant | An AI assistant acting for a member |
Contacts who have never opened, clicked or confirmed their subscription are marked Under review: they receive a capped share of each campaign until results are healthy. Contacts under review.
The Contacts page
Contacts lists everyone in the space, with counters for Active, Unreachable (unsubscribed, bounced or complained) and Under review. Filter by list, segment, status or source, or search by email and name.
Open a contact to see its details, attributes, lists, events and emails. From there you can:
- edit the name and attributes;
- subscribe it to a list, or Resubscribe it to a list it left (only do this if the person asked you to);
- Unsubscribe from everything;
- delete it for good.
To stop emailing someone, unsubscribe them instead: a deleted address could be added again by an import.
Delete a contact
Delete removes the contact with its subscriptions and events. Its sent emails stay in your reports without the address. If the address is suppressed, it stays suppressed: Kula won't email it again, even if it comes back in an import.
For a data deletion request, admins can tick Erase every trace: the address also leaves your suppression list, and Kula forgets it entirely.
To clean up your list, Delete unreachable on the Contacts page deletes every bounced and complained contact at once. Their addresses stay suppressed. Unsubscribed contacts are kept: they're what stops a later import from subscribing them again.