嵌入令牌与终端用户
签发、刷新、吊销嵌入令牌,以及终端用户的身份与封禁。
嵌入令牌是你的后端为一位终端用户签发的短期凭证。用它的人只能以这位用户的身份与指定智能体对话。
签发
POST /agent/v1/embed_tokens,用 API Key 鉴权,只在后端调用。
curl https://api-develop.deepraxis.com/agent/v1/embed_tokens \
-H "Authorization: Bearer $PRAXIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent": "agent_xxx",
"external_user_id": "customer_123",
"ttl_seconds": 900,
"system_message": [{ "type": "text", "text": "当前用户会员等级:金卡" }]
}'示例域名为 develop 环境,正式地址上线后替换。期望:HTTP 200。
| 字段 | 说明 |
|---|---|
agent | 必填。服务型智能体的 id 或短号,必须属于你的组织、未归档,并已设置嵌入策略 |
external_user_id | 必填。你系统里终端用户的稳定 ID,1–128 个字符,只含 A-Z a-z 0-9 _ . : @ -。在同一组织的同一智能体内唯一标识这位用户 |
ttl_seconds | 令牌有效期,60–3600 秒。缺省用嵌入策略的默认值,且不能超过策略的上限与 3600 秒 |
version | 固定使用的智能体版本。缺省时用策略里固定的版本,否则用签发时的最新版本。令牌签发后版本不再变化 |
system_message | 宿主上下文,文本块数组,合计不超过 8192 字节。见传入上下文 |
agent_override | { "system": "…" },替换该令牌的指令。仅当嵌入策略允许覆盖时可用,否则返回 EMBED_FIELD_NOT_ALLOWED |
budget_cents | 单个会话的预算(分)。缺省用策略默认值,不能超过策略上限 |
allowed_origins | 来源白名单的子集,缺省为策略里的全部来源 |
metadata | 原样保存的宿主元数据,最多 16 个键,键 1–64 字符,值字符串不超过 512 字符 |
hosted | 设为 true 时额外返回用于 Hosted 跳转的 hosted_url |
每次调用都会产生一份新的签发记录,签发不是幂等的。
返回:
{ "id": "emb_…", "token": "…", "expires_at": "2026-10-19T08:00:00.000Z" }id 是这次签发的标识,用于吊销与查询;token 交给前端;expires_at 是 ISO 8601 UTC 时间。
跳转到 Hosted
验证用户登录后调用以下函数,userId 必须来自服务端登录态:
export async function openHosted(userId: string) {
const response = await fetch("https://api-develop.deepraxis.com/agent/v1/embed_tokens", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.PRAXIS_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ agent: "agent_xxx", external_user_id: userId, hosted: true }),
});
if (!response.ok) throw new Error("Hosted issuance failed");
const { hosted_url } = await response.json();
return new Response(null, { status: 302, headers: { Location: hosted_url } });
}期望:浏览器跳转后进入托管对话页。hosted_url 的 #c=… 片段携带60 秒内有效、只能用一次的凭证,不是嵌入令牌。托管页自动向 POST /agent/v1/embed/exchange 提交 { "code": "…" },取得 { token, expires_at }。凭证已用、过期或无效时返回 NOT_FOUND(404),应重新签发,不要复用或分享这个链接。兑换凭证的期限与令牌有效期是两回事。
匿名访客
访客没有宿主登录态时,可向 POST /agent/v1/embed_tokens/anonymous 提交 { "publishable_key": "PRAXIS_API_KEY" }。这里的 PRAXIS_API_KEY 是可公开 key 的占位符,不能填服务器 API Key。响应含 { token, expires_at },新访客还会收到 visitor_secret;后续请求带上这个 visitor_secret 可延续访客身份。它是私有访客凭证,不要公开。
接口验证浏览器来源白名单,并执行可公开 key 的匿名限额。不接受调用方指定 external_user_id、指令、预算或 Hosted 选项。每日会话与花费上限按 UTC 自然日计算,统计实际会话,不把令牌刷新计为新会话。
刷新
Kit 需要令牌时调用你提供的 getToken(current):首次 current 为 null,更换时传入当前令牌。在里面请求你自己的后端,由后端重新签发并返回新令牌字符串即可。重新签发前先确认用户仍然登录。令牌只保存在浏览器内存里。
吊销
吊销单张令牌:
curl -X POST https://api-develop.deepraxis.com/agent/v1/embed_tokens/emb_xxx/revoke \
-H "Authorization: Bearer $PRAXIS_API_KEY"期望:返回带 revoked_at 的签发记录。该令牌立即失效,它打开的事件流会收到 session.error(EMBED_TOKEN_REVOKED)后关闭,其他令牌不受影响。重复吊销返回同一条记录。上游吊销失败时返回错误,记录保持未吊销,可重试。
GET /agent/v1/embed_tokens 列出签发记录,可按 agent_id、external_user_id 过滤,用 limit(1–100,默认 20)和 page 翻页。记录里不包含令牌本身。
封禁终端用户
在智能体的嵌入策略里维护封禁名单(blocked_end_users):名单里的 external_user_id 不能再获得令牌,签发返回 EMBED_USER_BLOCKED。名单在 Console 的嵌入设置里管理。
按终端用户管理(API 参考 为准):
POST /agent/v1/agents/{agent_id}/end_users/{external_user_id}/revoke_tokens:一次吊销该用户当前所有有效令牌,进行中的对话随即中断;POST .../block:封禁,同时立即吊销现有令牌,之后宿主为他签发新令牌会返回EMBED_USER_BLOCKED;POST .../unblock:解封。
Console「运营与管理 · 终端用户」页提供同样的操作(见 Console:运营与管理)。
终端用户只能访问自己的会话
用嵌入令牌调用 API 的是终端用户,不是你的组织。他只能创建和读取自己名下的会话,看不到同一智能体下其他用户的会话,也不能调用签发、吊销、列出令牌这类宿主接口(调用会得到 404)。身份来自令牌,不来自请求里的任何参数。