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 delivery status: sent, delivered, bounced, or complained.
fromstringOnly include sends at or after this ISO 8601 datetime.
tostringOnly include sends at or before this ISO 8601 datetime.
contactIdstringFilter by contact ID (uses an optimised query; the contact must exist).
templateIdstringFilter by template ID.
sequenceIdstringFilter by sequence ID.

Response

The delivery status is on the deliveryStatus field. Sends record fromAddress/toAddress (not email) and reference their origin via sequenceId/stepId when they come from a sequence.

{
  "items": [
    {
      "sendId": "snd_01H9...",
      "messageId": "0100018f...",
      "contactId": "cnt_01H8MZXK...",
      "templateId": "welcome-email",
      "sequenceId": "onboarding",
      "stepId": "welcome",
      "fromAddress": "hello@notifications.example.com",
      "toAddress": "alice@example.com",
      "subject": "Welcome, Alice!",
      "deliveryStatus": "delivered",
      "sentAt": "2025-09-15T11:00:00.000Z",
      "deliveredAt": "2025-09-15T11:00:02.000Z",
      "openedAt": "2025-09-15T12:30:00.000Z",
      "openCount": 1,
      "clickedAt": "2025-09-15T12:31:00.000Z",
      "clickCount": 1
    }
  ],
  "nextCursor": "eyJpZCI6InNuZF8wMUg5Li4uIn0="
}

Delivery statuses

The send's deliveryStatus field can be:

StatusDescription
sentThe email has been accepted by SES.
deliveredSES confirmed delivery to the recipient's mail server.
bouncedThe email bounced. A bounceType of hard or soft is included.
complainedThe recipient marked the email as spam.
rejectedSES rejected the email before sending.

The status query parameter filters on sent, delivered, bounced, and complained. A send originates from a sequence when sequenceId is present; otherwise it is transactional.

Errors

CodeDescription
VALIDATION_ERRORInvalid filter parameter, or from is after to.
CONTACT_NOT_FOUNDThe contactId filter references a contact that does not exist.

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,
});

Get send

GET /api/sends/:sendId

Returns a single send record by its ID.

Path parameters

ParameterTypeDescription
sendIdstringThe send ID.

Errors

CodeDescription
SEND_NOT_FOUNDNo send with this ID exists.

Examples

curl https://api.kraiter.com/api/sends/snd_01H9... \
  -H "Authorization: Bearer YOUR_API_KEY"
const send = await kraiter.sends.get("snd_01H9...");

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.items);
  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.