Samva is in early access — self-serve signup is limited. Have a team invite? Sign up with that email. Contact us for access.

TypeScript SDK

Reference for the samva TypeScript SDK — client config, email send methods, services, and error shapes.

The samva package is the official TypeScript/JavaScript SDK for the Samva email API. It is generated from the OpenAPI specification, so its surface mirrors the REST API exactly.

This page is a reference. For a step-by-step walkthrough of sending your first email, see Send an email.

Email first. Samva is launching with email. SMS, WhatsApp, and voice are staged and will be documented as they ship.

Installation

npm install samva
bash npm install samva
bash yarn add samva
bash pnpm add samva
bash bun add samva

Entrypoints

The samva package ships three entrypoints from a single install. They are all generated from the same OpenAPI surface, so they stay in sync with the REST API — pick the one that matches your runtime style.

ImportStyleWhen to use
samvaPromise (default)Most apps. Re-exports the Promise client.
samva/promisesPromise (explicit)The same Promise client as the root — use the explicit path when you also import samva/effect.
samva/effectNative Effect v4Effect-native apps. Returns Effects rather than wrapping the Promise client. Requires effect as a peer dependency.

The rest of this page documents the Promise client. For the Effect client, see Native Effect client below.

Client

createClient(config)

Creates a configured client instance. The organization context is derived from the API key — no organization slug or ID is required.

import { createClient } from "samva";

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

Config options

OptionTypeRequiredDefaultDescription
apiKeystringOne of apiKey / authTokenAPI key. Sent as the X-API-Key header.
authTokenstringOne of apiKey / authTokenOAuth bearer token (e.g. from samva login). Sent as Authorization: Bearer.
baseUrlstringNohttps://api.samva.appAPI base URL. Override for testing or self-hosting.

Pass exactly one of apiKey or authToken. Use apiKey for servers (the organization is derived from the key); use authToken for first-party or OAuth tooling, where the session is user-scoped — pass the active organization with headers: { "x-org-slug": "<slug>" }. See API keys and OAuth sessions.

Additional fields from the underlying generated HTTP client Config (such as headers and fetch) are also accepted.

Return shape

createClient returns a SamvaClient exposing the live services below plus client, the underlying HTTP client.

PropertyDescription
emailEmail send helper plus domain, sender, and template methods
messagesUnified message send and retrieval
contactsContact records
conversationsThreaded message grouping
webhooksEvent delivery configuration
apiKeysProgrammatic access management
organizationsOrganization settings
scheduledScheduled messages
clientUnderlying HTTP client

Calling convention

Methods take flat request parameters as the first argument. Request options such as throwOnError, headers, and signal are passed as an optional second argument.

Every method resolves to a result object:

FieldDescription
dataThe response payload on success (for example, data.id)
errorThe error payload on failure; undefined on success
const result = await samva.email.send({
  to: "ada@example.com",
  cc: "grace@example.com",
  replyTo: "support@example.com",
  subject: "Welcome to Samva",
  html: "<h1>Welcome!</h1>",
});

if (result.error) {
  console.error("Send failed:", result.error);
} else {
  console.log("Sent:", result.data?.id);
}

samva.email

The canonical surface for email.

email.send(input, options?)

The simplest way to send email. It is an SDK-only ergonomic wrapper over messages.send() — there is no email.send REST endpoint. Email fields are flattened directly into the input object (not nested under an email key).

const result = await samva.email.send({
  to: "ada@example.com",
  subject: "Welcome to Samva",
  html: "<h1>Welcome!</h1>",
});

Input fields

FieldTypeRequiredDescription
torecipient or recipient arrayYesRecipient(s). See Recipients.
ccrecipient or recipient arrayCarbon-copy recipient(s).
bccrecipient or recipient arrayBlind-carbon-copy recipient(s).
replyTostring or string[]Reply-To address(es) for the email.
subjectstringEmail subject line.
htmlstringHTML body. Provide html, text, or both.
textstringPlain-text body.
attachmentsarrayFile attachments.
templateIdstringTemplate to render instead of inline html/text.
templateDataobjectVariables passed to the template.
conversationIdstringAttach the message to an existing conversation.
inReplyToMessageIdstringThread the message as a reply to a prior message.
unsubscribeGroupIdstringUnsubscribe group to associate with the message.
metadataobjectArbitrary key/value metadata to attach to the message.

Recipients

to, cc, and bcc accept a single value or an array of any of:

FormExample
Email string"ada@example.com"
Email object{ email: "ada@example.com" }
Contact reference{ contactId: "contact_123" }
Contact object{ id: "contact_123" } (an object with id is treated as a contact)

Email helper methods

The email service also exposes domain, sender, and template management. All take the standard options object and return { data, error }.

MethodPurpose
listTemplates(options?)List email templates.
createTemplate(options)Create a template with a variable schema.
getStats(options?)Email sending statistics.
addDomain(options)Add a sending domain; returns the DNS records to set.
listDomains(options?)List sending domains.
verifyDomain(options)Trigger verification for a domain.
checkDomainVerification(options)Check verification status.
getDomainStatus(options)Current domain status.
getDomainById(options)Fetch a domain by ID.
removeDomain(options)Remove a domain.
addSender(options)Add a verified sender address.
listSenders(options?)List sender addresses.
checkSenderVerification(options)Check sender verification status.
removeSender(options)Remove a sender.

For domain verification steps, see Verify your domain.

samva.messages

The unified send and retrieval API. email.send() delegates to messages.send(); reach for messages.send() directly when you want the explicit nested shape, for example to address contacts by contactId, send to multiple recipients, or thread a reply.

messages.send(input, options?)

const result = await samva.messages.send({
  to: [{ contactId: "contact_123" }],
  cc: [{ email: "grace@example.com" }],
  channel: "email",
  email: {
    subject: "Welcome to Samva",
    html: "<h1>Welcome!</h1>",
    replyTo: "support@example.com",
  },
});

Input fields

FieldTypeRequiredDescription
torecipient arrayYesRecipients. Always an array. See Recipients.
ccrecipient arrayCarbon-copy recipients. Always an array.
bccrecipient arrayBlind-carbon-copy recipients. Always an array.
channel"email"YesSend channel. Email-only at launch.
emailobjectYesNested email content (see below).
conversationIdstringAttach to an existing conversation.
metadataobjectArbitrary key/value metadata.

The nested email object carries subject, html, text, replyTo, attachments, templateId, templateData, inReplyToMessageId, and unsubscribeGroupId — the same content fields that email.send() flattens into body.

Other message methods

MethodPurpose
list(options?)List messages.
get(options)Get a message by ID.
getStatus(options)Get delivery status for a message.
getEvents(options)Get the event log for a message.
remove(options)Delete a message.
const messages = await samva.messages.list({ channel: "email", limit: "20" });
const message = await samva.messages.get({ id: "msg_123" });
const events = await samva.messages.getEvents({ id: "msg_123" });

Other services

All services follow the same calling convention and result shape.

samva.contacts

MethodPurpose
create, update, removeManage a contact record.
get, find, listFetch and list contacts.
findOrCreateLook up a contact or create it if absent.
bulkImport, bulkDeleteBulk create or delete.
bulkUpdateStatus, bulkUpdateTagsBulk attribute updates.
exportExport contacts.
getActivityTimeline, getEngagement, getGroupMembershipsContact activity and grouping.

samva.conversations

MethodPurpose
create, updateManage a conversation.
getById, listFetch and list conversations.
addContacts, removeContactsManage conversation participants.

samva.webhooks

MethodPurpose
create, update, removeManage a webhook endpoint.
get, listFetch and list endpoints.
getStats, getLogsDelivery statistics and logs.
test, retryDeliverySend a test event or retry a delivery.
regenerateSecretRotate the signing secret.

For receiving and verifying webhook events, see Receive webhooks.

samva.apiKeys

MethodPurpose
create, update, removeManage an API key.
get, listFetch and list keys.
revoke, rotateRevoke or rotate a key.
getStats, getActivityUsage statistics and activity.

samva.organizations

MethodPurpose
get, updateRead and update organization settings.
getUsageUsage figures for the organization.

samva.scheduled

MethodPurpose
create, get, listManage scheduled messages.
cancelCancel a scheduled message.

Error handling

Methods do not throw on API errors by default. Inspect the result instead:

const result = await samva.email.send({
  to: "ada@example.com",
  subject: "Test",
  text: "Hello",
});

if (result.error) {
  // result.error holds the error payload
  console.error(result.error);
} else {
  console.log(result.data?.id);
}

Environment variables

Store the API key in an environment variable rather than hard-coding it.

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

Key format

Every Samva API key starts with sk_sm_. There is no separate live and test key — pass your key into the client as apiKey.

const samva = createClient({ apiKey: "sk_sm_..." });

See Authentication for key format and details.

Native Effect client

samva/effect is a first-class Effect v4 client. It returns Effects rather than wrapping the Promise client, so it composes directly into Effect programs. Install effect alongside samva:

npm install samva effect

Create a client inside an Effect and provide an HTTP layer:

import { Effect } from "effect";
import { FetchHttpClient } from "effect/unstable/http";
import { createClient } from "samva/effect";

const program = Effect.gen(function* () {
  const samva = yield* createClient({ apiKey: process.env.SAMVA_API_KEY! });

  return yield* samva.email.send({
    to: "ada@example.com",
    subject: "Welcome to Samva",
    html: "<h1>Welcome!</h1>",
  });
}).pipe(Effect.provide(FetchHttpClient.layer));

For application-wide dependency injection, use the SamvaClient service and provide its layer:

import { Effect } from "effect";
import { SamvaClient } from "samva/effect";

const program = Effect.gen(function* () {
  const samva = yield* SamvaClient;

  return yield* samva.email.send({
    to: "ada@example.com",
    subject: "Welcome to Samva",
    html: "<h1>Welcome!</h1>",
  });
}).pipe(Effect.provide(SamvaClient.layerFetch({ apiKey: process.env.SAMVA_API_KEY! })));

The Effect client exposes flat email and messages send helpers — the same email-first surface as the Promise client — plus a top-level raw property (e.g. samva.raw) for the full generated Effect operation surface. Errors surface through the Effect error channel rather than a { data, error } result, so handle them with the usual combinators (Effect.catchAll, Effect.match, and so on).

Support matrix

SDKPackageAPI versionRuntime
TypeScriptsamvav1Modern Node.js, Bun, and Deno (ESM)
REST APIv1Any HTTP client

The SDK is generated from the Samva OpenAPI specification using @hey-api/openapi-ts, so it stays in sync with the REST API. For other languages, use the REST API with your language's HTTP client.

See also

On this page