API
お客様のシステムから検証リクエストを作成し、署名リンクを相手方に送付して、署名後に証明書を取得できます。相手方の操作は変わりません。リンクを開き、アカウントなしでメッセージに 1 回署名するだけです。
API アクセスは Pro および Business に含まれます。キーはアカウント → API キーで作成できます。
認証
すべての呼び出しで、キーを bearer トークンとして送信してください。キーは作成時に一度だけ表示されます。当社はハッシュのみを保存します。
Authorization: Bearer signet_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ベース URL:https://basignet.com/api/v1。機械可読な仕様は /api/v1/openapi.json にあります。
リクエストの作成
curl https://basignet.com/api/v1/requests \
-H "Authorization: Bearer $SIGNET_KEY" \
-H "Content-Type: application/json" \
-d '{
"chain": "tron",
"targetAddress": "TNeiUDQmrGHbsC4oPd8L6dZdxyPQrrWyP2",
"reference": "KYC-2026-0412",
"anchor": true,
"messageLocale": "ru",
"expiresAt": "2026-10-31T23:59:59Z"
}'必須なのは chain のみです。targetAddress を空にすると、相手方が署名に使うアドレスを自分で指定できます。指定すると、そのアドレスでの署名が必須になります。
anchor: true を指定すると、署名後に証明書をオンチェーンでアンカリングし、その時点で月間上限にカウントされます。messageLocale はデフォルトメッセージの言語を設定します(「チェーンと言語」を参照)。message はメッセージ本文を独自のテキストに置き換えます。Nonce / Issued / Domain のフッターは常に付加されます。
レスポンスはリクエストオブジェクトです。signingUrl をお客様ご自身の連絡手段で相手方に送付してください。
リクエストの取得
curl https://basignet.com/api/v1/requests/{token} \
-H "Authorization: Bearer $SIGNET_KEY"リクエストオブジェクトを返します。status は pending、failed(最後の署名が検証に失敗。リンクは引き続き使用可能)、verified、expired のいずれかです。検証後は certificate が設定されます。
リクエストの一覧
curl "https://basignet.com/api/v1/requests?status=verified&limit=50" \
-H "Authorization: Bearer $SIGNET_KEY"
{ "object": "list", "data": [ …requests ], "hasMore": true, "nextBefore": "2026-09-30T10:12:03.117Z" }新しい順に返します。limit は 1~100(デフォルト 20)、status で絞り込み、before には前のページの nextBefore の値を指定します。
証明書
curl https://basignet.com/api/v1/requests/{token}/certificate \
-H "Authorization: Bearer $SIGNET_KEY" -o proof.json
curl "https://basignet.com/api/v1/requests/{token}/certificate?format=pdf" \
-H "Authorization: Bearer $SIGNET_KEY" -o certificate.pdf自己完結型の証明パケットを JSON で、または ?format=pdf で PDF として返します。リクエストが署名されるまでは 409 を返します。パケットは当社に依存せず、オープンソースの検証ツールで検証できます。
チェーンと言語
curl https://basignet.com/api/v1/chains
公開、キー不要:対応チェーン(id を chain として使用)と、messageLocale で使用できる言語。
Webhook
アカウント → Webhook でエンドポイントを設定すると、ポーリングの代わりに HTTPS POST を受信できます:
request.verified:相手方が署名し、証明書が発行されました。request.anchored:証明書がオンチェーンでアンカリングされました(anchor を指定して作成したリクエストのみ)。ping:アカウントページから送信されるテストイベント。
本文は { id, type, created, data: { request } } で、request は API が返すものと同じオブジェクトです。5 秒以内に任意の 2xx で応答してください。配信に失敗した場合は 1 分後、5 分後、30 分後、2、6、12、24 時間後に再試行され、その後失敗としてマークされます。重複を無視するには id を使用してください。
すべての POST には Signet-Signature: t=…,v1=… が付きます。v1 は、エンドポイントの署名シークレットで t + "." + raw body を計算した 16 進数の HMAC-SHA256 です。パース前に生の本文で検証し、数分より古いタイムスタンプは拒否してください:
// Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
function verifySignet(rawBody, header, secret, toleranceSec = 300) {
const { t, v1 } = Object.fromEntries(header.split(",").map((kv) => kv.split("=")));
if (!t || !v1 || Math.abs(Date.now() / 1000 - Number(t)) > toleranceSec) return false;
const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest();
const given = Buffer.from(v1, "hex");
return given.length === expected.length && timingSafeEqual(given, expected);
}# Python
import hmac, hashlib, time
def verify_signet(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
parts = dict(kv.split("=", 1) for kv in header.split(","))
t, v1 = parts.get("t"), parts.get("v1")
if not t or not v1 or abs(time.time() - int(t)) > tolerance:
return False
expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, v1)エラーと制限
HTTP/1.1 403
{ "error": { "type": "plan_required", "message": "API access is included in the Pro and Business plans." } }エラーは JSON で返されます:{ "error": { "type", "message" } }。タイプ:unauthorized(401)、plan_required(403)、not_found(404、他のアカウントのトークンの場合も含む)、conflict(409)、invalid_request(400)、rate_limited(429、Retry-After 付き)。
各キーは 1 分あたり 120 回まで呼び出せます。
リクエストオブジェクト
{
"object": "request",
"token": "q0tHA2UW6oiuuzVC1qtIf2N1dgKX6miW",
"status": "verified", // pending | failed | verified | expired
"chain": "ethereum",
"chainLabel": "Ethereum",
"targetAddress": null, // null = supplied by the signer
"reference": "KYC-2026-0412",
"anchor": true,
"signingUrl": "https://basignet.com/s/q0tHA2UW6oiuuzVC1qtIf2N1dgKX6miW",
"challenge": "BA Signet — Proof of Wallet Control\n…\nNonce: …\nIssued: …\nDomain: basignet.com",
"createdAt": "2026-09-30T09:58:41.201Z",
"expiresAt": null,
"completedAt": "2026-09-30T10:03:12.554Z",
"certificate": { // null until signed
"address": "0x5e3fbf618ef1cc1cc021e7fed95e07c6ff334ca8",
"sigType": "eip191",
"contentHash": "0xaa00c6f6…",
"verifiedAt": "2026-09-30T10:03:12.554Z",
"verifyUrl": "https://basignet.com/verify/0xaa00c6f6…",
"anchorStatus": "anchored", // unanchored | pending | anchored
"anchor": { // null until anchored
"chain": "polygon",
"txHash": "0x…",
"txUrl": "https://polygonscan.com/tx/0x…",
"blockNumber": 94660444,
"blockTime": "2026-09-29T15:30:06.000Z",
"merkleRoot": "0x…",
"bitcoinBlockHeight": null
}
}
}v1 の範囲内でフィールドが追加されることがあります。既存のフィールドの名前変更や削除は行いません。