接入
实时(WebSocket)
服务端 agent 用 WebSocket 接收 simail 事件:订阅、限额、吊销,以及重连时不丢事件。
docs.simail.ai/zh/realtime
长时间运行的 agent 可以保持一条连接,事件发生时就收到。
GET
wss://api.simail.ai/v0/ws需要 event_read。升级请求用 Authorization: Bearer <key> 认证。这只给服务端 agent:不要把 API key 放进浏览器。
import WebSocket from "ws";
const ws = new WebSocket("wss://api.simail.ai/v0/ws", { headers: { Authorization: `Bearer ${process.env.SIMAIL_API_KEY}` },});ws.on("open", () => { ws.send(JSON.stringify({ type: "subscribe", inbox_ids: ["shop-helper@simail.email"], event_types: ["message.received", "thread.locked"] }));});ws.on("message", (raw) => { const msg = JSON.parse(raw.toString()); if (msg.type === "event") handle(msg.event); // de-duplicate on msg.event.event_id});ws.on("close", (code) => scheduleReconnect(code));客户端到服务器,可选,任何时候:
{ "type": "subscribe", "inbox_ids": ["shop-helper@simail.email"], "event_types": ["message.received"], "include_non_wake": false }订阅只能收窄 key 能看到的范围。没有订阅时,你会收到 key 作用域里每一条唤醒了 agent 的事件。
服务器到客户端:
{ "type": "event", "event": { "event_id": "evt_…", "event_type": "message.received", "occurred_at": "2026-10-18T17:02:12Z", "inbox_id": "shop-helper@simail.email", "thread_id": "thr_…", "message_id": "msg_…", "data": { "wake": true } } }event 对象和其他地方一样是薄载荷;见事件类型。没有唤醒 agent 的事件会被跳过,除非订阅时带 include_non_wake: true。
- 一条连接最多 1 小时(key 更早过期则更短)。然后关闭,你重连,重连会再检查 key。
- 吊销或收窄 key、移除成员、退出控制台会话或暂停组织,会立刻关掉受影响的连接,码为
4401(revoked)。 - 每个组织 50 条连接,每把 key 10 条,每分钟 10 次握手。
- 客户端落后超过 1 MiB 会被断开。
- 服务器回答 ping,不会因此唤醒任何东西;空闲连接很便宜。
WebSocket 是快路径,不是日志。要不漏事件,记住你处理过的最后一条 event_id,重连后用存下的游标走 GET /v0/events 补上。按 event_id 去重。重连之间退避(例如 1 秒、2 秒、4 秒……直到 60 秒)。4401 之后不要用同一把 key 重连:它已被吊销或收窄。