API 文档

REST API v1

从您的系统维护型号、护照、生命周期事件、遥测与证明文件。基于 HTTPS 的 JSON 接口、带权限范围的密钥,以及不写入数据的测试模式。

基础地址
https://app.batteriepasswerk.com/api/v1
版本
1.1.0
版本

目前仅有第 1 版。出现更多版本后可在此处切换。

概览

API 与控制台使用同一套对象模型:型号是产品的主数据层,护照对应唯一一块物理电池,事件与测量值挂在护照之下。全部调用通过同一个基础地址,所有响应均为 JSON,错误也不例外。

一个密钥,一家公司

密钥决定所属公司。非本公司的标识符返回 404 而非 403,无法通过密钥推断其他公司的数据。

没有 DELETE

电池护照负有留存义务。第 1 版仅提供 GET、POST 与 PATCH,生命周期结束通过事件上报。

服务端掌管的字段

必填完成度、电池状态、短码与注册状态由服务端计算,这些字段可读但不可写。

与控制台同一套规则

额度、必填字段与角色完全一致。无法通过 API 创建控制台所禁止的内容。

第 1 步:创建密钥

API 密钥只能在控制台中创建,且只能由具备管理员角色的账户创建。所有者始终具备管理员角色。

  1. 打开集成页面

    在控制台左侧导航的管理分组下选择集成。仅管理员可见该入口。

  2. 创建 API 密钥

    在 API 访问区域点击创建 API 密钥,并填写可标识系统的名称,例如 SAP-North-Prod。

  3. 选择模式与权限范围

    开发使用测试模式,生产使用正式模式;随后选择预设或逐项权限,并可设置 30、90 或 365 天的有效期。

  4. 一次性保存明文

    密钥只显示一次。系统仅保存 SHA-256 哈希,因此事后无人可以读取,包括我们。

请像对待密码一样对待密钥:不要放入代码仓库、前端或日志。一旦泄露,请在控制台轮换密钥,旧密钥立即失效,新密钥只显示一次。

第 2 步:首次调用

GET /me 是连接测试。响应会返回公司、套餐、模式、生效的权限范围、速率限制以及当前合同年度的剩余额度。该调用成功即说明密钥、请求头与网络路径均正确。

export BPW_API_KEY="bpw_test_…"

curl -s https://app.batteriepasswerk.com/api/v1/me \
  -H "Authorization: Bearer $BPW_API_KEY"

第 3 步:在调试台中试用

控制台的集成页面提供 API 调试台入口。您可以从 OpenAPI 描述中选择端点、填写参数,使用当前登录会话而非密钥发送请求,并以可折叠的 JSON 树查看响应。每个调用都可复制为 cURL 直接在终端使用。写操作在调试台中默认以试运行方式执行。

身份验证

每个请求都需携带使用 Bearer 方案的 Authorization 请求头。密钥分为两类,可通过前缀区分。

密钥格式用途
正式bpw_live_ + 48 位十六进制字符生产环境,实际写入
测试bpw_test_ + 48 位十六进制字符开发与验收,不写入数据

接口同时接受已登录控制台用户的会话令牌,此时权限范围由角色决定。这是 API 调试台的工作方式,不适用于系统集成。缺少请求头或密钥无效时返回 401 及 WWW-Authenticate。同一 IP 每分钟失败 30 次后返回 429。

正式、测试与试运行

我们刻意不提供独立的沙箱数据库。测试密钥基于您真实的主数据运行,像生产环境一样校验权限、必填字段、序列号与额度,但不保存任何数据。

正式密钥测试密钥
读取真实数据真实数据
写入写入并返回 201完整校验,返回 200 与 dry_run: true
额度实际消耗仅做检查
日志记录记录并标记为试运行
速率限制每分钟 600 次每分钟 60 次

正式密钥也可以将单次请求作为试运行发送:使用请求头 X-BPW-Dry-Run: true。响应头 X-BPW-Mode 与 X-BPW-Dry-Run 始终表明实际生效的状态。

权限范围

每个密钥只携带调用方系统真正需要的权限。缺少所需权限时,接口返回 403 及 insufficient_scope。

权限范围允许的操作
models:read读取型号、校验草稿
models:write创建与修改型号
passes:read读取护照与事件,包含用于自制二维码的 public_url、gs1_link 与 short_url
passes:write创建与修改护照、上报事件
telemetry:read读取每个护照的遥测时间序列(1.1.0 起)
telemetry:write上报测量值
certificates:read读取并下载证明文件
suppliers:read读取供应商、数据请求与已交付的数值(1.1.0 起)
suppliers:write邀请供应商(1.1.0 起)
audit:read读取审计轨迹(1.1.0 起)

GET /me、GET /field-catalog 与 GET /openapi.json 无需权限范围。控制台预设包括:仅读取(全部读取权限)、ERP 同步、BMS 遥测(读取与上报)、全部、自定义;控制台会说明每个权限范围解锁的端点。每家公司最多十个有效密钥;每次密钥操作都会连同操作人与时间记入审计轨迹。

套餐

校验在每一次调用时执行,而不仅在创建密钥时。套餐变更立即生效:从 Enterprise 降级至 Pro 后,正式密钥仅保留 telemetry:read 与 telemetry:write。

套餐测试密钥正式密钥
Pilot、Starter支持,功能完整不支持
Pro支持仅 telemetry:read 与 telemetry:write
Enterprise支持全部权限范围
Archive、Lifetime支持,仅读取不支持

在留存类套餐中,所有写操作返回 403 及 tenant_read_only。遥测另需 Pro 及以上套餐,与密钥模式无关。

请求与响应

单个对象直接以 JSON 对象返回,列表则包裹在含 data、has_more 与 next_cursor 的结构中。

时间
时间戳为带毫秒的 UTC ISO 8601,日历日期为 YYYY-MM-DD。输入会被规范化;类似 2026-02-30 的日期会被拒绝。
null 与未提交
在 POST 与 PATCH 中,未提交的字段保持不变,null 表示清空该字段。空字符串会转为 null。
未知字段
会被拒绝而非忽略。ERP 中的拼写错误会立即暴露,而不会静默丢失数据。
标识符
小写 UUID。从 ERP 记录定位对象的常用方式是 GET /passes?serial=… 或 GET /models?code=…
字符集与缓存
UTF-8,Content-Type 为 application/json。所有响应均带 Cache-Control: no-store。

响应头

响应头含义
X-Request-Id本次调用的标识符,也出现在每个错误响应体与控制台的 API 日志中。
X-RateLimit-Limit / -Remaining / -Reset当前时间窗的额度,Reset 为 Unix 秒。
X-BPW-Modelive 或 test,取决于所用密钥。
X-BPW-Dry-Run为 true 时表示本次调用未写入任何数据。
Idempotent-Replayed为 true 时表示返回的是此前保存的响应。
Retry-After仅在 429 时出现:需等待的秒数。

错误

所有错误使用同一结构。type 按 HTTP 状态大致分组,code 稳定且供程序判断,message 为英文且可能变化。param 给出第一个出错字段(批量中例如 items[3].serial),details 列出全部。429 与 5xx 可退避重试,4xx 请勿自动重试。

400 Bad Request
HTTP/1.1 400 Bad Request
X-Request-Id: req_7f3c9a21e4b84c60

{
  "error": {
    "type": "invalid_request",
    "code": "validation_failed",
    "message": "One or more fields are invalid.",
    "param": "energy_kwh",
    "details": [
      { "param": "energy_kwh", "code": "invalid_type", "message": "energy_kwh must be a number." },
      { "param": "gtin", "code": "invalid_gtin", "message": "gtin must be a valid GS1 GTIN." }
    ],
    "request_id": "req_7f3c9a21e4b84c60"
  }
}
HTTPcode触发场景
400unknown_field字段不在结构定义中。details 会列出每个未知字段。
400validation_failed型号字段类型错误,details 列出全部相关字段。
400missing_field缺少必填字段,例如 code、model_id 或 serial。
400invalid_enum取值不在允许的列表中。
400invalid_serial序列号不符合 GS1 AI 21 字符集或过长。
400invalid_gtinGTIN 校验位无效。
400invalid_date / invalid_timestamp不是有效的日历日期或 ISO 8601 时间戳。
400duplicate_serial_in_batch同一批次中的两条记录使用了相同的序列号。
400out_of_range / no_measurement遥测数值超出范围,或未提供任何测量值。
400empty_patchPATCH 请求未包含任何可修改字段。
401missing_authorization未发送 Authorization 请求头。
401invalid_api_key密钥未知或格式错误。
401api_key_revoked / api_key_expired密钥已被吊销或已过期。
403plan_required当前套餐不允许该模式或权限范围。
403insufficient_scope密钥缺少该路由所需的权限范围。
403tenant_read_only留存类套餐,写操作被禁止。
404model_not_found / pass_not_found / certificate_not_found对象在您公司内不存在。非本公司的标识符同样返回 404。
404route_not_found路径不存在。可能是拼写错误或缺少 /v1。
405method_not_allowed该路径不支持此方法,Allow 响应头列出允许的方法。
409duplicate_code / duplicate_serial型号代码或序列号在您公司内已存在。
409limit_reached已达套餐额度。可通过 GET /me 查看当前状态。
422idempotency_key_reused相同的 Idempotency-Key 但内容不同。
429rate_limit_exceeded时间窗额度用尽。Retry-After 给出需等待的秒数。
500internal_error意外错误。请提供 request_id 以便排查。

分页

列表每页最多 200 条,默认 50 条。按创建时间倒序排列,遥测按测量时间排序。游标不透明,基于时间戳与标识符而非偏移量:遍历期间新增的数据既不会错位也不会被跳过。增量比对时,请记录上一页最大的 updated_at,并在下次运行时作为 updated_since 提交。

pagination.py
import requests

BASE = "https://app.batteriepasswerk.com/api/v1"
H = {"Authorization": f"Bearer {KEY}"}

def iterate(path, **params):
    cursor = None
    while True:
        r = requests.get(f"{BASE}{path}", headers=H,
                         params={**params, "limit": 200, "cursor": cursor})
        r.raise_for_status()
        page = r.json()
        yield from page["data"]
        if not page["has_more"]:
            return
        cursor = page["next_cursor"]

# Inkrementell: nur was sich seit dem letzten Lauf geändert hat
for p in iterate("/passes", updated_since="2026-09-01T00:00:00Z"):
    print(p["serial"], p["lifecycle_status"])

速率限制

固定 60 秒时间窗。每个响应都会给出剩余额度,超限时返回 429 及 Retry-After。一批 500 份护照仅计为一次请求,因此批量序列化很少触及上限。

调用方限制
正式密钥每分钟 600 次请求
测试密钥每分钟 60 次
调试台会话每分钟 120 次
失败的身份验证每 IP 每分钟 30 次
GET /openapi.json每 IP 每分钟 60 次

幂等性

每个 POST 都可携带 Idempotency-Key 请求头(最多 255 个字符),例如 ERP 中的单据号。

  • 首次执行:正常处理,响应按公司、密钥与幂等键保存 24 小时。
  • 使用完全相同的请求重试:返回已保存的响应并附带 Idempotent-Replayed: true,不会重复执行。
  • 使用不同内容重试:返回 422 及 idempotency_key_reused。
  • 仅保存 2xx 与 4xx。出现 429 或 5xx 后可使用相同的幂等键重试。
# Erster Versuch läuft in einen Timeout - Ergebnis unbekannt
curl -X POST https://app.batteriepasswerk.com/api/v1/passes \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Idempotency-Key: los-2026-09-0042" \
  -H "Content-Type: application/json" \
  -d '{ "items": [ … ] }'

# Gefahrlose Wiederholung mit demselben Schlüssel
# → 201 mit derselben Antwort, zusätzlich: Idempotent-Replayed: true

账户与目录

共十八个端点。每个端点标明所需权限范围、参数与完整示例。所有路径均相对于基础地址。

GET/me权限范围: 无需

连接测试与自身信息

返回公司、套餐、模式、生效的权限范围、速率限制以及当前合同年度的额度。每次集成的第一个调用。

响应
{
  "api_version": "v1",
  "mode": "test",
  "dry_run": true,
  "tenant": { "id": "8f21…c4", "name": "Muster GmbH", "plan": "enterprise" },
  "principal": {
    "kind": "api_key",
    "key": { "id": "0d4e…91", "label": "SAP-Nord-Prod", "prefix": "bpw_test_a1b2c3d4", "expires_at": null }
  },
  "scopes": ["models:read", "models:write", "passes:read", "passes:write", "telemetry:write", "certificates:read"],
  "read_only": false,
  "rate_limit": { "limit": 60, "window_seconds": 60 },
  "usage": {
    "contract_year_start": "2026-03-01T00:00:00.000Z",
    "models": { "used": 3, "max": null, "remaining": null },
    "passes": { "used": 18240, "quota": 25000, "quota_source": "plan",
                "remaining": 6760, "enforcement": "overage",
                "overage_units": 0, "overage_price_eur": 0.05, "blocked": false }
  },
  "server_time": "2026-09-09T08:14:02.118Z"
}
GET/field-catalog权限范围: 无需

必填字段规则与欧盟数据点

每条必填字段规则,包含 71 个欧盟官方数据点编号、法律依据、适用性以及可满足该规则的 API 字段,便于 ERP 将数据点映射到自有字段。

响应
{
  "rules_version": 9,
  "categories": ["lmt", "bess", "ind", "ev", "device", "sli"],
  "sections": ["identity", "conformity", "carbon", "materials", "circularity", "performance", "dynamic"],
  "data": [
    {
      "key": "gtin",
      "section": "identity",
      "resource": "model",
      "fields": ["gtin"],
      "fill_rule": "all",
      "eu_datapoints": [1],
      "legal_ref": "BR Art. 77(3)",
      "applicability": "always",
      "blocker": true,
      "second_life_exempt": false,
      "condition_note": { "de": null, "en": null }
    }
  ]
}
GET/openapi.json权限范围: 无需

机器可读的接口契约

OpenAPI 3.1,无需密钥即可公开获取,是客户端生成器与控制台调试台的基础。

响应
{
  "openapi": "3.1.0",
  "info": { "title": "Batteriepasswerk REST API", "version": "1.0.0" },
  "servers": [{ "url": "https://app.batteriepasswerk.com/api/v1" }],
  "paths": { "/me": { "get": { "operationId": "getMe" } } }
}

型号

GET/models权限范围: models:read

列出型号

最新在前,游标分页。增量比对请使用 updated_since。

参数

名称位置类型说明
limitqueryinteger 1-200每页数量,默认 50。
cursorquerystring上一页 next_cursor 返回的不透明游标。
codequerystring精确的型号代码,最多一个结果。
categoryquerylmt | bess | ind | ev | device | sli法规定义的电池类别。
statusqueryready | review | pending | crit内部处理状态。
updated_sincequeryISO 8601仅返回该时间点之后变更的型号。
curl -s "https://app.batteriepasswerk.com/api/v1/models?category=bess&limit=2" \
  -H "Authorization: Bearer $BPW_API_KEY"
GET/models/{id}权限范围: models:read

读取单个型号

全部业务字段以及服务端计算的必填完成度。未知或非本公司的标识符返回 404。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
curl -s https://app.batteriepasswerk.com/api/v1/models/f76b5107-d6c3-4527-8d04-0c89209bede1 \
  -H "Authorization: Bearer $BPW_API_KEY"
POST/models权限范围: models:write

创建型号

请求体包含可写的型号字段(见字段参考)。未知字段会被拒绝。返回 201 及记录与当前额度;使用测试密钥时返回 200、dry_run 与 id: null。

参数

名称位置类型说明
code *bodystring型号代码,公司内唯一。
categorybodylmt | bess | ind | ev | device | sli决定哪些必填字段适用。
gtinbodystring带有效校验位的 GS1 GTIN,决定公开访问地址。
second_lifebodyboolean依据第 7(5) 与 8(4) 条的二次利用豁免。
applicability_flagsbodyobject of boolean按字段目录中的规则声明不适用。
curl -s -X POST https://app.batteriepasswerk.com/api/v1/models \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: erp-model-4711" \
  -d '{
        "code": "BESS-10",
        "category": "bess",
        "name": "Home Storage 10",
        "chemistry": "LFP",
        "energy_kwh": 10.2,
        "nominal_voltage_v": 51.2,
        "gtin": "04012345678901",
        "ce_marked": true,
        "separate_collection": true
      }'
PATCH/models/{id}权限范围: models:write

更新型号

仅更新所提交的字段,null 表示清空,未提交的字段保持不变。系统会重新计算必填完成度。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
curl -s -X PATCH https://app.batteriepasswerk.com/api/v1/models/f76b5107-… \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "co2_kg_per_kwh": 61.4, "co2_study_url": "https://example.org/lca.pdf" }'
POST/models/validate权限范围: models:read

校验草稿,不写入数据

无状态:返回使用这些值时型号将达到的必填完成度,并列出所有缺失字段。适合在 ERP 中于写入前预检。

curl -s -X POST https://app.batteriepasswerk.com/api/v1/models/validate \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "BESS-10", "category": "bess", "energy_kwh": 10.2 }'

护照

GET/passes权限范围: passes:read

列出护照

最新在前。使用 serial 可精确定位一份护照,这是从 ERP 记录找到护照 ID 的常用方式。

参数

名称位置类型说明
limitqueryinteger 1-200每页数量,默认 50。
cursorquerystring上一页 next_cursor 返回的不透明游标。
model_idqueryuuid仅返回该型号的护照。
serialquerystring精确的序列号。
batchquerystring批次或生产批号。
statusqueryready | review | pending | crit内部处理状态。
lifecycle_statusqueryoriginal | repurposed | re-used | remanufactured | waste法定电池状态,欧盟数据点 67。
created_since / updated_sincequeryISO 8601时间筛选,按大于或等于处理。
curl -s "https://app.batteriepasswerk.com/api/v1/passes?serial=SN-000123" \
  -H "Authorization: Bearer $BPW_API_KEY"
GET/passes/{id}权限范围: passes:read

读取单份护照

单份护照,包含推导的电池状态、最新遥测值、注册状态,以及用于二维码打印和短链接的公开地址。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
curl -s https://app.batteriepasswerk.com/api/v1/passes/ffdad688-745f-475e-aaaa-e23112c0f041 \
  -H "Authorization: Bearer $BPW_API_KEY"
POST/passes权限范围: passes:write

创建护照,单条或批量

传入单个对象创建一份护照,items 最多 500 条即为批量。一次批量仅计为一次请求。批次内重复的序列号始终视为错误。

参数

名称位置类型说明
model_id *bodyuuid必须是您公司的型号。
serial *bodystring, max. 20GS1 AI 21 字符集,公司内唯一。
statusbodyready | review | pending | crit默认为 pending。
batchbodystring, max. 100批次或生产批号。
production_datebodyYYYY-MM-DD生产日期,欧盟数据点 9。
on_conflictbodyerror | skip仅批量可用:skip 跳过已存在的序列号而不中断。
curl -s -X POST https://app.batteriepasswerk.com/api/v1/passes \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: los-2026-09-0042" \
  -d '{
        "items": [
          { "model_id": "f76b5107-…", "serial": "SN-000123", "batch": "B04", "production_date": "2026-09-01" },
          { "model_id": "f76b5107-…", "serial": "SN-000124", "batch": "B04", "production_date": "2026-09-01" }
        ],
        "on_conflict": "skip"
      }'
PATCH/passes/{id}权限范围: passes:write

更新护照

可修改 status、batch 与 production_date。法定电池状态刻意不可直接设置,由事件推导得出。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
curl -s -X PATCH https://app.batteriepasswerk.com/api/v1/passes/ffdad688-… \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "ready" }'

生命周期事件

GET/passes/{id}/events权限范围: passes:read

读取事件链

护照的全部生命周期事件,最新在前。source 为 null 表示控制台录入,api 表示机器上报。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
limitqueryinteger 1-200每页数量,默认 50。
cursorquerystring上一页 next_cursor 返回的不透明游标。
响应
{
  "data": [
    { "id": "9c2e…41a7", "pass_id": "ffdad688-…", "event_type": "market",
      "event_date": "2026-09-05", "note": null, "source": "api",
      "created_at": "2026-09-05T09:12:44.201Z" }
  ],
  "has_more": false,
  "next_cursor": null
}
POST/passes/{id}/events权限范围: passes:write

上报事件

上报生命周期事件。法定电池状态由此推导并在响应中返回。recycled 与 eol 会终止该护照。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
event_type *bodymarket | repaired | reused | secondlife | remanufactured | recycled | eol事件类型。
event_datebodyYYYY-MM-DD默认为今天,按日历日期校验。
notebodystring, max. 500自由文本,例如工单或维修点编号。
curl -s -X POST https://app.batteriepasswerk.com/api/v1/passes/ffdad688-…/events \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "event_type": "secondlife", "event_date": "2031-04-18" }'

遥测

GET/passes/{id}/telemetry权限范围: telemetry:read

读取测量序列

某份护照的测量值,按 recorded_at 排序,最新在前。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
limitqueryinteger 1-200每页数量,默认 50。
cursorquerystring上一页 next_cursor 返回的不透明游标。
响应
{
  "data": [
    { "id": "7a41…c2", "pass_id": "ffdad688-…", "recorded_at": "2026-09-08T22:00:00.000Z",
      "soh_pct": 98.4, "soc_pct": 62, "cycle_count": 142, "negative_event": null,
      "created_at": "2026-09-08T22:00:03.774Z" }
  ],
  "has_more": true,
  "next_cursor": "eyJjIjoiMjAyNi0wOS0wOFQyMjowMDowMFoiLCJpIjoiN2E0MSJ9"
}
POST/passes/{id}/telemetry权限范围: telemetry:write

上报测量值

每次调用至少包含一个测量值或 negative_event。需要 Pro 及以上套餐,与密钥模式无关。超出范围的值返回 400。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
recorded_atbodyISO 8601来自设备的测量时间,默认为接收时间。
soh_pct, soc_pct, cycle_count, …bodynumber测量值,参见遥测字段参考。
negative_eventbodydeep_discharge | overheat | accident负面事件,欧盟数据点 69。
curl -s -X POST https://app.batteriepasswerk.com/api/v1/passes/ffdad688-…/telemetry \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "recorded_at": "2026-09-08T22:00:00Z",
        "soh_pct": 98.4,
        "soc_pct": 62,
        "cycle_count": 142,
        "temp_min_c": 11.2,
        "temp_max_c": 28.7
      }'

证明文件

GET/certificates权限范围: certificates:read

列出证明文件

已上传证明文件的元数据。validity 由 valid_until 推导,expiring 表示 30 天内到期。

参数

名称位置类型说明
limitqueryinteger 1-200每页数量,默认 50。
cursorquerystring上一页 next_cursor 返回的不透明游标。
model_idqueryuuid仅返回该型号的证明文件。
typequeryreach | material | duediligence | co2 | conformity | testreport | disassembly证明文件类型。
statusqueryreview | accepted审核状态。
响应
{
  "data": [
    { "id": "b2c8…19", "name": "UN 38.3 Testzusammenfassung", "type": "testreport",
      "issuer": "TÜV", "model_id": "f76b5107-…", "valid_until": "2027-05-30",
      "validity": "valid", "status": "accepted", "file_name": "un383.pdf",
      "file_size": 481221, "has_file": true }
  ],
  "has_more": false,
  "next_cursor": null
}
GET/certificates/{id}权限范围: certificates:read

含下载链接的证明文件

与列表相同,另含有效期 300 秒的签名下载链接。请勿缓存该链接,需要时重新获取。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
响应
{
  "id": "b2c8…19",
  "name": "UN 38.3 Testzusammenfassung",
  "type": "testreport",
  "validity": "valid",
  "download_url": "https://…/storage/v1/object/sign/certs/…?token=…",
  "download_expires_at": "2026-09-09T08:36:02.000Z"
}

供应商与数据请求

GET/suppliers权限范围: suppliers:read

列出供应商

贵公司至少邀请过一次的所有供应商,每个电子邮件地址一条记录。最新的在前。

参数

名称位置类型说明
limitqueryinteger 1-200每页数量,默认 50。
cursorquerystring上一页 next_cursor 返回的不透明游标。
响应
{
  "data": [
    {
      "id": "3f0c…9a",
      "name": "Zellwerk GmbH",
      "email": "einkauf@zellwerk.example",
      "created_at": "2026-09-09T08:12:40.211Z",
      "updated_at": "2026-09-09T08:12:40.211Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
GET/supplier-requests权限范围: suppliers:read

列出数据请求

发送给供应商的每个数据请求,含状态(invited、progress、delivered、expired)、所请求的字段、截止日期和提醒记录。最新的在前。

参数

名称位置类型说明
limitqueryinteger 1-200每页数量,默认 50。
cursorquerystring上一页 next_cursor 返回的不透明游标。
supplier_idqueryuuid仅此供应商的请求。
model_idqueryuuid仅此型号的请求。
statusqueryinvited | progress | delivered | expired请求状态。
响应
{
  "data": [
    {
      "id": "b7d2…41",
      "supplier_id": "3f0c…9a",
      "supplier_name": "Zellwerk GmbH",
      "supplier_email": "einkauf@zellwerk.example",
      "model_id": "0d1f…c8",
      "model_code": "BESS-10",
      "supplier_type": "cell",
      "status": "delivered",
      "fields": [{ "key": "cobalt_pct", "label": "Kobalt-Anteil", "unit": "%" }],
      "due_date": "2026-10-15",
      "invited_at": "2026-09-09T08:12:41.030Z",
      "expires_at": "2026-11-08T08:12:41.030Z",
      "delivered_at": "2026-09-12T14:03:07.512Z",
      "last_reminder_at": null,
      "reminder_count": 0,
      "created_at": "2026-09-09T08:12:41.030Z",
      "updated_at": "2026-09-12T14:03:07.512Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}
POST/supplier-requests权限范围: suppliers:write

邀请供应商

创建供应商(按电子邮件匹配)以及针对您某个型号的数据请求,并通过电子邮件发送免密码自助服务链接(60 天有效)。该链接仅出现在本次响应中。需要 Starter 及以上套餐,每家公司每小时最多 60 次邀请。试运行会校验全部内容,但不创建也不发送任何内容。

参数

名称位置类型说明
supplier_name *bodystring供应商公司名称,最多 200 个字符。
email *bodye-mail邀请的收件人,用于在贵公司内标识该供应商。
model_id *bodyuuid您的一个型号。
fields *bodyarray请求的字段 { key, label, unit?, label_en?, label_zh? },1 至 30 个。key:a-z、0-9、下划线。
supplier_typebodycell | material | bms供应商类型,可选。
due_datebodyYYYY-MM-DD数据交付截止日期,可选。
curl -s -X POST https://app.batteriepasswerk.com/api/v1/supplier-requests \
  -H "Authorization: Bearer $BPW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: erp-po-4711-cells" \
  -d '{
        "supplier_name": "Zellwerk GmbH",
        "email": "einkauf@zellwerk.example",
        "model_id": "0d1f…c8",
        "supplier_type": "cell",
        "due_date": "2026-10-15",
        "fields": [
          { "key": "cobalt_pct", "label": "Kobalt-Anteil", "unit": "%", "label_en": "Cobalt share" }
        ]
      }'
GET/supplier-requests/{id}权限范围: suppliers:read

读取数据请求及已交付的数值

一个请求及其 submissions:供应商按字段键交付的数值,若为文件证明则包含文件名。

参数

名称位置类型说明
id *pathuuid对象在您公司内的标识符。
响应
{
  "id": "b7d2…41",
  "supplier_name": "Zellwerk GmbH",
  "model_code": "BESS-10",
  "status": "delivered",
  "fields": [{ "key": "cobalt_pct", "label": "Kobalt-Anteil", "unit": "%" }],
  "submissions": [
    {
      "field_key": "cobalt_pct",
      "value": "6.2",
      "file_name": null,
      "file_size": null,
      "submitted_at": "2026-09-12T14:03:07.512Z"
    }
  ]
}

审计轨迹

GET/audit权限范围: audit:read

读取审计轨迹

数据库记录的贵公司每一次写入操作:谁(用户、API 密钥或系统)、做了什么(如 pass.create 的操作、对象、引用)以及何时。seq 与 row_hash 属于每家公司的哈希链,可证明数据未被篡改。最新的在前。

参数

名称位置类型说明
limitqueryinteger 1-200每页数量,默认 50。
cursorquerystring上一页 next_cursor 返回的不透明游标。
entity_typequerymodel | pass | cert | supplier | member | api_key对象类型。
actionquerystring精确操作,如 pass.create、model.update、supplier.invite。
entity_idqueryuuid关于此对象的记录。
actor_kindqueryuser | api_key | system操作者类型。
actor_key_idqueryuuid通过此 API 密钥写入的记录。
sincequeryISO 8601从此时间起。
untilqueryISO 8601至此时间止。
curl -s "https://app.batteriepasswerk.com/api/v1/audit?entity_type=pass&since=2026-09-01T00:00:00Z&limit=100" \
  -H "Authorization: Bearer $BPW_API_KEY"

型号字段

型号的全部可写字段均采用 snake_case,与控制台中的命名一致。EU 列给出对应的欧盟官方数据点编号(若有映射)。字符串上限为 4000 个字符。只读字段:id、readiness、readiness_detail、created_at、updated_at 与 public_url。

标识与管理

字段类型EU
codestring, Pflicht7
namestring-
categorylmt | bess | ind | ev | device | sli6
statusready | review | pending | crit-
gtinstring1
economic_operator_idstring2
manufacturing_sitestring8
weight_kgnumber10
unitsinteger-
warranty_monthsinteger35
second_lifeboolean-
applicability_flagsobject of boolean-

合规

字段类型EU
ce_markedboolean40
separate_collectionboolean40
substance_symbolsstring [ ] 41
conformity_responsiblestring2
conformity_declaration_idstring42
due_diligence_urlstring19

碳足迹

字段类型EU
co2_kg_per_kwhnumber17
carbon_perf_classstring18
co2_phasesobject17
co2_limit_okboolean17
co2_study_urlstring17
lca_method, lca_source_de, lca_source_en, co2_auditorstring-

材料

字段类型EU
chemistrystring12
hazard_de, hazard_en, hazard_detailstring13
substance_impact_de, substance_impact_enstring13
critical_materialsarray15
cathode, anode_de, anode_en, electrolytestring45
active_materials, material_originstring-

循环利用

字段类型EU
rec_cobalt_pct, rec_lithium_pct, rec_nickel_pct, rec_lead_pctnumber20-23
renewable_pctnumber24
recyclate_pctinteger-
eol_info_de, eol_info_enstring43
waste_prevention_url, separate_collection_url, collection_info_urlstring43
recycling_efficiency_pctnumber-
spare_part_numbersstring46
spare_source_postal, spare_source_email, spare_source_webstring47
disassembly_doc_urlstring48
disassembly_cert_iduuid48
safety_measures_urlstring49

性能与耐久性

字段类型EU
energy_kwhnumber11
nominal_voltage_vnumber27
voltage_min_v, voltage_max_vnumber26, 28
rated_capacity_ahnumber25
power_wnumber29
max_power_wnumber30
rated_cyclesinteger31, 59
cycle_life_teststring32
capacity_threshold_pctnumber33
temp_min_c, temp_max_cnumber34
temp_storage_min_c, temp_storage_max_cnumber34
round_trip_pctnumber36
rte_50_pctnumber37
internal_resistance_cell_mohm, internal_resistance_pack_mohmnumber38
c_ratenumber39
capacity_fade_pct, power_fade_pct, rte_fade_pctnumber52, 54, 58
expected_lifetime_yearsnumber60
hazard_classstring-
extinguishing_de, extinguishing_enstring14

护照字段

创建时可写:model_id、serial、status、batch 与 production_date;创建后可通过 PATCH 修改 status、batch 与 production_date。其余字段由服务端掌管。

字段含义
lifecycle_status法定电池状态,由事件链推导(欧盟 67)。
retired_at在上报 recycled 或 eol 后设置。
state_of_health_pct最近一次上报的遥测值。
short_code, short_url公开护照页面的短链接。
public_url, gs1_link型号具备 GTIN 时为 GS1 Digital Link,否则为基于标识符的地址。
registry_status, registry_uri, registry_registered_at, registry_error在欧盟登记系统中的注册状态。
supersedes_pass_id, superseded_by_pass_id二次利用与再制造时的护照链接关系。

事件类型及其推导出的状态

event_type之后的 lifecycle_status含义
market-投放市场。不改变状态,但是法定起点。
repaired-已维修,状态保持不变。
reusedre-used按原用途再使用。
secondliferepurposed二次利用,例如车用电池改作固定储能。
remanufacturedremanufactured再制造。
recycledwaste已回收。终止护照并设置 retired_at。
eolwaste生命周期结束但无回收凭证。

遥测字段

每次调用至少包含一个测量值或 negative_event。超出范围的数值返回 400、out_of_range,并在 param 中指出出错字段。

字段取值范围EU
recorded_atISO 8601-
soh_pct0-100-
soc_pct0-10071
soce_pct0-10061
capacity_kwh≥ 051
power_kw≥ 053
remaining_capacity_ah≥ 062
remaining_power_capability_pct0-10063
remaining_rte_pct0-10064
self_discharge_pct_month≥ 065
ohmic_resistance_mohm≥ 066
internal_resistance_increase_pct≥ 056
cycle_count≥ 0, integer68
negative_eventdeep_discharge | overheat | accident69
temp_min_c, temp_max_c≥ -27370
time_extreme_high_min, time_extreme_low_min, time_charging_extreme_high_min, time_charging_extreme_low_min≥ 070
energy_throughput_kwh, capacity_throughput_ah≥ 0-
notestring, max. 500-

Webhook

API 为拉取模式,Webhook 为推送模式。事件发生时会立即以签名方式推送到您的系统:pass.created、model.updated、supplier.delivered 与 cert.expiring。采用 HMAC-SHA256 签名,失败自动重试。成熟做法是:以 Webhook 作为触发信号,随后通过 API 读取对应资源,使数据始终以 API 为准。通过 API 的调用会触发与控制台操作相同的 Webhook。

版本管理与更新日志

版本体现在路径中。在 v1 内只会新增字段与端点,既有字段、错误码与语义保持不变。如需移除任何内容,我们会至少提前十二个月在此处、OpenAPI 文档中以及通过邮件通知管理员,并在 /v2 下并行运行后续版本。

版本日期变更
1.1.02026-09-09新增权限范围 telemetry:read、suppliers:read、suppliers:write 与 audit:read。新增端点 GET /suppliers、GET 与 POST /supplier-requests、GET /supplier-requests/{id}、GET /audit。已有含 passes:read 的密钥已自动补充 telemetry:read。
1.0.02026-09-09首次发布:型号、护照、事件、遥测、证明文件、字段目录、带试运行的测试密钥、幂等键、游标分页。

常见问题

REST API 现在可用吗?
可用。1.1.0 版本已投入生产:型号、护照、生命周期事件、遥测、证明文件、供应商请求、审计轨迹与字段目录。面向 ERP 与 MES 的完整接口属于 Enterprise 套餐,BMS 遥测接口自 Pro 起包含,而功能完整的测试密钥在所有套餐中均可获得,包括免费的 Pilot。
如何在不生成真实护照的情况下测试?
使用测试密钥。它基于您真实的主数据、权限、必填字段与额度完整校验每个请求,并返回与正式调用相同的结果,但不保存任何数据。我们刻意不提供独立的沙箱数据库,因为其中的虚构数据会随时间与现实脱节。
谁可以创建 API 密钥?
仅具备管理员角色的账户,其中始终包含所有者。该规则在三个层面强制执行:数据库、接口端点与界面。每一次密钥操作都会连同操作人与时间记入审计轨迹。
需要使用哪种编程语言?
任何支持 HTTPS 与 JSON 的语言。无需引入 SDK。如有需要,可基于 OpenAPI 3.1 文档,用常见生成器生成 Java、C#、Python、TypeScript 或 Go 的强类型客户端。
如何通过序列号找到护照 ID?
使用 GET /passes 并传入 serial 参数。序列号在公司内唯一,因此最多一个结果。许多集成会一次性解析出 ID,并在自有系统中与序列号一起保存。
请求超时了怎么办?
使用相同的 Idempotency-Key 重试。如果首次请求已被处理,您会收到已保存的响应而非重复数据。若相同密钥下的内容不一致,接口会拒绝该请求,而不会悄悄执行其他操作。
可以通过 API 删除护照吗?
不可以,这是有意为之。电池护照负有留存义务,因此第 1 版不提供删除操作。生命周期结束通过事件上报,例如回收,之后护照展示其最终状态。
我可以创建多少份护照?
额度取决于套餐,并在每次 GET /me 响应的 usage 中给出。enforcement 字段说明超出额度时的处理方式:hard 表示拒绝,overage 表示按份计费,contract 表示按约定用量且不阻断。

关于集成有疑问?

在初次沟通中,我们会明确哪些数据来自哪个系统、您的密钥需要哪些权限范围,以及序列化如何融入您的生产流程。

更新于 2026 年 9 月 9 日 · API 版本 1.1.0 · 非法律建议 · 以法规原文为准