Skip to content

Documentation

Last updated 7 September 2026

Everything needed to send your first email, and to understand why the key you send it with matters.

Start here

Four foundational concepts are worth reading before anything else.

  • Quickstart — install, set a key, send. Under ten lines.
  • Guardrails — scopes, recipient allowlists, CIDR IP restrictions, expiration dates, and approval mode.
  • Agent & Channel Provenance — native tracking for Claude, Cursor, and custom backend bots with zero code changes.
  • Domain setup — the four DNS records, and what each one is for.
  • Domain setup — the four DNS records (SPF, DKIM, DMARC, MX), and what each one is for.

Base URL and authentication

Every request is authenticated with a bearer token. Keys are environment-scoped and carry their own limits, IP allowlists, and persona tags.

Every request is authenticated with a bearer token. Keys are environment-scoped and carry their own limits, IP allowlists, expiration dates, and persona tags.

HTTP
POST https://api.sadasend.com/emails
Authorization: Bearer sada_live_sk_
Idempotency-Key: 6f1c2a80-
X-SadaSend-Agent: SupportBot
X-SadaSend-Source: agent
Content-Type: application/json

{
  "from": "hello@yourdomain.com",
  "to": "user@example.com",
  "cc": ["team@example.com"],
  "bcc": ["archive@yourdomain.com"],
  "subject": "Your receipt",
  "html": "<p>Thank you for your order.</p>",
  "agent_name": "SupportBot",
  "source": "agent"
}

API key modes and prefixes

The key prefix tells you its mode before the request hits the network:

Live (`sada_live_sk_…`): Normal production sending. Dispatches mail directly to receiving mailboxes.

Approval (`sada_agent_sk_…`): Human-in-the-loop mode for autonomous AI agents. Every send is held in pending_approval until reviewed and approved in your dashboard.

Test (`sada_test_sk_…`): Integration and CI mode. Validates schemas and templates without sending actual emails.

Channel & Agent Provenance

Every email accepted by SadaSend is automatically tagged with its ingress channel (mcp, sdk, api, smtp), sending persona source (agent, backend, automation, system), and optional agent identifier.

Provenance gives your team complete deliverability observability. You can filter the Email Activity log by agent name, inspect origin cards in the email detail drawer, and review agent deliverability health and bounce rates in your dashboard analytics.

JSON
// Ingress channels supported
"channel": "mcp" | "sdk" | "api" | "smtp"

// Sending persona sources
"source": "agent" | "backend" | "automation" | "system"

// Agent identifier (up to 128 characters)
"agent_name": "Claude 3.7 Assistant"

Rate limits and quota headers

Every API response emits standard rate limiting and quota headers, allowing clients and SDKs to track allowances in real time:

HeaderDescription
X-RateLimit-LimitMaximum recipient volume permitted in the key’s active rate limit window.
X-RateLimit-RemainingRemaining recipient capacity in the active rate limit window.
X-RateLimit-ResetSeconds until the current rate limit bucket resets.
Retry-AfterSeconds to wait before retrying when throttled with HTTP 429.
X-Quota-LimitTotal monthly email quota included in your current account plan.
X-Quota-UsedNumber of emails dispatched during the current monthly billing period.
X-Quota-ResetISO 8601 timestamp when your account plan’s monthly email quota resets.
X-Quota-OverageNumber of emails sent exceeding plan quota (billed at standard overage rate).

The onboarding sandbox domain

Every new account can send immediately from onboarding.sadasend.com without setting up DNS records first.

To protect shared reputation across all customers, the sandbox has a lifetime limit of 100 messages per account. Adding and verifying your own custom sending domain lifts this limit entirely.

Errors

Errors return a machine-readable code and a human-readable message. Both are always present.

JSON
{
  "error": "recipient_not_allowlisted",
  "message": "Key allowlist is [@example.com]. Recipient is outside it.",
  "docs": "https://www.sadasend.com/docs/errors#recipient_not_allowlisted"
}