开放平台接入说明
说明如何完成开放平台固定审查能力的接入与联调。
这项能力适合什么场景
如果你希望在另一个产品里直接调用 BidRisk 的招标审查或合同审查能力,而不是让用户手动进入主平台操作,那么当前开放平台就是最合适的接入方式。
当前已开放两个固定能力:
tender_review.v1contract_review.v1
接入形态固定为:
workspace- 完全异步
run webhook + result pull
接入前需要准备什么
在开始联调前,需要先完成应用开通并获取接入凭证。
通常包括:
- 开通应用接入
- 获取 API Key
- 如需接收回调,获取 Webhook 签名密钥
当前凭证发放不通过开放接口完成。
第一步:创建 Workspace
workspace 是开放平台的资料容器。
请求示例:
curl -X POST "http://localhost:8000/platform/v1/workspaces" \
-H "Content-Type: application/json" \
-H "X-API-Key: ${BIDRISK_API_KEY}" \
-d '{
"external_ref": "erp-project-001",
"title": "XX 项目审查"
}'
调用成功后会返回一个 workspace_id,后续上传、状态轮询和能力运行都围绕这个 workspace 进行。
第二步:上传文件
平台提供两种上传方式。
方式一:TUS 断点续传(推荐用于大文件)
适合大型 PDF 或网络不稳定的环境。
先获取当前工作区的上传配置:
curl -X POST "http://localhost:8000/platform/v1/workspaces/${WORKSPACE_ID}/upload-config" \
-H "X-API-Key: ${BIDRISK_API_KEY}"
平台会返回:upload_url、upload_token、project_id、user_id。
上传示例(使用 tus-js-client):
const upload = new tus.Upload(file, {
endpoint: uploadConfig.upload_url,
headers: { "Upload-Token": uploadConfig.upload_token },
metadata: {
filename: file.name,
project_id: String(uploadConfig.project_id),
user_id: String(uploadConfig.user_id),
upload_token: uploadConfig.upload_token,
},
});
upload.start();
方式二:标准 Multipart 上传(简单直观)
适合常规大小文件(如 < 50MB)或无法使用 TUS 客户端的场景。
直接调用以下接口:
curl -X POST "http://localhost:8000/platform/v1/workspaces/${WORKSPACE_ID}/files" \
-H "X-API-Key: ${BIDRISK_API_KEY}" \
-F "file=@/path/to/your/file.pdf"
成功返回:
{
"id": 123,
"filename": "file.pdf",
"parse_status": "pending",
"file_size": 1048576
}
第三步:等待资料就绪
文件上传完成后,不代表可以立刻发起审查。还需要等待平台完成解析与准备状态检查。
轮询接口:
curl "http://localhost:8000/platform/v1/workspaces/${WORKSPACE_ID}/status" \
-H "X-API-Key: ${BIDRISK_API_KEY}"
建议至少满足以下条件后再发起 run:
is_prepare_ready = true- 已有至少一个
parse_status = parsed的文件 - 发起招标审查时,已识别出招标文件,或
recommended_tender_file_id不为空 - 发起合同审查时,至少已有一个
doc_stage = contract的已解析文件
第四步:创建异步 Run
curl -X POST "http://localhost:8000/platform/v1/runs" \
-H "Content-Type: application/json" \
-H "X-API-Key: ${BIDRISK_API_KEY}" \
-d '{
"workspace_id": "'"${WORKSPACE_ID}"'",
"capability_code": "tender_review.v1",
"callback_url": "https://example.internal/api/bidrisk/webhook"
}'
说明:
- 当前支持
tender_review.v1与contract_review.v1 callback_url可选- 返回的
run_id是后续轮询和回调幂等处理的关键标识
第五步:获取结果
方式一:轮询 run 状态
curl "http://localhost:8000/platform/v1/runs/${RUN_ID}" \
-H "X-API-Key: ${BIDRISK_API_KEY}"
开放平台当前使用以下状态:
queuedrunningsucceededfailed
方式二:拉取结果
curl "http://localhost:8000/platform/v1/runs/${RUN_ID}/result" \
-H "X-API-Key: ${BIDRISK_API_KEY}"
成功时会返回四类核心信息:
summarydimensionsfindingsevidences
如果 run 还没结束,会返回:
error_code = run_not_completed
第六步:接收 Webhook
如果创建 run 时传入了 callback_url,平台会在 run 进入终态后回调接收端。
当前支持两个事件:
capability_run.completedcapability_run.failed
请求头包括:
X-BidRisk-Webhook-TimestampX-BidRisk-Webhook-SignatureX-BidRisk-Webhook-Event
签名算法:
- 原文:
timestamp + "." + request_body - 算法:
HMAC-SHA256 - 输出格式:
v1=<hex_digest>
Python 验签示例:
import hashlib
import hmac
def verify_bidrisk_webhook(secret: str, timestamp: str, body: bytes, signature: str) -> bool:
expected = hmac.new(
secret.encode("utf-8"),
timestamp.encode("utf-8") + b"." + body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(f"v1={expected}", signature)
常见阻断原因
创建 run 时,最常见的阻断并不是接口错误,而是资料尚未满足执行条件。当前常见值包括:
no_filesfiles_processingno_parsed_filesmissing_tender_filemissing_contract_file
这些错误通常意味着:
- 文件还没上传
- 文件刚上传完,还在解析
- 还没有可用的招标文件或合同文件
当前边界
第一阶段明确边界如下:
- 仅支持固定能力
tender_review.v1与contract_review.v1 - 不支持自定义 Agent
- 不支持用户自定义规则
- 不支持公开发放 API Key
- 结果交付方式固定为轮询和 webhook
建议的接入顺序
如果你准备做一次最小联调,建议按下面顺序:
- 完成应用开通并获取 API Key
- 创建一个
workspace - 上传一份对应场景的核心文件
- 轮询
workspace/status直到解析完成 - 创建
tender_review.v1或contract_review.v1run - 轮询
runs/{id}或接收 webhook - 拉取
runs/{id}/result