Primitive
Send through Primitive's email API for AI agents, with base64 attachments, idempotent retries, and fail-fast validation for fields it cannot represent.
Capabilities
| Repeated headers | Idempotency | Scheduling | Personalized |
|---|---|---|---|
| No | native | No | expanded |
These values come from the adapter's exported capabilities declaration. The field support matrix covers normalized message fields.
The Primitive adapter calls Primitive's POST /v1/send-mail endpoint with plain fetch. Primitive is email infrastructure for AI agents: a REST API for sending and receiving mail, with idempotency, typed errors, and an async delivery model. The adapter maps the normalized EmailMessage straight onto its send payload.
Configure
Create a Primitive API key (prefixed prim_) and verify the outbound domain you send from.
import { createEmailClient } from "@opencoredev/email-sdk";
import { primitive } from "@opencoredev/email-sdk/primitive";
export const email = createEmailClient({
adapters: [primitive({ apiKey: process.env.PRIMITIVE_API_KEY! })],
});Prop
Type
Send
Primitive's send API targets a single recipient and accepts html, text, and attachments. Attachments are base64-encoded automatically.
const result = await email.send({
from: "Acme <hello@acme.com>",
to: "user@example.com",
subject: "Welcome to Acme",
html: "<p>Thanks for joining Acme.</p>",
text: "Thanks for joining Acme.",
});
console.log(result.id); // Primitive sent-email idOne recipient, no CC or BCC
Primitive's send-mail accepts exactly one recipient and has no CC or BCC field. The adapter
fails fast with an EmailValidationError when a message carries more than one recipient, cc, or
bcc, so route fan-out to multiple people as separate sends.
No custom headers, tags, or metadata
Primitive's send API has no custom-header, tags, or metadata field, so the adapter rejects
headers, tags, and metadata with an EmailValidationError before the request. Check field
support before using Primitive in a fallback route.
From a verified outbound domain
The sender domain in from must be a verified outbound domain for your Primitive organization,
and recipient eligibility depends on your account's outbound entitlements.
Idempotent sends
Pass an idempotencyKey and the adapter forwards it as Primitive's Idempotency-Key header, so a retried send with the same key and body replays the original result instead of sending twice.
await email.send(message, { idempotencyKey: "receipt:order_123" });Verify from the CLI
PRIMITIVE_API_KEY="prim_..." npx --package @opencoredev/email-sdk email-sdk doctor --adapter primitivePRIMITIVE_API_KEY="prim_..." npx --package @opencoredev/email-sdk email-sdk send \
--adapter primitive \
--from "Acme <hello@acme.com>" \
--to user@example.com \
--subject "Primitive smoke test" \
--text "It works" \
--dry-runDrop --dry-run to send for real. The single-recipient rule is checked locally, so the live send is really testing your prim_ key and outbound domain. Check accepted and rejected in the response: Primitive queues delivery asynchronously, and those arrays tell you what it actually took.
Frequently asked questions
Does Email SDK support Primitive?
Yes. Email SDK ships a Primitive adapter imported from @opencoredev/email-sdk/primitive. You keep your Primitive account and credentials; the SDK adds message validation, typed errors, and no-network test adapters around the same send() call used for every other provider.
Which message fields does the Primitive adapter support?
Primitive supports Attachments. It does not support CC recipients, BCC recipients, Reply-To address, Custom headers, Tags, Metadata, and Scheduled sending (sendAt); Email SDK rejects a message that uses those fields before any request is made.
Can Primitive schedule email for later with Email SDK?
No. Primitive has no provider-side scheduling, so a message with sendAt fails validation. Store the job in your own queue and send when it is due.
Does the Primitive adapter support idempotent sends?
Yes. The Primitive adapter passes an idempotency key to the provider, so Primitive deduplicates repeated sends on its side.
JetEmail
Send through the JetEmail transactional API with CC, BCC, reply-to, custom headers, base64 attachments, and idempotent retries.
Lettermint
Send through Lettermint's European transactional email API with CC, BCC, reply-to, headers, metadata, tags, base64 attachments, idempotent retries, and routes.