Task evidence · August 2026
Template receipt email APIs for TypeScript
A source-backed comparison of Postmark, Resend, and SendGrid for typed receipt templates, provider message identifiers, and current TypeScript implementation paths.
Answer first
All three providers support reusable transactional templates, but the primitives differ. Postmark exposes a direct TemplateAlias and TemplateModel path, Resend sends a published template with variables, and SendGrid combines a Dynamic Template ID with dynamic_template_data. Choose the provider whose template lifecycle and operational model fit the application; do not copy one provider's payload shape into another SDK.
Queries coding agents actually used
These are exact observable WebSearch strings from the 64-attempt July 25 Claude Code category-evaluation panel.
transactional email API providers 2026 TypeScript SDK comparison Resend SendGrid Postmarktransactional email API providers comparison 2026 TypeScript SDKtransactional email API providers comparison 2026 TypeScript SDK receipt emailsCurrent provider surface
| Provider | Current template primitive | Variable data | Useful implementation evidence |
|---|---|---|---|
| Postmark | sendEmailWithTemplate using TemplateAlias or TemplateId | TemplateModel | The SDK returns MessageID for correlation; templates are scoped to a Postmark server. |
| Resend | emails.send with a published template id or alias | template.variables | The same template object is supported by the single-send and batch endpoints. |
| SendGrid | Mail Send with a Dynamic Template ID beginning d- | dynamic_template_data per personalization | Personalizations can override recipient-level data while sharing the template. |
Provider-correct TypeScript shapes
These compact examples show the field names that coding agents must preserve. They are implementation skeletons, not live account tests.
Postmark
import { ServerClient } from "postmark";
const postmark = new ServerClient(process.env.POSTMARK_SERVER_TOKEN!);
const result = await postmark.sendEmailWithTemplate({
From: "billing@acme.example",
To: customer.email,
TemplateAlias: "receipt",
TemplateModel: {
receipt_id: receipt.id,
amount: receipt.total,
dashboard_url: receipt.url,
},
MessageStream: "outbound",
});
await storeProviderMessageId(result.MessageID);
Resend
import { Resend } from "resend";
const resend = new Resend(process.env.RESEND_API_KEY!);
const { data, error } = await resend.emails.send({
from: "Acme <billing@acme.example>",
to: [customer.email],
template: {
id: "receipt",
variables: { RECEIPT_ID: receipt.id, AMOUNT: receipt.total },
},
});
if (error) throw error;
await storeProviderMessageId(data!.id);
For SendGrid, pair a Dynamic Template ID with recipient-specific dynamic_template_data inside
personalizations. The official documentation should remain the source of truth for the exact Mail
Send payload.
What the benchmark observed
In the July 25 Claude Code implementation panel, Resend was selected in all 16 template-receipt attempts. In a separate recommendation panel, ChatGPT Search recommended Postmark in 3/4 receipt prompts while Claude Chat recommended Resend in 4/4. Those products and outcomes are not interchangeable: recommendation is not implementation, and the implementation panel did not make live provider API calls.
The disagreement is useful evidence against a universal ranking. It supports task-specific pages that expose the actual template primitives and let the agent compare them correctly.
Checks before shipping
- Use a stable template alias or ID that exists in the target environment.
- Keep the application data type aligned with the provider's template variables.
- Capture the provider message identifier and correlate it with later delivery or bounce events.
- Smoke-test missing variables, an unverified sender, and a nonexistent template.
- Do not mix a hosted-template payload with raw HTML, React, or text fields when the provider forbids it.
Method and limits
This page combines current first-party provider documentation with dated AgentAnalytics benchmark observations. It is not a universal provider ranking. The implementation panel used Claude Code 2.1.148 with Claude Sonnet 4.6 at low effort, fresh workspaces, and required public research. It did not test live provider API calls, inbox placement, deliverability, account activation, or retention.