Source: https://cryptanio.com/zh/docs.html
Contract / release / updated: v1 / 1.0.0 62 / 2026-10-10

# API 文档

将 Cryptanio 连接到您的应用。

合同 v1 / 1.0.0 62 / 2026-10-10

[Markdown](https://cryptanio.com/zh/docs.md) [OpenAPI](https://cryptanio.com/openapi.json) [供 AI 智能体使用](https://cryptanio.com/docs/llms.txt)

## 开始使用

API 供您的服务器使用。请先在 Account 中配置项目、服务和地址池；API 在这些范围内执行密钥授权的操作。

- 验证账户，并在[我的服务](https://account.cryptanio.com/finance/services)中启用所需服务。
- 创建仅具备最低所需权限的 [API 密钥](https://account.cryptanio.com/api-keys)，并保存在服务器上。
- 选择任务：[监控地址](https://cryptanio.com/zh/docs.html#quickstart)、[创建账单](https://cryptanio.com/zh/docs.html#invoices)或[接收事件](https://cryptanio.com/zh/docs.html#webhooks)。

示例会对线上数据执行真实操作。创建或删除对象可能消耗服务配额。密钥从不嵌入示例，而是从环境变量读取。

## 给智能体的指令

将此指令粘贴到智能体的聊天或项目规则中。它帮助智能体了解服务、定价和参考文档，然后使用 REST API 或 SDK 编写应用集成。智能体可以使用您的语言回答。



### Agent instructions

```text
Learn how to integrate a server-side application with Cryptanio's public REST API before proposing or writing integration code.

Start here:
- Website: https://cryptanio.com/
- Documentation index: https://cryptanio.com/llms.txt
- Product, services and pricing: https://cryptanio.com/cryptanio.md
- API integration index: https://cryptanio.com/docs/llms.txt
- API guide: https://cryptanio.com/docs.md
- Exact API v1 contract: https://cryptanio.com/openapi.json
- FAQ: https://cryptanio.com/faq/index.md
- SDK setup and examples: https://cryptanio.com/docs.html#sdk

Read the relevant method reference before using it. Use the public API at https://api.cryptanio.com/v1. Do not assume a public sandbox exists.
Use HTTP requests or the documented SDK for the application's language. Match request fields, response schemas and errors to OpenAPI; do not invent endpoints or SDK methods.
Check the actual enabled networks, service, project and API key permissions. Product documentation is not evidence of a live payment, balance or deployment.
Keep API keys in the user's server environment or secret store. Never ask the user to paste a key into chat or put it in a URL, browser bundle or log.
Default to reading. Create, change or delete objects only when the user authorizes the specific task. Explain quota or billing consequences before a write.
Follow the documented confirmation, webhook verification, pagination and retry rules. Reuse an invoice's original Idempotency-Key and request when retrying.
Show the returned chain, asset, address, amount and expiry. Preserve payment_route.kind and its exact string value: destination_tag, memo, comment or reference is mandatory when present. The merchant order reference is a separate field.
For a payment QR use the returned payment_uri when present. A Solana Pay reference is not a wallet memo; do not rebuild its URI or replace it with a plain address. Offer the exact returned checkout_url only to the payer; never construct a checkout URL from an invoice ID. Neither a checkout redirect nor a QR scan confirms payment.
Distinguish pending, confirmed, rolled-back and simulated data. If a fact is unavailable, say so instead of guessing.
Answer the user's questions in their language. If a necessary product decision is not documented, ask instead of inventing it.
```



此段内容不含密钥或账户数据。请为集成使用最低所需权限的 API 密钥，并保存在应用服务器上。不要在智能体聊天中分享密钥。

## API 参考

### Monitoring 监控

[POST /v1/watches 创建 Monitoring 监控](https://cryptanio.com/zh/docs/reference/create-watch/) [GET /v1/watches 列出 Monitoring 监控](https://cryptanio.com/zh/docs/reference/list-watches/) [GET /v1/watches/{id} 获取 Monitoring 监控](https://cryptanio.com/zh/docs/reference/get-watch/) [DELETE /v1/watches/{id} 删除 Monitoring 监控](https://cryptanio.com/zh/docs/reference/delete-watch/)

### 事件

[GET /v1/events 列出事件](https://cryptanio.com/zh/docs/reference/list-events/)

### Payments

[GET /v1/payments 列出 Payments 事件](https://cryptanio.com/zh/docs/reference/list-payments/)

### 账单

[POST /v1/invoices 创建账单](https://cryptanio.com/zh/docs/reference/create-invoice/) [GET /v1/invoices 列出账单](https://cryptanio.com/zh/docs/reference/list-invoices/) [GET /v1/invoices/{id} 获取账单](https://cryptanio.com/zh/docs/reference/get-invoice/) [POST /v1/invoices/{id}/cancel 取消账单](https://cryptanio.com/zh/docs/reference/cancel-invoice/)

### Webhook

[POST /v1/endpoints 创建 webhook 端点](https://cryptanio.com/zh/docs/reference/create-endpoint/) [GET /v1/endpoints 列出 webhook 端点](https://cryptanio.com/zh/docs/reference/list-endpoints/) [DELETE /v1/endpoints/{id} 删除 webhook 端点](https://cryptanio.com/zh/docs/reference/delete-endpoint/)

### SSE

[GET /v1/stream 流式接收事件](https://cryptanio.com/zh/docs/reference/stream-events/)

### API 健康状态

[GET /v1/health 获取 API 健康状态](https://cryptanio.com/zh/docs/reference/get-health/)

### 网络

[GET /v1/chains 列出网络](https://cryptanio.com/zh/docs/reference/list-chains/)

## 身份验证

从服务器发送 `Authorization: Bearer <API_KEY>`。在 [Account → API 密钥](https://account.cryptanio.com/api-keys)中创建用于线上数据的密钥，仅授权所需项目和操作。目前不提供公开沙盒。

密钥可允许只读访问、指定操作、单个项目或服务，以及指定 IP/CIDR 范围。到期、暂停和撤销也影响访问。轮换密钥时，请创建具有适当限制的替代密钥，切换集成后再撤销旧密钥。切勿将密钥嵌入浏览器代码、移动应用或 URL。

| 权限范围 | 用途 |
| --- | --- |
| `watches` | Monitoring |
| `events` | 事件与付款 |
| `invoices` | Payments 账单 |
| `webhooks` | Webhook 端点 |
| `stream` | SSE |

各项限制同时适用，不能相互替代。`401` 表示密钥未被接受；`403` 可能表示权限不足或 IP 不被允许。无权访问的资源可能返回 `404`。参见[错误与重试](https://cryptanio.com/zh/docs.html#errors)。

## SDK：即用型客户端

下载所用语言的文件，保存到应用服务器，并将密钥传入构造函数。每个客户端均覆盖本参考中的全部 16 个方法。无需安装 npm、PyPI、Composer 或 crates.io 软件包；下载的文件就是 SDK。

| 语言 | 要求 | 文件 |
| --- | --- | --- |
| Node.js | Node.js 18+ | [cryptanio.mjs](https://cryptanio.com/files/sdk/node/cryptanio.mjs) |
| Python | Python 3.10+ | [cryptanio.py](https://cryptanio.com/files/sdk/python/cryptanio.py) |
| PHP | PHP 8.1+ / cURL | [Cryptanio.php](https://cryptanio.com/files/sdk/php/Cryptanio.php) |
| Go | Go 1.22+ | [cryptanio.go](https://cryptanio.com/files/sdk/go/cryptanio.go) |
| Rust | Rust 2021 / reqwest 0.12 / serde_json 1 | [cryptanio.rs](https://cryptanio.com/files/sdk/rust/cryptanio.rs) |

这些文件属于同一版本 `1.0.0 62`。[清单](https://cryptanio.com/files/sdk/manifest.json)包含版本、合约和各文件的 SHA-256。请先在环境中设置 `CRYPTANIO_API_KEY` 和 `CRYPTANIO_PROJECT_ID`。这些示例仅读取事件，但访问的是线上账户数据。

### Node.js

将示例保存为 .mjs 文件，与 cryptanio.mjs 放在一起。

 

### Node.js

```javascript
import { Cryptanio } from './cryptanio.mjs';
const key = process.env.CRYPTANIO_API_KEY;
const project = process.env.CRYPTANIO_PROJECT_ID;
if (!key || !project) throw new Error('Set API key and project ID');
const api = new Cryptanio(key);
const page = await api.listEvents({ project, limit: 25 });
console.log(page);
```



要读取现有发票的付款说明，请在`CRYPTANIO_RESOURCE_ID`中设置其ID。下一个示例会保留必需的`payment_route`、用于二维码的返回值`payment_uri`以及准确的`checkout_url`。通过自己的界面将结果交给付款人，不要写入公开日志。金额保持字符串格式，缺少的字段会被省略。



### Node.js

```javascript
import { Cryptanio } from './cryptanio.mjs';
const key = process.env.CRYPTANIO_API_KEY;
const invoiceID = process.env.CRYPTANIO_RESOURCE_ID;
if (!key || !invoiceID) throw new Error('Set API key and invoice ID');
const api = new Cryptanio(key);
const invoice = await api.getInvoice(invoiceID);
const payment = {
  chain: invoice.chain, asset: invoice.asset, address: invoice.address,
  amount: invoice.amount, expires_at: invoice.expires_at,
  payment_route: invoice.payment_route,
  payment_uri: invoice.payment_uri, checkout_url: invoice.checkout_url,
};
console.log(JSON.stringify(payment, null, 2));
```



### Python

将示例保存为 .py 文件，与 cryptanio.py 放在一起。

 

### Python

```python
import os
from cryptanio import Cryptanio
api = Cryptanio(os.environ['CRYPTANIO_API_KEY'])
page = api.list_events({
    'project': os.environ['CRYPTANIO_PROJECT_ID'], 'limit': 25
})
print(page)
```



要读取现有发票的付款说明，请在`CRYPTANIO_RESOURCE_ID`中设置其ID。下一个示例会保留必需的`payment_route`、用于二维码的返回值`payment_uri`以及准确的`checkout_url`。通过自己的界面将结果交给付款人，不要写入公开日志。金额保持字符串格式，缺少的字段会被省略。



### Python

```python
import json
import os
from cryptanio import Cryptanio
api = Cryptanio(os.environ['CRYPTANIO_API_KEY'])
invoice = api.get_invoice(os.environ['CRYPTANIO_RESOURCE_ID'])
payment = {field: invoice[field] for field in (
    'chain', 'asset', 'address', 'amount', 'expires_at',
    'payment_route', 'payment_uri', 'checkout_url'
) if field in invoice}
print(json.dumps(payment, ensure_ascii=False))
```



### PHP

将示例保存为 .php 文件，与 Cryptanio.php 放在一起；启用 cURL 扩展。

 

### PHP

```php
<?php
require __DIR__ . '/Cryptanio.php';
$key = getenv('CRYPTANIO_API_KEY');
$project = getenv('CRYPTANIO_PROJECT_ID');
if (!$key || !$project) throw new RuntimeException('Set API key and project ID');
$api = new Cryptanio($key);
$page = $api->listEvents(['project' => $project, 'limit' => 25]);
echo json_encode($page, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR);
```



要读取现有发票的付款说明，请在`CRYPTANIO_RESOURCE_ID`中设置其ID。下一个示例会保留必需的`payment_route`、用于二维码的返回值`payment_uri`以及准确的`checkout_url`。通过自己的界面将结果交给付款人，不要写入公开日志。金额保持字符串格式，缺少的字段会被省略。



### PHP

```php
<?php
require __DIR__ . '/Cryptanio.php';
$key = getenv('CRYPTANIO_API_KEY');
$invoiceID = getenv('CRYPTANIO_RESOURCE_ID');
if (!$key || !$invoiceID) throw new RuntimeException('Set API key and invoice ID');
$api = new Cryptanio($key);
$invoice = $api->getInvoice($invoiceID);
$payment = array_intersect_key($invoice, array_fill_keys([
    'chain', 'asset', 'address', 'amount', 'expires_at',
    'payment_route', 'payment_uri', 'checkout_url'
], true));
echo json_encode($payment, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR);
```



### Go

将文件放入 Go 模块内的 `cryptanio/` 目录。本示例使用模块 `example.local/myapp`；请将导入路径替换为您自己的模块名称。无需外部依赖。

 

### Go

```go
package main

import (
    "context"
    "fmt"
    "os"
    "example.local/myapp/cryptanio"
)

func main() {
    key, project := os.Getenv("CRYPTANIO_API_KEY"), os.Getenv("CRYPTANIO_PROJECT_ID")
    if key == "" || project == "" { panic("Set API key and project ID") }
    api, err := cryptanio.New(key, "", 0)
    if err != nil { panic(err) }
    page, err := api.ListEvents(context.Background(), map[string]any{
        "project": project, "limit": 25,
    })
    if err != nil { panic(err) }
    fmt.Println(page)
}
```



要读取现有发票的付款说明，请在`CRYPTANIO_RESOURCE_ID`中设置其ID。下一个示例会保留必需的`payment_route`、用于二维码的返回值`payment_uri`以及准确的`checkout_url`。通过自己的界面将结果交给付款人，不要写入公开日志。金额保持字符串格式，缺少的字段会被省略。



### Go

```go
package main

import (
    "context"
    "encoding/json"
    "os"
    "example.local/myapp/cryptanio"
)

func main() {
    key, invoiceID := os.Getenv("CRYPTANIO_API_KEY"), os.Getenv("CRYPTANIO_RESOURCE_ID")
    if key == "" || invoiceID == "" { panic("Set API key and invoice ID") }
    api, err := cryptanio.New(key, "", 0)
    if err != nil { panic(err) }
    invoice, err := api.GetInvoice(context.Background(), invoiceID)
    if err != nil { panic(err) }
    payment := make(map[string]any)
    for _, field := range []string{
        "chain", "asset", "address", "amount", "expires_at",
        "payment_route", "payment_uri", "checkout_url",
    } {
        if value, ok := invoice[field]; ok { payment[field] = value }
    }
    if err := json.NewEncoder(os.Stdout).Encode(payment); err != nil { panic(err) }
}
```



### Rust

将文件保存为 `src/cryptanio.rs`，示例保存为 `src/main.rs`。将下列依赖加入 `Cargo.toml`。这是同步阻塞客户端：不要直接在异步工作线程中运行。



### Cargo.toml

```toml
[dependencies]
reqwest = { version = "=0.12.24", default-features = false, features = ["blocking", "json", "rustls-tls"] }
serde_json = "=1.0.145"
```



 

### Rust

```rust
mod cryptanio;
use cryptanio::Cryptanio;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api = Cryptanio::new(&std::env::var("CRYPTANIO_API_KEY")?)?;
    let project = std::env::var("CRYPTANIO_PROJECT_ID")?;
    let page = api.list_events(&[("project", &project), ("limit", "25")])?;
    println!("{page}");
    Ok(())
}
```



要读取现有发票的付款说明，请在`CRYPTANIO_RESOURCE_ID`中设置其ID。下一个示例会保留必需的`payment_route`、用于二维码的返回值`payment_uri`以及准确的`checkout_url`。通过自己的界面将结果交给付款人，不要写入公开日志。金额保持字符串格式，缺少的字段会被省略。



### Rust

```rust
mod cryptanio;
use cryptanio::Cryptanio;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let api = Cryptanio::new(&std::env::var("CRYPTANIO_API_KEY")?)?;
    let invoice = api.get_invoice(&std::env::var("CRYPTANIO_RESOURCE_ID")?)?;
    let mut payment = serde_json::Map::new();
    for field in ["chain", "asset", "address", "amount", "expires_at",
                  "payment_route", "payment_uri", "checkout_url"] {
        if let Some(value) = invoice.get(field) {
            payment.insert(field.to_owned(), value.clone());
        }
    }
    println!("{}", serde_json::Value::Object(payment));
    Ok(())
}
```



### 调用方法

Node.js 和 PHP 使用 `listEvents`，Python 和 Rust 使用 `list_events`，Go 使用 `ListEvents`。每个方法对应[参考文档](https://cryptanio.com/zh/docs.html#reference)中的一个请求。筛选条件为对象或映射，Rust 中为键值对列表。Go 方法始终先接收 `context.Context`。未知筛选条件在发送请求前会被拒绝。

| Node.js / PHP 方法 | HTTP |
| --- | --- |
| `createWatch` | [POST /v1/watches](https://cryptanio.com/zh/docs/reference/create-watch/) |
| `listWatches` | [GET /v1/watches](https://cryptanio.com/zh/docs/reference/list-watches/) |
| `getWatch` | [GET /v1/watches/{id}](https://cryptanio.com/zh/docs/reference/get-watch/) |
| `deleteWatch` | [DELETE /v1/watches/{id}](https://cryptanio.com/zh/docs/reference/delete-watch/) |
| `listEvents` | [GET /v1/events](https://cryptanio.com/zh/docs/reference/list-events/) |
| `listPayments` | [GET /v1/payments](https://cryptanio.com/zh/docs/reference/list-payments/) |
| `createInvoice` | [POST /v1/invoices](https://cryptanio.com/zh/docs/reference/create-invoice/) |
| `listInvoices` | [GET /v1/invoices](https://cryptanio.com/zh/docs/reference/list-invoices/) |
| `getInvoice` | [GET /v1/invoices/{id}](https://cryptanio.com/zh/docs/reference/get-invoice/) |
| `cancelInvoice` | [POST /v1/invoices/{id}/cancel](https://cryptanio.com/zh/docs/reference/cancel-invoice/) |
| `createEndpoint` | [POST /v1/endpoints](https://cryptanio.com/zh/docs/reference/create-endpoint/) |
| `listEndpoints` | [GET /v1/endpoints](https://cryptanio.com/zh/docs/reference/list-endpoints/) |
| `deleteEndpoint` | [DELETE /v1/endpoints/{id}](https://cryptanio.com/zh/docs/reference/delete-endpoint/) |
| `streamEvents` | [GET /v1/stream](https://cryptanio.com/zh/docs/reference/stream-events/) |
| `getHealth` | [GET /v1/health](https://cryptanio.com/zh/docs/reference/get-health/) |
| `listChains` | [GET /v1/chains](https://cryptanio.com/zh/docs/reference/list-chains/) |

创建监控和 webhook 需要请求正文。单资源方法接收其字符串 ID。`createInvoice(body, idempotencyKey)` 要求使用由 ASCII 字母、数字、连字符或下划线组成的 16–80 字符密钥。重试时复用相同密钥和正文；SDK 不会生成新密钥，也不会自动重试。正文、错误和权限请参阅各方法页面。

### 响应、错误与流式传输

JSON 响应保留原字段名；ID、金额和游标仍为字符串。分页按各方法文档手动进行。错误提供 HTTP 状态、code、message 和 `Retry-After`。没有 HTTP 响应时，状态为 0（Rust 使用 `None`）。不跟随重定向。普通 JSON 响应上限为 8 MiB。默认超时为 30 秒，可配置至 300 秒。Python 中它适用于单次网络操作；其他客户端中覆盖整个请求，包括流式传输。超时并不能证明写操作未执行。

| 语言 / 错误 | 字段 |
| --- | --- |
| Node.js / Python: ApiError | `status, code, message, retry_after` |
| PHP: CryptanioError | `status, apiCode, getMessage(), retryAfter` |
| Go: *APIError | `Status, Code, Message, RetryAfter` |
| Rust: ApiError | `status: Option<u16>, code, message, retry_after` |

`streamEvents` 提供原始 SSE 字节，不负责重连或事件解析：Node.js `ReadableStream`、可关闭的 Python HTTP 响应、Go `io.ReadCloser` 或 Rust `blocking::Response`。不再需要时释放流。PHP 将数据块传给回调；返回 `false` 可停止。流式传输不能替代 webhook，也不保证历史重放；参见 [SSE 规则](https://cryptanio.com/zh/docs.html#stream)。

## 您的第一个监控

在 Account 中创建已启用 Monitoring 的项目，以及具有 watches 和 events 权限的密钥。按要求完成账户验证。从项目设置复制 ID，只添加您确实希望监控的地址。

在服务器环境中设置 `CRYPTANIO_API_KEY` 和 `CRYPTANIO_PROJECT_ID`。将示例地址替换为您自己的地址。此请求会关联真实监控，不会模拟交易。



### Shell / cURL

```bash
#!/usr/bin/env bash
set -euo pipefail
: "${CRYPTANIO_API_KEY:?Set CRYPTANIO_API_KEY}"
: "${CRYPTANIO_PROJECT_ID:?Set CRYPTANIO_PROJECT_ID}"
json_string() {
  local text="$1" char code index output='"'
  for ((index=0; index<${#text}; index++)); do
    char="${text:index:1}"
    case "$char" in
      '"'|'\') output+="\\$char" ;;
      *) printf -v code '%d' "'$char"
         if ((code < 32)); then printf -v char '\\u%04x' "$code"; fi
         output+="$char" ;;
    esac
  done
  printf '%s"' "$output"
}
response_file="$(mktemp)"
trap 'rm -f "$response_file"' EXIT
transfer_status=0
http_status="$(curl \
  --silent --show-error --max-time 30 --request POST \
  --header "Authorization: Bearer $CRYPTANIO_API_KEY" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data-binary '{"project":'"$(json_string "$CRYPTANIO_PROJECT_ID")"',"chain":"ethereum","address":"0x52908400098527886E0F7030069857D2E4169EE7","asset":"native","label":"Treasury"}' \
  "https://api.cryptanio.com/v1/watches" \
  --output "$response_file" --write-out '%{http_code}')" || transfer_status=$?
if [[ "$http_status" == 2?? ]]; then
  cat "$response_file"
  exit "$transfer_status"
fi
printf 'HTTP %s\n' "$http_status" >&2
cat "$response_file" >&2
exit 1
```



成功响应包含 `id`，请保存。`GET /v1/watches/{id}` 返回监控对象和设置，而非付款。要查看已检测活动，请请求 `GET /v1/events` 并按 `watch_id` 筛选。检测到交易前列表为空是正常的。[响应、错误及其他语言示例](https://cryptanio.com/zh/docs/reference/create-watch/)。

## Payments 账单

为项目启用 Payments，并在 Account 中向地址池添加受支持地址。请明确发送 project，不要依赖默认项目选择。amount 是以加密资产为单位的字符串；invoice_currency/invoice_amount 单独描述订单报价。

将 `CRYPTANIO_PROJECT_ID` 设为您的 Payments 项目，将 `CRYPTANIO_API_KEY` 设为具有 invoices 权限的密钥。新订单的 `CRYPTANIO_OPERATION_ID` 必须唯一；重试同一操作时复用它。账单创建于线上数据中。



### Shell / cURL

```bash
#!/usr/bin/env bash
set -euo pipefail
: "${CRYPTANIO_API_KEY:?Set CRYPTANIO_API_KEY}"
: "${CRYPTANIO_OPERATION_ID:?Set CRYPTANIO_OPERATION_ID}"
: "${CRYPTANIO_PROJECT_ID:?Set CRYPTANIO_PROJECT_ID}"
json_string() {
  local text="$1" char code index output='"'
  for ((index=0; index<${#text}; index++)); do
    char="${text:index:1}"
    case "$char" in
      '"'|'\') output+="\\$char" ;;
      *) printf -v code '%d' "'$char"
         if ((code < 32)); then printf -v char '\\u%04x' "$code"; fi
         output+="$char" ;;
    esac
  done
  printf '%s"' "$output"
}
response_file="$(mktemp)"
trap 'rm -f "$response_file"' EXIT
transfer_status=0
http_status="$(curl \
  --silent --show-error --max-time 30 --request POST \
  --header "Authorization: Bearer $CRYPTANIO_API_KEY" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header "Idempotency-Key: $CRYPTANIO_OPERATION_ID" \
  --data-binary '{"project":'"$(json_string "$CRYPTANIO_PROJECT_ID")"',"invoice_currency":"USD","invoice_amount":"12.50","reference":"order-42"}' \
  "https://api.cryptanio.com/v1/invoices" \
  --output "$response_file" --write-out '%{http_code}')" || transfer_status=$?
if [[ "$http_status" == 2?? ]]; then
  cat "$response_file"
  exit "$transfer_status"
fi
printf 'HTTP %s\n' "$http_status" >&2
cat "$response_file" >&2
exit 1
```



密钥必须允许 `invoices` 和 Payments；Monitoring 示例密钥可能被限制在其他服务。`Idempotency-Key` 包含 16-80 个 ASCII 字母、数字、`-` 和 `_`。使用同一密钥重复相同的规范化请求，会返回现有账单和 `201`；内容改变时返回 `409 conflict`。操作密钥在整个账户内生效。`reference` 不能替代它。

向买方显示返回的网络、资产、地址、`amount`和到期时间。如果存在`payment_route`，还必须传递其`kind`和准确的字符串值`value`：destination_tag、memo、comment或reference是将付款归属到该发票的必需信息。订单的`reference`字段是另一个独立字段。

如果返回了`payment_uri`，请将其原样用于付款二维码。Solana Pay reference不是钱包memo：不要用普通地址替换URI，也不要重新拼接URI。如果钱包无法携带必需的标识，请向付款人提供`checkout_url`或兼容的钱包。

`checkout_url`是新开发票的托管付款页面。只向付款人分享返回的准确URL，不要根据ID构造链接。此链接可显示付款详情和状态，因此不要写入公开日志。如果没有该字段，请显示完整的付款说明。浏览器跳转不能证明付款：请检查API或经过验证的webhook。

为区分订单，`asked`可能与amount不同。请将`amount_raw`作为任意精度整数进行核对。默认TTL为60分钟，最多10080分钟。发票列表接受`before`，但不返回next_before：使用最后一项的ID继续查询，遇到空页时停止。

[POST /v1/invoices 创建账单](https://cryptanio.com/zh/docs/reference/create-invoice/) [GET /v1/invoices 列出账单](https://cryptanio.com/zh/docs/reference/list-invoices/) [GET /v1/invoices/{id} 获取账单](https://cryptanio.com/zh/docs/reference/get-invoice/) [POST /v1/invoices/{id}/cancel 取消账单](https://cryptanio.com/zh/docs/reference/cancel-invoice/)

### `Customer`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `id` | `string` | 是 | 您系统中的客户标识符。; maxLength: `120` |

### `Product`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `id` | `string` | 否 | 您系统中的产品标识符。; maxLength: `120` |
| `name` | `string` | 否 | 产品名称。; maxLength: `200` |
| `quantity` | `integer` | 否 | 数量。; minimum: `1`; maximum: `1000000` |

### `Payer`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `comment` | `string` | 是 | 付款人留言。; maxLength: `500` |

### `InvoiceMetadata`

最多 20 对，总计不超过 8192 个 JSON 字节。不要包含密钥。

`object` 最多 20 对，总计不超过 8192 个 JSON 字节。不要包含密钥。

## Monitoring 监控

监控对象属于一个 Monitoring 项目。同一地址可在多个项目中使用，各自配置独立的方向和资产规则。请在 Account 中连接地址簿列表和 Address Sources；此 REST API 不提供其管理命令。

列表按 ID 降序排列。若存在 `next_before`，请在下一请求中作为 `before` 传入，并保持项目和筛选条件不变。`limit` 默认值为 50，上限为 200。将 ID 保存为字符串。移除监控会使其退出有效列表；此处移除不会从其他项目或地址簿删除该地址。

[POST /v1/watches 创建 Monitoring 监控](https://cryptanio.com/zh/docs/reference/create-watch/) [GET /v1/watches 列出 Monitoring 监控](https://cryptanio.com/zh/docs/reference/list-watches/) [GET /v1/watches/{id} 获取 Monitoring 监控](https://cryptanio.com/zh/docs/reference/get-watch/) [DELETE /v1/watches/{id} 删除 Monitoring 监控](https://cryptanio.com/zh/docs/reference/delete-watch/)

## 事件与历史

`/v1/events` 返回密钥可访问的跨服务事件；`/v1/payments` 仅限 Payments。可按 project、address、chain、type、watch_id 和 tx_id 筛选。`before` 是 ID 游标，不是日期；没有 from/to 筛选。`next_before` 可获取下一页。

检测到的事件历史最多可查询 30 天。这并不是所有已投递消息的档案：不保证能通过它恢复 notice 和 webhook.test 消息。REST Event 使用独立于 webhook 的结构；v1 内可能新增字段。

[GET /v1/events 列出事件](https://cryptanio.com/zh/docs/reference/list-events/) [GET /v1/payments 列出 Payments 事件](https://cryptanio.com/zh/docs/reference/list-payments/)

### `Event`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `event_id` | `string` | 是 | 不透明标识符；请保持为字符串。; minLength: `1` |
| `event_type` | `string` | 是 | 事件类型；可能添加新类型。 |
| `chain` | `string` | 是 | 网络代码。 |
| `service` | `string` | 否 | 已知时的服务。 |
| `watch_id` | `string` | 否 | 关联监控时的项目监控 ID。; minLength: `1` |
| `occurred_at` | `string` | 是 | RFC 3339 格式的 UTC 日期和时间。; `date-time` |
| `payment` | `object \| null` | 是 | 付款文档；非付款事件为 null。GET /events 不返回 contract/notice 载荷。 |
| `sandbox` | `boolean` | 否 | 测试事件；省略时为 false。 |

### `EventPayment`

REST/SSE 付款文档。字段取决于事件和网络；不是标准化的 webhook v1 结构。

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `tx_id` | `string` | 否 | 交易标识符。 |
| `index` | `integer` | 否 | 交易内的转账索引。; minimum: `0` |
| `height` | `integer` | 否 | 可确定时的区块高度。; minimum: `0` |
| `address` | `string` | 否 | 被观察的地址。 |
| `asset` | `string` | 否 | REST/SSE asset：字符串标识符，不是 webhook 中的 asset 对象。 |
| `amount_raw` | `string` | 否 | 以字符串表示的最小单位整数金额。; pattern: `^[0-9]+$` |
| `amount` | `string` | 否 | 精确十进制金额字符串；不要使用浮点数。; pattern: `^[0-9]+(?:\.[0-9]+)?$` |
| `decimals` | `integer` | 否 | 小数位数。; minimum: `0` |
| `confirmations` | `integer` | 否 | 确认数。; minimum: `0` |
| `revision` | `integer` | 否 | 转账状态修订号。; minimum: `0` |
| `direction` | `string` | 否 | 相对于被观察地址的方向。; `in`、`out` |
| `simulated` | `boolean` | 否 | 模拟事件。 |
| `late` | `boolean` | 否 | 延迟检测到的转账。 |
| `block_hash` | `string` | 否 | 区块哈希。 |
| `match_key` | `string` | 否 | 网络使用时的匹配标识符。 |
| `meta` | `object` | 否 |  |
| `invoice` | `object` | 否 |  |
| `customer` | `object` | 否 |  |
| `product` | `object` | 否 |  |
| `payer` | `object` | 否 |  |
| `metadata` | `object` | 否 |  |

## Webhook 事件

投递采用至少一次语义，因此事件可能多次到达。验证签名后，在集成中按 `event_id` 去重。将处理记录和业务变更持久化在同一个数据库事务中。tx_id/address/asset 组合不能替代 event_id，因为它会合并不同状态变化、方向和项目。

从已签名正文读取 `event_type` 和 `event_id`。X-Event-Type/X-Event-Id 请求头不包含在 HMAC 中；若使用它们，请与正文比较。更新付款时，请考虑 project_id、direction 和 payment.revision。不要假设投递有序；安全忽略未知类型，同时保留以供诊断。

| 类别 | 正文 |
| --- | --- |
| payment.pending / confirmed / rolled_back | 转入付款 |
| debit.pending / confirmed / rolled_back | 转出付款 |
| contract.approval / owner_added / owner_removed / threshold_changed / permissions_changed | contract |
| asset.unexpected | contract；该资产不会计为已接受的付款 |
| account.notice / account.notification / treasury.alarm / subscription.notice | notice.subject, notice.text |
| webhook.test | 不含付款的控制事件 |

`schema_version: v1` 根据事件类型承载 payment、contract 或 notice；webhook.test 不含这些内容。ID 和金额均为字符串。amount_raw 表示最小单位；amount 为十进制表示。通过 chains 检查网络和资产。完整对象结构见 [OpenAPI](https://cryptanio.com/openapi.json)。

| 请求头 | 含义 |
| --- | --- |
| X-Timestamp | 签名时的 Unix 秒数 |
| X-Signature | hex HMAC-SHA256(timestamp + '.' + raw body) |
| X-Event-Id / X-Event-Type | 与已签名的正文比较。 |
| X-Attempt | 从 1 开始的尝试次数 |

持久接收事件后返回 `2xx`。单次尝试超时为 10 秒。网络失败、408、425、429 和 5xx 最多重试 24 小时，延迟从 2 秒至 15 分钟，并加入随机抖动；遵守 Retry-After。不跟随重定向。其他 3xx/4xx 会结束投递；410 会停用目标及其积压消息。



### Webhook shape example (illustrative)

```json
{
  "schema_version": "v1",
  "event_id": "2300",
  "event_type": "payment.confirmed",
  "occurred_at": "2026-10-06T10:00:00Z",
  "project_id": "1002",
  "service": "monitoring",
  "mode": "test",
  "sandbox": true,
  "payment": {
    "chain": "ethereum",
    "direction": "in",
    "asset": {
      "symbol": "ETH"
    },
    "address": "0x52908400098527886E0F7030069857D2E4169EE7",
    "tx_id": "simulated_2300",
    "index": 0,
    "amount": "1.000000000000000000",
    "amount_raw": "1000000000000000000",
    "decimals": 18,
    "confirmations": 0,
    "revision": 1,
    "simulated": true
  }
}
```



### `Webhook`

公开签名 webhook v1 正文。payment.* 和 debit.* 包含 payment；contract.* 和 asset.unexpected 包含 contract；webhook.test 不含业务载荷；account.notice、account.notification、treasury.alarm 和 subscription.notice 包含 notice。按 event_id 对投递重试去重。

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `schema_version` | `string` | 是 | Webhook 载荷版本。; `v1` |
| `event_id` | `string` | 是 | 事件 ID：投递重试时不变。不同状态可能具有不同的 event_id 值。; minLength: `1` |
| `event_type` | `string` | 是 | 已签名正文中的类型；验证签名后再使用。可能添加新类型。 |
| `occurred_at` | `string` | 是 | RFC 3339 格式的 UTC 日期和时间。; `date-time` |
| `project_id` | `string` | 是 | 不透明标识符；请保持为字符串。; minLength: `1` |
| `service` | `string` | 否 | 适用时的项目服务。 |
| `mode` | `string` | 是 | 事件模式。; `live`、`test` |
| `sandbox` | `boolean` | 是 | 明确的模拟标志。 |
| `payment` | `object` | 否 |  |
| `contract` | `object` | 否 |  |
| `invoice` | `object` | 否 |  |
| `customer` | `object` | 否 |  |
| `product` | `object` | 否 |  |
| `payer` | `object` | 否 |  |
| `metadata` | `object` | 否 |  |
| `notice` | `object` | 否 |  |

### `WebhookPayment`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `chain` | `string` | 是 | 网络代码。 |
| `direction` | `string` | 是 | 转入付款：in；转出扣款：out。; `in`、`out` |
| `asset` | `object` | 是 |  |
| `address` | `string` | 是 | 被观察的地址。 |
| `tx_id` | `string` | 是 | 交易 ID。 |
| `index` | `integer` | 是 | 转账索引；不要假设任一网络均为 0。; minimum: `0` |
| `height` | `integer` | 否 | 已知时的区块高度。; minimum: `0` |
| `block_hash` | `string` | 否 | 已知时的区块哈希。 |
| `match_key` | `string` | 否 | 适用时的网络匹配标识符。 |
| `amount` | `string` | 是 | 精确十进制金额字符串；不要使用浮点数。; pattern: `^[0-9]+(?:\.[0-9]+)?$` |
| `amount_raw` | `string` | 是 | 以字符串表示的最小单位整数金额。; pattern: `^[0-9]+$` |
| `decimals` | `integer` | 是 | 小数位数。; minimum: `0` |
| `confirmations` | `integer` | 是 | 确认数。; minimum: `0` |
| `revision` | `integer` | 是 | 转账状态修订号。不要按交易标识合并不同的 event_id 值。; minimum: `0` |
| `late` | `boolean` | 否 | 延迟检测到的转账；不等同于账单的 late 状态。 |
| `simulated` | `boolean` | 否 | 模拟转账。 |
| `valuation` | `object` | 否 |  |

### `WebhookAsset`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `symbol` | `string` | 否 | 已知时的符号；不足以确定代币身份。 |
| `standard` | `string` | 否 | 已知时的代币标准。 |
| `contract` | `string` | 否 | 适用时，代币在其网络中的合约。 |
| `identifier` | `string` | 否 | 其他网络专用的代币标识符。 |

### `WebhookContract`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `chain` | `string` | 是 | 网络代码。 |
| `address` | `string` | 是 | 被观察的地址或合约。 |
| `tx_id` | `string` | 是 | 交易 ID。 |
| `index` | `integer` | 是 | 事件索引。; minimum: `0` |
| `height` | `integer` | 否 | 区块高度。; minimum: `0` |
| `block_hash` | `string` | 否 | 区块哈希。 |
| `kind` | `string` | 否 | 变更类型。 |
| `asset` | `string` | 否 | 受影响的资产标识（如已知）。 |
| `detail` | `object` | 否 |  |
| `simulated` | `boolean` | 否 | 模拟事件。 |

### `WebhookInvoice`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `id` | `string` | 是 | 不透明标识符；请保持为字符串。; minLength: `1` |
| `reference` | `string` | 否 | 订单参考编号。 |
| `status` | `string` | 否 | pending 等待付款；seen 已检测；partial 部分付款；paid 已结清；underpaid/overpaid/late 需要作出处理决定；expired 已过期限；canceled 已作废。; `pending`、`seen`、`paid`、`underpaid`、`partial`、`overpaid`、`expired`、`late`、`canceled` |
| `currency` | `string` | 否 | 订单报价币种。 |
| `amount` | `string` | 否 | 精确十进制金额字符串；不要使用浮点数。; pattern: `^[0-9]+(?:\.[0-9]+)?$` |

### `Notice`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `subject` | `string` | 是 | 通知主题。 |
| `text` | `string` | 是 | 通知文本。 |

### `Valuation`

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `currency` | `string` | 是 | 估值币种，例如 USD。 |
| `amount` | `string` | 是 | 精确十进制金额字符串；不要使用浮点数。; pattern: `^[0-9]+(?:\.[0-9]+)?$` |
| `rate` | `string` | 是 | 以十进制字符串表示的资产汇率。; pattern: `^[0-9]+(?:\.[0-9]+)?$` |
| `rate_at` | `string` | 是 | RFC 3339 格式的 UTC 日期和时间。; `date-time` |
| `provider` | `string` | 否 | 已知时的报价来源名称。 |

## 验证签名

在解析 JSON 前，对原始正文的全部字节验证 HMAC，包括空格和换行。时效检查限制重放，但不能替代持久化的 event_id 去重。示例仅接受 64 字符的十六进制签名，以及与服务器时间相差不超过 300 秒的时间戳。请使用对应 webhook 目标的密钥。



### Node.js

```javascript
import { createHmac, timingSafeEqual } from "node:crypto";
import { TextDecoder } from "node:util";

// rawBody is the original HTTP request Buffer, before JSON.parse or serialization.
export function verifyWebhook(secret, timestamp, rawBody, signature, nowSeconds = Math.floor(Date.now() / 1000)) {
  if (typeof secret !== "string" || secret.length === 0 || !Buffer.isBuffer(rawBody) || rawBody.length === 0 ||
      typeof timestamp !== "string" || !/^(0|[1-9][0-9]*)$/.test(timestamp) ||
      typeof signature !== "string" || !/^[0-9a-f]{64}$/i.test(signature) ||
      !Number.isSafeInteger(nowSeconds) || nowSeconds < 0) return false;

  const signedAt = Number(timestamp);
  if (!Number.isSafeInteger(signedAt) || Math.abs(nowSeconds - signedAt) > 300) return false;

  const expected = createHmac("sha256", secret).update(timestamp).update(".").update(rawBody).digest();
  return timingSafeEqual(expected, Buffer.from(signature, "hex"));
}

// headers is Node.js request.headers (lowercase names). Optional X-Event-Id/Type
// headers are not signed separately; compare them with the verified body.
export function readSignedWebhook(secret, timestamp, rawBody, signature, headers = {}, nowSeconds) {
  if (!verifyWebhook(secret, timestamp, rawBody, signature, nowSeconds) ||
      headers === null || typeof headers !== "object" || Array.isArray(headers)) return null;

  let event;
  try {
    event = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(rawBody));
  } catch {
    return null;
  }
  if (event === null || typeof event !== "object" || Array.isArray(event) || event.schema_version !== "v1" ||
      typeof event.event_id !== "string" || event.event_id.length === 0 ||
      typeof event.event_type !== "string" || event.event_type.length === 0) return null;

  for (const [header, field] of [["x-event-id", "event_id"], ["x-event-type", "event_type"]]) {
    if (headers[header] !== undefined && headers[header] !== event[field]) return null;
  }
  return event;
}
```



[下载 Node.js 示例](https://cryptanio.com/files/examples/webhook-node.mjs)



### Go

```go
package webhook

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"
	"strconv"
	"time"
	"unicode/utf8"
)

// VerifyWebhook checks the original HTTP body bytes before parsing JSON.
// Optional nowSeconds is used only for deterministic tests.
func VerifyWebhook(secret, timestamp string, rawBody []byte, signature string, nowSeconds ...int64) bool {
	if secret == "" || len(rawBody) == 0 || len(signature) != 64 || len(nowSeconds) > 1 {
		return false
	}
	signedAt, err := strconv.ParseInt(timestamp, 10, 64)
	if err != nil || signedAt < 0 || strconv.FormatInt(signedAt, 10) != timestamp {
		return false
	}
	now := time.Now().Unix()
	if len(nowSeconds) == 1 {
		now = nowSeconds[0]
	}
	if now < 0 || now-signedAt < -300 || now-signedAt > 300 {
		return false
	}
	provided, err := hex.DecodeString(signature)
	if err != nil || len(provided) != sha256.Size {
		return false
	}
	mac := hmac.New(sha256.New, []byte(secret))
	mac.Write([]byte(timestamp))
	mac.Write([]byte("."))
	mac.Write(rawBody)
	return hmac.Equal(mac.Sum(nil), provided)
}

// WebhookEvent contains only routing fields. Parse other fields from rawBody
// after ReadSignedWebhook succeeds; unknown fields are allowed.
type WebhookEvent struct {
	SchemaVersion string `json:"schema_version"`
	EventID       string `json:"event_id"`
	EventType     string `json:"event_type"`
}

// ReadSignedWebhook extracts event_id/type only from the verified body.
// X-Event-Id/Type are not signed separately; nonempty values must match the body.
func ReadSignedWebhook(secret, timestamp string, rawBody []byte, signature, eventIDHeader, eventTypeHeader string,
	nowSeconds ...int64) (*WebhookEvent, error) {
	if !VerifyWebhook(secret, timestamp, rawBody, signature, nowSeconds...) {
		return nil, errors.New("invalid webhook signature or timestamp")
	}
	var event WebhookEvent
	if !utf8.Valid(rawBody) || json.Unmarshal(rawBody, &event) != nil || event.SchemaVersion != "v1" ||
		event.EventID == "" || event.EventType == "" {
		return nil, errors.New("invalid webhook body")
	}
	if eventIDHeader != "" && eventIDHeader != event.EventID || eventTypeHeader != "" && eventTypeHeader != event.EventType {
		return nil, errors.New("webhook headers do not match the signed body")
	}
	return &event, nil
}
```



[下载 Go 示例](https://cryptanio.com/files/examples/webhook-go.go)

## Webhook 端点

为指定项目添加端口 443 上的公共 HTTPS URL。不允许 URL 凭据、片段、重定向和非公共目标。每个账户最多 20 个端点。各端点拥有独立秘密值，只在首次创建时返回，请保存在服务器上。

在相同项目和模式下再次创建同一 URL，会返回 200 和不含密钥的现有端点。新端点返回 201。DELETE 返回 `200` 以及 `id` 和 `deleted: true`，安全重复调用时亦然。密钥仅能查看自身模式和获准项目；投递遵循项目设置。

[POST /v1/endpoints 创建 webhook 端点](https://cryptanio.com/zh/docs/reference/create-endpoint/) [GET /v1/endpoints 列出 webhook 端点](https://cryptanio.com/zh/docs/reference/list-endpoints/) [DELETE /v1/endpoints/{id} 删除 webhook 端点](https://cryptanio.com/zh/docs/reference/delete-endpoint/)

## SSE 流

SSE 用于服务端集成和实时展示；它不保证投递，也不会重放遗漏事件。请使用带 Bearer 请求头的服务端 HTTP 客户端。标准浏览器 EventSource 无法发送此请求头；不要把 API 密钥放入浏览器代码或查询字符串。

消息使用 event: payment 和自身的 StreamEvent 结构，而非 webhook v1 或 REST Event。注释以冒号开头；心跳约每 20 秒到达。retry: 5000 是重连提示。断开后，请通过 events 获取仍可查询的区块链事件历史。

[GET /v1/stream 流式接收事件](https://cryptanio.com/zh/docs/reference/stream-events/)

### `StreamEvent`

SSE data 中的 JSON；与 webhook v1 不同。非付款事件省略 payment，可能包含 contract。

| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `event_id` | `string` | 是 | 不透明标识符；请保持为字符串。; minLength: `1` |
| `event_type` | `string` | 是 | 事件类型；可能添加新类型。 |
| `chain` | `string` | 是 | 网络代码。 |
| `service` | `string` | 否 | 已知时的服务。 |
| `watch_id` | `string` | 否 | 关联监控时的项目监控 ID。; minLength: `1` |
| `occurred_at` | `string` | 是 | RFC 3339 格式的 UTC 日期和时间。; `date-time` |
| `payment` | `object \| null` | 否 | 付款文档；非付款事件为 null。GET /events 不返回 contract/notice 载荷。 |
| `sandbox` | `boolean` | 否 | 测试事件；省略时为 false。 |
| `project_id` | `string` | 否 | 不透明标识符；请保持为字符串。; minLength: `1` |
| `project_name` | `string` | 否 | 项目名称。 |
| `url` | `string` | 否 | 指向 Account 事件的链接。; `uri` |
| `contract` | `object` | 否 |  |
| `mode` | `string` | 否 | live 或 test。; `live`、`test` |

## 付款与账单状态

区块链付款状态与订单状态不同。payment.pending 表示确认数不足时检测到付款，payment.confirmed 表示达到网络或项目的确认规则，payment.rolled_back 表示发生回滚。不要根据 pending、转出扣款或模拟事件履行订单。

| Invoice | 含义 |
| --- | --- |
| pending | 等待付款 |
| partial | 已收到部分款项；依照项目的部分付款政策处理 |
| paid | 付款已接受 |
| underpaid | 少付金额需要作出处理决定 |
| overpaid | 多付金额需要依照适用政策作出处理决定 |
| late | 到期后付款需要作出处理决定 |
| expired | 付款窗口已到期 |
| canceled | 账单已取消；记录仍可读取。 |

underpaid、overpaid 和 late 时存在 `needs_decision`。请在 Account 中处理这些状态。链重组和重新纳入区块可能产生新的状态变化及新的 `payment.revision`；confirmed 并不无条件保证未来不会变化。

## 错误与安全重试



### application/json

```json
{"error":{"code":"forbidden","message":"this API key is read-only"}}
```



业务逻辑使用 HTTP 状态和 error.code，诊断使用 message。成功列表包含 data；单个对象直接返回。Health 使用自身的 status/version 结构，在 503 时也如此。不要依赖 message 的确切措辞。

| HTTP | 操作 |
| --- | --- |
| 400 | 修正 JSON、格式和参数；不要原样重试。 |
| 401 | 检查密钥、到期、一时停用和撤销状态。 |
| 403 | 检查权限范围、读写模式、项目、服务、IP 和账户验证。 |
| 404 | 检查 ID、密钥模式和访问权限；限制可能使资源不可见。 |
| 402 | Monitoring 监控数量限制；请检查套餐。 |
| 409 | 冲突、服务未启用、地址池已占用或达到限制；请检查错误代码。 |
| 429 | 遵守 Retry-After；降低账户所有请求的合计速率 |
| 500 / 503 | 使用有界退避重试；创建账单只能使用原始 Idempotency-Key |

超时不代表操作没有执行。重试时不要改变账单的操作键。没有防重复保护的方法应先读取状态；不要假定所有 POST 都具有幂等性。

## 网络与限制

使用所选 API 主机上的 chains 获取其网络、资产、能力和确认数目录。出现在通用目录中并不保证网络在该环境启用，或支持所有操作。在 Account 中检查服务配额和预算；价格见定价页面。

账户的已认证 REST 配额为：无付费服务时每秒 10 个请求，有付费服务时每秒 50 个请求；短时突发容量为 20/100。账户的所有密钥和模式共享此配额。超额会返回 429 及 Retry-After。服务配额与 API 速率限制是独立的限制。

[服务定价与配额](https://cryptanio.com/zh/pricing/)

[GET /v1/health 获取 API 健康状态](https://cryptanio.com/zh/docs/reference/get-health/) [GET /v1/chains 列出网络](https://cryptanio.com/zh/docs/reference/list-chains/)

## API 版本

本参考描述版本 `1.0.0 62` 中的 `v1`；更新于 2026-10-10。使用新能力前，请通过 `GET /v1/health` 检查已部署版本。文档版本不能证明部署已完成。

| 公开 API | 合同 |
| --- | --- |
| `https://api.cryptanio.com` | `/v1` |

稳定集成请使用 `/v1`。无版本路径会选择环境当前的稳定合约；未知 `/vN` 返回 `404`。`X-API-Version` 标识合约；`X-Server-Version` 和 `health.version` 标识产品版本，不代表另一种 API 合约。

[下载 OpenAPI 3.1](https://cryptanio.com/openapi.json)

## API 变更

版本 `1.0.0 62` 提供可下载的 Node.js、Python、PHP、Go 和 Rust SDK，以及[面向 AI 智能体的本地 MCP](https://cryptanio.com/zh/mcp/)。参考文档、Markdown 和原始 HTTP 示例仍独立提供。不提供公开沙盒。API 行为不变。

在 v1 内，客户端应容忍新增响应字段。接受未知事件类型不代表履行订单或计入付款。使用变更前，请根据所选环境的版本检查其可用性。
