Skip to content
The AI-native email API

Install samva. Send in one call.

Install samva, pass your key, and call email.send. Then get back to the product. Or copy the setup brief and let your agent write the integration.

npm install samvaOpenAPI 3.1HOSTED MCP
import { createClient } from "samva";

const samva = createClient({ apiKey: process.env.SAMVA_API_KEY! });

const message = await samva.email.send({
  to: "ada@example.com",
  subject: "Your order shipped",
  html: "<p>Order #1042 is on its way.</p>",
});
POST /v1/messages201 · msg_7q2xk9mvt4znw8rh

See a reply land in the same thread.

Get a demo address and email it from your own account. Samva receives it as a signed webhook and replies in the same thread through the send API, the same calls your app makes.

Email Samva, get a reply

Get a demo address, email it, and watch Samva reply in the same thread.

  1. Your email arrivesWe reply to mail that passes DMARC.
  2. We reply in the same threadOne call to the send API.
  3. We confirm deliveryAccepted by your mail server.
  4. Your reply comes backHit reply and say anything.

Preparing security verification.

#01 — The API

Send, verify, generate from one contract.

SEND
POST /v1/messages
X-API-Key: samva_sk_live_...

{ "channel": "email",
  "to": [{ "email": "ada@example.com" }],
  "email": { "subject": "Your order shipped" } }

201  { "id": "msg_7q2xk9mvt4znw8rh", "status": "pending" }

One typed call. The compiler catches a bad payload before it ships.

SENDING AN EMAIL
WEBHOOKS & EVENTS
POST /webhooks/samva
webhook-id: whevt_7q2xk9mvt4znw8rh
webhook-timestamp: 1783503734
webhook-signature: v1,SGVsbG8...

{ "type": "message.delivered", "timestamp": "2026-07-08T09:42:14Z",
  "data": { "messageId": "msg_7q2xk9mvt4znw8rh" } }

verify({ body, id, timestamp, signature, secret })

Delivery, bounce, and inbound events, signed. Retries with backoff.

WEBHOOK REFERENCE
OPENAPI 3.1 & SDKS
# the typed TypeScript SDK
npm install samva

# the whole API, as one spec
GET https://api.samva.dev/v1/openapi.json
200 · openapi 3.1 · every endpoint, typed

Install the TypeScript SDK, or generate a client from OpenAPI 3.1.

OPENAPI SPEC
HOSTED MCP
{
  "mcpServers": {
    "samva": {
      "url": "https://mcp.samva.dev",
      "headers": { "X-API-Key": "samva_sk_live_..." }
    }
  }
}

Point your agent at mcp.samva.dev. Your agent gets sending, replies, domains, templates, campaigns, and webhooks as tools. API key or OAuth.

HOSTED MCP
0018SAMVA · SENDada@acme.coRe:message.sentmessage.deliveredmessage.receivedSAMVA APIemail.send() · POST /v1/messages1YOUR CUSTOMERreceives it, replies2INBOUNDreply threaded into conv_5nz8qd3hv6r0wxkt3SIGNED WEBHOOKmessage.received to your app4DELIVERYmessage.delivered or message.bounced5
  1. SAMVA APIemail.send() · POST /v1/messages
  2. YOUR CUSTOMERreceives it, replies
  3. INBOUNDreply threaded into conv_5nz8qd3hv6r0wxkt
  4. SIGNED WEBHOOKmessage.received to your app
  5. DELIVERYmessage.delivered or message.bounced

sent 18 · delivered 18 · replies threaded 3

Fig 1.Samva sends the email and reports each delivery event. Your customer's reply is threaded into the conversation of the email it answers, and a signed webhook brings it back to your app.
#02 — Replies

Replies come back to your app.

Turn on receiving for your domain. A reply to an email you sent arrives at your webhook as message.received, with the conversationId of the email it answers. Answer in the same thread by passing that id.

POST /webhooks/samva

{ "type": "message.received",
  "data": {
    "from": "ada@example.com",
    "subject": "Re: Your order shipped",
    "conversationId": "conv_01j8k5p7q9r2s4t6v8wx" } }
import { createClient } from "samva";

const samva = createClient({ apiKey: process.env.SAMVA_API_KEY! });

await samva.email.send({
  to: "ada@example.com",
  conversationId: "conv_01j8k5p7q9r2s4t6v8wx",
  subject: "Re: Your order shipped",
  html: "<p>It arrives Thursday.</p>",
});
ATTEMPTSattempt 3 / 8v1POST /hooks/samva200SIGNEDwebhook-signature: v1 on every request1RETRIESup to 8 attempts, with backoff2YOUR ENDPOINTanswers 200, the event is done3
  1. SIGNEDwebhook-signature: v1 on every request
  2. RETRIESup to 8 attempts, with backoff
  3. YOUR ENDPOINTanswers 200, the event is done
Fig 4.Each event is signed in the webhook-signature header and retried with backoff until your endpoint returns a successful 2xx response, up to 8 automatic attempts.
INBOUND EMAIL

Everything the one-way pipe leaves out.

#03 — Effect-native

The SDK ships an Effect-native client too.

Import Pascal-cased modules from samva/effect/* and call operations directly. Each operation composes into your Effect v4 program.

import { Effect } from "effect";
import * as Client from "samva/effect/client";
import * as Email from "samva/effect/email";

const program = Email.send({
  to: "ada@example.com",
  subject: "Your order shipped",
  html: "<p>It arrives Thursday.</p>",
}).pipe(
  Effect.catchTags({
    RateLimitedError: (e) => Effect.sleep(e.retryAfterSeconds * 1_000),
    ValidationError: (e) => Effect.log(e.fields),
  }),
  Effect.provide(Client.layerFetch({ apiKey: process.env.SAMVA_API_KEY! })),
);

const message = await Effect.runPromise(program);
Typed errors
Failures arrive as tagged errors you narrow with catchTags. RateLimitedError carries retryAfterSeconds, ValidationError carries the offending fields.
Layer-based services
Domain operations require Client.Service. Build Client.layerFetch once and provide it around the part of your program that calls Samva.
Schema-driven
Requests and responses are decoded through Schema, so a malformed payload fails at the boundary, not three calls later.
EFFECT SDK GUIDE
#04 — Agent tooling

Build it with your agent.

Samva publishes setup at /auth.md, so your agent picks the credential and writes the integration. Point it at hosted MCP, or paste the brief below.

COPY FOR YOUR AGENT
$ Read samva.dev/auth.md, create an API key, then follow the quickstart to integrate email.

Samva for ChatGPT, Claude, Cursor, and Grok

Open the Samva plugin in ChatGPT, connect one organization, and start with a read-only readiness check.

  • Claude logoClaudeComing soon
  • ChatGPT logoChatGPT
  • Cursor logoCursorComing soon
  • Grok logoGrokComing soon
Get notified

Numbers we publish, and the code that enforces them.

Free tier

Every month, no card

500emails

Past your allowance

Any paid plan, one rate

$0.50/ 1,000

Webhook delivery

Automatic attempts, then the log

8attempts

Signed events

What reaches your endpoint for one email

  1. 09:41:02message.sentmsg_8f2c1qd3hv6r0wxk
  2. 09:41:04message.deliveredmsg_8f2c1qd3hv6r0wxk
  3. 10:17:55message.receivedconv_5nz8qd3hv6r0wxkt

Send latency

p50, production, API to accepted

140ms

Prices, limits, and retries are read from the code that enforces them.

Read the docs, then send.

Your customers' business email runs on it too.

Small businesses use the same platform in Samva Mail: business email on their own domain, shared inboxes, and an AI assistant that answers the routine customer email. The conversations your API writes are the ones their team answers.

Samva for small businesses

Questions from developers.

Which languages can I use?

TypeScript has a typed SDK (npm install samva). Anything else calls REST, and the OpenAPI 3.1 spec generates a client in your language.

How do I verify a webhook?

Every event is signed and follows the Standard Webhooks spec. @samva/webhooks checks the signature for you in TypeScript. In other languages, verify with any Standard Webhooks library and your signing secret.

Can my coding agent set it up?

Yes. Point any MCP client that supports OAuth at mcp.samva.dev, or run samva login. A person approves the first credential.

What does it cost?

500 emails a month free, no card. Paid plans start at $5 for 15,000.

Send the first email from your editor.

Install samva, pass your key, and call email.send. The response carries the message id you track from there.

Related Resources