API 测试版文档

构建已验证域名的 agent 邮件工作流。

这些测试版文档涵盖所有者邮箱验证、API 认证、agent 技能配置、自定义域名接入、agent 邮箱、发送、入站 webhook、投递事件、速率限制以及投递控制。

开始

快速开始

LoftBox 个人版测试从一个所有者邮箱开始。注册会创建组织并向该邮箱发送一个 6 位验证令牌。只有在完成所有者邮箱验证后,LoftBox 才会返回第一个 API 密钥,且该明文密钥仅显示一次。验证还会向所有者发送一封欢迎邮件,说明测试版限制以及未来的管理员/计费注册路径。

个人版测试账户每日出站发送上限为 100 封。邮箱消息保留期默认为 7 天。企业接入、计费、组织成员管理以及更高限额均为路线图项目。

  • POST /v1/auth/signup创建个人版测试组织并发送所有者邮箱验证令牌。
  • POST /v1/auth/signup/verify验证所有者邮箱,一次性获取初始 API 密钥,并触发所有者欢迎通知。
  • POST /v1/agents创建一个带有所有者、用途和策略范围的 agent 身份。
  • POST /v1/domains为你掌控的域名启动自定义域名接入。
  • POST /v1/agents/{agent_id}/mailboxes创建 LoftBox 托管的测试邮箱或已验证的自定义域名邮箱。
  • POST /v1/messages从 agent 邮箱发送运营邮件。
  • GET /v1/mailboxes/{id}/inbox当 agent 没有 webhook 端点时,轮询未确认的入站消息。
端点

基础 URL 与机器可读文档

规范的公共 API 端点是 https://api.loftbox.net。主页保留了一个 /api/* 代理路径用于预览验证,但生产环境集成应使用专用的 API 主机名。

export BASE_URL="https://api.loftbox.net"
export LOFTBOX_API_KEY="lb_live_replace_me"

在接入集成之前,请先检查边缘节点和 schema:

curl -i "$BASE_URL/health"
curl -i "$BASE_URL/openapi.json"
curl -i "$BASE_URL/llms.txt"

https://loftbox.net/api 路由会剥离 /api 前缀并转发到相同的 Fly API 源站。请将其用于 Pages 预览检查,而非作为主要的集成 URL。

认证

API 认证

首先为个人版测试组织注册所有者邮箱。所有者会通过邮件收到一个验证令牌;验证调用会一次性返回初始 API 密钥并发送所有者欢迎通知。

export LOFTBOX_OWNER_EMAIL="[email protected]"

curl -i -X POST "$BASE_URL/v1/auth/signup" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "'"$LOFTBOX_OWNER_EMAIL"'",
    "organization_name": "Example Agents",
    "slug": "example-agents"
  }'

export LOFTBOX_VERIFICATION_TOKEN="123456"

curl -i -X POST "$BASE_URL/v1/auth/signup/verify" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "'"$LOFTBOX_OWNER_EMAIL"'",
    "verification_token": "'"$LOFTBOX_VERIFICATION_TOKEN"'"
  }'

将返回的服务端 API 密钥与 Authorization 请求头一起使用。切勿在浏览器、移动端客户端、公共日志或分析事件中暴露 API 密钥。

curl -i "$BASE_URL/v1/agents" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY"

请将密钥存储在服务端密钥存储中,例如 Fly secrets、由部署平台管理的环境变量,或专用的密钥管理器。不要将真实密钥粘贴到 issue 评论、截图、分析工具或浏览器代码中。

当操作员离职、密钥可能泄露,或某个环境不再需要 API 访问时,请轮换密钥。

Agent 配置

一行安装与 agent 提示词

Agent 可以安装公共的 LoftBox 邮件技能,然后仅用所有者邮箱即可运行接入流程。注册技能会从当前 agent 派生出组织标签、稳定的 external_id、agent slug 以及邮箱本地部分。注册后,已安装的发送和收件箱检查技能会使用所颁发的 API 密钥和邮箱 ID。

curl -fsSL https://loftbox.net/install.sh | sh
curl -fsSL https://loftbox.net/install.sh | sh -s -- --agent codex
curl -fsSL https://loftbox.net/install.sh | sh -s -- --agent claude
curl -fsSL https://loftbox.net/install.sh | sh -s -- --target "$HOME/.my-agent/skills"
If the LoftBox mail skill is missing, install it with:
curl -fsSL https://loftbox.net/install.sh | sh

Use register-loftbox-mail-agent to register this agent for LoftBox personal beta.
Ask me only for my owner email.
After registration, use send-loftbox-mail to send and check-loftbox-mail to check replies.
curl -fsSL https://loftbox.net/install.sh | sh -s -- --check
curl -fsSL https://loftbox.net/install.sh | sh -s -- --update

请仅将更新检查用作通知路径。安装新的技能包会改变 agent 行为,因此更新应在操作员批准后再执行。

仅在 agent 身份无法派生,或重复的外部 ID 属于另一个 agent 时,才询问其他取值。

域名

自定义域名接入

每个出站域名在邮箱使用前都必须经过验证。API 会返回所有权、入站路由、发件人对齐以及投递验证所需的 DNS 记录。

  1. 使用 POST /v1/domains创建域名。
  2. 使用 GET /v1/domains/{id}/dns获取所需记录。
  3. 在你的 DNS 托管商处添加返回的 TXT、MX、DKIM 和回退路径(return-path)记录。
  4. 在 DNS 传播完成后调用 POST /v1/domains/{id}/verify
  5. 在创建生产邮箱之前,请等待入站和出站状态均已验证。
curl -i "$BASE_URL/v1/domains" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain":"mail.example.com"}'

curl -i "$BASE_URL/v1/domains/domain_uuid/dns" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY"

curl -i -X POST "$BASE_URL/v1/domains/domain_uuid/verify" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY"

或者让 agent 通过统一的 onboard-business-domain 流程端到端驱动整个业务接入(邮箱认证 → 域名接入 → DNS)。将此提示词粘贴到你的 agent:

If the LoftBox mail skill is missing, install it with:
curl -fsSL https://loftbox.net/install.sh | sh

Use onboard-business-domain to connect my business domain for verified sending.
Ask me only for my owner email and the domain to send from.

1. Email auth: register my owner email. LoftBox emails a 6-digit token — ask me
   to paste it, then verify to obtain my organization API key (LoftBox-managed
   sending is available immediately once approved).
2. Domain onboard: run add <domain> (note the returned domain id), then read
   next_actions for the exact DNS records (TXT, DKIM, return-path, inbound MX).
   Show me each record (host, type, value).
3. DNS: let me add the records at my DNS host myself, or auto-apply them with
   apply-dns --provider route53|cloudflare using my own cloud credentials from
   the environment (they stay in my environment; LoftBox never receives them).
4. The domain re-verifies asynchronously on the server after DNS propagates.
   Poll status <domain_id> until inbound and outbound are both verified, then
   report — custom-domain sending activates once verified.
Operate only on my organization. Do not fabricate DNS values; use exactly what the API returns. If onboarding cannot proceed (domain previously deleted, or in use by another org), report it and stop.

官方技能 &amp; 源码

onboard-business-domain setup-loftbox-domain 是官方的 LoftBox 技能。它们发布在公共技能仓库中,并由 https://loftbox.net/install.sh 安装 &mdash; 如果某个 agent 找不到它们,说明其已安装的技能包已过期,重新运行安装程序即可添加它们。

setup-loftbox-domain 技能通过直接运行其脚本来调用(安装程序不会创建 setup-loftbox-domain shell 命令)。 $SKILL_DIR install.sh 放置该技能的位置 &mdash; 例如 ~/.claude/skills/setup-loftbox-domain ~/.codex/skills/setup-loftbox-domain,或在 Hermes 上的 ~/.hermes/skills/email/setup-loftbox-domain。该技能会调用 LoftBox API &mdash; 请严格使用 API 返回的 DNS 值,切勿凭空捏造:

SKILL_DIR=<path to setup-loftbox-domain>   # e.g. ~/.claude/skills/setup-loftbox-domain

python3 "$SKILL_DIR/scripts/setup_loftbox_domain.py" add <domain>
   # onboard the domain (idempotent: resolves an existing active row on 409)
python3 "$SKILL_DIR/scripts/setup_loftbox_domain.py" dns <id>
   # list the exact DNS records to set (TXT, DKIM, return-path, MX)
python3 "$SKILL_DIR/scripts/setup_loftbox_domain.py" status <id>
   # structured status: inbound/outbound flags + next_actions
python3 "$SKILL_DIR/scripts/setup_loftbox_domain.py" verify <id>
   # trigger verification after the DNS records are in place
python3 "$SKILL_DIR/scripts/setup_loftbox_domain.py" apply-dns <id> --provider route53|cloudflare [--dry-run] [--overwrite]
   # auto-apply the next_actions records using cloud credentials from your OWN
   # environment (they never leave it). With no credentials, add the records
   # manually instead — onboarding still completes.

onboard-business-domain 端到端编排 register-loftbox-mail-agent (邮箱认证)和 setup-loftbox-domain (域名接入 + DNS)。6 位邮箱令牌步骤需要人工参与,因此并非完全无人值守。

在启动阶段,个人版测试使用 LoftBox 托管的投递和 LoftBox 托管的入站 MX 处理。自定义域名仅在验证后启用。

邮箱

Agent 与邮箱

Agent 持有业务用途、所有权上下文以及稳定的外部 ID。邮箱将地址和域名关联到该 agent。请保持显示名称、所有者和策略范围足够清晰,以便操作员审查。

  • 每个运营 agent 或工作流角色使用一个邮箱。
  • 使用 external_id 进行重复检查和幂等的 agent 配置。
  • 为生产环境出站邮件使用已验证的自定义域名。
  • 当 agent 用途不明确时,禁用或暂停自主发送。
curl -i "$BASE_URL/v1/agents?external_id=hermes:support-agent" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY"
curl -i "$BASE_URL/v1/agents" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Support Agent",
    "slug": "support-agent",
    "external_id": "hermes:support-agent",
    "description": "Handles controlled support follow-up",
    "purpose": "Reply to support conversations after policy checks",
    "owner_label": "Customer Operations",
    "policy_scope": "agent"
  }'

curl -i "$BASE_URL/v1/agents/agent_uuid/mailboxes" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "local_part": "support-agent",
    "display_name": "Support Agent",
    "retention_days": 7
  }'

对于 LoftBox 托管的个人版测试域名,请省略 domain_id 。如果 agent 拥有 HTTPS 端点,请单独注册一个 agent webhook。

在已验证的自定义域名上,你可以将一个邮箱标记为通配邮箱(catch-all)(创建或更新时设置"is_catch_all": true )。该域名下任何没有精确匹配邮箱的地址都会路由到它——可用于以单个 agent 捕获 support@ sales@或 anything@yourdomain。

出站

发送消息

通过 API 从已验证的邮箱发送运营或事务性消息。LoftBox 会记录投递引用、投递状态、速率限制决策以及操作员审批结果。

curl -i "$BASE_URL/v1/messages" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "mailbox_id": "mailbox_uuid",
  "to": ["[email protected]"],
  "subject": "Support follow-up",
  "body_text": "Thanks for your message. We are checking this now.",
  "metadata": { "ticket_id": "ticket_123" },
  "send_at": "2030-01-01T09:00:00Z"
}'

传入 send_at (RFC3339,未来时间)以安排投递,并传入 Idempotency-Key 请求头以对重试去重(重放会返回原始消息)。使用 GET /v1/messages?q=<text>&label=<name>列出并搜索已发送或已接收的消息,并通过 POST/DELETE /v1/messages/{id}/labels组织会话线程。

LoftBox 不是批量营销发送工具。购买的名单、抓取的收件人以及通用 SMTP 中继用途均不在 MVP 策略范围内。

入站

入站 webhook 与轮询

回复会被存储为入站消息。拥有 HTTPS 端点的 agent 可以接收带签名的 webhook 事件;没有端点的 agent 应轮询邮箱收件箱并确认每一条已处理的消息。

  • message.inbound一条新的入站消息或回复已被解析、归入会话线程,并提供给已配置的 webhook。
  • message.delivered已报告向收件人投递成功。
  • message.failed出站投递永久失败或已耗尽重试处理。
curl -i "$BASE_URL/v1/agents/agent_uuid/webhooks" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/loftbox",
    "event_types": [
      "message.inbound",
      "message.delivered"
    ]
  }'

webhook 密钥在创建 webhook 时一次性返回。请立即存储它,并在信任事件内容之前验证每个入站签名。

curl -i "$BASE_URL/v1/mailboxes/mailbox_uuid/inbox?limit=20" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY"

curl -i -X POST "$BASE_URL/v1/mailboxes/mailbox_uuid/inbox/ack" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message_ids":["message_uuid_or_msg_public_id"]}'

仅在 agent 已持久化处理消息后才进行确认。空收件箱的轮询应退避;活跃轮询应使用适中的间隔,例如 30-60 秒。

入站

实时流(WebSocket)

无法托管 HTTPS webhook 的 agent(例如运行在 NAT 或防火墙之后)可以通过 WebSocket 实时订阅事件。该流承载与 webhook 相同的事件类型,具备亚秒级投递,并支持基于 cursor 的回放,以补齐断线期间错过的事件。需要 receive 范围(scope)。

  • GET /v1/wsWebSocket 升级。使用 Authorization: Bearer进行认证。使用 ?event_types= ?agent_id=进行过滤;使用 ?after=<cursor>恢复。
  • GET /v1/ws/asyncapi.json该流的 AsyncAPI 规范(公开)。
wscat -c "wss://api.loftbox.net/v1/ws?event_types=message.inbound" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY"

# frames: {"type":"ready",...} then {"type":"event","event":{...},"cursor":"..."}
# on reconnect, pass ?after=<last cursor> to replay missed events

当收到代码为 error lagged resync_required帧时,使用最后收到的 cursor 重新连接。

访问控制

权限与 API 密钥

API 密钥携带范围(scope)。粗粒度范围(send receive admin)隐含细粒度范围(message:send message:read domain:manage approval:decide keys:manage、…),因此现有密钥可继续工作,同时你可以为子 agent 颁发最小权限的子密钥。

  • POST /v1/auth/keys颁发子密钥。请求的范围必须是调用方范围的子集(不可提权)。可选 expires_in_days。明文密钥一次性返回。
  • GET /v1/auth/keys列出组织密钥(仅元数据,不含密文)。需要 keys:manage
  • DELETE /v1/auth/keys/{id}撤销一个密钥及其所有后代(级联)。允许的角色为 keys:manage 或该密钥的父级。
DMARC

DMARC 聚合报告

邮箱服务商(Gmail、Outlook、Yahoo 等)会每日发送 DMARC 聚合(rua)报告,汇总哪些源 IP 以你已验证域名的名义发送了邮件,以及 SPF/DKIM/DMARC 是否对齐。LoftBox 会将这些报告解析为结构化报告,以便你监控可投递性并发现伪冒。每份存储的报告还会记录经过认证的报告方域名。

  • GET /v1/dmarc/reports列出你组织的 DMARC 聚合报告,最新的在前。通过 before_date_end + before_id 进行 cursor 分页(一并返回为 next_cursor)。需要 domain:read
  • GET /v1/dmarc/reports/{id}获取一份报告及其按源 IP 划分的记录(消息计数、处置方式、DKIM/SPF 对齐、header-from)。需要 domain:read
curl -i "$BASE_URL/v1/dmarc/reports" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY"

curl -i "$BASE_URL/v1/dmarc/reports/REPORT_ID" \
  -H "Authorization: Bearer $LOFTBOX_API_KEY"

报告会随服务商提交而出现(通常每个报告方每日一次)。仅返回你自己已验证域名的报告;平台或未托管域名的报告绝不会被暴露。

事件

投递事件

投递状态在托管投递回调和内部发送状态之间已归一化。请使用事件 ID 和投递引用进行支持排查,而非私密的收件人数据。

  • queued:已被 LoftBox 接受以待投递。
  • sent:已接受用于出站投递。
  • delivered:已报告向收件人投递成功。
  • failed:投递永久失败或已耗尽重试。
  • blocked:策略、速率限制或报告控制阻止了发送。
控制

速率限制与报告控制

出站发送受组织、agent、邮箱、收件人和域名策略的限制。个人版测试组织每日发送上限为 100 封。高风险消息可以被暂停以待审批,然后才尝试投递。

通过退避来处理 429 响应。不要无限重试,也不要从另一个邮箱绕过审批暂停。

HTTP/1.1 429 Too Many Requests
Retry-After: 60
投递控制

托管投递与安全配置

LoftBox 为测试账户运营托管出站投递。公共文档应描述对客户可见的控制项,而不暴露内部供应商名称、凭据或路由细节。

  • 业务性质:面向已验证域名 AI agent 的、由 API 管理的运营邮件身份。
  • 邮件类型:事务性/系统通知、由已验证用户发起的 agent 回复、接入/测试消息,以及报告/联系处理。
  • 控制项:仅限已验证域名、明确的速率限制、投递日志、抑制/投诉处理,以及受监控的报告联系方式。
  • 公共页面: 隐私 条款,以及 反垃圾邮件策略

DNS 传播和投递验证的暂停应被视为配置状态,而非 API 代理或主页文档损坏的证据。