Kraiter
API Reference

Contacts

Create, list, update, and delete contacts. Retrieve a contact's sends, scheduled sends, sequence enrolments, segment memberships, and timeline.

Contacts represent the people in your audience. Each contact has a unique email address and a set of custom properties you can use for personalisation and segmentation.

Create contact

POST /api/contacts

Creates a new contact. The email address must be unique within your organisation.

Request body

FieldTypeRequiredDescription
emailstringYesThe contact's email address.
userIdstringNoYour own external identifier for the contact.
propertiesobjectNoKey-value pairs of custom properties (e.g. firstName, plan).

Response

Returns the created contact with a generated contactId. The derived object holds system-computed engagement fields, and subscribed/suppressed track consent and deliverability state.

{
  "contactId": "cnt_01H8MZXK...",
  "email": "alice@example.com",
  "properties": { "firstName": "Alice", "plan": "pro" },
  "derived": {
    "totalSends": 0,
    "totalOpens": 0,
    "totalClicks": 0,
    "lastEventAt": null
  },
  "subscribed": true,
  "suppressed": false,
  "createdAt": "2025-09-15T10:30:00.000Z",
  "updatedAt": "2025-09-15T10:30:00.000Z"
}

To create-or-update in a single call, use PUT /api/contacts (upsert by email); it returns the contact with an extra created boolean.

Errors

CodeDescription
VALIDATION_ERRORMissing or invalid email address.
CONTACT_EXISTSA contact with this email already exists.

Examples

curl -X POST https://api.kraiter.com/api/contacts \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alice@example.com",
    "properties": { "firstName": "Alice", "plan": "pro" }
  }'
const contact = await kraiter.contacts.create({
  email: "alice@example.com",
  properties: { firstName: "Alice", plan: "pro" },
});

List contacts

GET /api/contacts

Returns a paginated list of contacts. Passing an email query parameter instead performs an exact lookup and returns that single contact object (not a list).

Query parameters

ParameterTypeDefaultDescription
cursorstringPagination cursor from a previous response.
limitnumber20Number of contacts to return (max 100).
emailstringExact email lookup. When provided, returns the single matching contact (or CONTACT_NOT_FOUND) rather than a paginated list.

Response

{
  "items": [
    {
      "contactId": "cnt_01H8MZXK...",
      "email": "alice@example.com",
      "properties": { "firstName": "Alice" },
      "subscribed": true,
      "suppressed": false,
      "createdAt": "2025-09-15T10:30:00.000Z",
      "updatedAt": "2025-09-15T10:30:00.000Z"
    }
  ],
  "nextCursor": "eyJpZCI6ImNudF8wMUgi..."
}

Examples

curl "https://api.kraiter.com/api/contacts?limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Exact email lookup — returns a single contact object
curl "https://api.kraiter.com/api/contacts?email=alice@example.com" \
  -H "Authorization: Bearer YOUR_API_KEY"
const page = await kraiter.contacts.list({ limit: 10 });

Contact statistics

GET /api/contacts/stats

Returns tenant-wide contact counts. Useful for dashboards and headline figures.

Response

{
  "total": 1240,
  "suppressedCount": 18,
  "addedLast24h": 12,
  "addedLast7d": 86
}
FieldTypeDescription
totalnumberTotal contacts for the organisation.
suppressedCountnumberContacts currently suppressed (bounce or complaint).
addedLast24hnumberContacts created in the last 24 hours.
addedLast7dnumberContacts created in the last 7 days.

Examples

curl https://api.kraiter.com/api/contacts/stats \
  -H "Authorization: Bearer YOUR_API_KEY"

Get contact

GET /api/contacts/:id

Returns a single contact by ID.

Path parameters

ParameterTypeDescription
idstringThe contact ID.

Response

Returns the full contact object.

Errors

CodeDescription
CONTACT_NOT_FOUNDNo contact with this ID exists.

Examples

curl https://api.kraiter.com/api/contacts/cnt_01H8MZXK... \
  -H "Authorization: Bearer YOUR_API_KEY"
const contact = await kraiter.contacts.get("cnt_01H8MZXK...");

Update contact

PATCH /api/contacts/:id

Updates a contact's userId, properties, or subscription state. Only the fields you include are changed — omitted fields remain unchanged. At least one field must be provided. A contact's email address cannot be changed via this endpoint.

Path parameters

ParameterTypeDescription
idstringThe contact ID.

Request body

FieldTypeRequiredDescription
userIdstringNoNew external identifier for the contact.
propertiesobjectNoProperties to merge with existing properties.
subscribedbooleanNoSet the contact's marketing subscription state.

Response

Returns the updated contact.

Errors

CodeDescription
CONTACT_NOT_FOUNDNo contact with this ID exists.
VALIDATION_ERRORNo fields were provided to update.

Examples

curl -X PATCH https://api.kraiter.com/api/contacts/cnt_01H8MZXK... \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "properties": { "plan": "enterprise" } }'
const contact = await kraiter.contacts.update("cnt_01H8MZXK...", {
  properties: { plan: "enterprise" },
});

Delete contact

DELETE /api/contacts/:id

Permanently deletes a contact. This also removes any sequence enrolments and scheduled sends for the contact.

Path parameters

ParameterTypeDescription
idstringThe contact ID.

Response

Returns 204 No Content on success.

Errors

CodeDescription
CONTACT_NOT_FOUNDNo contact with this ID exists.

Examples

curl -X DELETE https://api.kraiter.com/api/contacts/cnt_01H8MZXK... \
  -H "Authorization: Bearer YOUR_API_KEY"
await kraiter.contacts.delete("cnt_01H8MZXK...");

List sends for contact

GET /api/contacts/:id/sends

Returns all emails sent to a specific contact.

Path parameters

ParameterTypeDescription
idstringThe contact ID.

Response

{
  "items": [
    {
      "sendId": "snd_01H9...",
      "templateId": "welcome-email",
      "deliveryStatus": "delivered",
      "sentAt": "2025-09-15T11:00:00.000Z"
    }
  ],
  "nextCursor": null
}

The list also accepts templateId and sequenceId query parameters to filter the contact's sends.

Examples

curl "https://api.kraiter.com/api/contacts/cnt_01H8MZXK.../sends" \
  -H "Authorization: Bearer YOUR_API_KEY"
const sends = await kraiter.contacts.listSends("cnt_01H8MZXK...");

List scheduled sends for contact

GET /api/contacts/:id/scheduled

Returns pending scheduled sends for a contact.

Path parameters

ParameterTypeDescription
idstringThe contact ID.

Response

Returns a paginated list of scheduled send objects.

Examples

curl "https://api.kraiter.com/api/contacts/cnt_01H8MZXK.../scheduled" \
  -H "Authorization: Bearer YOUR_API_KEY"
const scheduled = await kraiter.contacts.listScheduled("cnt_01H8MZXK...");

List sequence enrolments for contact

GET /api/contacts/:id/sequences

Returns the sequences a contact is currently enrolled in or has previously completed.

Path parameters

ParameterTypeDescription
idstringThe contact ID.

Response

This endpoint returns the full set of enrolments in a single items array (it is not cursor-paginated).

{
  "items": [
    {
      "sequenceId": "onboarding",
      "status": "active",
      "enrolledAt": "2025-09-15T10:30:00.000Z",
      "currentStep": 2
    }
  ]
}

Examples

curl "https://api.kraiter.com/api/contacts/cnt_01H8MZXK.../sequences" \
  -H "Authorization: Bearer YOUR_API_KEY"
const enrolments = await kraiter.contacts.listSequences("cnt_01H8MZXK...");

List segment memberships for contact

GET /api/contacts/:id/segments

Returns the segments a contact currently belongs to.

Path parameters

ParameterTypeDescription
idstringThe contact ID.

Response

This endpoint returns all current memberships in a single items array (it is not cursor-paginated). Each entry is enriched with the segment's name and cached memberCount.

{
  "items": [
    {
      "segmentId": "seg_01H9...",
      "name": "Active Users",
      "memberCount": 342,
      "computedAt": "2025-09-15T10:30:00.000Z"
    }
  ]
}

Examples

curl "https://api.kraiter.com/api/contacts/cnt_01H8MZXK.../segments" \
  -H "Authorization: Bearer YOUR_API_KEY"
const segments = await kraiter.contacts.listSegments("cnt_01H8MZXK...");

Get contact timeline

GET /api/contacts/:id/timeline

Returns a unified timeline of events, sends, delivery/engagement, sequence transitions, and scheduled sends for a contact, sorted in reverse chronological order (most recent first).

Path parameters

ParameterTypeDescription
idstringThe contact ID.

Query parameters

ParameterTypeDefaultDescription
limitnumber50Maximum number of entries to return (max 100).
fromstringOnly include entries at or after this ISO 8601 timestamp.
tostringOnly include entries at or before this ISO 8601 timestamp.

Response

Each entry has a type, a timestamp, and a data object whose shape depends on the type. The response uses hasMore (a boolean) rather than a cursor.

{
  "items": [
    {
      "type": "delivered",
      "timestamp": "2025-09-15T11:00:00.000Z",
      "data": {
        "sendId": "snd_01H9...",
        "templateId": "welcome-email"
      }
    },
    {
      "type": "event",
      "timestamp": "2025-09-15T10:45:00.000Z",
      "data": {
        "eventId": "evt_01H9...",
        "name": "page_viewed",
        "properties": { "url": "/pricing" }
      }
    }
  ],
  "hasMore": false
}

Entry type values include event, send, delivered, bounced, complained, opened, clicked, sequence_entered, sequence_exited, sequence_completed, and scheduled.

Examples

curl "https://api.kraiter.com/api/contacts/cnt_01H8MZXK.../timeline?from=2025-09-01T00:00:00.000Z" \
  -H "Authorization: Bearer YOUR_API_KEY"
const timeline = await kraiter.contacts.getTimeline("cnt_01H8MZXK...");