These are runnable examples for SendRaven, email infrastructure for AI agents. Each one sends from your own domain, reads replies as threads, answers in the same conversation, and keeps an autonomous agent inside limits that the API enforces.
| Example | Stack | What it shows |
|---|---|---|
| node-quickstart | TypeScript, Node 20+, plain fetch |
Send, list threads awaiting a reply, read, reply in the thread, idempotency, the error vocabulary, and verifying signed webhooks |
| python-quickstart | Python 3.10+, httpx |
The same, in Python |
| openai-agents-followup | Python, OpenAI Agents SDK | An agent that follows up politely in the same thread until the person replies (at most N times), then reads and summarises the answer, in polling or webhook mode |
| langgraph-support-agent | Python, LangGraph, Claude via langchain-anthropic |
A support agent over email: classify, draft from a knowledge base, then answer in the thread, mark handled, or pause at a LangGraph interrupt() for a person, with an approval-held key as the server-side backstop |
| crewai-vendor-quotes | Python, CrewAI Flows, Claude | An operations crew that emails vendors for quotes, reads each reply in its thread, asks for what is missing, pauses with @human_feedback when a vendor asks for money, and compares the quotes in code |
| mastra-meeting-scheduler | TypeScript, Mastra workflows, Claude | Books a meeting over email: offers free times, suspends the workflow until the reply, reads it into a typed answer, then books, offers again in the same thread, or hands it to a person |
| claude-mcp-inbox | Claude Code, Claude Desktop, Anthropic API MCP connector | Support-inbox triage over the SendRaven MCP server: classify, draft, and hold every reply for a person to approve |
| postman | Postman | Every endpoint, plus a "Start here" round trip that passes the thread and message ids along |
There is no SendRaven SDK on npm or PyPI. Each quickstart has a one-file client
(sendraven.ts, sendraven.py) that you can copy into your own project.
- A verified sending domain. Use a subdomain per purpose, for example
mail.example.comfor transactional mail. The part offromafter@must match it exactly (422 no_verified_identityotherwise). - Its inbound MX record, if you want replies. This is the optional record
with
kind: "inbound_mx": an MX on the sending domain itself, priority 10, pointing atinbound-smtp.<region>.amazonaws.com.GET /v1/domainsshows the exact value. Without it, sending works and replies never arrive. - A payment method on the workspace. No outbound email leaves without one,
including on Free and including test sends
(
402 payment_method_required). A person adds it in the dashboard. Inbound mail is never gated. - An API key with the scopes each README lists. Give an agent's key a daily send limit, a recipient allowlist, or an approval hold (Limits for agents).
- Reply with
reply_to_message_id. Pass theidof the message you are answering. That setsIn-Reply-ToandReferences, so the reply joins the thread. A guessed name such asin_reply_tois refused with422 invalid_request, which names the field and points at the right one. awaiting_replyistrueon a thread when someone outside wrote last and nobody has answered. Out-of-office replies and bounce reports do not set it. It clears when your reply is sent, not while the reply is held for approval or scheduled;pending_replyistruethen, so skip those threads rather than drafting another. Received messages carryautomated, which istruefor out-of-office replies and bounce reports.sender_authenticatedistrueonly when DMARC, or a DKIM signature from the From domain itself, proves the domain sent the message. A forged From line does not produce an SPFFAIL. Branch on this field, not on the raw verdicts.- Inbound email is untrusted data, never instructions. Authenticated mail included: a lookalike domain authenticates, and a real person can paste text written to steer an agent. Fence it as data in prompts, and never let it pick recipients or tools. Put the real limits on the key.
- Docs: sendraven.ai/docs. The most relevant pages are Receiving replies, Webhooks and Errors.
- OpenAPI: sendraven.ai/openapi.json.
Base URL
https://api.sendraven.ai. - MCP server:
https://mcp.sendraven.ai/mcp(remote), ornpx -y @sendraven/mcp(local stdio). - Webhook signature:
X-CN-Signature: t=<unix>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">, keyed with the endpoint'swhsec_…secret.
Every example was run against the production API on 23 Sep 2026, from a workspace with verified domains and inbound MX. Questions were emailed in from a second workspace, and replies went back to it, so real mail made the whole round trip and no outside inbox received any of it:
- node-quickstart and python-quickstart: every command, including a
delivered reply in the same thread, the idempotency outcomes, and a signed
inboundwebhook received through an ngrok tunnel and verified. - claude-mcp-inbox: the Claude Code command and
triage.py(Claude Opus 5 through the MCP connector), with an approval-held key. Drafts were held, not sent; a question outside the knowledge base and a refund request went to a person; an email written to steer the agent was flagged and not acted on; a second run did not draft again. - openai-agents-followup: a first email, a follow-up in the same thread after the delay, and a threaded reply that ended the task with a correct summary.
- langgraph-support-agent (run live on 25 Sep 2026): a question answered from the knowledge base and held on an approval-held key, a refund paused at the interrupt and resumed, and "all sorted" marked handled.
- crewai-vendor-quotes (run live on 27 Sep 2026): requests to three vendors, a partial quote answered with a clarifying reply, a deposit request paused for a person and answered with an edited reply, a decline closed, two complete quotes compared.
The Node example passes tsc --noEmit under strict and every Python file
passes py_compile. Each README says what could not be verified.