开发者
从你的后端验证 Spondeo 证明。
一次 REST 调用即可确认持有者所披露的声明——所属身份、机构类别、国家/地区——而绝不暴露其姓名、学校、雇主或邮箱。免费开发者层级:每月 500 次验证。
身份认证
使用 Authorization 请求头中的 API 密钥对验证调用进行认证:Authorization: Bearer sk_live_…(沙盒环境请使用 sk_test_…)。在你的个人中心创建和管理密钥。每个密钥的明文仅在创建时显示一次,且仅以哈希形式存储——请将其保存在服务端,切勿下发到浏览器。
接口
| 方法 | 路径 | 认证 | 用途 |
|---|---|---|---|
| POST | /v1/verify |
API 密钥 | 验证所提交的证明;返回披露的声明和一个稳定的化名标识。
请求字段:
{ vp_token, expected_audience, nonce, required? }响应:
{ valid, claims, pid, reason } |
| POST | /v1/sandbox/present |
API 密钥(测试) | 铸造一份沙盒测试证明用于验证(测试签发方;仅可用 sk_test_ 密钥验证)。
请求字段:
{ nonce, affiliation?, audience? }响应:
{ vp_token, audience, nonce } |
| POST | /v1/credentials |
无 | 发起一次所属身份验证(发送 6 位验证码)。
请求字段:
{ affiliation, email }响应:
{ id, status } |
| POST | /v1/credentials/{id}/code |
无 | 确认验证码并绑定持有者密钥;签发凭证。
请求字段:
{ code, holder_jwk }响应:
{ sd_jwt_vc, credential_id, holder_id, … } |
| DELETE | /v1/credentials/{id} |
持有者 | 撤销一份凭证(限持有者)。
请求字段:
{ holder_id }响应:
{ revoked } |
| GET | /status/{listId} |
无 | 公开的撤销状态列表。
请求字段:
—响应:
{ list_id, bits } |
快速开始
curl
curl -X POST https://vouchmesh.com/v1/verify \
-H "Authorization: Bearer sk_live_…" \
-H "content-type: application/json" \
-d '{"vp_token":"…","expected_audience":"spondeo:proof-link","nonce":"…","required":[{"claim":"affiliation","value":"enrolled_student"}]}'
SDK(TypeScript)
import { Spondeo } from "@spondeo/verify";
const spondeo = new Spondeo("sk_live_…", { baseUrl: "https://vouchmesh.com" });
const res = await spondeo.verify({
vpToken,
expectedAudience: "spondeo:proof-link",
nonce,
required: [{ claim: "affiliation", value: "enrolled_student" }],
});
if (res.valid) console.log(res.claims, res.pid);
零依赖的 SDK 位于仓库的 sdk/ 目录,并以 @spondeo/verify 发布。
Webhook 回调
在你的个人中心注册一个 Webhook,即可在凭证被撤销的那一刻收到通知。事件仅限于你验证过的凭证——你只会收到与你相关的撤销通知。仅接受公开的 http(s) URL(不接受 localhost 或私有/内部主机)。
在个人中心的 Webhook 一节注册一个 URL。每个 Webhook 仅返回一次签名密钥——请保存在服务端。 在个人中心管理你的密钥 →
事件载荷
发生撤销时,我们会向你的 URL 发送 POST 请求,附带请求头 X-Spondeo-Event: credential.revoked 及下方的 JSON 请求体。其中 status_list.idx 即你已用 /status/{listId} 核对的不透明索引——不含任何 PII。
{
"type": "credential.revoked",
"status_list": { "uri": "https://vouchmesh.com/status/1", "idx": 42 },
"occurred_at": 1717000000000
}
校验签名
每次投递都带有 X-Spondeo-Signature 请求头:它是对完整原始请求体、以你的 Webhook 密钥为密钥计算的十六进制 HMAC-SHA256。请基于原始字节重新计算,并在信任该事件前以常量时间进行比较。
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody is the EXACT bytes you received (do not re-serialize the parsed JSON).
function verify(rawBody, header, secret) {
const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected), b = Buffer.from(String(header || ""));
return a.length === b.length && timingSafeEqual(a, b);
}
通过 AI 智能体集成
三条机器可读的路径让智能体无需抓取本文档即可发现并调用 Spondeo。
- 智能体可读的概览
https://vouchmesh.com/llms.txt一份关于 Spondeo 功能及调用方式的纯文本摘要,供 LLM 直接读取。 - OpenAPI 3.1
https://vouchmesh.com/openapi.json完整的机器可读规范——将代码生成器指向它即可生成带类型的客户端。 - MCP 服务器 仓库的 mcp/ 目录中提供了一个模型上下文协议(MCP)服务器。它暴露两个工具——verify_affiliation_proof 与 sandbox_present。用 cd mcp && npm install && npm start 运行(环境变量 SPONDEO_API_KEY 与 SPONDEO_BASE_URL),然后将其加入你的 MCP 客户端配置:
{
"mcpServers": {
"spondeo": {
"command": "npx",
"args": ["tsx", "/abs/path/to/mcp/spondeo-mcp.ts"],
"env": {
"SPONDEO_API_KEY": "sk_live_…",
"SPONDEO_BASE_URL": "https://vouchmesh.com"
}
}
}
}
错误与限制
缺少或填错密钥的验证调用会返回 401 invalid_api_key。超出每月 500 次的免费层级后,密钥会返回 429 quota_exceeded。所有接口还额外受 IP 速率限制。Spondeo 绝不记录或泄露任何 PII——验证方只会看到持有者选择披露的类别/枚举声明。
401 invalid_api_keyMissing or unrecognized API key.429 quota_exceededPast the free tier of 500 verifications/month.429 rate_limitedPer-IP rate limit; retry after the window resets.