agentmail
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAgentMail — Email for AI Agents
AgentMail — 专为AI Agent打造的电子邮件服务
AgentMail gives AI agents real email addresses () with a REST API. Agents can send and receive email, sign up for services (GitHub, AWS, Slack, etc.), and get verification codes. A karma system prevents spam and keeps the shared domain's reputation high.
@theagentmail.netBase URL:
https://api.theagentmail.netAgentMail为AI Agent提供后缀为的真实邮箱地址,配套REST API。Agent可以收发邮件、注册各类服务(GitHub、AWS、Slack等)、接收验证码。内置的karma系统可防止垃圾邮件,维持共享域名的高信誉。
@theagentmail.netBase URL:
https://api.theagentmail.netQuick start
快速开始
All requests require header (API key from dashboard).
Authorization: Bearer am_...所有请求都需要携带请求头(API密钥可在控制台获取)。
Authorization: Bearer am_...Create an email account (-10 karma)
创建邮箱账号(扣除10 karma)
bash
curl -X POST https://api.theagentmail.net/v1/accounts \
-H "Authorization: Bearer am_..." \
-H "Content-Type: application/json" \
-d '{"address": "my-agent@theagentmail.net"}'Response:
{"data": {"id": "...", "address": "my-agent@theagentmail.net", "displayName": null, "createdAt": 123}}bash
curl -X POST https://api.theagentmail.net/v1/accounts \
-H "Authorization: Bearer am_..." \
-H "Content-Type: application/json" \
-d '{"address": "my-agent@theagentmail.net"}'返回结果:
{"data": {"id": "...", "address": "my-agent@theagentmail.net", "displayName": null, "createdAt": 123}}Send email (-1 karma)
发送邮件(扣除1 karma)
bash
curl -X POST https://api.theagentmail.net/v1/accounts/{accountId}/messages \
-H "Authorization: Bearer am_..." \
-H "Content-Type: application/json" \
-d '{
"to": ["recipient@example.com"],
"subject": "Hello from my agent",
"text": "Plain text body",
"html": "<p>Optional HTML body</p>"
}'Optional fields: , (string arrays), , (strings for threading), (array of where content is base64).
ccbccinReplyToreferencesattachments{filename, contentType, content}bash
curl -X POST https://api.theagentmail.net/v1/accounts/{accountId}/messages \
-H "Authorization: Bearer am_..." \
-H "Content-Type: application/json" \
-d '{
"to": ["recipient@example.com"],
"subject": "Hello from my agent",
"text": "Plain text body",
"html": "<p>Optional HTML body</p>"
}'可选字段:、(字符串数组)、、(用于邮件线程的字符串)、(对象数组,其中content为base64格式)。
ccbccinReplyToreferencesattachments{filename, contentType, content}Read inbox
读取收件箱
bash
undefinedbash
undefinedList messages
列出邮件
curl https://api.theagentmail.net/v1/accounts/{accountId}/messages
-H "Authorization: Bearer am_..."
-H "Authorization: Bearer am_..."
curl https://api.theagentmail.net/v1/accounts/{accountId}/messages
-H "Authorization: Bearer am_..."
-H "Authorization: Bearer am_..."
Get full message (with body and attachments)
获取完整邮件内容(包含正文和附件)
curl https://api.theagentmail.net/v1/accounts/{accountId}/messages/{messageId}
-H "Authorization: Bearer am_..."
-H "Authorization: Bearer am_..."
undefinedcurl https://api.theagentmail.net/v1/accounts/{accountId}/messages/{messageId}
-H "Authorization: Bearer am_..."
-H "Authorization: Bearer am_..."
undefinedCheck karma
查询karma余额
bash
curl https://api.theagentmail.net/v1/karma \
-H "Authorization: Bearer am_..."Response:
{"data": {"balance": 90, "events": [...]}}bash
curl https://api.theagentmail.net/v1/karma \
-H "Authorization: Bearer am_..."返回结果:
{"data": {"balance": 90, "events": [...]}}Register webhook (real-time inbound)
注册webhook(实时接收入站邮件)
bash
curl -X POST https://api.theagentmail.net/v1/accounts/{accountId}/webhooks \
-H "Authorization: Bearer am_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://my-agent.example.com/inbox"}'Webhook deliveries include two security headers:
- -- HMAC-SHA256 hex digest of the request body, signed with the webhook secret
X-AgentMail-Signature - -- millisecond timestamp of when the delivery was sent
X-AgentMail-Timestamp
Verify the signature and reject requests with timestamps older than 5 minutes to prevent replay attacks:
typescript
import { createHmac } from "crypto";
const verifyWebhook = (body: string, signature: string, timestamp: string, secret: string) => {
if (Date.now() - Number(timestamp) > 5 * 60 * 1000) return false;
return createHmac("sha256", secret).update(body).digest("hex") === signature;
};bash
curl -X POST https://api.theagentmail.net/v1/accounts/{accountId}/webhooks \
-H "Authorization: Bearer am_..." \
-H "Content-Type: application/json" \
-d '{"url": "https://my-agent.example.com/inbox"}'Webhook推送包含两个安全头:
- -- 请求体的HMAC-SHA256十六进制摘要,使用webhook密钥签名
X-AgentMail-Signature - -- 推送发送时的毫秒级时间戳
X-AgentMail-Timestamp
你需要验证签名,并且拒绝时间戳早于5分钟的请求,以防止重放攻击:
typescript
import { createHmac } from "crypto";
const verifyWebhook = (body: string, signature: string, timestamp: string, secret: string) => {
if (Date.now() - Number(timestamp) > 5 * 60 * 1000) return false;
return createHmac("sha256", secret).update(body).digest("hex") === signature;
};Download attachment
下载附件
bash
curl https://api.theagentmail.net/v1/accounts/{accountId}/messages/{messageId}/attachments/{attachmentId} \
-H "Authorization: Bearer am_..."Returns .
{"data": {"url": "https://signed-download-url..."}}bash
curl https://api.theagentmail.net/v1/accounts/{accountId}/messages/{messageId}/attachments/{attachmentId} \
-H "Authorization: Bearer am_..."返回结果: 。
{"data": {"url": "https://signed-download-url..."}}Full API reference
完整API参考
| Method | Path | Description | Karma |
|---|---|---|---|
| POST | | Create email account | -10 |
| GET | | List all accounts | |
| GET | | Get account details | |
| DELETE | | Delete account | +10 |
| POST | | Send email | -1 |
| GET | | List messages | |
| GET | | Get full message | |
| GET | | Get attachment URL | |
| POST | | Register webhook | |
| GET | | List webhooks | |
| DELETE | | Delete webhook | |
| GET | | Get balance + events |
| 方法 | 路径 | 描述 | Karma消耗/奖励 |
|---|---|---|---|
| POST | | 创建邮箱账号 | -10 |
| GET | | 列出所有账号 | 无 |
| GET | | 获取账号详情 | 无 |
| DELETE | | 删除账号 | +10 |
| POST | | 发送邮件 | -1 |
| GET | | 列出邮件 | 无 |
| GET | | 获取完整邮件 | 无 |
| GET | | 获取附件链接 | 无 |
| POST | | 注册webhook | 无 |
| GET | | 列出webhook | 无 |
| DELETE | | 删除webhook | 无 |
| GET | | 获取余额和变更记录 | 无 |
Karma system
Karma系统
Every action has a karma cost or reward:
| Event | Karma | Why |
|---|---|---|
| +100 | Purchase credits |
| +2 | Someone replied from a trusted domain |
| +10 | Karma refunded when you delete an address |
| -1 | Sending costs karma |
| -10 | Creating addresses costs karma |
Important rules:
- Karma is only awarded for inbound emails from trusted providers (Gmail, Outlook, Yahoo, iCloud, ProtonMail, Fastmail, Hey, etc.). Emails from unknown/throwaway domains don't earn karma.
- You only earn karma once per sender until the agent replies. If sender X emails you 5 times without a reply, only the first earns karma. Reply to X, and the next email from X earns karma again.
- Deleting an account refunds the 10 karma it cost to create.
When karma reaches 0, sends and account creation return HTTP 402. Always check balance before operations that cost karma.
每个操作都有对应的karma消耗或奖励:
| 事件 | Karma变动 | 说明 |
|---|---|---|
| +100 | 购买额度 |
| +2 | 收到可信域名的回复邮件 |
| +10 | 删除地址时返还karma |
| -1 | 发送邮件消耗karma |
| -10 | 创建地址消耗karma |
重要规则:
- 仅收到可信服务商(Gmail、Outlook、Yahoo、iCloud、ProtonMail、Fastmail、Hey等)的入站邮件可获得karma,来自未知/临时域名的邮件无法获得karma。
- 同一个发件人在Agent回复前仅可贡献一次karma:如果发件人X给你发了5封邮件且你没有回复,仅第一封可获得karma;回复X后,X的下一封邮件可再次获得karma。
- 删除账号会返还创建时消耗的10 karma。
当karma归零时,发送邮件和创建账号的请求会返回HTTP 402。请在执行消耗karma的操作前先查询余额。
TypeScript SDK
TypeScript SDK
typescript
import { createClient } from "@agentmail/sdk";
const mail = createClient({ apiKey: "am_..." });
// Create account
const account = await mail.accounts.create({
address: "my-agent@theagentmail.net",
});
// Send email
await mail.messages.send(account.id, {
to: ["human@example.com"],
subject: "Hello",
text: "Sent by an AI agent.",
});
// Read inbox
const messages = await mail.messages.list(account.id);
const detail = await mail.messages.get(account.id, messages[0].id);
// Attachments
const att = await mail.attachments.getUrl(accountId, messageId, attachmentId);
// att.url is a signed download URL
// Webhooks
await mail.webhooks.create(account.id, {
url: "https://my-agent.example.com/inbox",
});
// Karma
const karma = await mail.karma.getBalance();
console.log(karma.balance);typescript
import { createClient } from "@agentmail/sdk";
const mail = createClient({ apiKey: "am_..." });
// 创建账号
const account = await mail.accounts.create({
address: "my-agent@theagentmail.net",
});
// 发送邮件
await mail.messages.send(account.id, {
to: ["human@example.com"],
subject: "Hello",
text: "Sent by an AI agent.",
});
// 读取收件箱
const messages = await mail.messages.list(account.id);
const detail = await mail.messages.get(account.id, messages[0].id);
// 附件
const att = await mail.attachments.getUrl(accountId, messageId, attachmentId);
// att.url 是签名后的下载链接
// Webhooks
await mail.webhooks.create(account.id, {
url: "https://my-agent.example.com/inbox",
});
// Karma
const karma = await mail.karma.getBalance();
console.log(karma.balance);Error handling
错误处理
typescript
import { AgentMailError } from "@agentmail/sdk";
try {
await mail.messages.send(accountId, { to: ["a@b.com"], subject: "Hi", text: "Hey" });
} catch (e) {
if (e instanceof AgentMailError) {
console.log(e.status); // 402, 404, 401, etc.
console.log(e.code); // "INSUFFICIENT_KARMA", "NOT_FOUND", etc.
console.log(e.message);
}
}typescript
import { AgentMailError } from "@agentmail/sdk";
try {
await mail.messages.send(accountId, { to: ["a@b.com"], subject: "Hi", text: "Hey" });
} catch (e) {
if (e instanceof AgentMailError) {
console.log(e.status); // 402, 404, 401, 等
console.log(e.code); // "INSUFFICIENT_KARMA", "NOT_FOUND", 等
console.log(e.message);
}
}Common patterns
常见使用场景
Sign up for a service and read verification email
注册服务并读取验证邮件
typescript
const account = await mail.accounts.create({
address: "signup-bot@theagentmail.net",
});
// Use the address to sign up (browser automation, API, etc.)
// Poll for verification email
for (let i = 0; i < 30; i++) {
const messages = await mail.messages.list(account.id);
const verification = messages.find(m =>
m.subject.toLowerCase().includes("verify") ||
m.subject.toLowerCase().includes("confirm")
);
if (verification) {
const detail = await mail.messages.get(account.id, verification.id);
// Parse verification link/code from detail.bodyText or detail.bodyHtml
break;
}
await new Promise(r => setTimeout(r, 2000));
}typescript
const account = await mail.accounts.create({
address: "signup-bot@theagentmail.net",
});
// 使用该地址注册服务(浏览器自动化、API等)
// 轮询获取验证邮件
for (let i = 0; i < 30; i++) {
const messages = await mail.messages.list(account.id);
const verification = messages.find(m =>
m.subject.toLowerCase().includes("verify") ||
m.subject.toLowerCase().includes("confirm")
);
if (verification) {
const detail = await mail.messages.get(account.id, verification.id);
// 从detail.bodyText或detail.bodyHtml中解析验证链接/验证码
break;
}
await new Promise(r => setTimeout(r, 2000));
}Send email and wait for reply
发送邮件并等待回复
typescript
const sent = await mail.messages.send(account.id, {
to: ["human@company.com"],
subject: "Question about order #12345",
text: "Can you check the status?",
});
for (let i = 0; i < 60; i++) {
const messages = await mail.messages.list(account.id);
const reply = messages.find(m =>
m.direction === "inbound" && m.timestamp > sent.timestamp
);
if (reply) {
const detail = await mail.messages.get(account.id, reply.id);
// Process reply
break;
}
await new Promise(r => setTimeout(r, 5000));
}typescript
const sent = await mail.messages.send(account.id, {
to: ["human@company.com"],
subject: "Question about order #12345",
text: "Can you check the status?",
});
for (let i = 0; i < 60; i++) {
const messages = await mail.messages.list(account.id);
const reply = messages.find(m =>
m.direction === "inbound" && m.timestamp > sent.timestamp
);
if (reply) {
const detail = await mail.messages.get(account.id, reply.id);
// 处理回复
break;
}
await new Promise(r => setTimeout(r, 5000));
}Types
类型定义
typescript
type Account = { id: string; address: string; displayName: string | null; createdAt: number };
type Message = { id: string; from: string; to: string[]; subject: string; direction: "inbound" | "outbound"; status: string; timestamp: number };
type MessageDetail = Message & { cc: string[] | null; bcc: string[] | null; bodyText: string | null; bodyHtml: string | null; inReplyTo: string | null; references: string | null; attachments: AttachmentMeta[] };
type AttachmentMeta = { id: string; filename: string; contentType: string; size: number };
type KarmaBalance = { balance: number; events: KarmaEvent[] };
type KarmaEvent = { id: string; type: string; amount: number; timestamp: number; metadata?: Record<string, unknown> };typescript
type Account = { id: string; address: string; displayName: string | null; createdAt: number };
type Message = { id: string; from: string; to: string[]; subject: string; direction: "inbound" | "outbound"; status: string; timestamp: number };
type MessageDetail = Message & { cc: string[] | null; bcc: string[] | null; bodyText: string | null; bodyHtml: string | null; inReplyTo: string | null; references: string | null; attachments: AttachmentMeta[] };
type AttachmentMeta = { id: string; filename: string; contentType: string; size: number };
type KarmaBalance = { balance: number; events: KarmaEvent[] };
type KarmaEvent = { id: string; type: string; amount: number; timestamp: number; metadata?: Record<string, unknown> };