OneKeyToken API 文档

面向开发者、后端工程师和 AI 自动接入 Agent 的完整接入说明。像接 OpenAI 一样接入 OneKeyToken,由平台完成模型路由、客户归因、Token 计量、扣费账本和错误归一。

POST https://my.onekeytoken.com/v1/chat/completions
Authorization: Bearer okt-app-live-...
Content-Type: application/json
x-request-id: req_app_20260615_0001
x-customer-id: tenant_bank_001
x-user-id: employee_2381

{
  "model": "onekeytoken/auto",
  "messages": [
    { "role": "user", "content": "总结这张工单的处理建议" }
  ],
  "stream": false
}

OneKeyToken 开发者接入指南

版本:2026-06-15

状态:已同步到网站 API 文档、应用内开发文档和后端 docs service

适用对象:开发者、后端工程师、AI 编程助手、自动化接入 Agent

生产 API Base URL:https://my.onekeytoken.com/v1

本文以当前网关代码和生产域名为准。后续改动请先更新本 Markdown 源,再同步官网文档、应用内文档和后端 docs service。

1. 给 AI 的快速接入指令

如果你是 AI 编程助手,请按下面的契约接入 OneKeyToken:

  1. 使用 OpenAI Chat Completions 兼容接口。
  2. 将 SDK 的 base_url / baseURL 设置为 https://my.onekeytoken.com/v1
  3. 将 SDK 的 api_key / apiKey 设置为用户在 OneKeyToken 控制台创建的 Key:
  • 个人 API Key:形如 okt-user-live-...,用于当前账号自己调用模型。
  • 应用接入 Key:形如 okt-app-live-...,用于服务端 B2B2C 应用调用模型。
  1. 只在服务端保存和使用 Key,不要把 Key 放到浏览器、移动端 App、小程序或公开仓库。
  2. 调用 POST /chat/completions,完整 URL 是 https://my.onekeytoken.com/v1/chat/completions
  3. 每次业务调用生成唯一 x-request-id,例如 req_order_20260615_0001。同一账号或同一应用下重复使用会返回 409 conflict
  4. 使用应用接入 Key 时,优先传 x-customer-id 标识你的客户;如需统计终端用户,再传 x-user-id。传了 x-user-id 就必须同时传 x-customer-id
  5. model 使用控制台开放的模型 code,例如 onekeytoken/autodeepseek-chatqwen3.5-flash。推荐生产默认使用 onekeytoken/auto,由平台按模型策略自动路由。
  6. 当前生产主路径请使用非流式调用:stream: false 或不传 stream。不要默认传 stream: true
  7. 从响应读取 choices[0].message.contentusagerouting;从调用日志或账单中按 x-request-id 对账。

可复制的最小配置:

onekeytoken:
  protocol: openai_chat_completions_compatible
  base_url: https://my.onekeytoken.com/v1
  chat_completions_url: https://my.onekeytoken.com/v1/chat/completions
  auth:
    header: Authorization
    value: Bearer ${ONEKEYTOKEN_API_KEY}
  required_headers:
    Content-Type: application/json
    x-request-id: unique id per credential owner
  recommended_model: onekeytoken/auto
  production_default:
    stream: false
  attribution:
    application_key:
      customer_id_header: x-customer-id
      user_id_header: x-user-id
      rule: x-user-id requires x-customer-id
  response_fields:
    assistant_text: choices[0].message.content
    token_usage: usage
    route_info: routing
  retry_rule:
    do_not_retry_with_same_x_request_id_after_409: true

2. 接入前准备

2.1 创建 Key

在 OneKeyToken 个人中心或应用控制台创建 Key。

Key 类型前缀使用场景余额扣减是否允许前端暴露
个人 API Keyokt-user-live-...开发者、脚本、后端服务直接调用当前账号钱包不允许
应用接入 Keyokt-app-live-...SaaS / B2B2C 应用服务端代理客户请求customer_id 时扣客户钱包;无 customer_id 时扣应用所属账号钱包不允许

Key 必须具备 model:invoke 权限,否则网关会返回:

{
  "error": {
    "code": "forbidden",
    "message": "Application key cannot invoke models"
  }
}

2.2 设置模型范围

控制台中的模型范围会限制 Key 可调用的模型。调用时:

  • model 为空、autoonekeytoken/auto:走平台自动路由。
  • model 是具体模型 code:网关会校验账号、应用和 Key 是否允许该模型。
  • 如果模型不在允许范围内,返回 403 forbidden

2.3 充值和余额

调用模型会按上游返回的 usage 扣减 Token 余额并写入账本。

  • 个人 API Key:扣当前账号钱包。
  • 应用接入 Key + x-customer-id:扣该应用下对应客户钱包。
  • 应用接入 Key + 不传 x-customer-id:扣应用所属账号钱包,适合内部测试或统一余额模式。

3. API 基础信息

协议OpenAI Chat Completions compatible
Base URLhttps://my.onekeytoken.com/v1
Chat CompletionsPOST https://my.onekeytoken.com/v1/chat/completions
鉴权方式Authorization: Bearer <OneKeyToken Key>
请求格式Content-Type: application/json
当前生产建议非流式请求,stream: false

当前公开生产接入以 POST /v1/chat/completions 为主;不要使用历史旧地址或非生产域名。

4. Header 说明

Header必填示例说明
AuthorizationBearer okt-app-live-...OneKeyToken Key。必须是 Bearer 方案。
Content-Typeapplication/json请求体必须是 JSON。
x-request-id强烈建议req_20260615_0001调用幂等与对账 ID。同一账号或同一应用下必须唯一。未传时网关会生成,但调用方不容易对账。
x-customer-id应用 Key 推荐tenant_001你的业务客户 ID。用于客户钱包、客户账单、客户专有上游 Key 规则。
x-user-id可选user_9281客户下终端用户 ID。传它时必须同时传 x-customer-id
x-oktoken-customer-id可选tenant_001x-customer-id 的等价别名。
x-oktoken-user-id可选user_9281x-user-id 的等价别名。
x-oktoken-routing-debug调试可选1返回更详细的自动路由诊断。生产普通请求不建议常开。
x-oktoken-perf-timings调试可选1返回 Server-Timing 与网关内部耗时 header。排障时使用。

5. 请求体参数

OneKeyToken 会把 OpenAI 兼容参数转发给上游模型,但会先读取部分扩展字段做鉴权、路由、归因和扣费。

5.1 标准 Chat Completions 参数

参数类型必填示例说明
modelstring推荐onekeytoken/auto平台模型 code。为空、autoonekeytoken/auto 时走自动路由。
messagesarray[{"role":"user","content":"你好"}]对话消息数组,不能为空。
messages[].rolestringsystem / user / assistant / tool消息角色。具体支持范围取决于上游模型。
messages[].contentstring 或数组"生成摘要"消息内容。文本模型通常传字符串;多模态内容取决于模型能力。
temperaturenumber0.2随机性,常用范围 02
top_pnumber0.9nucleus sampling 参数。
max_tokensinteger512最大输出 Token。部分新模型也支持 max_completion_tokens
streambooleanfalse当前生产主路径请传 false 或不传。true 在 Node 网关路径会返回不支持。
stopstring 或 array["\n\n"]停止生成标记。
presence_penaltynumber0话题新颖性惩罚,是否生效取决于上游。
frequency_penaltynumber0重复惩罚,是否生效取决于上游。
response_formatobject{"type":"json_object"}JSON 输出等结构化要求,模型支持时生效。
toolsarrayOpenAI tools schema工具调用定义,模型支持时生效。
tool_choicestring 或 objectauto工具选择策略。

5.2 OneKeyToken 扩展参数

这些字段也可放在请求体中,但生产建议优先使用 Header,便于网关、代理和日志统一处理。

参数类型必填示例说明
customer_idstring应用 Key 推荐tenant_001x-customer-id 等价。平台不会转发给上游。
customerIdstring应用 Key 推荐tenant_001customer_id 的 camelCase 形式。
user_idstring可选user_9281x-user-id 等价。必须配合 customer_id。平台不会转发给上游。
userIdstring可选user_9281user_id 的 camelCase 形式。
userstring可选user_9281user_id 的兼容别名。

不要把 request_id 放在请求体里作为幂等依据。公开网关读取的是 x-request-id Header。

6. 调用示例

6.1 curl:个人 API Key

curl https://my.onekeytoken.com/v1/chat/completions \
  -H "Authorization: Bearer okt-user-live-REPLACE_WITH_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "x-request-id: req_personal_20260615_0001" \
  -d '{
    "model": "onekeytoken/auto",
    "messages": [
      { "role": "system", "content": "你是一个简洁可靠的中文助手。" },
      { "role": "user", "content": "用三句话介绍 OneKeyToken 的网关接入方式。" }
    ],
    "temperature": 0.2,
    "max_tokens": 512,
    "stream": false
  }'

6.2 curl:应用接入 Key + 客户归因

curl https://my.onekeytoken.com/v1/chat/completions \
  -H "Authorization: Bearer okt-app-live-REPLACE_WITH_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "x-request-id: req_app_20260615_0001" \
  -H "x-customer-id: tenant_bank_001" \
  -H "x-user-id: employee_2381" \
  -d '{
    "model": "onekeytoken/auto",
    "messages": [
      { "role": "user", "content": "总结这张工单的处理建议:客户反馈发票抬头错误,需要重开。" }
    ],
    "temperature": 0.2,
    "max_tokens": 512,
    "stream": false
  }'

6.3 JavaScript:OpenAI SDK

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.ONEKEYTOKEN_API_KEY,
  baseURL: "https://my.onekeytoken.com/v1"
});

const requestId = `req_js_${Date.now()}`;

const completion = await client.chat.completions.create(
  {
    model: "onekeytoken/auto",
    messages: [
      { role: "system", content: "你是企业知识库助手,回答要简洁。" },
      { role: "user", content: "请把下面的客户反馈整理成三条待办。" }
    ],
    temperature: 0.2,
    max_tokens: 512,
    stream: false
  },
  {
    headers: {
      "x-request-id": requestId,
      "x-customer-id": "tenant_bank_001",
      "x-user-id": "employee_2381"
    }
  }
);

console.log(completion.choices[0]?.message?.content);
console.log(completion.usage);
console.log(completion.routing);

6.4 JavaScript:fetch

const response = await fetch("https://my.onekeytoken.com/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ONEKEYTOKEN_API_KEY}`,
    "Content-Type": "application/json",
    "x-request-id": `req_fetch_${Date.now()}`,
    "x-customer-id": "tenant_bank_001"
  },
  body: JSON.stringify({
    model: "deepseek-chat",
    messages: [{ role: "user", content: "生成一份 100 字以内的日报摘要。" }],
    temperature: 0.2,
    max_tokens: 256,
    stream: false
  })
});

const body = await response.json();
if (!response.ok) {
  throw new Error(`${body.error?.code}: ${body.error?.message}`);
}
console.log(body.choices[0].message.content);

6.5 Python:OpenAI SDK

import os
import time
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["ONEKEYTOKEN_API_KEY"],
    base_url="https://my.onekeytoken.com/v1",
)

completion = client.chat.completions.create(
    model="onekeytoken/auto",
    messages=[
        {"role": "system", "content": "你是客服质检助手。"},
        {"role": "user", "content": "请判断这段客服回复是否礼貌,并给出改写建议。"},
    ],
    temperature=0.2,
    max_tokens=512,
    stream=False,
    extra_headers={
        "x-request-id": f"req_py_{int(time.time() * 1000)}",
        "x-customer-id": "tenant_bank_001",
        "x-user-id": "agent_2381",
    },
)

print(completion.choices[0].message.content)
print(completion.usage)

6.6 Python:requests

import os
import time
import requests

resp = requests.post(
    "https://my.onekeytoken.com/v1/chat/completions",
    headers={
        "Authorization": f"Bearer {os.environ['ONEKEYTOKEN_API_KEY']}",
        "Content-Type": "application/json",
        "x-request-id": f"req_requests_{int(time.time() * 1000)}",
        "x-customer-id": "tenant_bank_001",
    },
    json={
        "model": "qwen3.5-flash",
        "messages": [{"role": "user", "content": "请给我一个会议纪要模板。"}],
        "temperature": 0.2,
        "max_tokens": 512,
        "stream": False,
    },
    timeout=70,
)
data = resp.json()
if resp.status_code >= 400:
    raise RuntimeError(f"{data['error']['code']}: {data['error']['message']}")
print(data["choices"][0]["message"]["content"])

6.7 Node.js 后端代理:不要把 Key 暴露给前端

import express from "express";
import OpenAI from "openai";

const app = express();
app.use(express.json());

const client = new OpenAI({
  apiKey: process.env.ONEKEYTOKEN_APP_KEY,
  baseURL: "https://my.onekeytoken.com/v1"
});

app.post("/api/ai/chat", async (req, res, next) => {
  try {
    const currentTenantId = req.user.tenantId;
    const currentUserId = req.user.id;
    const requestId = `req_${currentTenantId}_${Date.now()}`;

    const completion = await client.chat.completions.create(
      {
        model: "onekeytoken/auto",
        messages: [
          { role: "system", content: "你是当前 SaaS 产品内置的 AI 助手。" },
          { role: "user", content: req.body.question }
        ],
        temperature: 0.2,
        max_tokens: 512,
        stream: false
      },
      {
        headers: {
          "x-request-id": requestId,
          "x-customer-id": currentTenantId,
          "x-user-id": currentUserId
        }
      }
    );

    res.json({
      requestId,
      answer: completion.choices[0]?.message?.content || "",
      usage: completion.usage,
      routing: completion.routing
    });
  } catch (error) {
    next(error);
  }
});

app.listen(3000);

7. 响应说明

成功响应兼容 OpenAI Chat Completions,并额外带 routing 字段。

{
  "id": "chatcmpl_...",
  "object": "chat.completion",
  "created": 1781510000,
  "model": "qwen3.5-flash",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "这里是模型回答。"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 128,
    "completion_tokens": 256,
    "total_tokens": 384
  },
  "routing": {
    "model_used": "qwen3.5-flash",
    "policy": "smart_balanced",
    "request_type": "general",
    "reason": "auto route selected by policy"
  }
}
字段说明
choices[0].message.contentAI 回答文本。
usage.prompt_tokens输入 Token 数。
usage.completion_tokens输出 Token 数。
usage.total_tokens总 Token 数,账单和用量统计会优先使用它。
routing.model_used实际路由到的平台模型 code。
routing.policy本次路由策略,例如 smart_balanced
routing.request_type平台识别的请求类型。
routing.reason路由原因摘要。

当请求头带 x-oktoken-routing-debug: 1 时,routing 会包含候选模型、评分、权重等更多调试字段。该模式适合排障,不建议在普通生产请求中常开。

8. 计费、账本和对账

8.1 扣费规则

OneKeyToken 使用上游返回的 usage 计算扣费:

扣费金额 = ceil(input_tokens * 输入单价 / 1,000,000 + output_tokens * 输出单价 / 1,000,000)
扣费 Token = usage.total_tokens 或 input_tokens + output_tokens

说明:

  • 价格单位是“分 / 百万 Token”存储,前端通常展示为“元 / M Token”。
  • 应用价表存在时,应用 Key 调用优先使用应用价表销售价。
  • 无应用价表覆盖时,使用模型目录价。
  • 模型成本仍按模型目录成本价记录,用于平台毛利和上游成本统计。

8.2 归因规则

调用方式归因字段账本
个人 API Key无需 customer_id账号钱包、账号账本
应用 Key,不传 customer_id应用、应用 Key应用所属账号钱包、账号账本
应用 Key,传 customer_id应用、客户客户钱包、客户账本
应用 Key,传 customer_id + user_id应用、客户、终端用户客户钱包、客户账本,附带终端用户归因

x-customer-id 是你的业务客户 ID,不需要提前在 OneKeyToken 手工创建。第一次调用时平台会按应用自动建立客户与客户钱包;如果余额不足,需要先在应用客户余额里充值或发放额度。

8.3 request_id 幂等与对账

x-request-id 是排查和对账的关键字段。

  • 每次新的模型调用必须使用新的 x-request-id
  • 同一账号或同一应用下重复使用会返回 409 conflict
  • 不同应用可以使用相同字符串,但不建议这样做,跨系统排查容易混淆。
  • 建议格式包含业务系统、场景、时间和随机串,例如 req_crm_ticket_20260615_7f3a9c

如果客户端网络超时但服务端可能已经完成扣费,不要盲目用新的 x-request-id 重试同一业务动作;应先用你的业务日志、OneKeyToken 调用日志或账单按旧 x-request-id 查询是否已完成。

9. 错误格式与排查

错误响应统一为:

{
  "error": {
    "code": "bad_request",
    "message": "messages must be a non-empty array",
    "details": {}
  }
}

常见错误:

HTTPcode常见 message处理方式
400bad_requestRequest body must be valid JSON检查 JSON 格式和 Content-Type
400bad_requestmessages must be a non-empty arraymessages 必须是非空数组。
400bad_requeststream=true is not supported by this gateway yet当前生产主路径改用 stream: false
400bad_requestx-customer-id is required when x-user-id is providedx-user-id 时补上 x-customer-id
401unauthorizedApplication key is required检查 Authorization: Bearer ... 是否存在。
401unauthorizedInvalid API keyKey 错误、已轮换、复制不完整或不是 OneKeyToken Key。
403forbiddenApplication key cannot invoke models给应用 Key 增加 model:invoke scope,或换可调用模型的 Key。
403forbiddenModel is not allowed by this application key检查应用模型策略和 Key 的模型范围。
403forbiddenCustomer token balance is insufficient给对应客户充值或发放 Token。
403forbiddenAccount token balance is insufficient给账号充值,或应用 Key 调用时传客户并给客户充值。
409conflictrequest_id has already been used for this credential owner生成新的 x-request-id;不要复用旧 ID 发起新调用。
429too_many_requestsRPM guardrail exceeded降低并发或在控制台调整限流。
502bad_gatewayUpstream provider request failed上游供应商、上游 Key 池或模型配置异常,稍后重试或联系运营。
504gateway_timeoutUpstream provider timed out上游超时,缩短输出、切换模型或稍后重试。

10. 模型选择建议

10.1 推荐模型写法

生产推荐:

{
  "model": "onekeytoken/auto"
}

平台会根据应用/账号模型范围、请求特征、价格、质量、延迟和健康状态选择实际模型。

如果业务必须固定模型,可以传具体模型 code:

{
  "model": "deepseek-chat"
}

或:

{
  "model": "qwen3.5-flash"
}

最终可用模型以控制台“模型调度”和“Key 模型范围”为准。文档示例只表示接入方式,不保证每个账号都已开通。

10.2 客户专有供应商 Key

运营可以在应用详情中配置“客户专有供应商模型 Key”。调用方不需要传供应商 Key,只需要正常传:

  • 应用接入 Key
  • x-customer-id
  • model

如果该应用、客户、模型存在专有上游 Key 绑定,网关会优先使用该专有 Key 转发上游;否则使用模型所属供应商的共享 Key 池策略。

11. 安全最佳实践

  1. Key 只放服务端环境变量、密钥管理系统或后端配置中心。
  2. 一个项目、一个环境、一个用途创建独立 Key,便于限流、禁用和审计。
  3. 生产 Key 建议配置 IP 白名单、RPM/TPM 限制和模型范围。
  4. 日志中只记录 Key 前缀,不记录完整 Key。
  5. 客户端请求你的后端时,用你自己的登录态鉴权;由你的后端再调用 OneKeyToken。
  6. 离职、泄露、上线切换后及时轮换 Key。

12. 生产接入检查清单

上线前请逐项确认:

  • [ ] 已创建生产个人 API Key 或应用接入 Key。
  • [ ] Key 状态为启用,scope 包含 model:invoke
  • [ ] Key 的模型范围包含要调用的模型,或允许 onekeytoken/auto 自动路由。
  • [ ] 钱包有足够余额;应用客户模式下,目标 customer_id 对应客户已有余额。
  • [ ] 服务端已设置 ONEKEYTOKEN_API_KEY 或等价安全密钥配置。
  • [ ] 请求带唯一 x-request-id
  • [ ] 应用 Key 的生产请求带 x-customer-id;如需终端用户统计,也带 x-user-id
  • [ ] 业务代码处理 401403409429502504
  • [ ] 业务日志记录 x-request-idcustomer_iduser_id、模型 code、耗时和错误码。
  • [ ] 完成 1 VU 小流量 canary,并核对调用日志、账本、余额扣减和用量统计闭合。

13. AI 自动接入规范

下面这段 JSON 可以直接给自动化接入 Agent 使用:

{
  "service": "OneKeyToken",
  "protocol": "openai_chat_completions_compatible",
  "base_url": "https://my.onekeytoken.com/v1",
  "endpoints": {
    "chat_completions": {
      "method": "POST",
      "path": "/chat/completions",
      "url": "https://my.onekeytoken.com/v1/chat/completions",
      "streaming_default": false
    }
  },
  "authentication": {
    "type": "bearer",
    "header": "Authorization",
    "value_template": "Bearer ${ONEKEYTOKEN_API_KEY}",
    "key_prefixes": {
      "personal": "okt-user-live-",
      "application": "okt-app-live-"
    },
    "server_side_only": true
  },
  "required_request_body": {
    "messages": [
      {
        "role": "user",
        "content": "string"
      }
    ]
  },
  "recommended_request_body": {
    "model": "onekeytoken/auto",
    "temperature": 0.2,
    "max_tokens": 512,
    "stream": false
  },
  "required_headers": {
    "Content-Type": "application/json",
    "x-request-id": "unique per account/application credential owner"
  },
  "application_key_headers": {
    "x-customer-id": "business customer id, recommended",
    "x-user-id": "end user id, optional, requires x-customer-id"
  },
  "do_not_send": {
    "request_id_in_body": "not used for gateway idempotency",
    "api_key_to_browser": "never expose credentials client-side"
  },
  "success_response_paths": {
    "assistant_text": "choices[0].message.content",
    "usage": "usage",
    "actual_model": "routing.model_used",
    "routing_policy": "routing.policy"
  },
  "error_response_shape": {
    "error": {
      "code": "string",
      "message": "string",
      "details": "object optional"
    }
  },
  "retry_policy": {
    "409_conflict": "do not retry with same x-request-id for a new call",
    "429_too_many_requests": "back off and reduce concurrency",
    "502_504": "retry with exponential backoff if business action is still needed; preserve idempotency strategy"
  }
}

14. 常见问题

Q1:可以直接把 OneKeyToken Key 放到前端调用吗?

不可以。无论个人 API Key 还是应用接入 Key,都必须放在服务端。前端应调用你自己的后端接口,由后端转发到 OneKeyToken。

Q2:为什么重复请求提示 request_id has already been used

x-request-id 是同一账号或同一应用下的唯一调用 ID。你把已经用过的 ID 用在了新的请求上。新请求生成新的 ID;网络异常排查时先按旧 ID 查日志,确认是否已经扣费。

Q3:应用 Key 不传 customer_id 可以吗?

可以,但会扣应用所属账号钱包,不会形成客户钱包归因。正式 B2B2C 业务建议始终传 x-customer-id

Q4:为什么传了 user_id 报错?

user_id 必须挂在某个客户下面。传 x-user-id 时同时传 x-customer-id

Q5:为什么响应里没有我请求的模型?

如果传的是 onekeytoken/autoauto 或不传 model,平台会自动路由。看响应里的 routing.model_used 才是实际模型。

Q6:怎么排查慢请求?

临时加请求头:

x-oktoken-perf-timings: 1
x-oktoken-routing-debug: 1

响应会带网关耗时和详细路由信息。排障完成后关闭这些调试 header。

Q7:当前支持流式输出吗?

当前生产主文档建议使用非流式调用。Node 网关路径对 stream: true 会返回 bad_request。如果后续生产启用独立流式网关,会在文档中单独补充 SSE / WebSocket 接入方式。

15. 完整非流式请求模板

{
  "model": "onekeytoken/auto",
  "messages": [
    {
      "role": "system",
      "content": "你是一个可靠、简洁、可审计的企业 AI 助手。"
    },
    {
      "role": "user",
      "content": "请总结以下客户反馈,并输出三条处理建议。"
    }
  ],
  "temperature": 0.2,
  "max_tokens": 512,
  "stream": false
}

对应 Header:

Authorization: Bearer okt-app-live-REPLACE_WITH_YOUR_KEY
Content-Type: application/json
x-request-id: req_your_system_20260615_0001
x-customer-id: tenant_001
x-user-id: user_001