# What is not billed: error codes and billing rules

> Original page: https://docs.blockvectra.com/en/guides/billing-rules/

BlockVectra meters requests in Compute Units (CU). Calls are billed only after a response is obtained; units are not deducted when a request arrives. This guide summarizes the billing determination rules across HTTP status codes, JSON-RPC calls, and the Data API, along with recommended actions for developers.

## HTTP Status Codes and Billing Rules [#http-status-codes-and-billing-rules]

The billing determination and handling rules for HTTP-level responses are as follows:

| HTTP Status | Response Body                                                                                                                           | Scenario                                                                                                                                                                                           | Billed?                                                                                       | Recommended Action                                                                                                                                                             |
| ----------: | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|         200 | JSON-RPC response (single or batch)                                                                                                     | Normal response; all JSON-RPC layer errors (parse error, method rejection, guard, upstream failure, node error) are also 200                                                                       | Evaluated per call                                                                            | Inspect `result` or `error` for each call; if an error is returned, see JSON-RPC error handling below                                                                          |
|         204 | Empty                                                                                                                                   | All calls in the request are notifications                                                                                                                                                         | Notifications are billed as normal                                                            | Notifications are accepted and processed in the background; no extra action required                                                                                           |
|         400 | Empty                                                                                                                                   | Malformed HTTP message (cannot parse request line or headers, invalid chunked encoding), or more than 10 s between two reads of the request body                                                   | No                                                                                            | Check HTTP request syntax, headers, and transmission continuity                                                                                                                |
|         402 | JSON, `-32020`                                                                                                                          | Insufficient balance, allowance exhausted (newly created keys return 503 rather than 402 before billing data is synchronized)                                                                      | No                                                                                            | Go to the Console [billing page](https://console.blockvectra.com/en/billing/) to check your balance and top up                                                                 |
|         403 | Empty                                                                                                                                   | Methods other than `POST` or `OPTIONS` on `/v1/{chain}` or `/v1/{chain}/{api_key}` (regardless of whether chain name is known)                                                                     | No                                                                                            | Change the HTTP request method to `POST` (or cross-origin `OPTIONS` preflight)                                                                                                 |
|         404 | JSON, `-32600` (`reason = unknown_chain`)                                                                                               | `POST` to an unknown `{chain}` (request body not read, key not checked)                                                                                                                            | No                                                                                            | Check the chain name in the URL against [Supported Chains](/en/chains/) (must be exact lowercase slug)                                                                         |
|         404 | empty body                                                                                                                              | Missing key on known chain, key unknown or disabled; unmatched path (e.g. `POST /v1`, `/v1/`, `POST /v1/{chain}/`)                                                                                 | No                                                                                            | Include chain in URL (`/v1/{chain}`) or provide an active API key in `x-api-key` header (brand-new or rotated keys take a few seconds to take effect; wait a moment and retry) |
|         408 | Empty                                                                                                                                   | Exceeded 35 s from reading request headers to returning response                                                                                                                                   | **Possible**: calls already forwarded to the node are billed as normal once the node responds | Do not unconditionally retry state-changing calls (e.g. `eth_sendRawTransaction`); a client disconnect does not cancel calls already forwarded                                 |
|         413 | Empty                                                                                                                                   | Request body > 2 MiB (2,097,152 bytes), checked after auth and balance admission                                                                                                                   | No                                                                                            | Keep request body under 2 MiB; split batches into smaller requests                                                                                                             |
|   414 / 431 | Empty                                                                                                                                   | URI too long (414) or request headers too large (431)                                                                                                                                              | No                                                                                            | Shorten request URI or trim HTTP request headers                                                                                                                               |
|         429 | JSON, `-32005` or `-32022`; carries `Retry-After` when CU token bucket is depleted (`-32005`); account rate limit 429 does not carry it | Bucket balance depleted → `-32005`; single request CU exceeds burst capacity → `-32022`; account call rate limit depleted → `-32005`; calls in single request exceed limit → `-32022`              | No                                                                                            | For `-32005` with `Retry-After`, wait the specified seconds before retrying; for `-32022`, split the request or reduce batch size (retrying as-is will never succeed)          |
|         503 | JSON, `-32021`, with `Retry-After`                                                                                                      | Billing data temporarily unavailable; server temporarily rejects request (not a balance issue, no need to top up); newly created keys return this until billing data syncs (usually a few seconds) | No                                                                                            | Not a balance issue, no need to top up; wait the seconds specified in `Retry-After` and retry                                                                                  |

> Note: When accessed through Cloudflare, Cloudflare may return 52x or 1015 error pages; these are not generated by the service.

## JSON-RPC Error Codes and Billing Rules [#json-rpc-error-codes-and-billing-rules]

The same error code can originate from the platform or the node, and **billing differs**:

* **Errors generated by the platform itself**: never billed;
* **Errors returned by the node**: passed through as-is and billed at the method weight, with only the node error codes listed below as exceptions.

### Rule Details [#rule-details]

* **Node errors not billed**: The node's `-32002` (batch timeout), `-32003` (batch response too large), and `-32600` (batch rejected as a whole) indicate that the node abandoned the call early and are not billed; notifications in the same batch are also not billed. `4444` indicates the requested block was pruned by the node (the node retains roughly 7 days of history), is not billed, and does not affect other calls in the batch. `-32000` (only for `historical state ... is not available`, and Erigon's `old data not available due to pruning...`) indicates the request falls outside the node's state history window (roughly 128 blocks), is not billed, and does not affect other calls in the batch. Erigon has a window of about 36 days, is not billed, and does not affect other calls in the batch.
* **Node errors billed**: Other errors returned by the node count as work done by the node and are billed at the method weight, such as `execution reverted` (`-32000` or `3` with `data`), the node's own `-32602 invalid argument`, or `-32601` returned for an `eth_*` method that passed platform admission but is not implemented by the node.
* **Balance admission and sync**: `-32020` indicates insufficient account balance and requires a top-up; `-32021` indicates billing data is temporarily unavailable and the request is temporarily rejected—this is not a balance issue, no need to top up, simply wait the seconds specified in `Retry-After` and retry. A newly created key returns `-32021` before the system reads billing data for its account (usually within a few seconds), not `-32020`; after reading, accounts with balance are accepted as normal, while accounts truly depleted or deleted receive `-32020` (402).
* **Upstream failures**: A `-32603` generated by the platform due to upstream communication failure or malformed response (`upstream unavailable`, `no response from upstream`, `malformed upstream response`) carries `data.reason: upstream_unavailable`; `internal gateway error` is generated only in extremely rare cases of internal task panic or cancellation, does not represent upstream failure, and carries no `data.reason`.
* **Notification billing**: Notifications (204) are billed as normal. Notifications are billed when the node processes the batch successfully: upstream HTTP 2xx; when the batch has calls with an id, at least one received a normal response and there are no `-32002`/`-32003`/`-32600` elements; requests containing only notifications are billed if the upstream returns 2xx with an empty body.

### JSON-RPC Error Codes Table [#json-rpc-error-codes-table]

|   Code | Source      | HTTP | Message                                                                        | Reason                                                          | Billed?                          | Recommended Action                                                                                                    |
| -----: | ----------- | ---: | ------------------------------------------------------------------------------ | --------------------------------------------------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| -32700 | BlockVectra |  200 | `parse error`                                                                  | -                                                               | No (costs 1 CU rate-limit token) | Fix request JSON syntax                                                                                               |
| -32600 | BlockVectra |  200 | `invalid request`                                                              | `invalid_request`                                               | No (costs 1 CU rate-limit token) | Fix JSON-RPC request syntax and structure                                                                             |
| -32600 | BlockVectra |  200 | `batch too large: max <N> calls`                                               | `batch_too_large` (+max)                                        | No                               | Split batch into calls under the limit (standard batch limit is 100)                                                  |
| -32600 | BlockVectra |  200 | `invalid request: ambiguous member name`                                       | `invalid_request`                                               | No                               | Remove duplicate or ambiguous member names in JSON objects                                                            |
| -32601 | BlockVectra |  200 | `method not available: <method>`                                               | -                                                               | No                               | Call only methods allowed for this chain (see [Supported Chains](/en/chains/))                                        |
| -32600 | BlockVectra |  404 | `unknown chain`                                                                | `unknown_chain`                                                 | No                               | Check the chain name in the URL                                                                                       |
| -32602 | BlockVectra |  200 | `eth_getLogs block range too large: max <N> blocks`                            | -                                                               | No                               | Narrow the `eth_getLogs` block range (limit defined per chain, e.g. 1000 blocks)                                      |
| -32602 | BlockVectra |  200 | `tracer not allowed`                                                           | -                                                               | No                               | Use an allowed native tracer (`callTracer`, `flatCallTracer`, `prestateTracer`, `4byteTracer`, `noopTracer`, or omit) |
| -32602 | BlockVectra |  200 | `trace timeout not allowed`                                                    | -                                                               | No                               | Set a valid Go duration string with timeout ≤ 30s                                                                     |
| -32010 | BlockVectra |  200 | `node is syncing; calls are temporarily unavailable`                           | -                                                               | No                               | Node is syncing, retry later (except for `eth_chainId`)                                                               |
| -32011 | BlockVectra |  200 | `historical state is not available beyond the most recent <N> blocks`          | -                                                               | No                               | Query a more recent block (target block must be within the state window; avoid safe/finalized/earliest tags)          |
| -32000 | BlockVectra |  200 | `transaction not found`                                                        | `not_found`                                                     | No                               | Verify transaction hash (`0x` + 64 hex characters)                                                                    |
| -32000 | BlockVectra |  200 | `block not found`                                                              | `not_found`                                                     | No                               | Verify block hash or number                                                                                           |
| -32000 | BlockVectra |  200 | `upstream response too large`                                                  | `response_too_large`                                            | No                               | Narrow query scope or split requests                                                                                  |
| -32005 | BlockVectra |  200 | `gateway overloaded, retry later`                                              | `overloaded`                                                    | No                               | Server temporarily overloaded, retry later                                                                            |
| -32005 | BlockVectra |  429 | `rate limit exceeded`                                                          | `key_rate_limit` / `free_plan_call_limit` / `concurrency_limit` | No                               | Reduce request frequency; honour `Retry-After` when present                                                           |
| -32022 | BlockVectra |  429 | `request cost <N> CU exceeds burst capacity <M> CU`                            | `request_exceeds_burst`                                         | No                               | Split request or batch so single-request CU is below burst capacity                                                   |
| -32022 | BlockVectra |  429 | `request has <N> calls, exceeding the free-plan limit of <M> calls per second` | `free_plan_batch_too_large` (+max)                              | No                               | Split batch to fit under per-second limit, or upgrade to a paid plan                                                  |
| -32603 | BlockVectra |  200 | `upstream unavailable`                                                         | `upstream_unavailable`                                          | No                               | Upstream communication failure, retry later                                                                           |
| -32603 | BlockVectra |  200 | `no response from upstream`                                                    | `upstream_unavailable`                                          | No                               | Upstream did not respond, retry later                                                                                 |
| -32603 | BlockVectra |  200 | `malformed upstream response`                                                  | `upstream_unavailable`                                          | No                               | Upstream response malformed, retry later                                                                              |
| -32603 | BlockVectra |  200 | `internal gateway error`                                                       | -                                                               | No                               | Rare internal error, retry later                                                                                      |
| -32020 | BlockVectra |  402 | `insufficient balance`                                                         | `balance_exhausted` / `free_grant_exhausted`                    | No                               | Go to Console [billing page](https://console.blockvectra.com/en/billing/) to top up, or wait for free refill          |
| -32021 | BlockVectra |  503 | `billing data temporarily unavailable`                                         | -                                                               | No                               | Billing data syncing (not a balance issue); wait `Retry-After` seconds and retry                                      |
|   4444 | Node        |  200 | `pruned history unavailable`                                                   | -                                                               | No                               | Requested block was pruned by node (\~7-day history retention); not billed; does not affect batch                     |
| -32000 | Node        |  200 | `historical state ... is not available`                                        | -                                                               | No                               | Outside node state history window (\~128 blocks); not billed; does not affect batch                                   |
| -32000 | Node        |  200 | `old data not available due to pruning...`                                     | -                                                               | No (Erigon, ETH mainnet)         | Outside node history window (Erigon \~36-day window); not billed; does not affect batch                               |
| -32002 | Node        |  200 | `<node message>`                                                               | -                                                               | No                               | Node timed out on batch and abandoned call; not billed; notifications in batch also not billed                        |
| -32003 | Node        |  200 | `<node message>`                                                               | -                                                               | No                               | Node batch response too large and abandoned; not billed; notifications in batch also not billed                       |
| -32600 | Node        |  200 | `<node message>`                                                               | -                                                               | No                               | Entire batch rejected by node; not billed; notifications in batch also not billed                                     |
|  Other | Node        |  200 | `<node message>`                                                               | -                                                               | **Yes** (method weight)          | Node performed work (e.g. `execution reverted`, node `-32602`, node `-32601`); check contract call parameters         |

## Data API Billing Rules [#data-api-billing-rules]

The Data API wraps read-only chain data into REST endpoints. Its billing and error handling follow these rules:

### Rule Details [#rule-details-1]

* "A Data API request is billed only when it succeeds."
* "Requests are metered and billed in Compute Units (CU); only 2xx successful responses are billed."
* "Chain-specific operations that are unavailable (e.g. unsupported chain or outside trace coverage) return HTTP 422 and are not billed."
* "Requests outside our data coverage are not billed but may count toward rate limits."
* "There are two exceptions for 404 errors: an unknown or not-public chain returns HTTP 404 with `error.code` `not_found` (decided before the key check, not billed, and not rate-limited; chain names must be exact lowercase slugs), while a missing, unknown, or disabled API key gets HTTP 404 with an empty body (identical to JSON-RPC). Requests exceeding rate limits return HTTP 429 (`error.code` `rate_limited` with `data.reason` `key_rate_limit`), and exhausted balances return HTTP 402 (`error.code` `insufficient_balance`); neither is billed."

### Data API Status Codes Table [#data-api-status-codes-table]

| HTTP Status | Error Code / Scenario                                                                                                                                                                                        | Billed?                                | Recommended Action                                                                                                       |
| ----------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
|         200 | Successful data response                                                                                                                                                                                     | **Yes** (Data API operation CU weight) | Parse `data`, `meta`, and `next_cursor` in the response envelope                                                         |
|         400 | Request parameters malformed or missing required fields                                                                                                                                                      | No                                     | Check and fix query or body parameters                                                                                   |
|         402 | Balance exhausted (`error.code: "insufficient_balance"`)                                                                                                                                                     | No                                     | Go to Console [billing page](https://console.blockvectra.com/en/billing/) to check balance and top up                    |
|         404 | Unknown or not-public chain (`error.code: "not_found"`, decided before the key check; does not count against rate limits), requested object does not exist, or API key missing/unknown/disabled (empty body) | No                                     | Check the chain slug in the URL (must be exact lowercase); pass a valid key in the `x-api-key` header                    |
|         409 | Requested block is above the current indexed height (`error.code: "not_indexed_yet"`, includes `indexed_through`)                                                                                            | No                                     | Query blocks up to `indexed_through` or retry later                                                                      |
|         409 | Requested block is above `finalized_block` (`error.code: "finality_exceeded"`)                                                                                                                               | No                                     | Wait until the block is finalized, or query an older block                                                               |
|         422 | Chain-specific operation unavailable (e.g. unsupported chain or outside trace coverage, `error.code: "no_coverage"`)                                                                                         | No (counts toward rate limits)         | Verify chain capabilities via `GET https://dev-api.blockvectra.network/v1/data/chains` to avoid queries outside coverage |
|         429 | Rate limit exceeded (`error.code: "rate_limited"`), or a single request costs more than the key's burst capacity (`error.code: "cost_exceeds_burst"`)                                                        | No                                     | Reduce request frequency; split oversized requests (a burst-exceeding request will never succeed as sent)                |
|         503 | Data service temporarily unavailable (`error.code: "unavailable"`), or the chain is busy (`error.code: "gateway_overloaded"`)                                                                                | No                                     | Retry later and honour `Retry-After` when present                                                                        |

> **Testing note**: These rules were confirmed on 2026-09-30 with a new free-plan account on the production environment: rejected methods (`-32601`), a syncing node (`-32010`), and the Data API's `409 finality_exceeded` and `422 no_coverage` did not add to usage, while successful calls were metered at the weights published by `GET /v1/plans`. This is a single observation, not a guarantee.

## Pricing and Upgrades [#pricing-and-upgrades]

The specific cost for all billed calls is determined by published CU weights:

* To inspect weights for all methods and operations, see the [method weight table](https://blockvectra.com/en/pricing/) and the [JSON-RPC CU Metering Rules](/en/api/json-rpc/#cu-metering-rules).
* For plan pricing and settlement details, see the [Pricing page](https://blockvectra.com/en/pricing/).
* Upgrading to a paid plan: making a paid top-up removes the Free Plan's per-second call limit; each key remains subject to CU rate and burst limits.

## Next steps [#next-steps]

* [Browse the datasets directory](https://blockvectra.com/en/data/) to see every dataset BlockVectra indexes.
* [See the free plan and pricing](https://blockvectra.com/en/pricing/#free) to check what your account includes.
* [Log in to the console](https://console.blockvectra.com/en/login/?next=%2Fen%2Fkeys%2F) to create an API key.
