TypeScript SDK
Reference for the samva TypeScript SDK, covering client setup, the email send facade, every service namespace, errors, and the native Effect client.
The samva package is the official TypeScript SDK for the Samva API. It is generated from the
OpenAPI document the API publishes, so every method matches
the operation it calls and covers the whole public API.
This page is a reference. For a step-by-step first send, see Send your first email.
Installation
npm install samvaEntrypoints
| Import | Style | When to use |
|---|---|---|
samva | Promise (default) | Most apps. |
samva/promises | Promise (explicit) | The same client as the root; use it when the same file also imports samva/effect. |
samva/effect/* | Native Effect v4 | Effect applications. One module per namespace, plus client. Requires effect as a peer dependency. |
samva/webhooks | Promise | Verify and decode signed webhook deliveries. samva/webhooks/effect is the Effect form. See Verify webhooks. |
The rest of this page documents the Promise client until Native Effect client.
Client
createClient(config)
import { createClient } from "samva";
const samva = createClient({ apiKey: process.env.SAMVA_API_KEY! });| Option | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | string | One of apiKey / authToken | none | API key, sent as X-API-Key. The organization comes from the key. |
authToken | string | One of apiKey / authToken | none | OAuth bearer token, such as a samva login session. |
baseUrl | string | No | https://api.samva.dev | API base URL. Override it for testing. |
headers | object | No | none | Headers sent on every request. |
fetch | function | No | global fetch | The fetch implementation to use. |
Pass exactly one of apiKey or authToken. With authToken, also pass the organization as
headers: { "x-org-slug": "<slug>" }. See Authentication.
The Promise client accepts string API keys and does not require Effect. The Effect client accepts
string | Redacted<string> and unwraps a Redacted key only for authentication.
The client sends an advisory x-samva-client header naming the SDK and its version. Override it
through headers, or set it to null in a call's request options to omit it. Samva does not use it
for authentication or authorization.
Calling convention
Every method takes one flat object of request parameters, path, query, and body fields together,
and resolves with the decoded success value. Request options such as headers and signal go in an
optional second argument. A failure throws; see Error handling.
const message = await samva.messages.get({ id: "msg_7q2xk9mvt4znw8rh" });Each method is named for the operation it calls in the API reference: for
example samva.contacts.bulkImport calls
Bulk import contacts, and the reference page documents its
parameters, response, and errors. samva.email.send is the one method with no operation of its own.
Namespaces
| Namespace | Covers | Effect module | Reference |
|---|---|---|---|
analytics | Aggregate send statistics and exports | samva/effect/analytics | Analytics |
apiKeys | API keys, rotation, and usage | samva/effect/api-keys | API keys |
attachments | A message's attachments and their download URLs | samva/effect/attachments | Attachments |
brands | Brand themes, logos, and footers that templates import | samva/effect/brands | Brands |
campaigns | Audience campaigns, their runs, and recipients | samva/effect/campaigns | Campaigns |
contactGroups | Static and dynamic contact groups and their members | samva/effect/contact-groups | Contact groups |
contacts | Contact records, bulk changes, and activity | samva/effect/contacts | Contacts |
conversations | Threads of related messages and their contacts | samva/effect/conversations | Conversations |
customFields | Custom contact field definitions | samva/effect/custom-fields | Contacts |
email | The send facade, domains, senders, tracking, review, and blocks | samva/effect/email | |
extensionInstallations | Install, enable, disable, and uninstall extensions, and read their runs | samva/effect/extension-installations | Mailbox extensions guide |
extensions | Publish mailbox extensions and read their versions | samva/effect/extensions | Mailbox extensions guide |
feedback | Reports to Samva about what was confusing, broken, or missing | samva/effect/feedback | Send feedback |
mailboxes | Mailboxes, threads, messages, grants, quarantine, and events | samva/effect/mailboxes | Mailboxes guides |
media | Organization-owned uploads for attachments | samva/effect/media | Media |
messages | Sending, listing, status, and events for messages | samva/effect/messages | Messages |
namespaces | Sub-tenants that confine mailboxes and keys | samva/effect/namespaces | Mailbox namespaces guide |
operations | Long-running operation status and retry | samva/effect/operations | Operations |
organizations | The organization record and its usage | samva/effect/organizations | Organizations |
scheduledMessages | Future sends: create, list, get, cancel, and resume | samva/effect/scheduled-messages | Scheduled messages |
subscriptions | Request and confirm recipient consent | samva/effect/subscriptions | Double opt-in |
templates | Template projects, families, workspaces, and publications | samva/effect/templates | Templates |
unsubscribeGroups | Unsubscribe groups and their suppressed addresses | samva/effect/unsubscribe-groups | Unsubscribe groups |
webhooks | Webhook endpoints, test deliveries, logs, retries, and secrets | samva/effect/webhooks | Webhooks |
whoami | The organization and credential behind the request | samva/effect/whoami | Get the calling credential |
raw | Every namespace unwrapped: result envelopes and the HTTP client | Client.raw | Raw access |
samva.email.send
email.send is an SDK-only facade over messages.send; both call
Send a message. It fixes the channel to email, flattens the
fields of the email object into its input, and accepts a single recipient or an array.
const message = await samva.email.send({
to: "ada@example.com",
cc: "grace@example.com",
replyTo: "support@example.com",
subject: "Welcome to Samva",
html: "<h1>Welcome!</h1>",
});
console.log("Sent:", message.id);The input takes to, cc, bcc, from, conversationId, and metadata from the message, plus
every field of the email object documented on
Send a message, such as subject, html, text,
attachments, templateId, templateData, inReplyToMessageId, and unsubscribeGroupId.
to, cc, and bcc accept a single value or an array of any of:
| Form | Example |
|---|---|
| Email string | "ada@example.com" |
| Email object | { email: "ada@example.com" } |
| Contact reference | { contactId: "contact_k9mvt4znw8rh7q2x" } |
| Contact object | { id: "contact_k9mvt4znw8rh7q2x" }, such as a contact the SDK returned |
Attachments reference ready media from samva.media or carry bounded base64 content; see
Send an attachment for the flow and limits.
Retry a send safely
Every email.send, messages.send, and email.addSender call sends an Idempotency-Key header.
The SDK generates a fresh key per call; pass your own idempotencyKey option when your code may
retry the same logical send. An identical retry returns the original message; reusing the key with a
different request returns a ConflictError. See Idempotency.
const receipt = await samva.email.send(
{ to: "ada@example.com", subject: "Your receipt", text: "Thanks for your order." },
{ idempotencyKey: "receipt:order-4417" },
);samva.messages.send
messages.send takes the message body of Send a message
directly: an explicit channel, recipient arrays, and content nested under email. Use it when the
send is about recipients, contacts, and conversations rather than one address.
const message = await samva.messages.send({
to: [{ contactId: "contact_k9mvt4znw8rh7q2x" }],
cc: [{ email: "grace@example.com" }],
channel: "email",
email: {
subject: "Welcome to Samva",
html: "<h1>Welcome!</h1>",
replyTo: "support@example.com",
},
});For when to use each shape, see Email and the messages API.
Error handling
Every error the API declares becomes a class named for its _tag, exported from samva, with the
error's fields as properties. All of them extend SamvaApiError. A network failure or an
unreadable response throws SamvaTransportError. The
Error reference lists every error and its fields.
import { RateLimitedError, SamvaApiError, SamvaTransportError } from "samva";
try {
const message = await samva.email.send({
to: "ada@example.com",
subject: "Test",
text: "Hello",
});
console.log(message.id);
} catch (error) {
if (error instanceof RateLimitedError) {
console.error(`Retry after ${error.retryAfterSeconds} seconds`);
} else if (error instanceof SamvaApiError) {
console.error(error._tag, error.status, error.message);
} else if (error instanceof SamvaTransportError) {
console.error("Network or response failure", error.cause);
} else {
throw error;
}
}Raw access
samva.raw exposes each namespace without the direct-value wrapper. A raw call returns the
{ data, error, request, response } envelope instead of throwing, which is useful when you need the
HTTP response itself.
const result = await samva.raw.messages.get({ id: "msg_7q2xk9mvt4znw8rh" });
if (result.error) {
console.error(result.response?.status, result.error);
} else {
console.log(result.data);
}Native Effect client
The samva/effect/* entrypoints form a native Effect v4 SDK. Each
namespace module exports operations that return Effects directly. Install the pinned peer alongside
samva:
npm install samva effect@4.0.0Import the client capability and the modules you use, and provide the fetch-backed client Layer at the program boundary:
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: "Welcome to Samva",
html: "<h1>Welcome!</h1>",
},
{ idempotencyKey: "welcome:customer-123" },
).pipe(Effect.provide(Client.layerFetch({ apiKey: process.env.SAMVA_API_KEY! })));
const message = await Effect.runPromise(program);Each module is the Pascal-cased namespace, imported from the path in the
Namespaces table, such as * as Contacts from "samva/effect/contacts". Operations
take the same flat parameter objects as the Promise client and depend on Client.Service through
the Effect environment.
Errors arrive in the Effect error channel as the tagged errors from the
Error reference, so Effect.catchTag("RateLimitedError", …)
works on any operation. samva/effect/categories exports helpers such as isRetryable. The
Effect client retries reads and sends on retryable failures by default; samva/effect/retry
configures or disables that. Paginated operations add pages and items Streams. Fields annotated
as absolute instants decode to Date, and secrets such as a new API key decode to Redacted.
Support matrix
| SDK | Package | API version | Runtime |
|---|---|---|---|
| TypeScript | samva | v1 | Node.js, Bun, and Deno (ESM) |
| REST API | none | v1 | Any HTTP client |
For other languages, use the REST API with your language's HTTP client.