哪些请求不计费:错误码与计费规则
详细梳理多链服务的计费判定规则。汇总 HTTP 状态码、JSON-RPC 错误码与 Data API 响应下的 CU 扣费条件,说明免费与免扣费异常场景,并提供开发者的错误处理与重试建议。
BlockVectra 服务按计算单元(CU,Compute Unit)计量。调用仅在得到应答后计费。本文汇总 HTTP 状态码、JSON-RPC 接口以及 Data API 在不同响应和错误场景下的计费判定规则,并列出推荐的开发者处理方式。
HTTP 状态码与计费判定
HTTP 层的请求拦截与处理结果计费规则如下:
以下方法规则适用于 /v1/{chain} 与 /v1/{chain}/{api_key} 的普通 HTTP 请求,不涵盖 /v1/chains 等具名路由。有效的 WebSocket 升级按 WebSocket 能力与鉴权规则处理,不套用普通 GET/HEAD 规则。
| HTTP 状态码 | 响应内容 | 场景说明 | 是否计费 | 开发者建议操作 |
|---|---|---|---|---|
| 200 | JSON-RPC 响应(单个或数组) | 正常应答;所有 JSON-RPC 层错误(解析错误、方法拒绝、上游失败、节点错误)也是 200 | 按调用判定 | 检查各调用的 result 或 error;若返回错误,参见下文 JSON-RPC 错误码处理方式 |
| 204 | 空 | 请求中全部调用都是 notification | notification 照常计费 | 无需额外操作 |
| 204 | 空 | OPTIONS 预检,链名已知或未知均如此 | 否 | 使用 POST 发送 JSON-RPC 请求 |
| 400 | 空 | HTTP 报文畸形(请求行或请求头无法解析、非法 chunked 编码)、请求体两次读之间超过 10 s | 否 | 检查 HTTP 请求格式、请求头与传输连贯性 |
| 402 | JSON,-32020 | 余额不足、额度耗尽;余额已知时 error.data 附带 balance_units 与 balance_cu | 否 | 前往控制台账单页或通过 GET /v1/topup/deposit-address(MCP get_deposit_address)获取专属地址链上充值(详见 Agent 充值指南) |
| 403 | 空 | /v1/{chain}、/v1/{chain}/{api_key} 上除 POST、OPTIONS、GET、HEAD 外的方法(链名已知或未知都一样) | 否 | 将 HTTP 请求方法改为 POST |
| 405 | 普通 GET:JSON-RPC -32600,error.data.reason: method_not_allowed;HEAD:空 body。两者均附 Allow: POST | 对已知且公开的链发送普通 GET 或 HEAD,先于 key 检查;即使该链不支持 WebSocket 也一样 | 否 | 使用 POST 调用 JSON-RPC |
| 401 | JSON,-32024(missing_api_key 或 invalid_api_key) | 已知链上没有 key、key 未知或被禁用 | 否 | 在 x-api-key 请求头中传入有效且处于生效中的 API key(新建或轮换的 key 约几秒钟生效,请稍等片刻再试) |
| 404 | POST/GET:JSON-RPC -32600(error.data.reason: unknown_chain);HEAD:空 body,不带 Allow | POST、GET 或 HEAD 到未知或未公开的 {chain},先于 key 检查 | 否 | 检查 URL 中的链名,核对支持的链列表(须为全小写 slug) |
| 404 | 空 body | 未匹配的路径(如 POST /v1、/v1/、POST /v1/{chain}/) | 否 | 在 URL 中补全链路径(/v1/{chain}) |
| 408 | 空 | 从收完请求头到返回响应超过 35 s | 可能:已转发给节点的调用在节点应答后照常计费 | 不要无条件重试会改变状态的调用(如 eth_sendRawTransaction);客户端断开不会撤销已转发的调用 |
| 413 | 空 | 请求体 > 2 MiB(2097152 字节;见完整 OpenAPI 参考中的“10. Limits at a glance”) | 否 | 缩减请求体大小(控制在 2 MiB 以内),拆减批量调用数量 |
| 414 / 431 | 空 | URI 过长(414)或请求头过大(431) | 否 | 缩短请求 URI 或精简 HTTP 请求头 |
| 429 | JSON,-32005 或 -32022;速率超限(-32005)时带 Retry-After;突发/批次过大(-32022)不带 | 桶余量不足(等补充后重试)→ -32005;单个请求的 CU 超过桶容量(等多久都不会成功,需拆小请求)→ -32022;账户调用速率上限余量不足 → -32005;单个请求的调用数超过上限(需拆小请求)→ -32022 | 否 | 若返回 -32005 且带 Retry-After,按其指定秒数等待后重试;若返回 -32022,需拆小请求或减小批次(按原样发送永远不会成功) |
| 503 | JSON,-32021,带 Retry-After | 计费状态暂时无法确认,服务端暂不受理该请求(这不是余额问题,无需充值);刚创建的 key 在系统读到包含其账户的计费数据之前(通常几秒内)也是这个应答,稍后重试即可 | 否 | 这不是余额问题,无需充值;按 Retry-After 秒数等待后稍后重试即可 |
说明:经 Cloudflare 访问时,Cloudflare 自身还可能返回 52x、1015 等错误页,那些不是本服务产生的。
扣费与余额响应头:HTTP 请求(JSON-RPC 与 Data API 均适用)携带
x-bv-meter: 1请求头时,产生扣费的响应会返回x-bv-cu-charged(本次请求计费的 CU,批量请求为合计值)以及x-bv-balance-units(本次扣费后账户的剩余余额单位,透支时可为负;余额未知时不带)。未携带x-bv-meter: 1、未产生计费的响应,以及 402、403、429、503 均不返回这两个响应头;浏览器脚本可通过 CORS 读取这两个响应头;WebSocket 不使用它们。余额扣除的是未结算用量合计向上取整到整数单位后的值;每小时结算向下取整,因此结算后所报余额可能增加最多一个单位。
JSON-RPC 错误码与计费规则
同一个错误码可能来自平台或节点,计费不同:
- 平台自身产生的错误:一律不计费;
- 节点返回的错误:原样透传并按方法权重计费,只有下表标明的节点错误码例外。
规则说明
- 节点免计费错误:节点的
-32002(批处理超时)、-32003(批响应过大)与-32600(批量被整体拒绝)表示节点提前放弃了调用,不计费;同一批里的 notification 也不计费。节点的-32601(已开放但节点未实现的方法)与-32603(节点内部故障)在 HTTP 和 WebSocket 上均不计费,且不影响同批其他调用或 notification。此外,4444(区块已被裁剪)以及超出节点状态回溯窗口(以GET /v1/chains的state_window_blocks为准)的-32000同样不计费,且不影响同批其他调用。 - 节点计费错误:节点返回的其他错误若反映链本身的执行结果,按方法权重计费,例如
execution reverted(-32000或带data的3)、节点自己的-32602 invalid argument。 - 余额准入与同步:
-32020表示账户余额不足,需要充值;余额已知时error.data.balance_units与error.data.balance_cu携带剩余额度(透支时可为负)。刚创建的 key 在最初几秒可能返回-32021(503),按Retry-After等待后重试即可。 - 上游故障:平台自产的
-32603属于上游通信故障或上游响应格式异常(upstream unavailable、no response from upstream、malformed upstream response)时,携带data.reason: upstream_unavailable。 - Notification 计费:notification(204)按方法权重计费。
JSON-RPC 错误码表
| 错误码 | 来源 | HTTP | 错误消息 | reason 标识 | 是否计费 | 开发者建议操作 |
|---|---|---|---|---|---|---|
| -32700 | BlockVectra | 200 | parse error | - | 否(扣 1 CU 限流令牌;见完整 OpenAPI 参考中的“9. Rate limiting”) | 修正 JSON 请求体语法 |
| -32600 | BlockVectra | 200 | invalid request | invalid_request | 否(扣 1 CU 限流令牌;见完整 OpenAPI 参考中的“9. Rate limiting”) | 修正 JSON-RPC 报文字段结构 |
| -32600 | BlockVectra | 200 | batch too large: max <N> calls | batch_too_large (+max) | 否 | 拆分为不超过上限调用的批次(单批上限通常为 100) |
| -32600 | BlockVectra | 200 | invalid request: ambiguous member name | invalid_request | 否 | 消除 JSON 对象中重复或歧义的成员名称 |
| -32601 | BlockVectra | 200 | method not available: <method> | - | 否 | 仅调用当前链允许的方法(核对支持的链方法策略) |
| -32600 | BlockVectra | 404 | unknown chain | unknown_chain | 否 | 检查 URL 中的链名 |
| -32602 | BlockVectra | 200 | eth_getLogs block range too large: max <N> blocks | - | 否 | 缩小 eth_getLogs 查询区块跨度(上限见该链规定,如 1000 块) |
| -32602 | BlockVectra | 200 | tracer not allowed | - | 否 | 改用内置原生 tracer(callTracer、flatCallTracer、prestateTracer、4byteTracer、noopTracer,或缺省) |
| -32602 | BlockVectra | 200 | trace timeout not allowed | - | 否 | 设置合法 duration 且超时时间 ≤ 30s |
| -32010 | BlockVectra | 200 | node is syncing; calls are temporarily unavailable | - | 否 | 节点同步中,稍后重试(eth_chainId 除外) |
| -32011 | BlockVectra | 200 | historical state is not available beyond the most recent <N> blocks | - | 否 | 改查较新的区块(目标区块须在状态窗口内,或避免使用 safe/finalized/earliest 标签) |
| -32000 | BlockVectra | 200 | transaction not found | not_found | 否 | 核对交易哈希(须为 0x + 64 位十六进制) |
| -32000 | BlockVectra | 200 | block not found | not_found | 否 | 核对区块哈希或高度 |
| -32000 | BlockVectra | 200 | upstream response too large | response_too_large | 否 | 缩小查询范围,拆分请求 |
| -32005 | BlockVectra | 200 | - | overloaded | 否 | 服务端临时过载,稍后重试 |
| -32005 | BlockVectra | 429 | rate limit exceeded | key_rate_limit / free_plan_call_limit / concurrency_limit | 否 | 降低发送频率,若带 Retry-After 按其等待 |
| -32022 | BlockVectra | 429 | request cost <N> CU exceeds burst capacity <M> CU | request_exceeds_burst | 否 | 拆小请求或批次,使单次 CU 低于突发上限 |
| -32022 | BlockVectra | 429 | request has <N> calls, exceeding the free-plan limit of <M> calls per second | free_plan_batch_too_large (+max) | 否 | 拆小批次至每秒调用限制以内,或充值升级付费方案 |
| -32603 | BlockVectra | 200 | upstream unavailable | upstream_unavailable | 否 | 上游通信故障,稍后重试 |
| -32603 | BlockVectra | 200 | no response from upstream | upstream_unavailable | 否 | 上游无响应,稍后重试 |
| -32603 | BlockVectra | 200 | malformed upstream response | upstream_unavailable | 否 | 上游响应格式异常,稍后重试 |
| -32603 | BlockVectra | 200 | - | - | 否 | 服务端内部罕见异常,稍后重试 |
| -32020 | BlockVectra | 402 | insufficient balance | balance_exhausted / free_grant_exhausted(附带 topup_url,余额已知时附带 balance_units / balance_cu) | 否 | 前往控制台账单页或通过 GET /v1/topup/deposit-address(MCP get_deposit_address)获取专属地址链上充值(详见 Agent 充值指南) |
| -32021 | BlockVectra | 503 | billing data temporarily unavailable | - | 否 | 计费数据同步中(非余额问题),按 Retry-After 等待后重试 |
| 4444 | 节点 | 200 | pruned history unavailable | - | 否 | 请求的区块已被节点裁剪,不计费,不影响同批其他调用 |
| -32000 | 节点 | 200 | historical state ... is not available | - | 否 | 请求超出节点的状态回溯窗口,不计费,不影响同批其他调用 |
| -32000 | 节点 | 200 | old data not available due to pruning... | - | 否 | 超出节点历史保留范围(窗口以 state_window_blocks 为准),不计费,不影响同批其他调用 |
| -32002 | 节点 | 200 | <node message> | - | 否 | 节点批处理超时提前放弃,不计费;同一批里的 notification 也不计费 |
| -32003 | 节点 | 200 | <node message> | - | 否 | 节点批响应过大提前放弃,不计费;同一批里的 notification 也不计费 |
| -32601 | 节点 | 200 | <node message> | - | 否 | 已开放的方法未被节点实现,改用其他支持的方法 |
| -32603 | 节点 | 200 | <node message> | - | 否 | 节点内部故障,退避后重试 |
| -32600 | 节点 | 200 | <node message> | - | 否 | 批量被节点整体拒绝,不计费;同一批里的 notification 也不计费 |
| 其他 | 节点 | 200 | <node message> | - | 是(方法权重) | 链本身的执行结果(如 execution reverted、节点自己的 -32602),按方法 CU 权重计费;需检查合约调用逻辑或入参 |
Data API 计费规则
Data API 将只读链数据包装为 REST 接口,其计费与错误处理遵循以下规则:
规则说明
- 仅 2xx 成功响应计费。
- 链专有操作不可用或超出覆盖范围(如不支持的链或 trace 覆盖外)返回 HTTP 422
no_coverage,不计费但占限流配额。 - HTTP 401、402、404 与 429 响应均不计费。扣费响应头说明见上方 HTTP 状态码与计费判定。
Data API 状态码表
| HTTP 状态码 | 错误代码 / 场景 | 是否计费 | 开发者建议操作 |
|---|---|---|---|
| 200 | 成功返回数据 | 是(按 Data API 操作 CU 权重) | 正常解析响应中的 data、meta 与 next_cursor |
| 400 | 请求参数无法解析或缺失必要字段 | 否 | 检查并修正请求参数 |
| 402 | 余额耗尽(error.code: "insufficient_balance",余额已知时附带 balance_units 与 balance_cu) | 否 | 前往控制台账单页或通过 GET /v1/topup/deposit-address(MCP get_deposit_address)获取专属地址链上充值(详见 Agent 充值指南) |
| 401 | API key 缺失、未知或被禁用(error.code: "missing_api_key" 或 "invalid_api_key") | 否 | 在 x-api-key 请求头中传入有效且处于生效中的 API key |
| 404 | 链未知或暂未公开(error.code: "not_found")、请求的对象不存在 | 否 | 检查 URL 中的链名(须为全小写 slug)与请求路径 |
| 409 | 请求区块或窗口高于当前已索引高度(error.code: "not_indexed_yet",附带 indexed_through) | 否 | 改查不高于 indexed_through 的区块或稍后重试 |
| 422 | 链专有操作不可用(如该链不支持或在 trace 覆盖范围之外,error.code: "no_coverage") | 否(照常消耗限流配额) | 通过免费无需 key 的 GET /v1/status(data_features)核对链支持的功能 |
| 429 | 超出调用速率限制(error.code: "rate_limited"),或单个请求的 CU 超过该 key 的突发容量(error.code: "cost_exceeds_burst") | 否 | 降低请求频次;拆小过大的请求(超过突发容量的请求按原样重试永远不会成功) |
| 503 | 数据服务暂时不可用(error.code: "unavailable"),或该链繁忙(error.code: "gateway_overloaded") | 否 | 稍后重试;带 Retry-After 时按其等待 |
查询余额(GET /v1/account)
开发者与 Agent 可以直接查询当前 key 对应的余额与限额信息,无需消耗计算单元(CU):
curl -H "x-api-key: $BLOCKVECTRA_API_KEY" https://api.blockvectra.com/v1/account- 完全免费:
GET /v1/account调用自身完全免费,不计费且不产生用量扣除;即使账户余额为 0 或为负数也始终返回 HTTP 200 并携带当前余额(从不返回 402)。 - 鉴权规则:仅从
x-api-key请求头读取 API key(不读取路径中的 key 或 Bearer token)。未带 key 返回 401missing_api_key;key 未知、已禁用或已吊销返回 401invalid_api_key(key 过期返回 403key_expired;服务临时不可用时返回 503auth_unavailable或billing_unavailable并附带Retry-After)。 - 独立限速:每个 key 每秒最多允许 5 次请求,独立于 CU 计量与计费规则;超出后返回 HTTP 429
rate_limited并附带Retry-After响应头(见完整 OpenAPI 参考中的“10. Limits at a glance”)。
响应字段说明:
key_id:API key 自身的标识 ID(不暴露数字账户 ID)。plan:套餐类型(free表示账户拥有免费套餐每秒调用额度;否则为paid)。balance_units:账户剩余余额(单位 units,可为 0 或负数)。balance_cu:按当前折算规则换算后的 CU 余额。balance_as_of_age_ms:服务端自底层读取该余额至今所经历的毫秒数。key:该 key 的限额与生命周期属性:cu_per_sec:该 key 的每秒 CU 速率上限(令牌桶补充速率)。burst_cu:该 key 的 CU 突发容量上限(令牌桶容量)。cu_cap:该 key 的总 CU 上限;未设置时为null。cu_cap_remaining:该 key 剩余的可用 CU 额度(可为 0 或负数);未设置上限时为null。expires_at:RFC 3339 格式的到期时间戳;永不过期时为null。
响应示例:
{
"key_id": "<key_id>",
"plan": "<plan>",
"balance_units": <integer>,
"balance_cu": <integer>,
"balance_as_of_age_ms": <integer>,
"key": {
"cu_per_sec": <integer>,
"burst_cu": <integer>,
"cu_cap": <integer_or_null>,
"cu_cap_remaining": <integer_or_null>,
"expires_at": "<expires_at_or_null>"
}
}定价与升级
所有计费调用的具体开销均按公布的 CU 权重计算:
- 查看各方法与操作的完整权重,请参阅方法权重表与 JSON-RPC CU 计量规则。
- 了解套餐价格与结算细则,请参阅定价页。
- 升级至付费方案:充值后不再受免费套餐的每秒调用次数上限约束;每个 key 仍有 CU 速率与突发上限。
链上充值流程
当账户余额不足或需要提升调用速率上限时,可在控制台按以下流程进行链上充值:
- 登录控制台:登录 BlockVectra 控制台。
- 进入账单页:进入「账单」页面(Billing)。
- 获取专属地址:在「链上充值」卡片中复制账户专属的充值地址或扫描二维码。
- 发起转账:只使用页面明确列出的支持网络与 USDC / USDT / USDG 转账到该专属地址。支持的网络与最低充值金额以控制台账单页为准。
- 自动到账:检测到转账后显示为「处理中」,到账后余额自动增加。
注意事项:
- 只接受控制台列出的网络与代币。转错链或转错代币无法自动入账。
- 每笔转账请确保达到控制台注明的最低充值金额。
- 首次充值成功到账后,账户转为付费账户,解除免费套餐的每秒调用上限。
Agent 或服务器程序可用 API key 直接调用充值接口,见 Agent 程序化充值指南。
Webhook 推送计费
推送按已送达数据事件、成功历史查询与计费地址日分别计价。除事件历史外的管理调用、失败投递、自动重试与控制事件免费。每个已送达事件收取一次费用;客户重放与重组后规范链事件的重投是新的计费投递。地址费按各订阅在 UTC 日内在线期间的最大地址数计算,账户免费地址额度由各订阅共享,较早创建的订阅优先使用。同一地址放在两个订阅中计为两份;添加链只影响事件费用,不增加地址费。
接入、签名校验与投递恢复见区块链 Webhook API 指南。稳定币收款指南提供收款校验与轮询补扫路径;WebSocket 订阅使用自身的连接与通知计量规则。请求错误见错误参考。下表权重来自 GET /v1/plans。
| 用量 | 计费单位 | CU |
|---|---|---|
push.address_day | 计费地址日 | 33 |
push.history | 成功的历史查询请求 | 25 |
push.log | 已送达的数据事件 | 150 |
push.native_transfer | 已送达的数据事件 | 150 |
push.token_transfer | 已送达的数据事件 | 150 |
每账户每 UTC 日免费地址数:1000
每账户每 UTC 日的免费地址额度,由所有订阅组共享,与套餐无关。对每个组,统计其在该日在线期间的最大地址数;按组 ID 升序分配额度。同一地址在两个组中计为两份;组内链的数量不会使地址数成倍增加。整日离线或已删除的组不计入。对每个组,扣除分配给它的额度后,将剩余地址数乘以 `method_weights` 中的 `push.address_day` CU 权重。当前配置的额度来自地址日计费所用的同一定价策略;它不是账户容量上限,也不是每个组各自独立的额度。
示例:10 个已送达的 native.transfer 事件、2 次成功历史查询与 10 个计费地址日,消耗 10 × 150 + 2 × 25 + 10 × 33 = 1880 CU。计费地址日已扣除账户免费地址额度。
下一步
最后更新: