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/sendsReturns a paginated list of send records with optional filtering.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
cursor | string | — | Pagination cursor from a previous response. |
limit | number | 20 | Number of sends to return (max 100). |
status | string | — | Filter by status: queued, sent, delivered, bounced, complained, or rejected. |
contactId | string | — | Filter by contact ID. |
templateId | string | — | Filter 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
| Status | Description |
|---|---|
queued | The email has been accepted and is waiting to be sent. |
sent | The email has been handed off to SES. |
delivered | SES confirmed delivery to the recipient's mail server. |
bounced | The email bounced (hard or soft). |
complained | The recipient marked the email as spam. |
rejected | The send was rejected before reaching SES (e.g. suppressed contact). |
Send sources
Errors
| Code | Description |
|---|---|
VALIDATION_ERROR | Invalid 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:
| Field | Description |
|---|---|
sentAt | When the email was handed off to SES. |
deliveredAt | When SES confirmed delivery. |
openedAt | When the recipient first opened the email (tracked via pixel). |
clickedAt | When the recipient first clicked a tracked link. |
bouncedAt | When the bounce notification was received. |
complainedAt | When the spam complaint was received. |
These fields are null until the corresponding event occurs.