YOUR FIRST INTEGRATION
快速开始
完成租户准备、价目发布、事件交付与证据下载。所有写入都由你自己的服务端完成。
还没有租户?
先运行无需账号的合成示例,或申请免费接入。当前租户开通仍需运营方处理,不会在此页面自动创建。
01 准备服务地址与凭据
你需要已开通的租户、服务根地址、管理凭据,以及可运行 curl 与 jq 的 Bash 终端。示例中的 ledger.example.com 仅为占位地址。凭据只放服务端或终端环境变量,不要放进网页。
# Use your assigned service and tenant. Keep tokens in your shell only.
export OT_API_ROOT="https://ledger.example.com"
export OT_TENANT="your-tenant"
read -rs -p "Admin credential: " OT_ADMIN_TOKEN; echo
export OT_ADMIN_TOKEN02 发布价目并创建摄入凭据
先将示例表达式替换成合同约定的价目。p 与 c 是本次事件的计价 token 变量;示例系数仅说明语法,不代表任何模型的实际价格。金额单位为 micro USD,权威计算在服务端。这里的价目与 Open Tally 平台免费计划无关。
PRICING_HASH=$(curl --fail-with-body -sS "$OT_API_ROOT/tenant/pricing" \
-H "Authorization: Bearer $OT_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
--data '{"expr":"tier(\"standard\", p * 2 + c * 8)","label":"Your agreed price list"}' \
| jq -er '.pricing.hash')
export PRICING_HASH
curl --fail-with-body -sS "$OT_API_ROOT/tenant/credentials" \
-H "Authorization: Bearer $OT_ADMIN_TOKEN" \
-H "Content-Type: application/json" \
--data '{"label":"billing-exporter"}'
# Securely save the returned token; it is shown only once.
read -rs -p "Ingest credential: " OT_INGEST_TOKEN; echo
export OT_INGEST_TOKEN03 从真实计费记录交付事件
将一个真实 outbox 事件映射为 real-event.json,再选择下方客户端提交。保留稳定的 source_event_id,重试同一事件时不要重新生成 ID。页面仅生成文档,不连接你的账本。
查看字段模板 与实际数据替换规则
这是带占位说明的字段模板,不能直接提交。把所有占位符换成真实记录,计数与时间使用 JSON 整数。不要编造生产用量;synthetic 流量会拒签,示例体验请用公开夹具。
{
"stream": "your-stream",
"source_event_id": "<stable ID from your billing outbox>",
"generation": 6,
"occurred_at_ms": "<actual event time in milliseconds; JSON integer>",
"input": {
"RequestID": "<actual request ID>",
"StartedAtMs": "<actual request start; JSON integer>",
"Model": "<your catalog model identifier>",
"UnitType": "token",
"PromptTokens": "<actual input tokens; JSON integer>",
"CompletionTokens": "<actual output tokens; JSON integer>",
"Billable": true,
"Currency": "USD",
"UsageSemantic": "<openai or anthropic, matching actual upstream accounting>",
"UpstreamProvider": "<provider identifier>",
"UpstreamModelName": "<upstream declared model name>",
"Pricing": {
"ExprHash": "<published pricing hash>",
"P": "<billable p; JSON integer>",
"C": "<billable c; JSON integer>",
"Len": "<context len; JSON integer>"
}
}
}// Node.js 22+. real-event.json comes from your billing outbox.
import { readFile } from 'node:fs/promises';
const event = JSON.parse(await readFile('real-event.json', 'utf8'));
const response = await fetch(
process.env.OT_API_ROOT + '/t/' + process.env.OT_TENANT + '/ingest/events',
{
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.OT_INGEST_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify([event]),
redirect: 'error',
},
);
const result = await response.json();
if (!response.ok || result.success !== true) {
throw new Error(JSON.stringify(result));
}
console.log(result); // enqueued means accepted, not yet signed or sealed# Python 3. Use a real event from your billing outbox.
import json, os, urllib.request
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, *args, **kwargs):
return None
with open("real-event.json", encoding="utf-8") as source:
event = json.load(source)
url = os.environ["OT_API_ROOT"] + "/t/" + os.environ["OT_TENANT"] + "/ingest/events"
request = urllib.request.Request(url,
data=json.dumps([event]).encode(),
headers={"Authorization": "Bearer " + os.environ["OT_INGEST_TOKEN"],
"Content-Type": "application/json"}, method="POST")
with urllib.request.build_opener(NoRedirect).open(request, timeout=30) as response:
result = json.load(response)
if result.get("success") is not True:
raise RuntimeError(result)
print(result) # enqueued is not a verification result# jq is required. real-event.json must contain one real event object.
jq -s '.' real-event.json > batch.json
curl --fail-with-body -sS \
"$OT_API_ROOT/t/$OT_TENANT/ingest/events" \
-H "Authorization: Bearer $OT_INGEST_TOKEN" \
-H "Content-Type: application/json" \
--data-binary @batch.jsonHTTP 成功和 enqueued 仅表示已接收,不表示已签发、已时间戳或已上链。批量失败时保留原事件 ID 重试,并按事件状态检查原因。
04 查看状态 下载并复验
在控制台找到实际已签发的流与序号,确认承诺和时间戳就绪。验证器请从公开分发信息获取并核对来源;此处不使用示例 TSA 根来验证真实账本。
curl --fail-with-body -sS "$OT_API_ROOT/tenant/status" \
-H "Authorization: Bearer $OT_ADMIN_TOKEN"
# Choose an actual issued stream and sequence from the console.
export OT_STREAM="your-stream"
export OT_SEQ="1"
curl --fail-with-body -sS -G \
"$OT_API_ROOT/t/$OT_TENANT/api/receipt/bundle" \
--data-urlencode "stream=$OT_STREAM" --data-urlencode "seq=$OT_SEQ" \
-o bundle.json
opentally-verify -bundle bundle.json -json
# Anonymous disclosure may SKIP amount checks. Inspect every check.此下载命令使用匿名披露,只能获得哈希层。要重算供应成本或核对客户明细,按对应角色使用 audit grant 或 customer token 取证。SKIPPED 不能读成 PASS。
继续阅读验证与披露