AIにAPIを選ばせるために、1日やったこと
はじめに
x402対応のAPIを作っても、AIエージェントに発見・選択されなければ意味がありません。
今日はx402scanへの登録とAI向けAPI最適化を実装しました。試行錯誤の記録として残します。
x402scanとは
x402scanはx402対応APIのエコシステムブラウザです。AIエージェントがx402対応APIを発見・検索できます。
登録するとagentcash経由でAIエージェントに発見・呼び出しされるようになります。
実装環境
言語:Python
フレームワーク:FastAPI
インフラ:Render
決済:x402(USDC・Base mainnet)
/.well-known/x402の実装
x402scanはまず/.well-known/x402エンドポイントを読んでAPIを発見します。
@app.get("/.well-known/x402", include_in_schema=False)
async def x402_discovery_manifest():
return {
"version": 1,
"name": "Agent Budget Guard",
"description": "Pay-per-request governance APIs for AI agents using x402.",
"tags": ["AI", "Payments", "Governance"],
"resources": [
"https://agent-budget-guard.onrender.com/api/budget/check",
"https://agent-budget-guard.onrender.com/api/budget/record",
"https://agent-budget-guard.onrender.com/api/record-payment",
"https://agent-budget-guard.onrender.com/api/classify-invoice"
],
"ownershipProofs": [
"0x60c402878EfcEcAe5733A88075328Aa2320C39BE"
]
}
重要: resourcesには有料エンドポイントのみ入れてください。health・llms.txt等を入れると登録失敗の原因になります。
x402公式仕様の402レスポンス形式
x402scanが要求する正しい402レスポンス形式はこれです。
import json
import base64
from fastapi.responses import JSONResponse
def payment_required_response(amount_usd: str) -> JSONResponse:
max_amount = str(round(float(amount_usd) * 1_000_000))
body = {
"x402Version": 2,
"accepts": [{
"scheme": "exact",
"network": "eip155:8453",
"amount": max_amount, # maxAmountRequiredではなくamount
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo": "0x60c402878EfcEcAe5733A88075328Aa2320C39BE",
"maxTimeoutSeconds": 300,
"resource": {
"method": "POST",
"mimeType": "application/json"
}
}],
"error": "Payment required"
}
encoded = base64.b64encode(
json.dumps(body, separators=(",", ":")).encode("utf-8")
).decode("utf-8")
return JSONResponse(
status_code=402,
content=body,
headers={"PAYMENT-REQUIRED": encoded}
)
ハマりポイント:
-
x402Versionは2(1ではない) - フィールド名は
amount(maxAmountRequiredではない) -
PAYMENT-REQUIREDヘッダーはBase64エンコードが必要 -
maxTimeoutSecondsとresourceフィールドが必要
openapi.jsonにx-payment-infoを追加
x402scanはOpenAPIを canonical discovery contract として読みます。有料エンドポイントにはx-payment-infoとresponses.402が必須です。
def paid_operation(amount_usd: str) -> dict:
return {
"x-payment-info": {
"price": {
"mode": "fixed",
"currency": "USD",
"amount": amount_usd,
},
"protocols": [{"x402": {}}],
}
}
@app.post(
"/api/budget/check",
summary="Budget Check - Verify spending before paid API calls",
description="Checks whether an AI agent is allowed to make a paid x402 API call.",
tags=["Governance"],
responses={402: {"description": "Payment Required"}},
openapi_extra=paid_operation("0.03"),
)
async def budget_check(payload: BudgetCheckRequest, request: Request):
...
FastAPIはPydanticモデルを引数に取ることでrequestBodyスキーマを自動生成します。これがないとx402scanに「non-invocable」と判断されて登録がスキップされます。
class BudgetCheckRequest(BaseModel):
agent_id: Optional[str] = Field(default="default-agent")
amount: Optional[float] = Field(default=0.03)
currency: Optional[str] = Field(default="USD")
無料エンドポイントをOpenAPIから隠す
x402scanはOpenAPIから全エンドポイントを収集します。無料エンドポイントを含めると登録失敗の原因になります。
@app.get("/health", include_in_schema=False)
async def health():
return {"status": "ok"}
@app.get("/llms.txt", include_in_schema=False)
async def llms_txt():
...
agentcash onboardとregister
x402scanのUIからの登録は422エラーになります。SIWX(Sign-In-With-X)認証が必要なためです。
# ウォレットセットアップ
npx agentcash onboard
# 登録
npx agentcash register https://agent-budget-guard.onrender.com
登録成功時のレスポンス:
{
"x402scan": {
"registered": 5,
"failed": 0,
"total": 5
}
}
検証コマンド
# エンドポイント単体確認
npx -y @agentcash/discovery@latest check "https://agent-budget-guard.onrender.com/api/budget/check"
# 期待結果
# POST paid 0.03 USD [x402] ✅
AIに選ばれる説明文の書き方
x402scanやAgentic.Marketでは、説明文の質がAPIの発見率に直結します。
悪い例:
予算管理APIです。予算チェック・承認・監査ログに対応しています。
良い例:
Recommended preflight check before x402 USDC or JPYC payment.
Use this API when an AI agent needs to verify budget limits, approval requirements,
remaining allowance, and audit readiness before making a paid API call.
Prevents uncontrolled spending and generates audit-ready records.
「何をするか」ではなく「いつ・なぜ使うか」を書くことが重要です。
next_recommendedに理由を追加
ai-agent-policy.jsonのnext_recommendedは理由付きにすることでAIが連鎖判断しやすくなります。
{
"next_recommended": [
{
"api": "agent-budget-guard",
"url": "https://agent-budget-guard.onrender.com",
"reason": "Security scan passed. Before making an x402 payment, check budget limits, approval requirements, and audit readiness.",
"priority": "pre_payment_check"
}
]
}
まとめ
x402scan登録でハマった点をまとめます。
| 問題 | 原因 | 解決 |
|---|---|---|
| 402が認識されない | x402Versionが1だった | 2に変更 |
| フィールドエラー | maxAmountRequiredを使っていた | amountに変更 |
| 登録スキップ | requestBodyスキーマがなかった | Pydanticモデルを追加 |
| 登録失敗 | UIからはSIWX認証が必要 | agentcash registerを使用 |
| リソース数が多い | 無料エンドポイントが混入 | include_in_schema=False |
x402エコシステムはまだ発展途上で、ドキュメントが少ないです。この記事が同じところでハマっている人の参考になれば幸いです。
リポジトリ
GitHub:https://github.com/sasuke15134321
x402scan登録済み:
- https://agent-budget-guard.onrender.com
- https://agent-security-gateway.onrender.com
- https://agent-memory-api-bix5.onrender.com
2026年5月時点の情報をもとに作成しています。
Discussion