Truncus Email
Truncus is a transactional email API for delivering alerts, reports, receipts, and notifications. EU-native infrastructure (AWS SES eu-west-1), deterministic delivery with idempotency enforcement and full event tracing.
When to Use
Use this skill when a workflow needs to send email: system alerts, generated reports, order receipts, password resets, onboarding sequences, monitoring notifications, or any programmatic email delivery.
Authentication
Truncus uses Bearer token authentication. The API key is read from the TRUNCUS_API_KEY environment variable.
Header format:
CODEBLOCK0
API keys use the prefix tr_live_ followed by 64 hex characters. If the key is missing, malformed, or revoked, the API returns HTTP 401 with an error code (MISSING_API_KEY, INVALID_API_KEY, or API_KEY_REVOKED).
Send Endpoint
CODEBLOCK1
Required Headers
| Header | Value | Required |
|---|
| INLINECODE5 | INLINECODE6 | Yes |
| INLINECODE7 |
Unique string per send attempt | Yes |
|
Content-Type |
application/json | Yes |
The Idempotency-Key header is mandatory. Requests without it receive HTTP 400 with code MISSING_IDEMPOTENCY_KEY. If a duplicate key is submitted, the API returns the original message without re-sending (status duplicate).
Required Body Fields
| Field | Type | Description |
|---|
| INLINECODE13 | string | Recipient email address (single address) |
| INLINECODE14 |
string | Sender address (must be a verified domain) |
|
subject | string | Email subject line (non-empty) |
At least one of html, react, or template_id must be provided for the email body.
| Field | Type | Description |
|---|
| INLINECODE19 | string | HTML body (max 256KB) |
| INLINECODE20 |
string | React Email JSX template (max 64KB) |
|
template_id | string | Server-side template ID |
Optional Body Fields
| Field | Type | Description |
|---|
| INLINECODE22 | string | Plain text fallback (max 128KB) |
| INLINECODE23 |
string[] | CC recipients |
|
bcc | string[] | BCC recipients |
|
variables | object | Template variable substitution (handlebars-style) |
|
metadata | object | Arbitrary key-value metadata stored with the email |
|
tenant_id | string | Multi-tenant isolation identifier |
|
attachments | Attachment[] | Up to 10 attachments, total max 10MB |
|
send_at | string (ISO 8601) | Schedule send for a future datetime (must be future) |
|
track_opens | boolean | Enable open tracking pixel (default:
true) |
|
track_clicks | boolean | Enable click tracking rewrites (default:
true) |
Attachment object:
CODEBLOCK2
Request Example
CODEBLOCK3
Response Handling
Success (HTTP 200)
CODEBLOCK4
Scheduled (HTTP 200)
When send_at is provided:
CODEBLOCK5
Duplicate (HTTP 200)
When the same Idempotency-Key is reused:
CODEBLOCK6
Queued with Retry (HTTP 200)
On transient provider errors:
CODEBLOCK7
Validation Error (HTTP 400)
CODEBLOCK8
Domain Error (HTTP 400)
CODEBLOCK9
Suppressed (HTTP 200)
All recipients on suppression list:
CODEBLOCK10
Provider Failure (HTTP 502)
CODEBLOCK11
Authentication Error (HTTP 401)
CODEBLOCK12
Scope Error (HTTP 403)
CODEBLOCK13
Rate Limiting
Truncus enforces three layers of rate limiting:
- 1. Burst limit: 10 requests/second, 60 requests/minute per API key
- Monthly plan cap: Free = 3,000, Pro = 25,000, Scale = 250,000 emails/month
- Domain daily cap: per-domain warmup limits
When rate limited, the API returns HTTP 429 with these headers:
| Header | Description |
|---|
| INLINECODE36 | Maximum requests per minute (60) |
| INLINECODE37 |
Requests remaining in current window |
|
X-RateLimit-Reset | Unix timestamp when window resets |
|
Retry-After | Seconds to wait before retrying |
Monthly usage headers are included on every successful response:
| Header | Description |
|---|
| INLINECODE40 | Monthly email quota |
| INLINECODE41 |
Emails sent this billing month |
|
X-Monthly-Remaining| Emails remaining this month |
On rate limit (429), wait for the number of seconds in Retry-After before retrying.
Get Email Details
CODEBLOCK14
Requires the read_events scope. Returns the email with its full event timeline:
CODEBLOCK15
Cancel Scheduled Email
CODEBLOCK16
Requires the send scope. Only emails with status scheduled can be cancelled. Returns HTTP 409 if the email is in any other state.
CODEBLOCK17
Sandbox Mode
Set the X-Truncus-Sandbox: true header to validate the request and persist the email without actually sending via SES. Useful for testing integrations. Sandbox emails receive a sandbox- prefixed provider message ID.
CODEBLOCK18
Response includes "sandbox": true.
Local Dev Mode
If TRUNCUS_API_KEY is not set in the environment, do not attempt to call the API. Instead:
- 1. Print the full request payload that would be sent (to, from, subject, body preview).
- Log: INLINECODE51
- Return a simulated success with
message_id: "local-simulated". - Direct the user to https://truncus.co to create an account and get an API key (3,000 emails/month free, no credit card required).
Safety Rules
- 1. Never send email unless the user explicitly asks. Do not send as a side effect of another action.
- Confirm recipients before sending. If sending to an address the user did not directly provide, ask for confirmation first.
- Always use a unique Idempotency-Key. Generate a UUID for each send attempt. Never reuse keys across different emails.
- Never fabricate a success response. If the API call fails or is simulated, report it honestly.
- Do not send to large recipient lists. Truncus accepts a single
to address per request. For bulk sends, confirm the intent and send individual requests. - Respect suppression. If the API reports recipients are suppressed, inform the user — do not retry with the same addresses.
- Handle rate limits gracefully. On 429, wait for the
Retry-After duration, then retry once. Report the limit to the user if it persists.
Truncus Email
Truncus 是一款事务性邮件 API,用于发送警报、报告、收据和通知。基于欧盟原生基础设施(AWS SES eu-west-1),通过幂等性强制执行和完整事件追踪实现确定性投递。
使用场景
当工作流需要发送邮件时使用此技能:系统警报、生成的报告、订单收据、密码重置、入职流程、监控通知或任何程序化邮件投递。
身份认证
Truncus 使用 Bearer 令牌认证。API 密钥从 TRUNCUSAPIKEY 环境变量中读取。
请求头格式:
Authorization: Bearer APIKEY>
API 密钥使用前缀 trlive 后跟 64 个十六进制字符。如果密钥缺失、格式错误或已被吊销,API 将返回 HTTP 401 状态码及错误代码(MISSINGAPIKEY、INVALIDAPIKEY 或 APIKEYREVOKED)。
发送端点
POST https://truncus.co/api/v1/emails/send
必需请求头
| 请求头 | 值 | 必需 |
|---|
| Authorization | Bearer <TRUNCUSAPIKEY> | 是 |
| Idempotency-Key |
每次发送尝试的唯一字符串 | 是 |
| Content-Type | application/json | 是 |
Idempotency-Key 请求头是强制性的。没有该请求头的请求将收到 HTTP 400 状态码及代码 MISSINGIDEMPOTENCYKEY。如果提交了重复的密钥,API 将返回原始消息而不重新发送(状态为 duplicate)。
必需请求体字段
| 字段 | 类型 | 描述 |
|---|
| to | string | 收件人邮箱地址(单个地址) |
| from |
string | 发件人地址(必须是已验证的域名) |
| subject | string | 邮件主题行(非空) |
必须提供 html、react 或 template_id 中的至少一个作为邮件正文。
| 字段 | 类型 | 描述 |
|---|
| html | string | HTML 正文(最大 256KB) |
| react |
string | React Email JSX 模板(最大 64KB)|
| template_id | string | 服务端模板 ID |
可选请求体字段
| 字段 | 类型 | 描述 |
|---|
| text | string | 纯文本备选(最大 128KB) |
| cc |
string[] | 抄送收件人 |
| bcc | string[] | 密送收件人 |
| variables | object | 模板变量替换(Handlebars 风格) |
| metadata | object | 与邮件一起存储的任意键值元数据 |
| tenant_id | string | 多租户隔离标识符 |
| attachments | Attachment[] | 最多 10 个附件,总大小最大 10MB |
| send_at | string (ISO 8601) | 计划在未来时间发送(必须是未来时间) |
| track_opens | boolean | 启用打开追踪像素(默认:true) |
| track_clicks| boolean | 启用点击追踪重写(默认:true) |
附件对象:
json
{
filename: report.pdf,
content: ,
content_type: application/pdf
}
请求示例
bash
curl -X POST https://truncus.co/api/v1/emails/send \
-H Authorization: Bearer $TRUNCUSAPIKEY \
-H Idempotency-Key: $(uuidgen) \
-H Content-Type: application/json \
-d {
to: recipient@example.com,
from: notifications@yourapp.com,
subject: 您的周报已就绪,
html:
周报
所有系统运行正常。
,
text: 周报\n\n所有系统运行正常。,
metadata: { report
type: weekly, userid: usr_123 }
}
响应处理
成功(HTTP 200)
json
{
status: sent,
message_id: cuid-字符串,
providermessageid: ses-消息ID,
warnings: []
}
已计划(HTTP 200)
当提供了 send_at 时:
json
{
status: scheduled,
message_id: cuid-字符串,
send_at: 2026-03-15T10:00:00.000Z
}
重复(HTTP 200)
当重复使用相同的 Idempotency-Key 时:
json
{
status: duplicate,
message_id: cuid-字符串,
email_status: sent,
created_at: 2026-03-11T14:30:00.000Z
}
已排队并重试(HTTP 200)
当出现临时提供商错误时:
json
{
status: queued,
message_id: cuid-字符串,
retry_scheduled: true,
retry_at: 2026-03-11T14:30:30.000Z
}
验证错误(HTTP 400)
json
{
error: to: 无效的邮箱地址,
code: INVALID_REQUEST
}
域名错误(HTTP 400)
json
{
status: blocked,
reason: 发送域名未找到或未为此项目配置,
code: DOMAINNOTFOUND
}
已屏蔽(HTTP 200)
所有收件人都在屏蔽列表中:
json
{
status: blocked,
reason: 所有收件人均已被屏蔽,
code: ALLRECIPIENTSSUPPRESSED,
message_id: cuid-字符串,
suppressed_addresses: [bounced@example.com]
}
提供商故障(HTTP 502)
json
{
status: failed,
message_id: cuid-字符串,
error: SES 错误消息,
code: PROVIDER_ERROR
}
认证错误(HTTP 401)
json
{
error: 缺少 Authorization 请求头,
code: MISSINGAPIKEY
}
权限错误(HTTP 403)
json
{
error: 缺少必需的作用域:send,
code: SCOPE_REQUIRED
}
速率限制
Truncus 实施三层速率限制:
- 1. 突发限制:每个 API 密钥每秒 10 个请求,每分钟 60 个请求
- 月度计划上限:免费版 = 3,000,专业版 = 25,000,扩展版 = 250,000 封邮件/月
- 域名每日上限:按域名的预热限制
当触发速率限制时,API 返回 HTTP 429 状态码及以下请求头:
| 请求头 | 描述 |
|---|
| X-RateLimit-Limit | 每分钟最大请求数(60) |
| X-RateLimit-Remaining |
当前窗口剩余请求数 |
| X-RateLimit-Reset | 窗口重置的 Unix 时间戳 |
| Retry-After | 重试前需等待的秒数 |
每次成功响应都会包含月度使用量请求头:
| 请求头 | 描述 |
|---|
| X-Monthly-Limit | 月度邮件配额 |
| X-Monthly-Sent |
本账单月已发送邮件数 |
| X-Monthly-Remaining | 本月剩余邮件数 |
遇到速率限制(429)时,请等待 Retry-After 中指定的秒数后再重试。
获取邮件详情
GET https://truncus.co/api/v1/emails/{id}
需要 read_events 作用域。返回邮件及其完整事件时间线:
json
{
id: cuid-字符串,
to: recipient