# 快速上手

> 原文地址: https://docs.blockvectra.com/zh/quickstart/

本页只讲最少够用的内容：怎么拿到 API key、怎么选择链、怎么调用 JSON-RPC、Data API 请求长什么样。

## 1. 获取 API key

> **还没有 API key？**
>
> 如果你还没有 BlockVectra API key：请用户登录 [console.blockvectra.com](https://console.blockvectra.com/zh/login/?next=%2Fzh%2Fkeys%2F) 建一个 key，并设置为环境变量 `BLOCKVECTRA_API_KEY`。不要让用户把 key 贴进对话。


前往[控制台](https://console.blockvectra.com/zh/login/?next=%2Fzh%2Fkeys%2F)，用 GitHub、Google 或以太坊钱包登录（首次登录自动开户）。新账户注册即得 3,000 万 CU，无需信用卡。然后创建 API key。创建后可以直接在控制台里发一次测试请求，确认 key 可用。创建时 secret 只显示一次，请立即妥善保存。新建、轮换或吊销 key 后，约几秒钟才在所有接口生效；刚创建的 key 立即调用若返回 404，请稍等片刻再试。若在 Agent 或 CI 等无浏览器环境中运行，可参考[程序化开户指南](https://docs.blockvectra.com/zh/guides/programmatic-signup/)通过钱包签名自主开户建 key。

key 的样子是 `rgw_` 加 64 位十六进制字符，例如 `rgw_1f2e...`（已截断）。请保管好，
拿到 key 的任何人都能消耗你的余额。

> 余额不足时网关返回 HTTP 402（JSON-RPC 错误码为 `-32020`；Data API 为 `error.code` `insufficient_balance`），去控制台[账单页](https://console.blockvectra.com/zh/billing/)查看余额与充值方式。


## 选择链

BlockVectra 的每个端点都按链区分：JSON-RPC 请求在 URL 路径中带上链名 `{chain}`，Data API 请求则在路由前加上链名。当前已开放的链及对应链名见[支持的链](https://docs.blockvectra.com/zh/chains/)。

本页所有示例均使用 `robinhood_mainnet`。

> **提示**：把示例 URL 中的 `robinhood_mainnet` 换成[支持的链](https://docs.blockvectra.com/zh/chains/)里的任一 `{chain}`，即可调用对应链。同一个 API key 适用于所有支持的链。

## 2. 调用 JSON-RPC

JSON-RPC 端点按链区分：`POST /v1/{chain}/{api_key}`（key 放在路径中），或 `POST /v1/{chain}`（key 放在 `x-api-key` 请求头中）。`{chain}` 是链名，与 Data API 使用的链名相同；Robinhood Chain 的链名是 `robinhood_mainnet`，所以本页示例使用的端点是 `https://api.blockvectra.com/v1/robinhood_mainnet`。同一个 API key 可用于所有已支持的链。暂不支持 WebSocket。虽然 API 返回了 `Access-Control-Allow-Origin: *`，但请妥善保管 API key，端点设计为由后端服务调用，而非在浏览器前端代码中直接暴露 key。

key 有三种传法：放在 URL 路径中（`POST /v1/{chain}/{api_key}`，只使用路径中的 key，忽略两个请求头）、放在 `x-api-key` 请求头中，或放在 `Authorization: Bearer <api_key>` 请求头中。

### key 放在 URL 路径中

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

curl -s "https://api.blockvectra.com/v1/robinhood_mainnet/$BLOCKVECTRA_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
```


  **TypeScript**

```ts
import { createPublicClient, http } from "viem";

const key = process.env.BLOCKVECTRA_API_KEY!;
const client = createPublicClient({
  transport: http(`https://api.blockvectra.com/v1/robinhood_mainnet/${key}`),
});

console.log(await client.getBlockNumber());

// 运行方式：npx tsx example.mts
```


  **Python**

```python
import os

from web3 import Web3

w3 = Web3(Web3.HTTPProvider("https://api.blockvectra.com/v1/robinhood_mainnet/" + os.environ["BLOCKVECTRA_API_KEY"]))
print(w3.eth.block_number)
```


  **Go**

```go
// 运行方式：go mod init example && go get github.com/ethereum/go-ethereum && go mod tidy && go run .
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/ethereum/go-ethereum/ethclient"
)

func main() {
	client, err := ethclient.Dial("https://api.blockvectra.com/v1/robinhood_mainnet/" + os.Getenv("BLOCKVECTRA_API_KEY"))
	if err != nil {
		log.Fatal(err)
	}
	number, err := client.BlockNumber(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(number)
}
```


  **Rust**

```toml
[dependencies]
alloy = { version = "1", features = ["provider-http", "rpc-types"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```

```rust
use alloy::providers::{Provider, ProviderBuilder};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("BLOCKVECTRA_API_KEY")?;
    let url = format!("https://api.blockvectra.com/v1/robinhood_mainnet/{key}");
    let provider = ProviderBuilder::new().connect_http(url.parse()?);
    println!("{}", provider.get_block_number().await?);
    Ok(())
}
```


### key 放在请求头中

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

curl -s "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
```


  **TypeScript**

```ts
import { createPublicClient, http } from "viem";

const key = process.env.BLOCKVECTRA_API_KEY!;
const client = createPublicClient({
  transport: http("https://api.blockvectra.com/v1/robinhood_mainnet", {
    fetchOptions: { headers: { "x-api-key": key } },
  }),
});

console.log(await client.getBlockNumber());

// 运行方式：npx tsx example.mts
```


  **Python**

```python
import os

from web3 import Web3

key = os.environ["BLOCKVECTRA_API_KEY"]
# request_kwargs 会整体替换掉 provider 的默认请求头，所以这里必须重新带上
# Content-Type，否则网关无法解析请求体。
headers = {"Content-Type": "application/json", "x-api-key": key}
w3 = Web3(Web3.HTTPProvider("https://api.blockvectra.com/v1/robinhood_mainnet", request_kwargs={"headers": headers}))
print(w3.eth.block_number)
```


  **Go**

```go
// 运行方式：go mod init example && go get github.com/ethereum/go-ethereum && go mod tidy && go run .
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/ethereum/go-ethereum/ethclient"
	"github.com/ethereum/go-ethereum/rpc"
)

func main() {
	ctx := context.Background()
	c, err := rpc.DialOptions(ctx, "https://api.blockvectra.com/v1/robinhood_mainnet", rpc.WithHeader("x-api-key", os.Getenv("BLOCKVECTRA_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}
	number, err := ethclient.NewClient(c).BlockNumber(ctx)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(number)
}
```


  **Rust**

```toml
[dependencies]
alloy = { version = "1", features = ["provider-http", "rpc-types"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
reqwest = "0.13"
```

```rust
use alloy::providers::{Provider, ProviderBuilder};
use alloy::rpc::client::RpcClient;
use reqwest::header::{HeaderMap, HeaderValue};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("BLOCKVECTRA_API_KEY")?;

    let mut headers = HeaderMap::new();
    headers.insert("x-api-key", HeaderValue::from_str(&key)?);
    let http_client = reqwest::Client::builder().default_headers(headers).build()?;

    let rpc_client = RpcClient::new_http_with_client(http_client, "https://api.blockvectra.com/v1/robinhood_mainnet".parse()?);
    let provider = ProviderBuilder::new().connect_client(rpc_client);

    println!("{}", provider.get_block_number().await?);
    Ok(())
}
```


> **不要加结尾斜杠**
>
> 用请求头传 key 时，请按上面的写法原样调用 `https://api.blockvectra.com/v1/robinhood_mainnet`：URL 以链名结尾，**不带**结尾斜杠。
>   JSON-RPC 只在 `/v1/{chain}` 和 `/v1/{chain}/{api_key}` 两种路径上提供，带结尾斜杠（如 `/v1/{chain}/`）或不带链段的请求（如 `/v1` 或 `/v1/`）返回 404 且响应体为空。
>   旧路径 `/v1/{api_key}` 则返回带有 `error.data.reason: "unknown_chain"` 错误的 `404`。


`Authorization: Bearer <api_key>` 请求头同样有效。在 `POST /v1/{chain}` 上，非空的
`x-api-key` 优先于 Bearer；只有 `x-api-key` 缺失或为空时才使用 Bearer。路径传法忽略两个请求头。

### 批量调用

传一个数组即可在一次请求里发起多个调用（单批最多 100 个）。注意每个 API key 都有一个 CU 令牌桶（`cu_per_sec` 补充速率、`burst_cu` 突发容量——默认 400 CU/s、突发 1,600 CU；在控制台 Keys 表按 key 显示）；单个请求（包括整批 JSON-RPC 批量调用）若总 CU 超过该 key 的突发容量，即使未达到 100 个调用的上限也会被拒绝并返回 `-32022 request_exceeds_burst`；需拆分为较小的批次。下面这个例子在一次往返里
同时读取链 ID 和某个地址的余额：

**cURL**

```bash
curl -s "https://api.blockvectra.com/v1/robinhood_mainnet" \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '[
    {"jsonrpc":"2.0","id":1,"method":"eth_chainId"},
    {"jsonrpc":"2.0","id":2,"method":"eth_getBalance","params":["0x1111111111111111111111111111111111111111","latest"]}
  ]'
```


  **TypeScript**

```ts
import { createPublicClient, http } from "viem";

const key = process.env.BLOCKVECTRA_API_KEY!;
const client = createPublicClient({
  transport: http("https://api.blockvectra.com/v1/robinhood_mainnet", {
    batch: true,
    fetchOptions: { headers: { "x-api-key": key } },
  }),
});

// viem 会把同时发出的请求自动合并成一次 JSON-RPC 批量调用。
const [chainId, balance] = await Promise.all([
  client.getChainId(),
  client.getBalance({ address: "0x1111111111111111111111111111111111111111" }),
]);
console.log(chainId, balance);

// 运行方式：npx tsx example.mts
```


  **Python**

```python
import os

from web3 import Web3

key = os.environ["BLOCKVECTRA_API_KEY"]
headers = {"Content-Type": "application/json", "x-api-key": key}
w3 = Web3(Web3.HTTPProvider("https://api.blockvectra.com/v1/robinhood_mainnet", request_kwargs={"headers": headers}))

with w3.batch_requests() as batch:
    batch.add(w3.eth.chain_id)
    batch.add(w3.eth.get_balance("0x1111111111111111111111111111111111111111"))
    chain_id, balance = batch.execute()

print(chain_id, balance)
```


  **Go**

```go
// 运行方式：go mod init example && go get github.com/ethereum/go-ethereum && go mod tidy && go run .
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	"github.com/ethereum/go-ethereum/rpc"
)

func main() {
	ctx := context.Background()
	c, err := rpc.DialOptions(ctx, "https://api.blockvectra.com/v1/robinhood_mainnet", rpc.WithHeader("x-api-key", os.Getenv("BLOCKVECTRA_API_KEY")))
	if err != nil {
		log.Fatal(err)
	}

	var chainID, balance string
	calls := []rpc.BatchElem{
		{Method: "eth_chainId", Result: &chainID},
		{Method: "eth_getBalance", Args: []any{"0x1111111111111111111111111111111111111111", "latest"}, Result: &balance},
	}
	if err := c.BatchCallContext(ctx, calls); err != nil {
		log.Fatal(err)
	}
	for _, call := range calls {
		if call.Error != nil {
			log.Fatal(call.Error)
		}
	}
	fmt.Println(chainID, balance)
}
```


  **Rust**

```toml
[dependencies]
alloy = { version = "1", features = ["provider-http", "rpc-types"] }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
reqwest = "0.13"
```

```rust
use alloy::primitives::{Address, U256};
use alloy::rpc::client::RpcClient;
use reqwest::header::{HeaderMap, HeaderValue};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let key = std::env::var("BLOCKVECTRA_API_KEY")?;

    let mut headers = HeaderMap::new();
    headers.insert("x-api-key", HeaderValue::from_str(&key)?);
    let http_client = reqwest::Client::builder().default_headers(headers).build()?;
    let rpc_client = RpcClient::new_http_with_client(http_client, "https://api.blockvectra.com/v1/robinhood_mainnet".parse()?);

    let address: Address = "0x1111111111111111111111111111111111111111".parse()?;
    let mut batch = rpc_client.new_batch();
    let chain_id = batch.add_call::<_, U256>("eth_chainId", &())?;
    let balance = batch.add_call::<_, U256>("eth_getBalance", &(address, "latest"))?;
    batch.send().await?;

    println!("{} {}", chain_id.await?, balance.await?);
    Ok(())
}
```


响应是一个数组，顺序与请求一致，按 `id` 对应。

如果网关直接拒绝整个批量请求——余额不足、限流、突发容量超限，或超过 100 个调用（见下方[常见错误](#常见错误)）——它会返回一个单独的 JSON-RPC 错误对象而不是数组；此时 viem 的 `batch: true` 模式只会报出一个不透明的 `UnknownRpcError`，请改为单独重试一次调用以查看真实错误。

## 3. 了解 CU 计量

每个被计费的调用都会消耗一定的 &#x2A;*CU（Compute Unit）**：便宜的调用比如 `eth_blockNumber`、
`eth_chainId` 只要 1 CU；常见读取比如 `eth_getBlockByNumber` 是几 CU；较重的调用比如
`eth_call`、`eth_getLogs` 更贵；`debug_trace*` 最贵。
结算按账户、按小时账期汇总扣费，向下取整为整计费单位（1 计费单位 = 1000 CU），未满 1 单位的余数结转到下一期（跨期合计扣费为 `floor(累计 CU / 1000)`）；结算在账期结束约 15 分钟后执行。例如：上期结转 508 CU，本期消耗 2557 CU，合计 3065 CU，本期扣除 3 个计费单位，余数 65 CU 继续结转至下一期。当前价格见[定价](https://blockvectra.com/zh/pricing/)。

完整的方法权重表与错误码见 [API 参考 → JSON-RPC](https://docs.blockvectra.com/zh/api/json-rpc/)；
本页只演示请求的基本形态。

### 常见错误

| 你做了什么                                                                                                                          | 会收到什么                                                        | 建议操作                                                                                                    |
| ------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
| 未知或暂未开放的链名，或旧路径 `/v1/{api_key}`                                                                                                | HTTP `404`，JSON 响应体包含 `error.data.reason: "unknown_chain"`   | 检查 URL 中的链名                                                                                             |
| 不带链段的请求（如 `/v1` 或 `/v1/`），或 API key 缺失、未知或被禁用                                                                                  | HTTP `404`，空 body                                            | 在 URL 中补全链名（`/v1/{chain}`），或使用有效且处于生效中的 API key（刚新建或轮换的 key 约几秒钟生效，请稍等片刻再试）                             |
| 余额为零或为负                                                                                                                        | HTTP `402`，JSON-RPC 错误码 `-32020`                             | 充值或等待免费额度周期补足                                                                                           |
| 请求过于频繁（超出限流或网关临时过载）                                                                                                            | HTTP `429`（或 `200`），JSON-RPC 错误码 `-32005`                    | 稍后重试（若响应头带 `Retry-After` 请按其等待）                                                                         |
| 单个请求或整批调用的 CU 超过 key 突发容量（`burst_cu`，默认 1,600 CU；默认速率 400 CU/s），或免费套餐单批调用数超过每秒上限（25 次/秒）                                                             | HTTP `429`，JSON-RPC 错误码 `-32022`（`request_exceeds_burst`）    | 拆分请求或减小批次（即使未达到 100 个调用上限，按原样发送永远不会成功）                                                                  |
| 上游节点暂时不可用                                                                                                                      | HTTP `200`，JSON-RPC 错误码 `-32603`（`upstream unavailable`），不计费 | 重试请求                                                                                                    |
| 历史状态查询超出该链的状态窗口（以太坊：约最近 250,000 个区块）                                                                                           | HTTP `200`，JSON-RPC 错误码 `-32011`，不计费                         | 改查较新的区块                                                                                                 |
| 交易或区块未找到，或响应过大；以太坊上超出近期窗口的区块 / 收据 / 日志查询亦返回 -32000 "old data not available due to pruning"（不计费，见[支持的链 → 以太坊](https://docs.blockvectra.com/zh/chains/#以太坊)） | HTTP `200`，JSON-RPC 错误码 `-32000`                             | 修改请求（核对交易哈希或区块号；格式不合法的 trace 哈希同样返回交易未找到）                                                               |
| 使用了不支持的 tracer 或超时参数（`debug_trace*`）                                                                                           | HTTP `200`，JSON-RPC 错误码 `-32602`，不计费                         | 改用内置原生 tracer（`callTracer`、`flatCallTracer`、`prestateTracer`、`4byteTracer`、`noopTracer`，或缺省）且超时时间 ≤ 30s |
| 调用了该链方法表不允许的方法（见[支持的链](https://docs.blockvectra.com/zh/chains/)）                                                                                           | HTTP `200`，JSON-RPC 错误码 `-32601`，不计费                         | 仅调用该链允许的方法                                                                                              |
| 请求体不是合法 JSON                                                                                                                   | HTTP `200`，JSON-RPC 错误码 `-32700`，不计费                         | 修正 JSON 请求体语法                                                                                           |
| 单批调用数超过 100                                                                                                                    | HTTP `200`，JSON-RPC 错误码 `-32600`（`batch too large`），不计费      | 拆分为不超过 100 个调用的批次                                                                                       |

以上这些拒绝一律不计费；每个被受理并得到应答的调用按公布的 CU 权重计费，不计费的情况见[错误码表](https://docs.blockvectra.com/zh/api/json-rpc/#错误码表)的「是否计费」列。对于 `debug_trace*` 调用，tracer 必须为内置原生 tracer（`callTracer`、`flatCallTracer`、`prestateTracer`、`4byteTracer`、`noopTracer`，或缺省）且超时时间 ≤ 30s（`-32602`）。

## 4. 调用 Data API

Data API 把只读链数据（区块、交易、余额、持有者、DEX 活动等）包装成 REST/JSON 接口。除 `GET https://api.blockvectra.com/v1/data/chains` 外，所有路由都带链标识前缀：下面路径中的 `robinhood_mainnet` 就是链标识（即 `/chains` 和 `meta` 中的 `chain` 字段）。`GET https://api.blockvectra.com/v1/data/chains` 仅列出已公开的链，只返回 `{"data": [...]}`（没有 `meta`，也没有 `next_cursor`）。请求按 CU 计费（仅对 2xx 成功响应计费）。

每次请求需要带与 JSON-RPC 相同的 API key——通过 `x-api-key` 请求头传递。每个链相关路由的成功响应都使用同一套信封：`data`（数据本体）、`next_cursor`（不透明字符串，只在有下一页时才出现，否则这个字段整个不存在，不是 `null`）、以及 `meta`（`chain`、`chain_slug`（`chain` 的大写形式）、`chain_external_id`、`as_of_block`、`finalized_block`、`coverage`、`refreshed_at`）。每个错误响应一般是 `{"error":{"code","message"}}` 两个字段，仅 `409 not_indexed_yet` 额外带 `indexed_through`（已索引到的最高区块）；如果链未知或暂未公开，网关在检查 key 之前返回HTTP `404`，`error.code` 为 `not_found`（不计费且不占限流；链名必须为全小写 slug）；如果是 API key 缺失、未知或被禁用时，网关返回 HTTP `404` 且 body 为空（与 JSON-RPC 相同）。超出限流时返回 HTTP `429`（`error.code` 为 `rate_limited`，`data.reason` 为 `key_rate_limit`），余额耗尽时返回 HTTP `402`（`error.code` 为 `insufficient_balance`），两者均不计费。超过 2^53 的数值（余额、代币数量）一律是十进制字符串，不是 JSON 数字。

**按区块号查区块：**

**cURL**

```bash
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/blocks/72838701" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const res = await fetch("https://api.blockvectra.com/v1/data/robinhood_mainnet/blocks/72838701", {
  headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
});
const body = await res.json();
console.log(body);

// 运行方式：npx tsx example.mts
```


  **Python**

```python
import os, requests

res = requests.get(
    "https://api.blockvectra.com/v1/data/robinhood_mainnet/blocks/72838701",
    headers={"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]},
)
print(res.json())
```


```json
{
  "data": {
    "number": 72838701,
    "hash": "0x9f2c1e7a4b6d3f805e1c9a72b4d6f1e0a3c8b5d7e2f4a1c6b9d3e7f0a2c4b6d8",
    "parent_hash": "0x1a3c5e7f9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e7b9d1f3a",
    "timestamp": "2026-09-26T05:41:07Z",
    "miner": "0x00000000000000000000000000000000000a4b05",
    "gas_limit": 32000000,
    "gas_used": 4821932,
    "base_fee_per_gas": "100000000",
    "state_root": "0x2b4d6f8a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d",
    "transactions_root": "0x3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f9a1c3e5b7d9f1a3c5e",
    "receipts_root": "0x4d6f8a1c3e5b7d9f1a3c5e7b9d1f3a5c7e9b1d3f5a7c9e1b3d5f7a9c1e3b5d7f",
    "tx_count": 239,
    "size": 48213,
    "l1_block_number": null,
    "extra": {}
  },
  "meta": {
    "chain": "robinhood_mainnet",
    "chain_slug": "ROBINHOOD_MAINNET",
    "chain_external_id": "eip155:4663",
    "as_of_block": 72838957,
    "finalized_block": 72838701,
    "coverage": "full",
    "refreshed_at": "2026-09-27T02:15:03Z"
  }
}
```

高于已索引链头（`as_of_block`）的区块号返回 `409`（`error.code: "not_indexed_yet"`），`indexed_through` 会告诉你已索引到的最高区块——数据还没到，稍后重试即可。不高于 `as_of_block` 但高于 `finalized_block` 的区块号返回 `409`（`error.code: "finality_exceeded"`）。不高于 `finalized_block` 但没有对应行的区块号（从未索引过，或被 reorg 回滚）返回 `404`（`error.code: "not_found"`）——最终性余量因链而异，见[支持的链](https://docs.blockvectra.com/zh/chains/)。

**查看数据新鲜度**（每个被跟踪的数据集落后链头多少，适合做状态页或调用前的自检）：

**cURL**

```bash
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/status/freshness" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const res = await fetch("https://api.blockvectra.com/v1/data/robinhood_mainnet/status/freshness", {
  headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
});
const body = await res.json();
console.log(body);

// 运行方式：npx tsx example.mts
```


  **Python**

```python
import os, requests

res = requests.get(
    "https://api.blockvectra.com/v1/data/robinhood_mainnet/status/freshness",
    headers={"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]},
)
print(res.json())
```


```json
{
  "data": [
    {
      "dataset": "blocks",
      "category": "raw",
      "max_block_number": 72838957,
      "max_day": null,
      "max_time": "2026-09-27T02:15:01Z",
      "seconds_behind": 0,
      "blocks_behind": 0,
      "days_behind": null,
      "checked_at": "2026-09-27T02:15:07Z"
    }
  ],
  "meta": {
    "chain": "robinhood_mainnet",
    "chain_slug": "ROBINHOOD_MAINNET",
    "chain_external_id": "eip155:4663",
    "as_of_block": 72838957,
    "finalized_block": 72838701,
    "coverage": "full",
    "refreshed_at": "2026-09-27T02:15:07Z"
  }
}
```

*（示例已精简：实际响应每个数据集一行，这里只列出 `blocks` 这一行；`traces` 行还会额外带 `coverage_from_block`、`coverage_to_block`、`coverage_complete`。）*

如果该链的新鲜度数据暂时不可用，会返回 `503`（`error.code: "unavailable"`），而不是返回不完整的结果；响应头带 `Retry-After`（秒）——请至少等待该时长后重试。

**查询某地址的 ERC-20 余额**（每 6 小时整体刷新一次的快照，只保留非零余额，按 token 排序）：

**cURL**

```bash
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/balances" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const res = await fetch(
  "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/balances",
  { headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! } },
);
const body = await res.json();
console.log(body);

// 运行方式：npx tsx example.mts
```


  **Python**

```python
import os, requests

res = requests.get(
    "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/balances",
    headers={"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]},
)
print(res.json())
```


```json
{
  "data": [
    { "token": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599", "balance": "500000000", "symbol": "WBTC", "decimals": 8 },
    { "token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "balance": "1250000000", "symbol": "USDC", "decimals": 6 }
  ],
  "meta": {
    "chain": "robinhood_mainnet",
    "chain_slug": "ROBINHOOD_MAINNET",
    "chain_external_id": "eip155:4663",
    "as_of_block": 72838957,
    "finalized_block": 72838701,
    "coverage": "full",
    "refreshed_at": "2026-09-27T02:10:00Z"
  }
}
```

没有任何非零余额的地址仍会返回 `200` + `data: []`——不会是 `404`。可以传 `?limit=`（默认 50，最大 500），并用返回的 `next_cursor` 翻页。

完整的端点覆盖——区块、交易、地址、代币、NFT、DEX、代币化股票——参见 [API 参考 → Data API](https://docs.blockvectra.com/zh/api/data/)。

## 接下来看什么

* [API 参考 → JSON-RPC](https://docs.blockvectra.com/zh/api/json-rpc/) —— 方法、CU 权重、错误码
* [完整 JSON-RPC 参考](https://docs.blockvectra.com/zh/api/json-rpc/reference/) —— 全部支持方法的完整规范、请求参数与返回格式
* [API 参考 → Data API](https://docs.blockvectra.com/zh/api/data/) —— 链数据的 REST 接口
* [数据集](https://docs.blockvectra.com/zh/datasets/) —— 各支持链上可用的派生数据集
* [指南](https://docs.blockvectra.com/zh/guides/) —— API 集成、CU 用量管理与多链工作流实战指南
* [支持的链](https://docs.blockvectra.com/zh/chains/) —— 网络标识符与端点 URL

> **迁移提示**
>
> BlockVectra 现已支持多链。所有链相关请求都会在 URL 中带上链名 `{chain}`（JSON-RPC 形如 `/v1/{chain}/{api_key}`，Data API 形如 `/v1/data/{chain}/…`）。旧路径 `/v1/{api_key}` 返回 HTTP 404 与 `error.data.reason: "unknown_chain"` 错误，而不带链段的请求（如 `/v1` 或 `/v1/`）返回 HTTP 404 且响应体为空。同一个 API key 适用于所有支持的链。


## 常见问题

### 支持哪些链？

目前支持 4 条链：BNB Smart Chain、以太坊、HyperEVM、Robinhood Chain。以 `GET /v1/chains` 为准，新链上线后自动出现。各链实时状态见[状态页](https://blockvectra.com/zh/status/)。 [查看支持的链](https://blockvectra.com/zh/chains/)

### 支持 WebSocket 吗？

不支持。接口规格明确没有 WebSocket：eth_subscribe 与 eth_unsubscribe 返回 -32601；需要跟进新事件时请轮询 eth_getLogs。 [查看 eth_getLogs 与转账指南](https://docs.blockvectra.com/zh/guides/logs-vs-transfers/)

### 能查历史状态和 trace 吗？

可以，但因链而异。历史状态窗口以 /v1/chains 的 state_window_blocks 字段为准（null 表示全历史）；trace 是否开放看该链 methods.allow 是否包含 debug_trace*；单次 eth_getLogs 的区块跨度上限是 max_logs_block_range。 [查看链目录与逐链参数](https://blockvectra.com/zh/chains/)

### 一个 key 能用于所有链吗？

可以。同一个 API key 适用于所有支持链的 JSON-RPC，并在已开放的链上调用 Data API；key 属于账户，不绑定特定链。 [查看「一个 key 切链」指南](https://docs.blockvectra.com/zh/guides/one-key-many-chains/)
