# Một API key cho nhiều chuỗi: chuyển ví dụ sang chuỗi khác

> Source: https://docs.blockvectra.com/vi/guides/one-key-many-chains/

## 1. Một API key cho tất cả chuỗi được hỗ trợ

Cùng một API key hoạt động trên tất cả chuỗi được hỗ trợ cho JSON-RPC, và cho Data API trên các chuỗi có cung cấp dịch vụ này. API key thuộc tài khoản của bạn và không gắn với một chuỗi cụ thể; không cần tạo API key riêng cho từng mạng.

Tín dụng và giới hạn tốc độ được chia sẻ giữa tất cả mạng cũng như giữa JSON-RPC API và Data API; chúng không được tách theo mạng. Xem quy tắc tính phí chi tiết tại [trang bảng giá](https://blockvectra.com/vi/pricing/).

* **Số dư dùng chung**: Tiền nạp và tín dụng miễn phí áp dụng cho tất cả chuỗi. Lệnh gọi trên bất kỳ chuỗi nào cũng trừ từ cùng số dư tài khoản.
* **Giới hạn tốc độ dùng chung**: Tốc độ nạp lại Compute Unit (CU) và dung lượng burst của một API key áp dụng trên tất cả chuỗi. Giới hạn lệnh gọi mỗi giây của gói miễn phí được chia sẻ giữa tất cả chuỗi được hỗ trợ, thay vì tách riêng cho từng chuỗi.
* **Cách nâng cấp**: Sau khi nạp tiền, bạn không còn bị ràng buộc bởi giới hạn lệnh gọi mỗi giây của gói miễn phí; mỗi API key vẫn chịu giới hạn tốc độ CU và burst, như mô tả trong [tài liệu JSON-RPC](https://docs.blockvectra.com/vi/api/json-rpc/#method-policy).

## 2. Cấu trúc URL và tham số `{chain}`

Mỗi yêu cầu có phạm vi theo chuỗi chỉ định mạng đích trong đường dẫn URL bằng `{chain}`. Tham số `{chain}` là mã định danh slug viết thường của chuỗi (ví dụ `robinhood_mainnet`).

| Dịch vụ                   | Xác thực                     | Mẫu URL                      | Mô tả                                                        |
| ------------------------- | ---------------------------- | ---------------------------- | ------------------------------------------------------------ |
| JSON-RPC                  | API key trong đường dẫn URL  | `POST /v1/{chain}/{api_key}` | Dạng đơn giản nhất, phù hợp với curl và HTTP client          |
| JSON-RPC                  | API key trong header yêu cầu | `POST /v1/{chain}`           | Truyền API key qua header yêu cầu `x-api-key: {api_key}`     |
| Data API                  | Route REST                   | `GET /v1/data/{chain}/…`     | Truyền API key qua header yêu cầu `x-api-key: {api_key}`     |
| Danh sách chuỗi công khai | Không cần xác thực           | `GET /v1/chains`             | Danh sách chuỗi và thông tin tĩnh công khai (không tính phí) |
| Trạng thái công khai      | Không cần xác thực           | `GET /v1/status`             | Trạng thái dịch vụ hiện tại và đầu chuỗi (không tính phí)    |

`GET /v1/chains` trả về cờ `jsonrpc` và `data` cho mỗi chuỗi. Dùng URL JSON-RPC để truy cập chuỗi khi chuỗi cung cấp JSON-RPC, và dùng `GET /v1/data/{chain}/…` khi cờ `data` là `true` (Data API chỉ phục vụ những chuỗi này).

> **Mẹo**: Khi truyền API key qua header yêu cầu, URL phải kết thúc bằng tên chuỗi, **không có** dấu gạch chéo ở cuối. JSON-RPC chỉ được phục vụ tại `/v1/{chain}` và `/v1/{chain}/{api_key}`. Yêu cầu có dấu gạch chéo ở cuối (như `/v1/{chain}/`) hoặc thiếu thành phần chuỗi trả HTTP 404 với body rỗng. Yêu cầu tới `{chain}` không xác định trả HTTP 404 với `error.data.reason: "unknown_chain"` (không tính phí).

## 3. Khám phá chuỗi và khả năng bằng lập trình

Các chuỗi được hỗ trợ và khả năng của chúng được cung cấp động. Không viết cứng danh sách chuỗi tĩnh trong ứng dụng. Thay vào đó, khám phá mạng khả dụng và khả năng của chúng khi chạy:

### Khám phá thông tin tĩnh qua `GET /v1/chains`

Endpoint công khai này không cần xác thực, không tính phí và trả về tất cả chuỗi được cung cấp công khai:

```http
GET /v1/chains
```

Ví dụ phản hồi:

```json
{
  "chains": [
    {
      "chain": "robinhood_mainnet", "name": "Robinhood Chain", "chain_id": 4663,
      "jsonrpc": true,
      "data": true,
      "methods": {
        "allow": ["eth_blockNumber", "eth_call", "eth_chainId", "debug_traceTransaction"],
        "deny": ["eth_newFilter", "eth_newBlockFilter", "eth_newPendingTransactionFilter", "eth_getFilterLogs", "eth_getFilterChanges", "eth_uninstallFilter", "eth_subscribe", "eth_unsubscribe"]
      },
      "max_logs_block_range": 1000,
      "state_window_blocks": 900
    }
  ]
}
```

Tham chiếu trường:

* `chain`: Slug định danh chuỗi (dùng cho `{chain}` trong URL)
* `name`: Tên hiển thị dễ đọc
* `chain_id`: Chain ID EIP-155 (số nguyên thập phân)
* `jsonrpc`: JSON-RPC có được bật hay không
* `data`: Data API có được bật hay không
* `methods`: Chính sách phương thức JSON-RPC của chuỗi, gồm `allow` (phương thức được phép) và `deny` (phương thức bị từ chối rõ ràng)
* `max_logs_block_range`: Khoảng khối tối đa được phép trong một yêu cầu `eth_getLogs`
* `state_window_blocks`: Kích thước cửa sổ trạng thái lịch sử tính bằng khối; `null` khi không bị giới hạn

### Kiểm tra tình trạng hoạt động qua `GET /v1/status`

Endpoint công khai này không cần xác thực, không tính phí và trả về mức độ sẵn sàng của dịch vụ cùng thông tin đầu chuỗi:

```http
GET /v1/status
```

Ví dụ phản hồi:

```json
{
  "checked_at": "2026-09-28T12:00:00Z",
  "gateway": {
    "status": "ok"
  },
  "chains": [
    {
      "chain": "robinhood_mainnet", "name": "Robinhood Chain", "chain_id": 4663,
      "jsonrpc": true,
      "data": true,
      "data_features": ["blocks", "transactions", "address_transactions", "transfers", "token_metadata", "freshness"],
      "status": "ok",
      "head": {
        "block": 73017329,
        "time": "2026-09-28T11:59:58Z",
        "lag_seconds": 2
      }
    }
  ]
}
```

Tham chiếu trường:

* `gateway.status`: Trạng thái dịch vụ (`ok` hoặc `degraded`)
* `chains[].data_features`: Các khả năng Data API cung cấp cho chuỗi này
* `chains[].status`: Trạng thái hoạt động của node (`ok` hoặc `unavailable`)
* `chains[].head`: Đầu chuỗi mới nhất (`block`, `time`, `lag_seconds`)

## 4. Khác biệt giữa các chuỗi cần lưu ý

Khi chuyển giữa các chuỗi, kiểm tra các trường được cung cấp trong `GET /v1/chains`:

1. **Phương thức được phép và chính sách (`methods.allow` / `methods.deny`)**: Các phương thức JSON-RPC khả dụng khác nhau theo mạng dựa trên chính sách phương thức. Yêu cầu phương thức không được phép trả HTTP 200 với mã lỗi JSON-RPC `-32601` (`method not available`, không tính phí).
2. **Khoảng khối log (`max_logs_block_range`)**: Khoảng khối tối đa cho truy vấn `eth_getLogs` khác nhau theo chuỗi. Vượt giới hạn của chuỗi trả HTTP 200 với mã lỗi JSON-RPC `-32602` (`eth_getLogs block range too large`, không tính phí).
3. **Cửa sổ lưu giữ trạng thái (`state_window_blocks`)**: Chuỗi lưu toàn bộ lịch sử trả `null`. Trên chuỗi có cắt bỏ trạng thái, truy vấn trạng thái lịch sử ngoài cửa sổ trả HTTP 200 với mã lỗi JSON-RPC `-32011` (`historical state is not available beyond the most recent <N> blocks`, không tính phí).
4. **Tính năng và phạm vi bao phủ Data API (`data` / `data_features`)**: Các chuỗi cung cấp một bộ dữ liệu được liệt kê trên trang [Chuỗi được hỗ trợ](https://docs.blockvectra.com/vi/chains/). Truy vấn bộ dữ liệu mà chuỗi không hỗ trợ, hoặc khối trước phạm vi đã lập chỉ mục, trả HTTP `422` (`error.code` là `no_coverage`, không tính phí). Khi dịch vụ tạm thời không khả dụng — ví dụ chuỗi đang bận — yêu cầu trả HTTP `503` với header `Retry-After` (không tính phí).

## 5. Ví dụ mã

Mẫu khởi đầu đầy đủ: [blockvectra/multichain-viem](https://github.com/blockvectra/multichain-viem)

Cùng một đoạn mã chạy trên các chuỗi khác nhau bằng cách cập nhật biến chuỗi (hoặc đọc từ `GET /v1/chains`), truy vấn `eth_blockNumber` qua JSON-RPC và độ mới của bộ dữ liệu qua Data API:

**cURL**

```bash
export BLOCKVECTRA_API_KEY="rgw_your_api_key"

# Change the chain variable to target another chain from Supported Chains
CHAIN="robinhood_mainnet"

# 1. JSON-RPC: Query eth_blockNumber (POST /v1/{chain}, key in the x-api-key header).
RPC_URL="https://api.blockvectra.com/v1/$CHAIN"
curl -s "$RPC_URL" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'

# 2. Data API: Query dataset freshness (GET /v1/data/{chain}/status/freshness)
curl -s "https://api.blockvectra.com/v1/data/$CHAIN/status/freshness" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
// Change this variable to target another chain, or read it dynamically from GET /v1/chains
const chain = "robinhood_mainnet";
const apiKey = process.env.BLOCKVECTRA_API_KEY!;

// 1. JSON-RPC: Call eth_blockNumber (POST /v1/{chain})
const rpcUrl = `https://api.blockvectra.com/v1/${chain}`;
const rpcResponse = await fetch(rpcUrl, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": apiKey,
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "eth_blockNumber",
    params: [],
  }),
});
const rpcResult = await rpcResponse.json();
console.log(`[${chain}] JSON-RPC blockNumber:`, rpcResult.result);

// 2. Data API: Query freshness (GET /v1/data/{chain}/status/freshness)
const dataUrl = `https://api.blockvectra.com/v1/data/${chain}/status/freshness`;
const dataResponse = await fetch(dataUrl, {
  headers: {
    "x-api-key": apiKey,
  },
});
const dataResult = await dataResponse.json();
console.log(`[${chain}] Data API freshness:`, dataResult.data);
```


  **Python**

```python
import os
import requests

# Change this variable to target another chain, or read it dynamically from GET /v1/chains
chain = "robinhood_mainnet"
api_key = os.environ["BLOCKVECTRA_API_KEY"]

# 1. JSON-RPC: Call eth_blockNumber (POST /v1/{chain})
rpc_url = f"https://api.blockvectra.com/v1/{chain}"
headers = {
    "Content-Type": "application/json",
    "x-api-key": api_key,
}
rpc_payload = {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_blockNumber",
    "params": [],
}
rpc_resp = requests.post(rpc_url, json=rpc_payload, headers=headers)
print(f"[{chain}] JSON-RPC blockNumber:", rpc_resp.json().get("result"))

# 2. Data API: Query freshness (GET /v1/data/{chain}/status/freshness)
data_url = f"https://api.blockvectra.com/v1/data/{chain}/status/freshness"
data_resp = requests.get(data_url, headers={"x-api-key": api_key})
print(f"[{chain}] Data API freshness:", data_resp.json().get("data"))
```


### Ví dụ phản hồi

Phản hồi thành công của JSON-RPC `eth_blockNumber` (tính phí theo trọng số CU của phương thức):

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x45a27f1"
}
```

Phản hồi thành công của Data API `GET /v1/data/{chain}/status/freshness` (tính phí bằng CU, chỉ phản hồi thành công 2xx mới bị tính phí):

```json
{
  "data": [
    {
      "dataset": "blocks",
      "category": "raw",
      "max_block_number": 72313256,
      "max_day": null,
      "max_time": "2026-09-28T03:41:07Z",
      "seconds_behind": 0,
      "blocks_behind": null,
      "days_behind": null,
      "checked_at": "2026-09-28T03:41:10Z"
    },
    {
      "dataset": "traces",
      "category": "raw",
      "max_block_number": 72313256,
      "max_day": null,
      "max_time": "2026-09-28T03:41:07Z",
      "seconds_behind": 0,
      "blocks_behind": null,
      "days_behind": null,
      "coverage_from_block": 72050949,
      "coverage_to_block": 72313256,
      "coverage_complete": true,
      "checked_at": "2026-09-28T03:41:10Z"
    },
    {
      "dataset": "dex_prices",
      "category": "derived",
      "max_block_number": null,
      "max_day": "2026-09-27",
      "max_time": "2026-09-27T00:00:00Z",
      "seconds_behind": 99667,
      "blocks_behind": null,
      "days_behind": 1,
      "checked_at": "2026-09-28T03:41:10Z"
    }
  ],
  "meta": {
    "chain": "robinhood_mainnet",
    "chain_slug": "ROBINHOOD_MAINNET",
    "chain_external_id": "eip155:4663",
    "as_of_block": 72313256,
    "safe_block": 72313100,
    "finalized_block": 72313000,
    "coverage": "full",
    "refreshed_at": "2026-09-28T03:41:10Z"
  }
}
```

## Các bước tiếp theo

* [Duyệt danh mục bộ dữ liệu](https://blockvectra.com/vi/data/) để xem mọi bộ dữ liệu BlockVectra lập chỉ mục.
* [Xem gói miễn phí và bảng giá](https://blockvectra.com/vi/pricing/#free) để kiểm tra những gì tài khoản của bạn bao gồm.
* [Đăng nhập bảng điều khiển](https://console.blockvectra.com/login/?next=%2Fkeys%2F) để tạo API key.
