互客鱼 返回主站

API 参考

小部件 API

Widget API 是捆绑的 JavaScript 对话的公共 HTTP 表面。 您通常不会自己调用它 — widget loader 会这样做 — 但这里的契约已记录在案, 因此您可以构建自定义客户端、审计流量或模拟小部件进行测试。

所有端点都在 /api/v1/widget 下。 身份验证是由 /init 颁发的签名 JWT。 CORS 对跨源嵌入的 POST 是宽松的。

POST POST /v1/widget/init

为访客启动小部件。无需身份验证 — 但请求的 Origin 标头必须匹配智能体的 allowed_origins(参见 Allowed origins)。

请求

POST /api/v1/widget/init
Origin: https://your-site.com
Content-Type: application/json

{
    "agent_id": "01HXY...",
    "page_url": "https://your-site.com/pricing",
    "anon_id": "anon_abc123"     // 可选;在重新加载时持久化访客
}

响应 (200)

{
    "data": {
        "conversation_id": "01HXZ...",
        "visitor_id": "01HXY...",
        "anonymous_id": "anon_abc123",
        "jwt": "eyJhbGciOiJIUzI1NiI...",
        "expires_at": "2026-05-07T13:00:00Z",
        "agent": {
            "id": "01HXY...",
            "name": "Aria",
            "persona": { "name": "Aria", "tone": "friendly" },
            "theme": { "primary": "#111827", ... },
            "starter_prompts": [ "..." ],
            "language_default": "en"
        },
        "branding": { "show": true, "label": "...", "url": "...", "logo_url": "...", "display_mode": "logo_only" },
        "behavior_rules": [ ... ],
        "messages": [ ... ],          // last 30 messages of the resumed conversation
        "reverb": { "app_key": "...", "host": "...", "port": 8080, "scheme": "wss" }
    }
}

错误响应

状态代码原因
404agent_not_found智能体不存在或未发布。
403origin_forbiddenOrigin 不在 allowed_origins 中。
429plan_limit_reached工作区超过其每月对话配额。
429(throttled)每 IP 速率限制命中(默认 60 rpm)。

POST POST /v1/widget/messages/stream

流式端点。SSE 响应。身份验证:Authorization: Bearer <jwt>。 将此用于访客体验 — 所有其他方法都是同步且较慢的。

请求

POST /api/v1/widget/messages/stream
Authorization: Bearer eyJhbGciOiJIUzI1NiI...
Content-Type: application/json

{
    "message": "What's your refund policy?",
    "page_url": "https://your-site.com/pricing",
    "page_context": { ... }       // optional; structured data extracted from the current page
}

响应 (Server-Sent Events)

HTTP/1.1 200 OK
content-type: text/event-stream

data: {"event":"token","token":"Our "}

data: {"event":"token","token":"refund "}

data: {"event":"token","token":"policy is 30 days "}

data: {"event":"citations","citations":[{"id":1,"url":"https://your-site.com/refunds"}]}

data: {"event":"done","conversation_id":"01HXZ..."}

Token 事件在前几百毫秒内最快到达 — 这是热路径上 1 秒到首个 token 的目标。 citations 事件在流式传输完成后到达一次;done 关闭流。

POST POST /v1/widget/messages

/messages/stream 的同步版本。在一个 JSON 有效负载中返回完整响应。 较慢(访客等待完整响应)但更容易与非浏览器客户端集成。

响应

{
    "data": {
        "message_id": "01HXZ...",
        "conversation_id": "01HXZ...",
        "content": "Our refund policy is 30 days...",
        "citations": [{"id": 1, "url": "..."}],
        "low_confidence": false
    }
}

POST POST /v1/widget/leads

提交捕获的联系信息。身份验证:与消息相同的 JWT。

POST /api/v1/widget/leads
Authorization: Bearer eyJhbGciOiJIUzI1NiI...

{
    "name": "Alex",
    "email": "alex@example.com",
    "phone": "+1...",
    "fields": { "company": "Acme" }   // 任何智能体定义的自定义字段
}

在 (agent_id, email) 上去重:重复提交更新现有潜在客户而不是创建新的。 每个 JWT 每个窗口速率限制为 5 个请求 — 抗滥用。

POST POST /v1/widget/events

轻量级客户端分析。小部件用遥测事件调用此端点(启动器打开、CTA 点击、关闭、滚动触发器触发)。 身份验证:JWT。速率限制。

{
    "event": "cta.click",
    "rule_id": "01HXY...",
    "metadata": { ... }
}

JWT 格式

HS256,使用 WIDGET_JWT_SECRET 签名。声明:

{
    "iss": "hukeyu",
    "iat": 1714900000,
    "exp": 1714903600,           // 60 分钟
    "agent_id": "01HXY...",
    "visitor_id": "01HXY...",
    "conversation_id": "01HXZ..."
}

Token 范围限定为单个对话。重新初始化以获取新对话的新 token。 验证发生在 WidgetJwt::verify() 中 — 无效签名、过期 token 或篡改的声明都返回 401。

速率限制

端点限制
/init60 rpm每 IP + agent_id (throttle:widget-init)
/messages, /messages/stream, /events, /conversation/*, DELETE /me30 rpm每 JWT (throttle:widget-session)
/leads5 rpm每 JWT (throttle:widget-leads)

All return 429 with a Retry-After header on limit.