Kraiter
Guides

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.

SDK
const contact = await kraiter.contacts.create({
  email: 'alice@example.com',
  properties: {
    name: 'Alice',
    plan: 'pro',
    signupDate: '2025-06-15',
  },
});
cURL
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:

PropertyTypeDescription
emailstringThe contact's email address (unique identifier)
createdAtdateWhen the contact was created
updatedAtdateWhen the contact was last modified
unsubscribedbooleanWhether the contact has opted out
suppressedbooleanWhether 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.

SDK
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:

SDK
const contact = await kraiter.contacts.get('alice@example.com');
cURL
curl https://api.kraiter.com/contacts/alice%40example.com \
  -H "Authorization: Bearer YOUR_API_KEY"

Listing and filtering contacts

List contacts with pagination:

SDK
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.

SDK
await kraiter.contacts.update('alice@example.com', {
  properties: {
    plan: 'enterprise',
  },
});

To remove a property, set its value to null:

SDK
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.

SDK
await kraiter.contacts.delete('alice@example.com');
cURL
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 ignoreUnsubscribe is 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 suppressionReason indicating why (bounce or complaint)

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.

Check contact status
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');
}