Send an email
Send a transactional email with the Samva TypeScript SDK or the REST API.
This guide shows the fastest way to send an email with Samva — from a single line of TypeScript to a raw REST call in the language of your choice. Each recipe is self-contained; pick the one that matches your stack.
Email first. Samva is launching with email. SMS, WhatsApp, and voice are staged and will be documented as they ship.
You need a Samva API key. Grab one from your dashboard. Brand-new accounts can send a first test email right away; verify a sending domain before you send from your own address or move real traffic into production. See Verify your domain when you're ready to set that up.
Send with the TypeScript SDK
The email.send() facade is the canonical path: pass the recipient, subject, and HTML body
directly and you're done.
-
Install the SDK.
bash npm install samvabash bun add samvabash yarn add samva -
Create a client and send the email.
import { createClient } from "samva"; const samva = createClient({ apiKey: process.env.SAMVA_API_KEY! }); const result = await samva.email.send({ to: "ada@example.com", subject: "Welcome to Samva", html: "<h1>Welcome!</h1><p>Thanks for joining.</p>", }); if (result.error) { console.error("Failed to send:", result.error); } else { console.log("Email sent:", result.data?.id); }
The to field accepts a single value or an array, and each entry can be a plain email
string, { email }, or { contactId }. You can also pass text for a plaintext fallback,
plus optional fields like attachments, templateId, templateData, and metadata. See the
TypeScript SDK reference for the full surface.
Send to an existing contact or multiple recipients
email.send() is a thin facade over the unified messages.send() API. Reach for
messages.send() directly when you need to address existing contacts by contactId, send to
multiple recipients, or thread into an existing conversation — here to is always an array and
the email content is nested under email.
await samva.messages.send({
to: [{ contactId: "9b2c0e3a-7d41-4f2e-8a16-1f2c3d4e5f60" }, { email: "grace@example.com" }],
channel: "email",
email: {
subject: "Welcome to Samva",
html: "<h1>Welcome!</h1><p>Thanks for joining.</p>",
},
});For why the facade and the unified API exist side by side, see Email and the unified API.
Send with the REST API
There is no email.send HTTP endpoint — the SDK facade is sugar over POST /v1/messages.
Every REST call uses that endpoint with the unified body shape: a channel of email and the
content nested under email. Authenticate with the X-API-Key header.
curl -X POST https://api.samva.app/v1/messages \
-H "X-API-Key: sk_sm_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": [{ "email": "ada@example.com" }],
"channel": "email",
"email": {
"subject": "Welcome to Samva",
"html": "<h1>Welcome!</h1><p>Thanks for joining.</p>",
"text": "Welcome! Thanks for joining."
}
}'To address an existing contact, swap email for contactId in the to array — both forms
hit the same endpoint:
curl -X POST https://api.samva.app/v1/messages \
-H "X-API-Key: sk_sm_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"to": [{ "contactId": "9b2c0e3a-7d41-4f2e-8a16-1f2c3d4e5f60" }],
"channel": "email",
"email": { "subject": "Welcome to Samva", "html": "<h1>Welcome!</h1>" }
}'import requests
headers = {
"X-API-Key": "sk_sm_your_api_key",
"Content-Type": "application/json",
}
response = requests.post(
"https://api.samva.app/v1/messages",
headers=headers,
json={
"to": [{"email": "ada@example.com"}],
"channel": "email",
"email": {
"subject": "Welcome to Samva",
"text": "Welcome! Thanks for joining.",
},
},
)
print(response.json())package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
payload := map[string]any{
"to": []map[string]string{{"email": "ada@example.com"}},
"channel": "email",
"email": map[string]string{
"subject": "Welcome to Samva",
"text": "Welcome! Thanks for joining.",
},
}
body, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST",
"https://api.samva.app/v1/messages",
bytes.NewBuffer(body))
req.Header.Set("X-API-Key", "sk_sm_your_api_key")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
}<?php
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://api.samva.app/v1/messages',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: sk_sm_your_api_key',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'to' => [['email' => 'ada@example.com']],
'channel' => 'email',
'email' => [
'subject' => 'Welcome to Samva',
'text' => 'Welcome! Thanks for joining.',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
print_r(json_decode($response, true));A successful call returns the new message with its id and status:
{
"id": "4f8e1c2a-3b6d-4e9f-a012-3456789abcde",
"status": "pending"
}For every parameter, status code, and pagination detail, see the REST API reference.