Skip to content
Inbound email API

Inbound email lands in your app.

Receive email on your domain, parse it, and get it in your app as a signed webhook, threaded to the email it answers. No shared inbox, no janky script matching replies to users.

From their inbox to your app

A customer replies.
Your app gets the context.

A customer replies. Your app gets the email, the sender's address, and the conversation it belongs to.

Incoming emailPreview

Maya

maya@example.com

To: support@reply.example.com

Re: Your order A-1042

Could you update the delivery address?

I've attached the details.

Thanks,
Maya

delivery-address.pdf

PDF · 18 KB

A reply to order A-1042, kept with the conversation that started it.

POST /webhooks/samva

Example event · excerpt

{
  "type": "message.received",
  "data": {
    "messageId": "msg_7q2xk9mvt4znw8rh",
    "channel": "email",
    "direction": "inbound",
    "from": "maya@example.com",
    "to": "support@reply.example.com",
    "subject": "Re: Your order A-1042",
    "conversationId": "conv_8r3ym2nkv5xpq9tw",
    "hasAttachments": true,
    "isAutoReply": false,
    "body": "Could you update the delivery address? I've attached the details. Thanks, Maya"
  }
}

Verify the webhook signature before using these fields. The body contains HTML when available, otherwise text.

  1. 01

    Receive the reply

    Enable receiving on your domain and route incoming email to your registered webhook.

  2. 02

    Verify the event

    Check the signature, then use messageId and conversationId to connect the reply to your app.

  3. 03

    Read the details

    Fetch the email for attachment metadata and content links, or the conversation for its history.

support@acme.coFrom: AdaRe: Your receiptconv_5nz8qd3hv6r0wxktINBOUND ADDRESSmail to support@acme.co1PARSEDheaders, body, attachments2THREADEDfiled under its conversation3
  1. INBOUND ADDRESSmail to support@acme.co
  2. PARSEDheaders, body, attachments
  3. THREADEDfiled under its conversation
Fig 3.A reply comes in on your domain, is parsed, and is filed under the conversation of the email it answers.

Receive, parse, and reply in three steps.

  1. Turn on receiving.

    For a domain you send from, or a subdomain like reply.yourapp.com if your team's inbox already lives on the root domain.

  2. Get the webhook.

    Each email arrives parsed as message.received, with the sender, subject, body, an attachments flag, and the conversation id. Verify the signature and dedupe on the webhook id.

  3. Reply in the thread.

    Send with inReplyToMessageId. The answer stays on the same conversation in the customer's inbox and in yours.

What your app gets.

  • Parsed, not raw

    Headers, text and HTML bodies, and attachments you can download by id.

  • Threaded to the right conversation

    Matched by reply headers. An email with no reply headers is matched by subject and participants. A new conversation starts when nothing matches.

  • Auto-replies flagged

    Out-of-office and other automatic replies are marked, so they don't page your support queue.

  • Readable by your agent

    Your coding agent can fetch any conversation by id through MCP or the SDK.

An email parser that hands you fields, not MIME.

  • Sender and recipients

    The webhook carries from, to, and toEmails, every address of yours the email was routed through. The message details add cc, bcc, and reply-to.

  • Subject and bodies

    The webhook has subject and a body: the HTML when there is one, otherwise the text. The message details return signed links to the HTML, the text, and the raw MIME.

  • Attachments

    hasAttachments tells you whether to look. List them by message, with filename, content type, size, and whether each is inline, then fetch any one by id through a time-limited download link.

  • Threading headers

    Message-ID, In-Reply-To, and References are parsed and returned with the message. They place the email in its conversation, and conversationId is in the webhook.

  • Auto-replies, with the reason

    isAutoReply is in the webhook. The message details say why: out-of-office, auto-response, delivery status, or read receipt.

One reply, wherever your app needs it.

message.received
POST /hooks/samvayour endpoint, signature checked
Support queueticket
Customer recordnote
Your agentdraft reply

Samva signs the webhook. Your endpoint checks the signature, then hands the reply to whatever needs it.

A parse webhook, or an inbound email API.

Inbound email API compared with a parse webhook
What your app receivesParse webhookThe email, in the shape that webhook postsSamvaA signed message.received webhook with the sender, subject, body, and conversation id
Which thread it joinsParse webhookYou match the replySamvaFiled on the conversation of the email it answers. Your next send stays there when you pass that conversation or message
How you replyParse webhookA separate send you thread yourselfSamvaSend with inReplyToMessageId so the answer stays in the customer's thread
AttachmentsParse webhookOften included in the payloadSamvahasAttachments on the webhook, then each file by id
Automatic repliesParse webhookYou detect themSamvaisAutoReply is on the webhook, with the reason on the message

A parse webhook hands you an email. The inbound email API hands you that email with the sender's address and the conversation it belongs to.

Read next: Parse and reply · Run the inbound replies example · Receive email in Node.js · Receive email in Python · Move SendGrid Inbound Parse · Move Mailgun Routes · inbound.new alternative · Support replies · Email for an agent

Common questions.

What is an inbound email API?

It receives email on a domain you control and gives your app the parsed message. Samva delivers each one as a signed message.received webhook, with the sender's address and the conversation of the email it answers. Reply by passing that conversation, or the message it answers, on the next send.

What does Samva's email parser return?

A `message.received` webhook with the sender, the addresses it was routed through, the subject, a body, attachment and auto-reply flags, and the conversation id. The message details add the threading headers, cc and bcc, signed links to the HTML, text, and raw MIME, and each attachment.

How do I turn an incoming email into a webhook?

Enable receiving on a domain and point it at an HTTPS endpoint that subscribes to `message.received`. Samva accepts the email, parses it, and POSTs it to your endpoint as a signed JSON event. Verify the signature over the raw body before you read it. The Node.js and Python guides show a working handler for each.

Will this break our existing inbox?

Receiving moves the mail records for the domain you pick. Use a subdomain if your team's email already runs on the root domain.

How does Samva know which conversation a reply belongs to?

From the reply's headers. An email with no reply headers is matched by subject and participants. Outbound email carries the headers replies need.

Can I get attachments?

Yes. The webhook says whether an email has attachments; fetch each one by id.

Does Samva clean quoted text out of replies?

Not yet. You get the body as the sender wrote it, including any quoted history.

How is this different from a parse webhook?

A parse webhook hands you an email. Samva hands you the email with the sender's address and the conversation id, already threaded to the email it answers.

The rest of the email API.

Handle your first reply today.

Related Resources