Contacts
SDK reference for creating, reading, updating, and deleting contacts in Kraiter.
The kraiter.contacts namespace provides methods for managing your contact records — the people you send email to. Each contact has a unique ID (contactId), an email address, and an optional set of custom properties.
create
Creates a new contact.
const contact = await kraiter.contacts.create({
email: 'alice@example.com',
properties: {
firstName: 'Alice',
plan: 'pro',
},
});Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The contact's email address. Must be unique within your tenant. |
userId | string | No | Your own identifier for the contact, if you have one. |
properties | Record<string, string | number | boolean | null> | No | Arbitrary key-value pairs to store against the contact. |
Returns
Promise<Contact> — the newly created contact object.
Errors
| Code | When |
|---|---|
CONFLICT | A contact with this email address already exists. |
VALIDATION_ERROR | The email address is invalid. |
get
Retrieves a contact by ID. Returns null if no contact is found rather than throwing.
const contact = await kraiter.contacts.get('con_abc123');
if (contact) {
console.log(contact.email);
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | The contact ID. |
Returns
Promise<Contact | null> — the contact object, or null if not found.
getByEmail
Looks up a contact by email address. Returns null if no contact is found rather than throwing an error.
const contact = await kraiter.contacts.getByEmail('alice@example.com');
if (contact) {
console.log(contact.contactId);
} else {
console.log('Contact not found');
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The email address to look up. |
Returns
Promise<Contact | null> — the contact object, or null if not found.
upsert
Creates a contact if none exists with the given email, or merges the supplied properties into the existing contact. This is idempotent, so it is the safest choice when importing or syncing contacts you may have seen before.
const result = await kraiter.contacts.upsert({
email: 'alice@example.com',
properties: { plan: 'pro' },
});
console.log(result.created); // true if newly created, false if updatedParameters
| Parameter | Type | Required | Description |
|---|---|---|---|
email | string | Yes | The contact's email address. |
userId | string | No | Your own identifier for the contact, if you have one. |
properties | Record<string, string | number | boolean | null> | No | Properties to set or merge. |
Returns
Promise<UpsertContactResponse> — the contact object plus a created boolean (true when a new contact was created, false when an existing one was updated).
list
Lists contacts with cursor-based pagination.
const page = await kraiter.contacts.list({ limit: 50 });
for (const contact of page.items) {
console.log(contact.email);
}
// Fetch the next page
if (page.nextCursor) {
const next = await kraiter.contacts.list({ cursor: page.nextCursor });
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | number | No | Maximum number of contacts to return per page. |
cursor | string | No | Pagination cursor from a previous response's nextCursor. |
Returns
Promise<{ items: Contact[]; nextCursor?: string }> — a page of contacts. nextCursor is present only when more results exist.
update
Updates an existing contact. Only the fields you include are changed; omitted fields are left untouched. The email address is immutable — create a new contact if the address changes.
const updated = await kraiter.contacts.update('con_abc123', {
properties: {
plan: 'enterprise',
},
});Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | The contact ID to update. |
userId | string | No | Updated external identifier. |
properties | Record<string, string | number | boolean | null> | No | Properties to set or overwrite. |
subscribed | boolean | No | Whether the contact is subscribed to marketing email. |
Returns
Promise<Contact> — the updated contact object.
Errors
| Code | When |
|---|---|
NOT_FOUND | No contact exists with this ID. |
delete
Permanently deletes a contact.
await kraiter.contacts.delete('con_abc123');Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | The contact ID to delete. |
Returns
Promise<void>
Errors
| Code | When |
|---|---|
NOT_FOUND | No contact exists with this ID. |
stats
Returns tenant-wide contact statistics.
const stats = await kraiter.contacts.stats();
console.log(stats.total); // total contacts
console.log(stats.suppressedCount); // bounced or complained
console.log(stats.addedLast24h);
console.log(stats.addedLast7d);Returns
Promise<ContactStats> — an object with the following fields:
| Field | Type | Description |
|---|---|---|
total | number | Total number of contacts. |
suppressedCount | number | Number of suppressed contacts (bounced or complained). |
addedLast24h | number | Contacts added in the last 24 hours. |
addedLast7d | number | Contacts added in the last 7 days. |
listSends
Retrieves the send history for a contact, one page at a time.
const page = await kraiter.contacts.listSends('con_abc123');
for (const send of page.items) {
console.log(send.templateId, send.sentAt, send.deliveryStatus);
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | The contact ID. |
limit | number | No | Maximum items per page. |
cursor | string | No | Pagination cursor. |
Returns
Promise<{ items: ContactSend[]; nextCursor?: string }> — a page of send records.
listScheduledSends
Retrieves scheduled sends for a contact, one page at a time.
const page = await kraiter.contacts.listScheduledSends('con_abc123');
for (const scheduled of page.items) {
console.log(scheduled.templateId, scheduled.scheduledFor);
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | The contact ID. |
limit | number | No | Maximum items per page. |
cursor | string | No | Pagination cursor. |
Returns
Promise<{ items: ContactScheduledSend[]; nextCursor?: string }> — a page of scheduled send records.
listSequences
Returns the sequences a contact is enrolled in, one page at a time.
const page = await kraiter.contacts.listSequences('con_abc123');
for (const entry of page.items) {
console.log(entry.sequenceId, entry.status, entry.currentStepId);
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | The contact ID. |
limit | number | No | Maximum items per page. |
cursor | string | No | Pagination cursor. |
Returns
Promise<{ items: ContactSequenceEntry[]; nextCursor?: string }> — a page of sequence enrolment records.
listSegments
Returns the segments a contact belongs to, one page at a time.
const page = await kraiter.contacts.listSegments('con_abc123');
for (const entry of page.items) {
console.log(entry.segmentId, entry.name, entry.isMember);
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | The contact ID. |
limit | number | No | Maximum items per page. |
cursor | string | No | Pagination cursor. |
Returns
Promise<{ items: ContactSegmentEntry[]; nextCursor?: string }> — a page of segment membership records.
getTimeline
Returns a chronological feed of events and interactions for a contact. The timeline is time-window based rather than cursor based: narrow it with from/to and cap it with limit.
const timeline = await kraiter.contacts.getTimeline('con_abc123', {
from: '2025-06-01T00:00:00Z',
limit: 100,
});
for (const entry of timeline.items) {
console.log(entry.type, entry.timestamp, entry.data);
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
contactId | string | Yes | The contact ID. |
limit | number | No | Maximum entries to return. |
from | string | No | Only include entries at or after this ISO 8601 timestamp. |
to | string | No | Only include entries at or before this ISO 8601 timestamp. |
Returns
Promise<{ items: TimelineEvent[]; hasMore: boolean }> — the matching timeline entries. hasMore is true when more entries exist beyond limit within the requested window.