日本語

本番 v3 API

確認できる x402 の証拠を開発に役立てる。

authentication なしで public evidence を照会するか、Ethereum wallet で sign in して endpoint を登録・運用できます。response は名前付き observation を示します。composite trust score は提供しません。

ベース URL https://ifandonlyif.io

01 · クイックスタート

公開証拠を照会する。

公開済み Evidence Card に API key は不要です。

図解付きの証拠例を読む

endpoint URL で evidence を GET
curl -G "https://ifandonlyif.io/api/v3/evidence/check" \
  --data-urlencode \
  "url=https://api.example.com/paid-resource"
2 つの公開経路

observed card は、endpoint が active で、opt-out されておらず、discovery observation がある場合、owner の claim 前でも public にできます。「ownership 未検証」の表示と固定の disclaimer が付きます。verified tier の最初の公開には、ownership verification の成功と、passing した initial または scheduled observation が 3 件以上必要です。404 は public card がないことを意味し、安全 verdict ではありません。lookup は probe を開始せず、保存済み evidence を読み取ります。

ホームページの 監視対象として送信 は POST /api/v3/discovery/submit を {"url":"https://api.example.com/paid"} とともに呼びます。この public route は discovery ingestion が有効である必要があり、general rate limit に加え IP ごとに毎分 10 submission までです。202 と queued は candidate が記録されたことを意味します(即時 enqueue は best-effort)。known は再 enqueue しません。どちらも monitoring や公開を保証しません。worker は observation 前に robots.txt、opt-out、eligibility、backoff rule を適用します。payment-network selector は observed option を比較するだけで、worker が検証する option を制限しません。

submission 後、page は最大 1 分間、5 秒ごとに GET /api/v3/discovery/status?url=… を polling し、利用可能になれば public card を読み込みます。この read-only route は {"url":"…","status":"pending"} を返し、必要に応じて retry_after_seconds を含みます。ほかの state: available、deferred、unavailable、unobserved、disabled。no-store で、IP ごと毎分 30 回まで。Check progress は再 submission せずに read を再開します。delay、error、unavailable は自動確認を停止します。rejection と opt-out の詳細は非公開です。

user-initiated lookup が 404 を返すと、submission status を一度読みます。submission を提示するのは確認済みの unobserved だけで、pending または deferred では進捗を提示します。URL format が有効でも monitoring eligibility にはなりません。lookup は自動 submission せず、submission に ownership claim は不要です。

成功 response の envelope

200 application/json
{
  "success": true,
  "data": {
    "endpoint": {
      "id": "ENDPOINT_UUID",
      "url": "https://api.example.com/paid-resource",
      "name": "Example x402 API"
    },
    "operational_status": "passing",
    "ownership": {
      "status": "verified",
      "method": "iff-well-known"
    },
    "protocol": {
      "status": "pass",
      "version": 2,
      "payment_options": [],
      "check_codes": ["x402_v2_valid"]
    },
    "availability": [
      {
        "window": "24h",
        "samples": 288,
        "reachable_rate": 100,
        "protocol_pass_rate": 99.7,
        "p50_latency_ms": 84,
        "p95_latency_ms": 190
      }
    ],
    "freshness": {
      "status": "fresh",
      "observed_at": "2026-07-12T04:30:00Z",
      "interval_seconds": 300
    },
    "evidence": {
      "report_hash": "HEX_SHA256",
      "monitor_id": "iff-production-monitor",
      "monitor_version": "3.0.0",
      "monitor_signature_algorithm": "ML-DSA-65",
      "monitor_signature": "BASE64_ML_DSA_65_SIGNATURE",
      "monitor_public_key": "BASE64_ML_DSA_65_PUBLIC_KEY"
    }
  }
}

02 · Authentication

ウォレットでサインインする。

owner setup は wallet-connect dashboard ではなく API を使用します。65-byte EIP-191 personal_sign signature を生成できる Ethereum externally owned account(EOA)と、endpoint origin への deployment access が必要です。contract-wallet signature(EIP-1271 / EIP-6492)は非対応です。owner route は login challenge 後に発行される短時間有効な access token を使います。

  1. challenge を要求

    challenge は domain、URI、chain、wallet、nonce、expiry に bind されます。

  2. 正確な message に署名

    返された message は変更せず、同じ wallet address で wallet の personal_sign method に渡してください。wallet prompt で domain、wallet、expiry を確認します。これは login signature であり、payment や token approval ではありません。IFF が private key や recovery phrase を必要とすることはありません。

  3. 交換とローテーション

    access_token、refresh_token、token_type、expires_in を受け取ります。以下の owner example では access token を $ACCESS_TOKEN として使用してください。refresh token はすべて single-use です。refresh 後は両方の token を新しい response のものに置き換えます。

1. Create challenge
curl "https://ifandonlyif.io/api/v3/auth/challenge" \
  -H "content-type: application/json" \
  -d '{"wallet_address":"0xYOUR_WALLET"}'
2. signature を検証 · request の形式
curl "https://ifandonlyif.io/api/v3/auth/verify" \
  -H "content-type: application/json" \
  -d '{
    "challenge_id":"CHALLENGE_UUID",
    "wallet_address":"0xYOUR_WALLET",
    "message":"EXACT_MESSAGE_FROM_SERVER",
    "signature":"0xSIGNATURE"
  }'

curl では署名できません。signature は wallet から得ます。上記は request template です。元の challenge_id と message を wallet の signature とともに送信し、body は JSON.stringify({ challenge_id: challenge.challenge_id, wallet_address: wallet, message: challenge.message, signature }) のような JSON serializer で作成してください。JSON に literal newline を貼り付けたり message を再構築したりしないでください。token は URL、screenshot、source code、shell history に残さないでください。

3. refresh token を更新
curl "https://ifandonlyif.io/api/v3/auth/refresh" \
  -H "content-type: application/json" \
  -d '{"refresh_token":"REFRESH_TOKEN"}'

challenge は 5 分で expiry し、1 回だけ使用できます。owner response には Cache-Control: no-store が付与されます。

03 · Ownership

endpoint を登録し、制御権を証明する。

registration は credentials、query string、fragment、redirect のない port 443 の public HTTPS endpoint だけを受け付けます。owner access ではなく claim attempt を作成します。

response には一意の claim_attempt_id と ownership object(challenge、expires_at、verification_url、document)が含まれます。challenge の有効期間は 24 時間です。authentication 済みの wallet は独立した attempt を作成できますが、pending attempt では private observation の閲覧、manual probe、Webhook 管理、ERC-8004 連携、公開停止はできません。

Register endpoint
curl "https://ifandonlyif.io/api/v3/endpoints" \
  -H "authorization: Bearer $ACCESS_TOKEN" \
  -H "content-type: application/json" \
  -d '{
    "url":"https://api.example.com/paid-resource",
    "name":"Example x402 API",
    "description":"Payment-gated resource"
  }'

201 Created: 新しい endpoint と claim attempt。200 OK: 既存 endpoint に新しい attempt を追加。endpoint_id を ENDPOINT_UUID として保存し、polling 用に claim_attempt_id を保持してください。どちらも verification を queue せず、owner access も付与しません。待つ間は繰り返し registration しないでください。

1 つの endpoint では、response の ownership.document を変更せず ownership.verification_url に公開します。例:

https://api.example.com/.well-known/iff-trust.json

同じ origin の endpoint はこの file を共有します。追加前に現在の document を backup してください。既存の single claim を {"claims":[...]} の最初の item にして新しい ownership.document を append するか、既存 array に append します。ほかの endpoint の claim と正確な challenge は維持してください。file 全体を最新 response で置き換えないでください。IFF は merge しません。

従来の single-claim format も利用できます。multi-endpoint format の top-level field は claims のみで、1〜64 個の object を含み、各 object は endpoint_id、owner_wallet、challenge だけを持ちます。API が返した空でない値(canonical な小文字 UUID、Ethereum address、完全一致の challenge)を使います。wallet 比較は大文字・小文字を区別しません。body は 16 KiB 以内。未知または重複する JSON field、重複 endpoint ID、format の混在、不正な項目があるとファイル全体が拒否されます。更新時はその endpoint の項目だけを置き換えます。定期的な domain-control の再確認のため、検証後も有効な claim を公開しておいてください。

ownership verification を queue に入れる
curl -X POST \
  "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/verify-ownership" \
  -H "authorization: Bearer $ACCESS_TOKEN"

この verification request は 202 Accepted を返します。job は queue 済みですが、まだ verified ではありません。Retry-After(現在 5 秒)に従い、同じ wallet の access token で poll してください。

ownership attempt を確認
curl "https://ifandonlyif.io/api/v3/endpoints?page=1&page_size=20" \
  -H "authorization: Bearer $ACCESS_TOKEN"

data.claim_attempts[].id から保存した attempt ID を探し(必要なら次のページも)、status、outcome_code、verification_failures を確認します。pending は成功ではありません。verified は proof が通過、failed、expired、superseded は終了した attempt です。data.endpoints は現在有効な ownership を列挙します。後からの登録は別の wallet の challenge を更新しません。owner を置き換えられるのは成功した same-origin proof だけで、移転は古い Webhook を無効にし公開資格をリセットします。

確認失敗後も attempt が pending なら、ファイルを修正し、24 時間以内に verification を再度 queue してください。期限切れまたは終了した attempt では、同じ URL を再登録し、新しい document を公開して新しい attempt を queue します。verification の 409: 利用可能な pending attempt なし。503: queue 利用不可で、成功ではありません。backoff で再試行。401: token 更新または再ログインが必要です。

ownership が通過した後

owner access と最初の公開は別です。verified-tier card は ownership verification 完了後、initial または scheduled observation が 3 回以上通過すると公開されます。manual probe は含まれません。待機中の公開 404 は ownership の失敗ではありません。owner 専用の履歴で調べます。

private observation history を読む
curl "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/observations?page=1&page_size=20" \
  -H "authorization: Bearer $ACCESS_TOKEN"

data.observations と各 probe_type を確認します。非公開の診断は下の command を実行し、新しい manual observation をこの履歴で polling します。202 は queue に入ったことだけを示します。manual の結果は public card、公開資格、manifest、通知を変更しません。

非公開の診断を queue に入れる
curl -X POST \
  "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/probes" \
  -H "authorization: Bearer $ACCESS_TOKEN"

次に変更通知を設定します。monitoring を停止して card を非公開にするには、下の owner 専用操作を使います。Webhook と送信待ち delivery も停止しますが、immutable observation、claim-attempt の監査情報、transparency-log entry は残ります。キャッシュ済みの card は最大 30 秒表示されることがあります。再開するには同じ URL を登録し、control を再度証明してください。

monitoring を停止して非公開にする · endpoint state を変更します
curl -X DELETE \
  "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID" \
  -H "authorization: Bearer $ACCESS_TOKEN"

停止に成功すると 204 No Content を返します。wallet に現在有効な verified または stale claim がない場合、owner management route は 404 を返します(pending attempt だけでは不十分)。claim が stale の場合、履歴と停止は使えますが、ownership が再検証されるまで Webhook 作成と manual probe は 409 を返します。

証拠の境界

ownership が証明するのは monitoring 対象 origin の control だけです。backend の運用者、payment 後の動作、endpoint が safe かどうかは証明しません。

04 · Reference

endpoint リファレンス.

:id で終わる path parameter は UUID です。pagination は page と最大 100 の page_size を受け付けます。各 GET route は HEAD にも応答します。public route と POST /api/v3/verify は Access-Control-Allow-Origin: * を返し、authentication が必要な route は返しません。

公開と authentication

MethodPathPurpose
GET/healthliveness と大まかな dependency boolean(service name、version、component label は含みません)。
GET/api/v3/evidence/check?url=…normalized endpoint URL による公開 evidence card。
GET/api/v3/evidence/endpoints/:idendpoint ID による公開 evidence card。
GET/api/v3/evidence/manifests/:idmanifest ID を指定し、ETag 付きの immutable な日次 evidence manifest を取得します。これは上の endpoint ID とは別の ID 空間です。manifest ID は Evidence Card の anchor.manifest_uri から取得してください。ここに endpoint ID を渡すと、理由を示すメッセージとともに 404 を返します。
GET/api/v3/log/anchors/latestsigned transparency-log tree head に対する、最新の submitted または confirmed ERC-8004 anchor。
POST/api/v3/auth/challengeone-time wallet challenge を作成します。
POST/api/v3/auth/verifyEIP-191 signature を検証し、token pair を発行します。
POST/api/v3/auth/refreshsingle-use refresh token を rotate します。
POST/api/v3/verify受け取った x402 requirement を independent observation と preflight-check します。
GET/api/v3/receipts/keys任意かつ実験的な Service Receipt v2 の current および retained public key(v1 key は previous として掲載)。
GET/api/v3/badge/:id.jsonendpoint の current requirement consistency 用 shields.io endpoint-badge JSON。

authenticated wallet と endpoint owner

下のすべての route に Authorization: Bearer <access_token> が必要です。登録、polling、verification は attempt を作成した wallet 用で、management route は verified または stale の ownership が必要です。

MethodPathPurpose
POST/api/v3/endpoints独立した、authorization を付与しない claim attempt と ownership challenge を作成します。
GET/api/v3/endpointsauthoritative endpoint と、この wallet の claim-attempt audit status を一覧表示します。
DELETE/api/v3/endpoints/:idimmutable evidence を保持したまま endpoint を非公開にします。
POST/api/v3/endpoints/:id/verify-ownershipwell-known ownership verification を queue に入れます。
POST/api/v3/endpoints/:id/probesowner-only manual observation を queue に入れます。
GET/api/v3/endpoints/:id/observationspagination された full observation history を読み取ります。
POST/api/v3/endpoints/:id/webhooksstatus または requirement change 用の owner webhook を作成します。secret は 1 回だけ返されます。
GET/api/v3/endpoints/:id/webhookssecret を含めずに active target を一覧表示します。
DELETE/api/v3/endpoints/:id/webhooks/:webhookIdwebhook と pending delivery を deactivate します。
POST/api/v3/endpoints/:id/erc8004owner が保持する ERC-8004 agent identity を link します。

05 · Response model

各ディメンションを独立して読む。

ownership
現在の domain-control status、method、verification time。
protocol
最新の x402 parse result、version、名前付き check、advertised payment option。
availability
24 時間・7 日間の sample、percentage rate、p50/p95 latency。
freshness
最新の observation が publication freshness window 内にあるかどうか。
evidence
canonical report hash、monitor identity、ML-DSA-65 signature(旧 report は Ed25519)、public key。
anchor
任意の daily manifest chain status と transaction provenance。

rate は 0 から 100 の百分率です。missing measurement は省略されるか null です。pass と推論しないでください。

observed tier の probe は UTC 日ごとにも集計されます。終了した日は 1 つの日次確認ドキュメントに封印され、その hash は 1 つの leaf として transparency log に入ります。change-only storage を有効にすると、署名付き observation 全体は observed state が変化したときだけ保存されます。GET /api/v3/evidence/observed-confirmations/:day(または /latest)は元の body、document_hash、leaf_hash と commitment level(sealed、logged、anchored)を返します。これは monitor が観測した統計であり、すべての probe が実行された証明ではありません。

06 · Webhooks

すべての delivery を検証する。

derived operational status が変わると owner subscription は endpoint.status_changed を、eligible observation が異なる payment requirement fingerprint を示すと endpoint.requirement_changed を受け取ります(attack の証明ではありません)。manual probe はどちらも発火せず、observed-tier card は subscription 権限を付与しません。

subscription を作成
curl "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/webhooks" \
  -H "authorization: Bearer $ACCESS_TOKEN" \
  -H "content-type: application/json" \
  -d '{"target_url":"https://hooks.example.com/iff"}'

作成には verified ownership が必要で、成功すると 201 Created とともに id、target_url、secret を返します。ID を WEBHOOK_UUID として保存し、secret は受信側 server に保管してください。secret は一度しか表示されず、再取得できません。target は公開 HTTPS/443 で、credentials、query string、fragment、redirect を含められません。有効な target の重複、または有効な subscription が 10 件を超えると 409 を返します。

subscription を作成してもテストイベントは送信されません。イベントは対象となる observation の変化で発生し、probe ごとではありません。通知に頼る前に、受信側で下の header を検証してください。

X-IFF-Timestamp: 1700000000 X-IFF-Signature: sha256=<hex digest> Idempotency-Key: <delivery uuid>
  1. 許容する clock-skew window 外の timestamp を拒否します。
  2. one-time secret を使い、timestamp + "." + raw_body に対して HMAC-SHA256 を計算します。
  3. hex digest を constant time で比較します。
  4. Idempotency-Key で deduplicate します。繰り返された delivery にも 2xx を返します。
有効な subscription の一覧 · secret は返しません
curl "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/webhooks" \
  -H "authorization: Bearer $ACCESS_TOKEN"
subscription を 1 件停止 · 通知状態を変更します
curl -X DELETE \
  "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/webhooks/WEBHOOK_UUID" \
  -H "authorization: Bearer $ACCESS_TOKEN"

一覧は data にあります。削除すると 204 No Content を返し、送信待ち delivery を停止しますが、endpoint の公開は停止しません。secret を失ったら削除して作り直してください。secret を client-side code に公開してはいけません。

07 · Preflight

支払う前に確認する。

受け取った x402 payment requirement に対して action する前に、IFF の独立した signed observation と比較します。URL を probe せず、保存するのは observation がない場合の normalized URL だけです。verdict は consistent、diverged、unobserved、stale のいずれかで、composite score はなく、safety、delivery、trust の主張もしません。

requirement を検証
curl "https://ifandonlyif.io/api/v3/verify" \
  -H "content-type: application/json" \
  -d '{
    "url":"https://api.example.com/v1/quote",
    "payment_required":{"x402Version":2,"accepts":[{
      "scheme":"exact",
      "network":"eip155:8453",
      "asset":"0xab12cd34ab12cd34ab12cd34ab12cd34ab12cd34",
      "amount":"1000",
      "payTo":"0xef56ab78ef56ab78ef56ab78ef56ab78ef56ab78",
      "maxTimeoutSeconds":60
    }]}
  }'
TypeScript SDK
npm install @ifandonlyif/x402-preflight — verify()、wrapFetch()、または同梱の MCP command を使用できます。 SDK ガイドを読む.
Direct API
任意の language から POST /api/v3/verify を使用できます。public preflight check に API key は不要です。
Badge
![x402 evidence](https://img.shields.io/endpoint?url=https://ifandonlyif.io/api/v3/badge/ENDPOINT_UUID.json)

実験的 capability showcase:Service Receipt v2

Service Receipt v2 は単一の verification result に対する任意の signed artifact で、core preflight contract には含まれません。response、verification-request digest、5 分間の action window を IFF 専用の ML-DSA-65 receipt key で結び付けます。receipt を省略するか null を送れば response は変わりません。{} または "version":"2" は v2 を発行し、"1" は 422 を返します。既存の v1 receipt は引き続き検証できます。

実験的な receipt を有効にする
"receipt":{"version":"2","nonce":"checkout_7f3a"}
Signed artifact
この機能を有効にして成功すると、他の response field を変更せずに service_receipt が追加されます。
Local verifier
単独の envelope または API response 全体を Receipt showcase(英語) に貼り付けてください。検証はブラウザ内でローカルに実行されます。
現在および過去の receipt key を取得
curl "https://ifandonlyif.io/api/v3/receipts/keys"
x402 payment receipt ではありません

Service Receipt は payment、service delivery、caller identity、remote execution、result correctness、safety を証明しません。receipt key が内包された result に署名したことを記録するだけです。

verification check を分けて扱う

有効な ML-DSA-65(v2)または Ed25519(v1)signature は、内包された key が receipt に署名したこと(provenance であり attestation ではない)を示しますが、その key が申告された issuer に属することは示しません。same-origin HTTPS key directory との一致は認識されます。最も厳格な policy では、正確な issuer と、独立した経路で pin した完全な sha256: fingerprint も照合します。復号した signed subject が正で、外側の response と比較します。参照された evidence は専用の proof を検証するまで未検証です。IFF は現在 compute_proof を null に設定します。

08 · エラーと制限

evidence を推論せずに失敗として扱う。

error envelope
{
  "error": true,
  "message": "human-readable reason"
}
status意味
400不正な JSON、UUID、URL、pagination、または input shape。
401token が missing、invalid、expired、replayed、または token type が不正。
403authenticated wallet は request された resource を所有していません。
404public evidence または要求された owner resource がありません。
409ownership state、duplicate target、または resource state が conflict しています。
422無効な x402 requirement、receipt version、または receipt nonce。
429rate limit に到達しました。backoff して retry します。
503evidence repository、queue、registry、receipt issuance、または別の dependency が unavailable です。
セキュリティ上の前提

IFF は external observer です。paid canary transaction を実行せず、payment-safety の主張をせず、payment 後の delivery を保証せず、endpoint が trustworthy かも判断しません。monitor signature が示すのは provenance と tamper evidence であり、attestation ではありません。