包装义务监测
语言: 简体中文

包装义务监测 · 开发者访问

API 和 Webhook

请在以下示例中使用您所订阅产品的 URL。将 API 密钥保存在您的服务器上。 打开交互式 API 文档 ↗

读取公开记录

curl 'https://verpackung.getregisters.com/api/v1/feeds/de-packaging-compliance/records?limit=50&offset=0'

公开响应仅包含每本登记册最近三条记录。更早的记录内容需要 PRO;直接访问记录 URL 只能看到有限预览。即使筛选后的某页没有记录,也应继续跟随 next_offset,直到其值为 null。请引用每条记录的原始 source_url。发布日期和观测日期代表不同事件。

读取 PRO 记录

curl 'https://verpackung.getregisters.com/api/v1/feeds/de-packaging-compliance/records?limit=50&offset=0' \
  -H 'Authorization: Bearer YOUR_SCOPED_KEY'

在账户中创建或轮换密钥. 密钥仅适用于此产品,且仅在付费访问权限有效时可用。

导出格式

PRO 提供 CSV、Excel (.xlsx)、XML、RSS 和 Atom。所有格式均使用您所订阅产品的 API 密钥及相同的筛选条件。例如,可按以下方式将最多 100 条记录下载为 Excel 工作簿:

curl 'https://verpackung.getregisters.com/api/v1/feeds/de-packaging-compliance/records/export.xlsx?limit=100&offset=0' \
  -H 'Authorization: Bearer YOUR_SCOPED_KEY' \
  -D export-headers.txt -o records.xlsx

将 xlsx 替换为 csv、xml、rss 或 atom。添加 document_type=adopted 或 facility_id=YOUR_FACILITY_ID 等筛选条件。跟随响应 Link 请求头中 rel="next" 的链接,直到该链接不再出现,并在每次请求中保留 Authorization 请求头。每页最多 100 条记录;筛选后某页可能为空,但后面仍有下一页。

对于 RSS 和 Atom,请配置支持 Authorization 请求头的阅读器。阅读器 URL 不包含密钥。条目使用稳定的记录 ID;不会翻页的阅读器只接收最新一页。如需获取每条记录,请使用支持分页的 API。

读取记录历史

curl 'https://verpackung.getregisters.com/api/v1/records/RECORD_ID/history?limit=50&offset=0' \
  -H 'Authorization: Bearer YOUR_SCOPED_KEY'

将 RECORD_ID 替换为返回的记录 ID。历史以数组形式返回,最新版本在前。每次将 offset 增加当前页的长度,直到返回页长度小于请求的 limit。新版本可能来自来源变化,也可能来自提取内容修正。

通过 MCP 连接

curl 'https://verpackung.getregisters.com/api/v1/mcp' \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"read_register","arguments":{"feed_id":"de-packaging-compliance"}}}'

访问 PRO 字段时,请添加相同的 Authorization 请求头。此端点也支持 initialize、tools/list 和 notifications/initialized。如需读取完整登记册,请使用上述 REST 分页方式。

验证 Webhook 签名

签名请求头格式为 X-Register-Signature: t=TIMESTAMP,v1=HEX_DIGEST。解析 JSON 前,请先验证原始请求正文。请持久保存已成功处理的 X-Register-Event ID,避免重试导致副作用重复。

import { createHmac, timingSafeEqual } from 'node:crypto';

export function verify(rawBody, header, secret) {
  const fields = Object.fromEntries(header.split(',').map(x => x.split('=')));
  const timestamp = Number(fields.t);
  if (!Number.isFinite(timestamp) || Math.abs(Date.now()/1000 - timestamp) > 300) return false;
  if (!/^[a-f0-9]{64}$/.test(fields.v1 || '')) return false;
  const expected = createHmac('sha256', secret).update(fields.t + '.').update(rawBody).digest();
  const supplied = Buffer.from(fields.v1, 'hex');
  return supplied.length === expected.length && timingSafeEqual(supplied, expected);
}

请在持久记录事件后才返回成功响应。投递重试有次数上限;账户中会显示最近一次记录的结果。确认收到投递,不代表您的应用已完成事件处理。