Email and the unified API
Why Samva exposes both an email-first send facade and a unified messages API, and how the design keeps the email path stable while leaving room for staged channels.
Samva gives you two ways to send email: a small, email-shaped email.send() facade and a
broader messages.send() API that maps directly onto POST /v1/messages. They are not competing
products or different transports — they are two views of the same send pipeline. This page explains
why both exist, how they relate, and what that design buys you over time.
Email first. Samva is launching with email. SMS, WhatsApp, and voice are staged and will be documented as they ship.
Two shapes, one pipeline
Underneath, every send Samva performs is a message: a piece of content, a recipient, and a channel
that carries it. The unified API names those parts explicitly. When you call messages.send(), you
declare the channel, list your recipients in to, and nest the channel-specific content under a
matching key:
await samva.messages.send({
to: [{ contactId: "contact_123" }],
channel: "email",
email: {
subject: "Welcome to Samva",
html: "<h1>Welcome!</h1><p>Thanks for joining.</p>",
},
});The email.send() facade is the same call wearing email-shaped clothes. It assumes the channel is
email, flattens the email content up to the top level of the input, and accepts a single recipient
or an array. The result is a call that reads like sending an email rather than configuring a generic
message:
const result = await samva.email.send({
to: "ada@example.com",
subject: "Welcome to Samva",
html: "<h1>Welcome!</h1>",
});There is no separate email.send HTTP endpoint. The facade is an SDK-only ergonomic wrapper: it
builds the unified body shape for you and posts it to POST /v1/messages. From the server's point of
view, both snippets above are the same request to the same endpoint. The difference lives entirely in
the SDK, in service of the developer reading the code.
Why a facade at all
Most email you send is straightforward. You have an address, a subject, and some HTML, and you want
the call site to say exactly that. Forcing every send to spell out channel: "email" and nest content
under an email: key adds ceremony to the common case without adding meaning — the channel is obvious
when you reached for email.send().
The facade optimizes for that common case. Flattening the email fields directly into the SDK input keeps the simple path short and removes a layer of nesting you would otherwise repeat on every send. It is the canonical way to send a one-off transactional email, and it is what the send an email guide walks through.
That convenience is deliberately narrow. The facade does not hide the unified API or replace it — it sits on top of it. When your needs outgrow "one address, one subject, one body," you drop down to the API the facade was built on, and nothing about the underlying send changes.
When to reach for the unified API
Reach for messages.send() (or POST /v1/messages directly) when the send is no longer a single
self-contained email:
- Addressing existing contacts. The unified
toarray accepts{ contactId }, so you can send to a contact you already store in Samva without re-supplying their email address. - Multiple recipients. When you are addressing a list rather than one person, the array form of
tois the natural fit. - Threading a reply. When a send belongs to an existing conversation, the unified body is where you express that relationship so the message lands in the right thread.
The dividing line is conceptual, not performance- or feature-based: the facade is for "send this email
to this address," and the unified API is for everything that needs to talk about messages, recipients,
contacts, and conversations as first-class things. Because the facade compiles down to the same
request, you can start with email.send() and move to messages.send() later without rethinking how
your email is delivered.
REST is always the unified shape
The split between a facade and a unified API is an SDK convenience. It does not exist over the wire.
Every REST integration — whether or not you use the TypeScript SDK — sends to POST /v1/messages
using the unified body: a channel, a to array, and channel content nested under its key. If you
are calling the API directly, there is one shape to learn, and the SDK's email.send() is simply
producing that shape on your behalf.
This is why the REST reference and the TypeScript SDK reference can describe the same capability from two angles without contradiction: one documents the unified endpoint, the other documents the ergonomics layered over it.
Room for staged channels
The word "unified" in the unified API is forward-looking. Modeling a send as a channel plus
channel-specific content is what lets Samva add channels without reworking the parts that are already
stable. Today channel: "email" is the only value you would use; the email: {...} block carries the
subject, HTML, and text. Tomorrow, a new channel slots in as another channel value with its own
content block, addressed through the same to array and the same POST /v1/messages endpoint.
Crucially, that growth does not touch the email path. The email.send() facade is pinned to email by
definition, so adding SMS, WhatsApp, or voice cannot change how it behaves, what fields it takes, or
what it sends. Email-first code written today keeps working unchanged as the platform's channel set
grows. The unified shape absorbs the new channels; the email facade stays exactly as small as it is now.
This is the tradeoff the two-API design resolves. A single generic API would make every email verbose. A single email-only API would have no room to grow. By offering the facade for the common case and the unified API as its foundation, Samva keeps the simple thing simple while leaving the model open — and keeps the staged channels a future addition rather than a future migration.
Related
How Samva works
Understand the email model behind Samva — how a send flows from your code to the inbox, the core objects that model email, and the single-API philosophy that ties them together.
Authentication and tenancy
How API keys identify your code to Samva's email API, how organizations isolate your data, and why every record is tenant-scoped.