Contacts
Manage your audience with custom properties, suppression, and filtering.
Contacts are the foundation of Kraiter. Every email you send, every sequence enrolment, and every event is tied to a contact. A contact is uniquely identified by their email address within your tenant.
Creating a contact
Create a contact by providing an email address and optional properties.
const contact = await kraiter.contacts.create({
email: 'alice@example.com',
properties: {
name: 'Alice',
plan: 'pro',
signupDate: '2025-06-15',
},
});curl -X POST https://api.kraiter.com/contacts \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"properties": {
"name": "Alice",
"plan": "pro",
"signupDate": "2025-06-15"
}
}'If a contact with the same email already exists, the request will return an error. Use the update endpoint to modify existing contacts.
Contact properties
Every contact has two categories of properties: system properties and custom properties.
System properties
System properties are managed automatically by Kraiter:
| Property | Type | Description |
|---|---|---|
email | string | The contact's email address (unique identifier) |
createdAt | date | When the contact was created |
updatedAt | date | When the contact was last modified |
unsubscribed | boolean | Whether the contact has opted out |
suppressed | boolean | Whether the contact is suppressed |
Custom properties
Custom properties are key-value pairs you define. Each property has a type:
- string — Text values (e.g. name, plan, city)
- number — Numeric values (e.g. age, orderCount)
- boolean — True/false values (e.g. isVip, hasCompletedOnboarding)
- date — ISO 8601 date strings (e.g. signupDate, lastPurchase)
Properties are set when creating or updating a contact. You can use them in templates with Liquid variables, in segment rules, and in sequence conditions.
await kraiter.contacts.update('alice@example.com', {
properties: {
orderCount: 5,
isVip: true,
lastPurchase: '2025-11-20',
},
});Derived properties
Derived properties are computed automatically from a contact's engagement data. These are read-only and cannot be set manually:
- lastEmailSentAt — When the last email was sent to this contact
- lastEmailOpenedAt — When the contact last opened an email
- lastEmailClickedAt — When the contact last clicked a link in an email
- emailsSentCount — Total number of emails sent to this contact
- emailsOpenedCount — Total number of email opens
- emailsClickedCount — Total number of link clicks
Derived properties are available in segment rules and sequence conditions, making it easy to target engaged or inactive contacts.
Retrieving contacts
Fetch a single contact by email address:
const contact = await kraiter.contacts.get('alice@example.com');curl https://api.kraiter.com/contacts/alice%40example.com \
-H "Authorization: Bearer YOUR_API_KEY"Listing and filtering contacts
List contacts with pagination:
const { items, nextCursor } = await kraiter.contacts.list({
limit: 50,
});
// Fetch the next page
const nextPage = await kraiter.contacts.list({
limit: 50,
cursor: nextCursor,
});Updating a contact
Update a contact's properties. Only the properties you include will be modified; existing properties are preserved.
await kraiter.contacts.update('alice@example.com', {
properties: {
plan: 'enterprise',
},
});To remove a property, set its value to null:
await kraiter.contacts.update('alice@example.com', {
properties: {
temporaryFlag: null,
},
});Deleting a contact
Delete a contact permanently. This removes all associated data including event history and sequence enrolments.
await kraiter.contacts.delete('alice@example.com');curl -X DELETE https://api.kraiter.com/contacts/alice%40example.com \
-H "Authorization: Bearer YOUR_API_KEY"Suppression vs unsubscribe
It is important to understand the difference between these two states:
Unsubscribed
A contact unsubscribes when they explicitly opt out of marketing emails — typically by clicking the unsubscribe link in an email. Unsubscribed contacts:
- Will not receive sequence emails or campaign emails
- Can still receive transactional emails (if
ignoreUnsubscribeis set) - Can be resubscribed via the API
Suppressed
A contact is suppressed when Kraiter detects a delivery problem — a hard bounce or a spam complaint. Suppressed contacts:
- Will not receive any emails (including transactional)
- Cannot be resubscribed without first removing the suppression
- Have a
suppressionReasonindicating why (bounceorcomplaint)
This distinction ensures you respect both user preferences and technical delivery constraints. Attempting to send to a suppressed address would harm your sender reputation, so Kraiter blocks all sends to suppressed contacts.
const contact = await kraiter.contacts.get('alice@example.com');
if (contact.suppressed) {
console.log(`Suppressed: ${contact.suppressionReason}`);
} else if (contact.unsubscribed) {
console.log('Contact has unsubscribed');
} else {
console.log('Contact is active');
}