Metazoon BlockchainAPI
Read-only API · OpenAPI 3.0.3

米塔链接口,一次讲清楚

资产、类别、流转、统计的对外只读通道。三层权限、HMAC 签名、游标分页、字段白名单—— 响应里不会出现手机号、身份证与真实姓名。

线上可用 · 2026-10-21 Base URL https://api.metazoon.com 7 个端点 限流 10 req/s(burst 40)

鉴权

两级权限,按调用方身份发放。米塔族 APP 属 L2;公开目录类只需 L1。

L1 公开 Key

只需请求头 X-Api-Key。可读链枚举、类别列表、资产列表(不含手机号维度)。

L2 合作方 / 自家产品

在 L1 基础上加 X-Timestamp + X-Signature(HMAC-SHA256)。 可读流转记录、全局统计、按手机号查资产、批量手机号查询。

L2 签名算法

canonical = METHOD + "\n" + PATH + "\n" + QUERY + "\n" + sha256_hex(body) + "\n" + timestamp
signature = hex( HMAC_SHA256( secret, canonical ) )
变量说明
METHODGET / POST,大写
PATH不含域名与 ?,如 /v1/stats
QUERY原始 query string(不含 ?),无参数时为空串
body原始字节的 SHA256;GET 无 body 时为 sha256("")
timestamp秒级 Unix 时间戳,与服务端偏差 ≤ 300 秒

签名示例(Python)

import hashlib, hmac, time, requests

ts = str(int(time.time()))
canon = "\n".join(["GET", "/v1/stats", "",
                      hashlib.sha256(b"").hexdigest(), ts])
sig = hmac.new(SECRET.encode(), canon.encode(), hashlib.sha256).hexdigest()

r = requests.get("https://api.metazoon.com/v1/stats", headers={
    "X-Api-Key": KEY, "X-Timestamp": ts, "X-Signature": sig})
凭据只发给后端,不要放进 App 包体或前端。L2 的 secret 一旦落到客户端就等于公开。

快速开始

四步从零到第一条数据。

  1. 取 Key —— 向米塔链申请 L1 或 L2 凭据(L2 会同时给出 secret)。
  2. 打通 L1 —— 先确认网络与 Key 正常:
    curl -s "https://api.metazoon.com/v1/chains" \
      -H "X-Api-Key: pk_pub_xxx"
  3. 加签名调 L2 —— 按上面的待签串算法生成 X-Signature,先打 /v1/stats 验证。
  4. 接业务 —— 列表类用 cursor 翻页;需要持续同步用 updatedSince 增量(注意 deleted:true)。

端点

共 7 个。点开看参数与响应示例。

GET/v1/chains  L1

支持的区块链枚举,供其他接口的 chainId 取值。

{ "data": [
  { "chainId": 1, "code": "WC", "name": "文昌链(Avata)", "explorer": "https://explorer.avata.bianjie.ai" },
  { "chainId": 2, "code": "ZX", "name": "至信链(ZX)", "explorer": "https://zxscan.qq.com" }
] }
GET/v1/classes  L1

类别列表。chainId 按链筛、classId 精确查单个、limit ≤ 200 + cursor 翻页。

GET /v1/classes?chainId=1&limit=50
→ { "data": [ … ], "nextCursor": "…", "hasMore": true }
GET/v1/nfts  L1 / L2

一个端点四种用法:

场景调用级别
列表?chainId=1&limit=50 + cursorL1
精确查?nftNo=MC0%2310%2F10(# / 必须 URL 编码)L1
增量同步?updatedSince=2026-10-21T00:00:00Z + cursorL1
按手机号?phone=13800138000L2

响应字段:nftNo nftId chainId classId className name imageUrl displayUrl metaUrl ownerType ownerKey txHash blockHeight mintedAt updatedAt deleted。

增量模式会返回已删除记录:{"nftNo":"MC5#3/10000","deleted":true}。 收到就删本地副本,否则数据只增不减。
GET/v1/transfers  L2

流转记录(铸造 / 编辑 / 转移 / 销毁)。支持 nftNo 过滤、updatedSince 增量、游标分页。

GET/v1/stats  L2

全链汇总:资产总数、类别总数、按链分布、类别 Top20。

{ "data": {
  "totalAssets": 74655, "totalClasses": 34,
  "byChain": [ { "chainId": 1, "count": 73449 }, … ],
  "topClasses": [ { "classId": …, "className": "MC5", "count": … }, … ]
} }
GET/v1/assets/summary  L2  NEW · v1.1

按手机号聚合「类目 → 件数」。给「我的资产」类目卡片用,不必拉全量列表自行聚合。

GET /v1/assets/summary?phone=13800138000

{ "data": {
  "ownerKey": "u_4b5232f1c543ade1",
  "totalAssets": 369, "totalClasses": 20,
  "classes": [
    { "classId": "metade89…", "className": "MC5", "name": "MC5",
      "chainId": 1, "count": 171 }, …
  ]
} }

只统计 status=1 且在库资产(黑洞 / 销毁 / 寄售不计入);空持仓返回 classes: [] 而非 404; 与 /v1/assets/lookup 的 assetCount 同口径。

POST/v1/assets/lookup  L2

批量问「这批手机号注册了吗 / 各有几件」,单次 ≤ 100 个。请求传手机号,响应不回显手机号,用 index 对应。

POST /v1/assets/lookup
{ "phones": ["13800138000", "13900139000"] }

→ { "data": [
  { "index": 0, "valid": true, "registered": true, "assetCount": 369, "ownerKey": "u_…" },
  …
] }

错误码与限流

对外接口返回真实 HTTP 状态码,错误体统一为 {"error":{"code","message","requestId"}}。

HTTPcode含义
400invalid_argument参数缺失或格式错(如 phone 非 11 位、日期非法)
401missing_credential没带 X-Api-Key
401invalid_keyKey 无效或已停用
401bad_signature签名不匹配 / 时间戳超出 ±300s
403scope_deniedL1 越权访问 L2 接口
403ip_not_allowed来源 IP 不在白名单
404not_found资源或接口不存在
429rate_limited超出配额,看 Retry-After 头退避重试
限流:10 req/s,burst 40,按 X-Api-Key 分桶(无 Key 时退化为按 IP)。 需要更高配额请联系米塔链调整。

版本与变更

以 docs/api-v1-openapi.yaml 的 info.version 为唯一事实来源。

版本日期变更
1.1.02026-10-21新增 GET /v1/assets/summary(按手机号聚合类目计数,L2)
1.0.02026-10-21首个对外版本:chains / classes / nfts / transfers / stats / assets.lookup

版本号规则

变更类型版本动作
新增端点 / 新增可选参数 / 新增响应字段minor +1(1.0.0 → 1.1.0)
修正实现、文档措辞,契约不变patch +1(1.1.0 → 1.1.1)
删字段 / 改语义 / 改鉴权新开 /v2,v1 保留过渡期