Kraiter
API Reference

Sends

Query send history with filtering by status, contact, and template.

The Sends API provides access to your email send history. Every email sent through Kraiter — whether transactional, sequence-based, or campaign-driven — is recorded as a send with status tracking.

List sends

GET /api/sends

Returns a paginated list of send records with optional filtering.

Query parameters

ParameterTypeDefaultDescription
cursorstringPagination cursor from a previous response.
limitnumber20Number of sends to return (max 100).
statusstringFilter by status: queued, sent, delivered, bounced, complained, or rejected.
contactIdstringFilter by contact ID.
templateIdstringFilter by template ID.

Response

{
  "data": [
    {
      "id": "snd_01H9...",
      "contactId": "cnt_01H8MZXK...",
      "email": "alice@example.com",
      "templateId": "welcome-email",
      "templateName": "Welcome Email",
      "subject": "Welcome, Alice!",
      "status": "delivered",
      "source": "sequence",
      "sourceId": "onboarding",
      "sentAt": "2025-09-15T11:00:00.000Z",
      "deliveredAt": "2025-09-15T11:00:02.000Z",
      "openedAt": "2025-09-15T12:30:00.000Z",
      "clickedAt": "2025-09-15T12:31:00.000Z"
    }
  ],
  "nextCursor": "eyJpZCI6InNuZF8wMUg5Li4uIn0="
}

Send statuses

StatusDescription
queuedThe email has been accepted and is waiting to be sent.
sentThe email has been handed off to SES.
deliveredSES confirmed delivery to the recipient's mail server.
bouncedThe email bounced (hard or soft).
complainedThe recipient marked the email as spam.
rejectedThe send was rejected before reaching SES (e.g. suppressed contact).

Send sources

SourceDescription
transactionalSent via the Send endpoint.
sequenceSent as part of a Sequence.

Errors

CodeDescription
VALIDATION_ERRORInvalid filter parameter (e.g. unrecognised status value).

Examples

# List all sends
curl "https://api.kraiter.com/api/sends?limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by status
curl "https://api.kraiter.com/api/sends?status=bounced&limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by contact
curl "https://api.kraiter.com/api/sends?contactId=cnt_01H8MZXK..." \
  -H "Authorization: Bearer YOUR_API_KEY"

# Filter by template
curl "https://api.kraiter.com/api/sends?templateId=welcome-email" \
  -H "Authorization: Bearer YOUR_API_KEY"
// List recent sends
const sends = await kraiter.sends.list({ limit: 20 });

// Filter by status
const bounced = await kraiter.sends.list({
  status: "bounced",
  limit: 50,
});

// Filter by contact
const contactSends = await kraiter.sends.list({
  contactId: "cnt_01H8MZXK...",
});

// Combine filters
const filtered = await kraiter.sends.list({
  status: "delivered",
  templateId: "welcome-email",
  limit: 100,
});

Paginating through results

Use cursor-based pagination to iterate through large result sets:

let cursor: string | undefined;
const allBounced: Send[] = [];

do {
  const page = await kraiter.sends.list({
    status: "bounced",
    limit: 100,
    cursor,
  });
  allBounced.push(...page.data);
  cursor = page.nextCursor ?? undefined;
} while (cursor);

console.log(`Total bounced sends: ${allBounced.length}`);
# First page
curl "https://api.kraiter.com/api/sends?status=bounced&limit=100" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Subsequent pages (use nextCursor from previous response)
curl "https://api.kraiter.com/api/sends?status=bounced&limit=100&cursor=eyJpZCI6InNuZF8wMUg5Li4uIn0=" \
  -H "Authorization: Bearer YOUR_API_KEY"

Engagement timestamps

Each send includes optional engagement timestamps that are populated as events occur:

FieldDescription
sentAtWhen the email was handed off to SES.
deliveredAtWhen SES confirmed delivery.
openedAtWhen the recipient first opened the email (tracked via pixel).
clickedAtWhen the recipient first clicked a tracked link.
bouncedAtWhen the bounce notification was received.
complainedAtWhen the spam complaint was received.

These fields are null until the corresponding event occurs.