Kraiter
Guides

Events

Track custom events and system events to trigger automations and build engagement profiles.

Events are actions or occurrences associated with a contact. Kraiter supports both custom events you send via the API and system events generated automatically when emails are sent, opened, clicked, bounced, or complained about.

Events are the primary mechanism for triggering sequence enrolments and building a timeline of contact activity.

Sending custom events

Track a custom event by providing the contact's email and an event name. You can optionally include properties with additional context.

SDK
await kraiter.events.track({
  email: 'alice@example.com',
  name: 'purchase.completed',
  properties: {
    orderId: 'ORD-12345',
    amount: 79.99,
    currency: 'GBP',
    items: 3,
  },
});
cURL
curl -X POST https://api.kraiter.com/api/events \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "alice@example.com",
    "name": "purchase.completed",
    "properties": {
      "orderId": "ORD-12345",
      "amount": 79.99,
      "currency": "GBP",
      "items": 3
    }
  }'

Event naming conventions

Use dot-separated names to organise events into categories:

  • purchase.completed, purchase.refunded
  • feature.activated, feature.deactivated
  • onboarding.step1, onboarding.step2, onboarding.completed

Event names are case-sensitive. Choose a consistent naming pattern and stick with it.

Event properties

Properties are arbitrary key-value pairs attached to an event. They are stored with the event and can be used for filtering and analysis. Property values can be strings, numbers, or booleans.

The contact must exist

Event tracking looks the contact up by email. If no contact matches that address, the request fails with a CONTACT_NOT_FOUND error (HTTP 404) — events do not auto-create contacts. Create (or upsert) the contact first, then track events against it:

SDK
// Ensure the contact exists before tracking
await kraiter.contacts.upsert({ email: 'new-user@example.com' });

await kraiter.events.track({
  email: 'new-user@example.com',
  name: 'signup.started',
});

System events

Kraiter automatically generates events for email lifecycle activities. These events use the email.* namespace:

EventDescription
email.sentAn email was successfully sent to the contact
email.deliveredThe email was delivered to the recipient's mail server
email.openedThe contact opened the email (via tracking pixel)
email.clickedThe contact clicked a link in the email
email.bouncedThe email bounced (hard or soft)
email.complainedThe contact reported the email as spam
email.unsubscribedThe contact unsubscribed via the one-click link

System events are created automatically and cannot be sent via the API. They include metadata such as the send ID, template ID, and sequence ID (if applicable).

Using events to trigger sequences

Events are a key way to start automated sequences. When defining a sequence, you can set an event-based trigger so that contacts are automatically enrolled when a matching event is received.

Sequence YAML
trigger:
  event: purchase.completed

steps:
  - action: email
    template: order-confirmation
  - action: delay
    duration: 3d
  - action: email
    template: review-request

In this example, whenever a purchase.completed event is tracked for a contact, they are enrolled in the sequence and receive the order confirmation email immediately, followed by a review request three days later.

See the Sequences guide for more on triggers and conditions.

Listing events

List events across your whole tenant, most recent first. Pass the optional name parameter to filter by event name:

SDK
const { items, nextCursor } = await kraiter.events.list({
  limit: 25,
});
cURL
curl "https://api.kraiter.com/api/events?limit=25" \
  -H "Authorization: Bearer YOUR_API_KEY"

Filter the tenant-wide feed by event name:

SDK
const purchases = await kraiter.events.list({
  name: 'purchase.completed',
});

To list events for a single contact, use listForContact with the contact's ID (a ULID, not the email address):

SDK
const { items } = await kraiter.events.listForContact(contactId, {
  name: 'purchase.completed',
});
cURL
curl "https://api.kraiter.com/api/events/contacts/CONTACT_ID?name=purchase.completed" \
  -H "Authorization: Bearer YOUR_API_KEY"

Tenant-wide event feed

Kraiter provides a live feed of events across all contacts in your tenant. This is useful for monitoring activity in real time from the dashboard.

Events are retained for your tenant's retention period. Older events are automatically archived.

Best practices

  • Be specific with event names. purchase.completed is better than purchase because it leaves room for purchase.started, purchase.refunded, etc.
  • Include relevant properties. Properties make events useful for analysis. Include identifiers (order IDs, plan names) and values (amounts, counts).
  • Do not include sensitive data. Avoid putting passwords, tokens, or personally identifiable information beyond the email address in event properties.
  • Use events for sequence triggers. Rather than manually enrolling contacts in sequences via the API, use events to automate enrolment based on user behaviour.