繁中

正式版 v3 API

以可查驗的 x402 證據開發。

無須驗證即可查詢公開證據,或使用 Ethereum 錢包登入以註冊並 管理 endpoint。回應會提供具名觀察紀錄,絕不提供綜合 trust score。

基礎 URL https://ifandonlyif.io

01 · Quickstart

查詢公開證據。

已發布的 Evidence Card 不需要 API key。

閱讀圖解證據範例

依 endpoint URL 取得證據
curl -G "https://ifandonlyif.io/api/v3/evidence/check" \
  --data-urlencode \
  "url=https://api.example.com/paid-resource"
兩種發布路徑

observed 卡片可在擁有者認領前公開,條件是 endpoint 啟用、未 opt-out 且已有 discovery observation。卡片帶有「擁有權未驗證」標示與固定 disclaimer。verified tier 首次發布需完成擁有權驗證,且至少三筆通過的 initial 或 scheduled observation。404 表示沒有公開卡片,不是安全 verdict。查詢只讀取已儲存的證據,不啟動 probe。

首頁的 提交以供監控 會呼叫 POST /api/v3/discovery/submit,內容為 {"url":"https://api.example.com/paid"}。此公開 route 需啟用 discovery ingestion,除通用 rate limit 外,每個 IP 每分鐘最多 10 次提交。202 加 queued 表示已記錄 candidate(立即排入佇列僅盡力而為);known 不會再次排入。兩者都不保證監控或發布。worker 觀察前會套用 robots.txt、opt-out、資格及 backoff 規則。payment-network selector 只比較已觀察的選項,不限制 worker 驗證哪些選項。

提交後,頁面每五秒輪詢一次 GET /api/v3/discovery/status?url=…,最多一分鐘,可用時載入公開卡片。此唯讀 route 回傳 {"url":"…","status":"pending"},可能附帶 retry_after_seconds。其他狀態:available、deferred、unavailable、unobserved、disabled。no-store,每個 IP 每分鐘 30 次。查看進度 可不重新提交而繼續讀取。延遲、錯誤與 unavailable 會停止自動檢查。拒絕與 opt-out 細節保持私密。

使用者發起的查詢回傳 404 時,會讀取一次提交狀態。只有已確認的 unobserved 會提供提交;pending 或 deferred 則提供進度。URL 格式有效不等於具備監控資格。查詢不會自動提交,提交也不要求認領擁有權。

成功回應封裝

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

使用錢包登入。

擁有者設定使用 API,沒有 wallet-connect dashboard。你需要能產生 65-byte EIP-191 personal_sign signature 的 Ethereum externally owned account(EOA),以及 endpoint origin 的部署存取權。不支援 contract-wallet signature(EIP-1271 / EIP-6492)。擁有者 route 使用登入 challenge 後核發的短效 access token。

  1. 要求 challenge

    challenge 會綁定 domain、URI、chain、wallet、nonce 與到期時間。

  2. 簽署完全相同的訊息

    以同一錢包地址,將回傳的 message 原封不動交給 personal_sign。請在提示中核對 domain、wallet 與 expiry。這是登入 signature,不是 payment 或 token approval。IFF 永遠不需要你的 private key 或 recovery phrase。

  3. 交換並輪替

    取得 access_token、refresh_token、token_type 與 expires_in。下方範例以 $ACCESS_TOKEN 代表 access token。每個 refresh token 僅能使用一次:refresh 後請替換兩個 token。

1. 建立 challenge
curl "https://ifandonlyif.io/api/v3/auth/challenge" \
  -H "content-type: application/json" \
  -d '{"wallet_address":"0xYOUR_WALLET"}'
2. 驗證 signature · 請求格式
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 來自你的錢包。上例是 request template。請提交原始的 challenge_id 與 message 及錢包的 signature,並以 JSON serializer 建立 body,例如 JSON.stringify({ challenge_id: challenge.challenge_id, wallet_address: wallet, message: challenge.message, signature })。不要將 literal newline 貼入 JSON,也不要自行重建 message。token 請勿出現在 URL、截圖、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 五分鐘後到期且只能使用一次。擁有者回應使用 Cache-Control: no-store。

03 · 擁有權

註冊並證明對 endpoint 的控制權。

註冊只接受 port 443 的公開 HTTPS endpoint,且不得含 credentials、query string、fragment 或 redirect。它建立 claim attempt,不授予擁有者存取權。

回應含唯一的 claim_attempt_id 與 ownership object(challenge、expires_at、verification_url、document)。challenge 有效 24 小時。任何已驗證錢包都可建立獨立 attempt;pending attempt 不能讀取 private observation、手動 probe、管理 webhook、連結 ERC-8004 或取消發布。

註冊 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,並保留 claim_attempt_id 供 polling。兩者都不排入 verification,也不授予 owner access。等待時請勿重複註冊。

對於單一 endpoint,請將回應中的 ownership.document 原封不動發布在 ownership.verification_url,例如:

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

同一 origin 的 endpoint 共用此檔案。新增前請備份目前的 document。將既有 single claim 包成 {"claims":[...]} 的第一項並附加新的 ownership.document,或直接附加到既有 array。保留其他 endpoint 的 claim 與完全相同的 challenge。切勿以最新回應取代整個檔案;IFF 不會合併。

舊版 single-claim format 仍受支援。multi-endpoint format 只有一個 top-level field claims:1–64 個 object,每個恰含 endpoint_id、owner_wallet 與 challenge,使用 API 提供的非空值(canonical lowercase UUID、Ethereum wallet address、完全相同的 challenge)。wallet 比對忽略大小寫。body 須在 16 KiB 以內。unknown 或重複的 JSON field、重複 endpoint ID、混用 format 或任何 malformed entry 都會使整個檔案被拒絕。更新時只替換該 endpoint 的項目。請持續保留有效 claim,供定期 domain-control recheck。

將擁有權驗證排入佇列
curl -X POST \
  "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/verify-ownership" \
  -H "authorization: Bearer $ACCESS_TOKEN"

此 verification request 回傳 202 Accepted:job 已排入佇列,尚未驗證。請遵循 Retry-After(目前為 5 秒),再用同一錢包的 access token polling:

查看你的擁有權嘗試
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 已結案。data.endpoints 列出 authoritative ownership。後續註冊不會輪替另一錢包的 challenge。只有成功的 same-origin proof 可取代 owner;transfer 會停用舊 webhook 並重設發布資格。

檢查失敗後 attempt 仍為 pending 時,請修正已部署的檔案,並在 24 小時內重新排入 verification。attempt 已到期或結案時,請重新註冊該 URL、發布新 document 並排入新 attempt。verification 回傳 409:沒有可用的 pending attempt。503:queue 不可用,不代表通過;請以 backoff 重試。401:更新 token 或重新登入。

擁有權驗證通過後

owner access 與首次發布是不同步驟。verified-tier card 在 ownership verification 完成且至少三筆通過的 initial 或 scheduled observation 後才公開;manual probe 不計入。等待期間公開 404 不代表 ownership 驗證失敗。請用僅限 owner 的 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。要求 private diagnostic 時,執行下方命令,再 polling 此 history 等候新的 manual observation。202 僅確認已排入佇列。manual 結果不會變更 public card、發布資格、manifest 或通知。

將私人診斷排入佇列
curl -X POST \
  "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/probes" \
  -H "authorization: Bearer $ACCESS_TOKEN"

接著請設定變更通知。要停止監控並隱藏卡片,請使用下方僅限 owner 的動作。它也會停用 webhook 與 pending delivery,但保留 immutable observation、claim-attempt audit 與 transparency-log entry。快取的卡片最多可再顯示 30 秒。要恢復,請重新註冊該 URL 並再次證明控制權。

停止監控並取消發布 · 會變更 endpoint 狀態
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 時,history 與停止仍可用,但建立 webhook 或 manual probe 會回傳 409,直到 ownership 再次驗證。

證據界線

ownership 只證明對受監控 origin 的控制權,不證明誰操作 backend、付款後會發生什麼,或 endpoint 是否安全。

04 · Reference

endpoint 參考資料。

以 :id 結尾的路徑參數為 UUID。分頁接受 page 與最大 100 的 page_size。每個 GET route 也回應 HEAD。公開 route 與 POST /api/v3/verify 回傳 Access-Control-Allow-Origin: *;需 authentication 的 route 不回傳。

公開與驗證

方法路徑用途
GET/healthLiveness 與依賴是否可用的概略布林值(不含服務名稱、版本或元件標籤)。
GET/api/v3/evidence/check?url=…依 normalized endpoint URL 取得已發布的 Evidence Card。
GET/api/v3/evidence/endpoints/:id依 endpoint ID 取得已發布的 Evidence Card。
GET/api/v3/evidence/manifests/:id依 manifest ID 取得附有 ETag、不可變的每日 evidence manifest。它與上述 endpoint ID 使用不同的 ID 空間。請從 Evidence Card 的 anchor.manifest_uri 取得 manifest ID;若在此傳入 endpoint ID,會回傳 404 並說明原因。
GET/api/v3/log/anchors/latest已簽署 transparency-log tree head 最新提交或已確認的 ERC-8004 anchor。
POST/api/v3/auth/challenge建立一次性的 wallet challenge。
POST/api/v3/auth/verify驗證 EIP-191 signature 並簽發 token pair。
POST/api/v3/auth/refresh輪替只能使用一次的 refresh token。
POST/api/v3/verify將收到的 x402 requirement 與獨立 observation 進行 Preflight 比較。
GET/api/v3/receipts/keys可選實驗性功能 Service Receipt v2 目前使用與保留的 public key(v1 key 列為 previous)。
GET/api/v3/badge/:id.json用於 shields.io endpoint badge 的 JSON,描述 endpoint 目前的 requirement consistency。

已驗證的錢包與 endpoint 擁有者

下方每個 route 都需要 Authorization: Bearer <access_token>。registration、polling 與 verification 限建立 attempt 的 wallet;management route 需 verified 或 stale ownership。

方法路徑用途
POST/api/v3/endpoints建立獨立的 claim attempt 與 ownership challenge,不會授予權限。
GET/api/v3/endpoints列出具有效擁有權的 endpoint 與此錢包的 claim-attempt 稽核狀態。
DELETE/api/v3/endpoints/:id取消發布 endpoint,並保留不可變的 evidence。
POST/api/v3/endpoints/:id/verify-ownership將 well-known ownership verification 排入佇列。
POST/api/v3/endpoints/:id/probes將僅限 owner 的 manual observation 排入佇列。
GET/api/v3/endpoints/:id/observations分頁讀取完整的 observation history。
POST/api/v3/endpoints/:id/webhooks建立用於 status 或 requirement 變更的 owner Webhook;secret 只會回傳一次。
GET/api/v3/endpoints/:id/webhooks列出作用中的 target,不含 secret。
DELETE/api/v3/endpoints/:id/webhooks/:webhookId停用 Webhook 與待傳送項目。
POST/api/v3/endpoints/:id/erc8004連結 owner 持有的 ERC-8004 agent identity。

05 · 回應模型

分別解讀各項維度。

ownership
目前的 domain-control 狀態、方式與驗證時間。
protocol
最新的 x402 解析結果、版本、各項具名檢查與宣告的 payment option。
availability
24 小時與 7 天的樣本、百分比與 p50/p95 latency。
freshness
最新 observation 是否仍在發布所需的 freshness window 內。
evidence
Canonical report hash、monitor identity、ML-DSA-65 signature(舊 report 為 Ed25519)與 public key。
anchor
可選的每日 manifest 鏈上狀態與 transaction provenance。

rate 為 0 至 100 的百分比。缺少的 measurement 會略去或為 null;請勿推論為通過。

observed tier 的 probe 也會按 UTC 日計數。每個結束的日子會封存成一份每日確認文件,其 hash 以一個 leaf 進入 transparency log;啟用 change-only storage 後,只有 observed state 變動時才保存完整的簽章 observation。GET /api/v3/evidence/observed-confirmations/:day(或 /latest)回傳原始 body、document_hash、leaf_hash 與承諾等級:sealed、logged 或 anchored。這是 monitor 觀測到的統計,不證明每次 probe 都實際執行。

06 · Webhook

驗證每一次傳送。

衍生的 operational status 改變時,owner subscription 收到 endpoint.status_changed;合格 observation 顯示不同 payment requirement fingerprint 時,收到 endpoint.requirement_changed(不證明攻擊)。manual probe 不觸發任何事件;observed-tier card 不授予 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 存放於接收端伺服器;secret 只顯示一次,無法取回。target 須為公開 HTTPS/443,不得含 credentials、query string、fragment 或 redirect。作用中 target 重複或作用中訂閱超過 10 個,回傳 409。

建立訂閱不傳送測試事件。事件隨符合資格的 observation 變更而觸發,不隨每次 probe。依賴通知前,請先驗證下列 header。

X-IFF-Timestamp: 1700000000 X-IFF-Signature: sha256=<hex digest> Idempotency-Key: <delivery uuid>
  1. 拒絕超出允許 clock-skew 範圍的 timestamp。
  2. 使用僅顯示一次的 secret,對 timestamp + "." + raw_body 計算 HMAC-SHA256。
  3. 以 constant-time 比較 hex digest。
  4. 依 Idempotency-Key 去重;重複傳送仍應回應 2xx。
列出作用中的訂閱 · 不會傳回 secret
curl "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/webhooks" \
  -H "authorization: Bearer $ACCESS_TOKEN"
停止一個訂閱 · 會變更通知狀態
curl -X DELETE \
  "https://ifandonlyif.io/api/v3/endpoints/ENDPOINT_UUID/webhooks/WEBHOOK_UUID" \
  -H "authorization: Bearer $ACCESS_TOKEN"

清單位於 data。刪除回傳 204 No Content,停止待傳送項目,不取消發布 endpoint。遺失 secret 時請刪除並重建訂閱。切勿在 client-side code 暴露 secret。

07 · Preflight

付款前先檢查。

對收到的 x402 payment requirement 採取行動前,先與 IFF 獨立且已簽署的 observation 比較。它不 probe URL,且僅在尚無 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
可從任何程式語言使用 POST /api/v3/verify。公開 Preflight 檢查不需要 API key。
Badge
![x402 evidence](https://img.shields.io/endpoint?url=https://ifandonlyif.io/api/v3/badge/ENDPOINT_UUID.json)

實驗性功能展示:Service Receipt v2

Service Receipt v2 是單一 verification result 的可選 signed artifact,不屬於 core preflight contract。它將 response、verification-request digest 與五分鐘 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"}
已簽署的 artifact
成功選用此功能後會新增 service_receipt,不會變更其他 response field。
本機 verifier
將獨立 envelope 或完整 API response 貼入Receipt 展示頁(英文)。驗證會在瀏覽器本機執行。
取得目前與先前的 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 檢查

有效的 ML-DSA-65(v2)或 Ed25519(v1)signature 表示內含的 key 簽署了 receipt(provenance,不是 attestation),但不表示該 key 屬於聲稱的 issuer。符合 same-origin HTTPS key directory 的 key 可辨識;最嚴格的 policy 還會比對確切 issuer 與獨立釘選的完整 sha256: fingerprint。解碼後的 signed subject 才具權威,須與外層 response 比較。引用的 evidence 在其專屬 proof 通過前仍未驗證。IFF 目前將 compute_proof 設為 null。

08 · 錯誤與限制

失敗時不要推論證據。

錯誤封裝
{
  "error": true,
  "message": "human-readable reason"
}
狀態含義
400JSON、UUID、URL、分頁或輸入結構格式錯誤。
401token 缺少、無效、過期、重放或類型錯誤。
403已通過 authentication 的錢包不擁有所請求的資源。
404公開 evidence 或所請求的 owner 資源不存在。
409ownership 狀態、重複 target 或資源狀態衝突。
422x402 requirement、receipt version 或 receipt nonce 無效。
429已達 rate limit;請以 backoff 重試。
503Evidence repository、queue、registry、receipt 簽發或其他依賴不可用。
安全假設

IFF 是外部 observer。它不執行 paid canary transaction、不作 payment-safety 主張、不保證付款後的 delivery,也不判定 endpoint 是否值得信任。monitor signature 顯示 provenance 與 tamper evidence,不是 attestation。