API Reference
Connect any app to Sendinel in minutes. Identify contacts, fire events, send transactional email, and wire up AI agents — all through a single REST API or the TypeScript SDK.
Quick Start
Sendinel is an email operations control plane. Send transactional email, run campaigns, track events, and manage contacts — all through a REST API or the MCP server.
mail.sendinel.ai — a shared sending domain that's already configured, warmed, and ready to send. You can add your own domain any time, but you don't need one to get your first email out the door.Get your API key
Go to Dashboard → Settings → API Keys and create a new key. Keys are prefixed with snk_ and scoped to read, write, or admin. Most integrations need write scope.
Keys are hashed (SHA-256) before storage. The plaintext is shown once and cannot be retrieved again.
Option A — TypeScript SDK (recommended)
Option B — curl
TypeScript SDK
@sendinel/sdk is a zero-dependency TypeScript client for the Sendinel v1 API. Works in Node.js 18+ (uses native fetch). Full type coverage included.
Full example
Error handling
Retry behavior
The SDK retries automatically on network errors, 429 Too Many Requests, and 5xx responses. Up to 3 attempts with exponential backoff (100ms, 200ms, 400ms). Respects Retry-After headers. 4xx errors (except 429) are not retried — they indicate a problem with the request.
Identify API
Create or update a contact profile. Safe to call on every user action — idempotent by email address. Authenticated via API key with write scope.
identify when a user signs up, logs in, or upgrades — same pattern as Segment and Customer.io. Sendinel merges properties, appends tags, and handles deduplication automatically.Request body
Response — 201 Created (new contact)
Response — 200 OK (existing contact updated)
Merge semantics
| Field | Behavior on update |
|---|---|
| Primary key — not updatable | |
| first_name / last_name | Overwritten only if non-empty string provided |
| properties | Deep merge — new keys added, existing keys updated only if re-specified |
| tags | Appended — existing tags preserved, duplicates removed |
| site_id | Upserts site subscription, enrolls in signup campaigns (first create only) |
Examples
Events API
Fire a named event for a contact. Enrolls them in any active triggered campaigns that match the event name. Authenticated via API key with write scope.
source: "api") so the event can be recorded and campaigns can enroll. You don't need to call identify first — though calling both gives you richer contact data.Request body
Success response
Examples
How campaign triggering works
When an event is received, Sendinel finds all active campaigns with type: "triggered"and a matching trigger_event_name. For each match, a new enrollment is created if the contact is not already enrolled (any non-exited status). The contact begins receiving the campaign sequence starting from the first step.
If no campaigns match the event name, a 200 is returned with enrollments_created: 0. You can fire test events from the dashboard: open a triggered campaign and click Send Test Event.
Transactional Email API
Send a single transactional email immediately. Checks plan limits, rate limits, and the suppression list before sending. The from address and name come from the site configuration. Authenticated via API key with write scope.
Request body
Success response
Examples
Tracking: Open tracking (1x1 pixel) and click tracking (link wrapping) are automatically injected into the HTML body. Set tracking: false to disable.
Conversion Tracking
Track conversions and attribute revenue to email campaigns. Revenue is attributed to the most recent email sent to the contact within a 7-day window. Authenticated via API key with write scope.
Request body
Success response
Attribution logic
Sendinel looks up the most recent email sent to that contact within 7 days. If found, the conversion is attributed to that email and its campaign (last-touch attribution). Revenue data appears in the dashboard overview automatically.
If order_id is provided, duplicate conversions with the same order ID are rejected with 409 Conflict.
Webhooks
Sendinel processes delivery events from your email provider to update status, log opens and clicks, and handle bounces and complaints automatically.
Setup
In your Resend dashboard, add a webhook pointing to:
For per-project routing (BYOD with multiple projects):
All webhook payloads are verified using Svix signature verification. Set RESEND_WEBHOOK_SECRET in your environment. Per-project secrets are supported and stored encrypted.
Supported events
| Event | Description | Action |
|---|---|---|
| email.delivered | Email accepted by recipient server | Updates email_log status → 'delivered' |
| email.opened | Recipient opened the email | Updates status → 'opened', increments open count |
| email.clicked | Recipient clicked a tracked link | Updates status → 'clicked', logs URL in clicked_urls |
| email.bounced | Hard or soft bounce | Updates status → 'bounced', adds suppression record |
| email.complained | Recipient marked as spam | Updates status → 'complained', adds suppression, unsubscribes contact |
Bounces and complaints trigger Slack alerts if configured. Failed webhook processing is retried via a dead letter queue with exponential backoff (up to 5 attempts).
MCP Integration
Sendinel ships an MCP (Model Context Protocol) server. Every campaign, contact, segment, analytics, and template operation is accessible to AI agents — list campaigns, add contacts, generate emails, check deliverability, approve drafts, and more without writing a line of code.
Two connection methods
| Transport | Best for | How |
|---|---|---|
| stdio | Local clients — Claude Desktop, Cursor, Claude Code | npx @sendinel/mcp-server (env vars injected) |
| HTTP/SSE | Remote agents, web apps, non-stdio clients | https://sendinel.ai/api/mcp/sse — Bearer token auth |
Available tool groups
| Group | Tools | Description |
|---|---|---|
| analytics | 6 | Stats, domain health, engagement insights, deliverability checks, performance reports |
| campaigns | 10 | Create, clone, enroll, launch, list enrollments; AI email generation with brand voice |
| contacts | 18 | CRUD, import, merge, tags, segments, preview, test sends, suppressions |
| segments | 6 | Create, update, delete, preview; natural language segment builder |
| drafts | 4 | Create, list, approve, reject AI-generated drafts |
| templates | 4 | Create, list, update, archive email templates |
| data | 8 | Audit log, scoring rules, DMARC reports, contact score explanation, data export |
| sites | 2 | Create and update sending sites |
| gdpr | 2 | Delete contact data (Article 17), list deletion log |
API keys can be scoped to specific tool groups. Destructive operations use a two-call confirmation pattern.
AI Clients
Connect Sendinel to any MCP-compatible AI client. Once connected, your agent has all 48 tools available to manage your email operations conversationally.
Claude Desktop
Open Settings → Developer → Edit Config and add:
Claude Code
Add to your project's .mcp.json:
Or install the /sendinel Claude Code skill for a guided setup:
Cursor
Open Settings → MCP → Add Server and paste:
OpenAI Codex CLI
Example agent conversation
Rate Limits
Rate limits are enforced per project using a sliding window. Limits vary by plan and operation type.
| Plan | Send API | Read endpoints | Write endpoints |
|---|---|---|---|
| Free | 10 req / 5 min | 60 req / 5 min | 30 req / 5 min |
| BYOD | 100 req / 5 min | 300 req / 5 min | 150 req / 5 min |
| Managed | 100 req / 5 min | 300 req / 5 min | 150 req / 5 min |
Rate limit headers
When rate limited, the API returns 429 Too Many Requests with a Retry-After header. The SDK handles 429s automatically with backoff and retry.
Error Codes
All error responses return a JSON body with an error field describing the issue.
| Status | Meaning | Common causes |
|---|---|---|
| 400 | Bad Request | Missing required fields, invalid email format, body too large |
| 401 | Unauthorized | Missing or invalid API key, expired key |
| 403 | Forbidden | API key lacks required scope (write scope needed for mutations) |
| 404 | Not Found | Invalid site_id or resource ID |
| 409 | Conflict | Duplicate idempotency_key (email already sent), duplicate order_id |
| 422 | Unprocessable | Contact limit reached — cannot auto-create contact (track endpoint) |
| 429 | Rate Limited | Too many requests in the current window |
| 500 | Server Error | Internal error — retry with exponential backoff |
Need help? support@sendinel.ai