API keys
Reference API key formats, the X-API-Key header, rate limits, and authentication errors for Samva's email API.
Samva authenticates email API requests with an API key sent in the X-API-Key header. This page documents key format, request authentication, rate limiting, and authentication errors. For the model behind keys, how one binds to an organization and scopes every request, see Organizations and tenancy.
API key format
Production keys start with samva_sk_live_; keys minted outside production start with
samva_sk_test_. Each key authenticates requests for the organization it belongs to.
Using API keys
Include the key in the X-API-Key header on every request.
The SDK reads the key from the apiKey option and sets the header for you.
import { createClient } from "samva";
const samva = createClient({ apiKey: process.env.SAMVA_API_KEY! });Store keys in environment variables, never in source. The full key value is shown only once at creation time.
Key handling
| Practice | Detail |
|---|---|
| Use environment variables | Read the key from the environment; never hardcode it in source. |
| Scope permissions | Set the minimum permissions required when creating a key. |
| Rotate keys | Replace keys periodically and after any suspected exposure. |
| Monitor usage | Track per-key usage in the Samva Dashboard. |
Permissions
Every endpoint declares one resource:action permission, and a key is refused when its grants do
not cover it. The required permission is published on each operation in the OpenAPI document as
x-samva-scope, so you can read it per endpoint in the API reference.
| Resource | Actions | Covers |
|---|---|---|
messages | create, read, update, delete | Sends, scheduled sends, campaigns, drafts, media |
email | send, read | Blocks, tracking policy, statistics, delivery logs |
domains | create, read, update, delete | Sending domains, senders, branded tracking, catch-all, forwarding rules |
contacts | create, read, update, delete | Contacts, groups, custom fields, unsubscribe groups |
conversations | create, read, update, delete | Conversations and their participants |
templates | create, read, update, delete | Templates, families, presets, fonts, design settings |
webhooks | create, read, update, delete | Endpoints, deliveries, secrets |
apiKeys | create, read, update, delete, rotate | Keys and their usage records |
organization | read, update, delete | Workspace record, settings, usage |
analytics | read | Aggregate messaging statistics and exports |
billing | read, update | Overage settings |
member | invite, remove, update | Team membership |
Sending and provisioning are deliberately separate. email is traffic: it sends mail and reads
what happened to it. What the mail is sent from is domains, with its own lifecycle: your sending
domains and senders, their DNS and branded tracking, catch-all, and forwarding. A key scoped to send
cannot delete the domain it sends from, so a compromised send key cannot take your sending identity
with it.
The action follows the method unless the endpoint says otherwise: GET reads, POST creates,
PATCH and PUT update, DELETE deletes. A resource that has no such action uses its nearest
one, so an email mutation such as adding a block requires email:send. Endpoints that read
through a POST body, such as POST /v1/contacts/find, require the read action instead. An
endpoint whose method overstates it says so: POST /v1/email/domains/{id}/default requires
domains:update, not domains:create, because it changes a domain rather than adding one.
A few endpoints require more than one permission, published space-separated. POST /v1/contacts/bulk-import requires contacts:create contacts:update, because upsertByEmail
overwrites contacts that already exist.
Key lifecycle
Keys are created and managed under Developers → API Keys in the Samva Dashboard. Each key carries a set of permissions and an optional expiry, both set at creation. The full key value is returned only at creation time and is not retrievable afterward; a lost key must be replaced. Keys can be revoked at any time, and a revoked key stops authenticating immediately.
Rate limiting
Send throughput is limited per organization at a rate set by your plan. Every API key draws from that same allowance, first-come, so adding keys does not add throughput and a key sending continuously at the limit will throttle your other keys while it does. Each key carries its own burst cap, at half the organization's burst, so no single key can absorb your entire burst in one spike.
Requests authenticated with a session or an OAuth token draw on the organization limit only.
When a limit is exceeded, the request returns 429 Too Many Requests with a RateLimitedError
body and a Retry-After header:
{
"_tag": "RateLimitedError",
"retryAfterSeconds": 1
}Back off for at least retryAfterSeconds seconds before sending the request again. For the
per-plan rates, the burst allowance, and the response headers, see
Rate limiting in the REST API reference.
Authentication errors
Errors are returned as tagged JSON bodies. Each body carries a _tag identifying the error and a message describing it.
| Status | _tag | Description | Resolution |
|---|---|---|---|
401 | UnauthorizedError | Invalid or missing API key | Check the X-API-Key header value |
403 | ForbiddenError | Insufficient permissions | Use a key with the required scope |
Invalid or missing API key
Returned when the API key cannot be validated.
{
"_tag": "UnauthorizedError",
"message": "Invalid API key"
}Insufficient permissions
Returned when the key is valid but its grants do not cover the endpoint's permission. The message names the exact resource:action the request needed.
{
"_tag": "ForbiddenError",
"message": "Caller requires contacts:create permission"
}These are the authentication-specific errors. For the full list the API can return, with each error's fields and how to resolve it, see the Error reference.
Related
Organizations and tenancy
How keys map to organizations and how requests are scoped.
API keys and OAuth sessions
When to use a durable key versus an OAuth login session.
TypeScript SDK
Client setup and service methods.
REST API
Endpoints, request bodies, and responses.
Error reference
Every error the API can return, with resolutions.