API Reference
The Kerabie Mail REST API lets you send emails, manage mailboxes, contacts, calendar events, and more. Available on every plan tier, including Free — generate a key under API Keys in the sidebar.
Authentication
API requests are authenticated with an API key in the X-API-Key header — not Authorization: Bearer (that's used for browser/mobile session tokens instead, obtained via /auth/login, not for API keys). Generate keys with the send scope under API Keys in the sidebar — available on every plan tier, including Free.
X-API-Key: YOUR_API_KEY
Content-Type: application/jsonSending isn't rate-limited by requests-per-minute — each mailbox has its own daily send quota (with an hourly sub-limit to catch bursts) that scales with the mailbox owner's plan, visible via GET /subscriptions/me. Exceeding it returns 429. Mailboxes connected over plain IMAP relay through your own external provider and aren't subject to this quota at all.
API keys
Manage keys programmatically, or from API Keys in the sidebar. These management endpoints themselves are authenticated with your browser/mobile session, not an API key.
https://api.kerabie.email/api-keyshttps://api.kerabie.email/api-keys| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | required | A label for you — not sent anywhere |
| scopes | string[] | optional | Defaults to ["send"]. See scopes below |
| expires_at | string | optional | ISO 8601 datetime — the key stops working after this |
| allowed_ips | string[] | optional | IPs/CIDRs allowed to use this key (e.g. "203.0.113.0/24"). Omit to allow all |
| blocked_ips | string[] | optional | IPs/CIDRs denied even if also in allowed_ips — checked first |
Scopes
send, mailboxes:read, mailboxes:write, domains:read, domains:write, webhooks, contacts:read, contacts:write. Hosting partners also have partner:* scopes — see the Partner API docs.
Response 201
{
"id": 42,
"name": "Production",
"key": "ker_9f8a...",
"key_prefix": "ker_9f8a",
"scopes": ["send", "mailboxes:read"],
"allowed_ips": null,
"blocked_ips": null,
"expires_at": null,
"created_at": "2026-05-17T10:00:00Z"
}https://api.kerabie.email/api-keys/{id}| Parameter | Type | Required | Description |
|---|---|---|---|
| allowed_ips | string[] | optional | Replaces the allowlist — pass [] to clear it |
| blocked_ips | string[] | optional | Replaces the blocklist — pass [] to clear it |
| is_active | boolean | optional | Set false to revoke without deleting the record |
https://api.kerabie.email/api-keys/{id}https://api.kerabie.email/api-keys/{id}/usageResponse 200
{
"today": 12,
"last_7_days": 340,
"last_30_days": 1204,
"daily": [{ "date": "2026-05-17", "count": 12 }, ...]
}Errors
All errors return JSON with a detail field.
{ "detail": "Incorrect password." }| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 204 | Deleted (no body) |
| 400 | Bad request — check payload |
| 401 | Missing or invalid API key |
| 403 | Feature not available on your plan |
| 404 | Resource not found |
| 422 | Validation error — check field types |
| 429 | Rate limit exceeded |
| 500 | Server error — contact support |
Send email
https://api.kerabie.email/mail/send| Parameter | Type | Required | Description |
|---|---|---|---|
| from_email | string | required | Sender address (must be a mailbox you own) |
| to | string[] | required | Recipient email addresses (max 50) |
| cc | string[] | optional | CC recipients |
| bcc | string[] | optional | BCC recipients |
| subject | string | optional | Email subject line — defaults to the template’s own subject when template_id is given |
| body_html | string | optional | HTML body. At least one of body_html/body_text/template_id must resolve to content |
| body_text | string | optional | Plain-text body (fallback) |
| template_id | integer | optional | Send using a saved template (see Templates below) instead of inline subject/body_html |
| variables | object | optional | {{placeholder}} substitutions applied to the template’s subject and body — ignored without template_id |
| reply_to | string | optional | Reply-To address |
| track_opens | boolean | optional | Embed a read-receipt tracking pixel — requires a plan with read-receipt support, silently ignored otherwise |
| scheduled_at | string | optional | ISO 8601 datetime (future, UTC) — queues instead of sending immediately |
| unsend_window | integer | optional | Seconds to hold before dispatch (max 30), for an "undo send" window |
| attachments | object[] | optional | Array of {filename, content_base64, content_type}. Total size capped by the sender’s plan |
| sandbox | boolean | optional | Runs the full pipeline (validation, quota checks skipped, tracking, webhooks) without an actual SMTP delivery — for integration testing. Doesn’t count against your daily/hourly quota, and is tagged "sandbox": true on any webhook events it triggers. Not supported together with scheduled_at. |
Request — inline content
curl -X POST https://api.kerabie.email/mail/send \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_email": "hello@yourdomain.com",
"to": ["user@example.com"],
"subject": "Hello from the API",
"body_html": "<p>This was sent via the Kerabie Mail API.</p>"
}'Request — using a saved template
{
"from_email": "hello@yourdomain.com",
"to": ["user@example.com"],
"template_id": 1,
"variables": { "first_name": "Ada", "order_id": "12345" }
}Response 200
{
"message_id": "3fa31ded-d28f-4973-af7b-9ed56ef842d1",
"status": "sent",
"scheduled_at": null,
"scheduled_id": null
}status is "scheduled" instead of "sent" when scheduled_at or unsend_window is set — track or cancel it with the endpoints below, using the returned scheduled_id.
https://api.kerabie.email/mail/scheduledhttps://api.kerabie.email/mail/scheduled/{id}Templates
Reusable HTML emails with {{placeholder}} tags — build them visually under Templates in the sidebar (11 starter designs included, or start blank), then send with them via template_id on POST /mail/send above. Each template's ID is shown on its edit page and is copyable from the templates list.
https://api.kerabie.email/mail/templateshttps://api.kerabie.email/mail/templates| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | required | Template name |
| subject | string | optional | Default subject — can contain {{placeholder}} tags |
| body_html | string | required | HTML body — can contain {{placeholder}} tags |
| is_shared | boolean | optional | Whether other users on a shared inbox can use this template |
https://api.kerabie.email/mail/templates/{id}https://api.kerabie.email/mail/templates/{id}https://api.kerabie.email/mail/templates/{id}Inbox
https://api.kerabie.email/inbox| Parameter | Type | Required | Description |
|---|---|---|---|
| string | required | Mailbox address | |
| folder | string | optional | IMAP folder name (default: INBOX) |
| page | integer | optional | Page number (default: 1) |
| per_page | integer | optional | Items per page (default: 50, max: 100) |
| starred_only | boolean | optional | Return only starred messages |
| unseen_only | boolean | optional | Return only unread messages |
Response 200
{
"messages": [
{
"uid": 42,
"subject": "Hello",
"from": "sender@example.com",
"date": "2026-05-17T09:30:00Z",
"seen": false,
"starred": false,
"has_attachments": false,
"size": 4200
}
],
"total": 87,
"page": 1,
"per_page": 50
}https://api.kerabie.email/inbox/{uid}| Parameter | Type | Required | Description |
|---|---|---|---|
| string | required | Mailbox address |
https://api.kerabie.email/inbox/{uid}| Parameter | Type | Required | Description |
|---|---|---|---|
| string | required | Mailbox address | |
| seen | boolean | optional | Mark read (true) or unread (false) |
| starred | boolean | optional | Star or unstar the message |
| folder | string | optional | Move to this IMAP folder (e.g. Archive, Trash) |
https://api.kerabie.email/inbox/{uid}| Parameter | Type | Required | Description |
|---|---|---|---|
| string | required | Mailbox address |
https://api.kerabie.email/inbox/folders| Parameter | Type | Required | Description |
|---|---|---|---|
| string | required | Mailbox address |
Contacts
Contacts require a Pro or Premium plan.
https://api.kerabie.email/contacts| Parameter | Type | Required | Description |
|---|---|---|---|
| search | string | optional | Filter by name, email, or company |
https://api.kerabie.email/contacts| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | required | Contact full name |
| string | required | Email address | |
| phone | string | optional | Phone number |
| company | string | optional | Company name |
https://api.kerabie.email/contacts/{id}https://api.kerabie.email/contacts/{id}Calendar
Calendar requires a Pro or Premium plan.
https://api.kerabie.email/calendar| Parameter | Type | Required | Description |
|---|---|---|---|
| from | string | optional | ISO 8601 start date |
| to | string | optional | ISO 8601 end date |
https://api.kerabie.email/calendar| Parameter | Type | Required | Description |
|---|---|---|---|
| title | string | required | Event title |
| start | string | required | ISO 8601 start datetime |
| end | string | required | ISO 8601 end datetime |
| all_day | boolean | optional | All-day event (default: false) |
| description | string | optional | Event notes |
| location | string | optional | Physical or virtual location |
| color | string | optional | Hex color code for display |
| attendees | string[] | optional | Attendee email addresses |
https://api.kerabie.email/calendar/{id}https://api.kerabie.email/calendar/{id}Labels
https://api.kerabie.email/labelshttps://api.kerabie.email/labels| Parameter | Type | Required | Description |
|---|---|---|---|
| name | string | required | Label name |
| color | string | required | Hex color (e.g. #416758) |
https://api.kerabie.email/labels/{id}Usage
https://api.kerabie.email/mail/mailbox-usage| Parameter | Type | Required | Description |
|---|---|---|---|
| string | required | Mailbox address |
{
"email": "you@example.com",
"plan": "Pro",
"storage": { "used_mb": 234.5, "limit_mb": 10240, "percentage": 2.3 },
"emails_today": { "sent": 12, "limit": 500, "percentage": 2.4 },
"ai_today": { "used": 5, "limit": 50, "unlimited": false, "percentage": 10.0 }
}