A2Ax402no LLM · deterministic

ip402 GeoIP Agent

A paid IP-intelligence agent speaking the A2A protocol: send an IPv4/IPv6 address in a message, pay $0.01 per lookup in USDC (Base or Solana mainnet, or Arc testnet) via the in-message a2a-x402 extension, get normalized geolocation + ASN data back as a JSON artifact. No accounts, no API keys.

Looking for the plain HTTP API (GET /v1/geo, OpenAPI, MPP)? That lives at ip402.xyz — this host is the agent-to-agent surface.

Endpoints

JSON-RPC 2.0 (SendMessage) POST https://agent.ip402.xyz/a2a

This agent speaks A2A 1.0 only. Every request must carry A2A-Version: 1.0 and activate the payment extension with A2A-Extensions: https://github.com/google-agentic-commerce/a2a-x402/blob/main/spec/v0.2 — an absent version header means 0.3 per the spec and is rejected with VersionNotSupportedError (-32009).

How a lookup works

  1. Ask. SendMessage with a text part ("Where is 8.8.8.8?") or a data part ({"ip":"8.8.8.8","lang":"en"}).
  2. Payment required. The agent answers with a task in state TASK_STATE_INPUT_REQUIRED; its message metadata carries x402.payment.status = "payment-required" and x402.payment.required — the exact x402 accepts (USDC on Base eip155:8453 and Solana mainnet, and USDC on Arc testnet eip155:5042002).
    Arc testnet is different: that accept is settled by Circle Gateway, so the signature is against the GatewayWalletBatched domain in extra and spends a balance you have deposited into the GatewayWallet on Arc. Plain wallet USDC on Arc cannot pay it; a standard x402 signer will fail verification. Deposit first with @circle-fin/x402-batching (steps). Its settlement receipt is a Circle transfer id, not a tx hash.
  3. Pay & receive. Sign an x402 PaymentPayload (e.g. with the x402 SDK) and re-send it with the same taskId in metadata["x402.payment.payload"]. The agent verifies and settles on-chain, then completes the task with the geo JSON artifact and a settlement receipt in x402.payment.receipts.

Try turn 1 now (free)

This calls the live endpoint from your browser — an unpaid request only ever returns the payment challenge; nothing is charged.



  

Turn 1 — curl

curl -s https://agent.ip402.xyz/a2a \
  -H 'Content-Type: application/json' \
  -H 'A2A-Version: 1.0' \
  -H 'A2A-Extensions: https://github.com/google-agentic-commerce/a2a-x402/blob/main/spec/v0.2' \
  -d '{
    "jsonrpc": "2.0", "id": 1, "method": "SendMessage",
    "params": {"message": {
      "messageId": "m1", "role": "ROLE_USER",
      "parts": [{"text": "Where is 8.8.8.8?", "mediaType": "text/plain"}]
    }}
  }'

The result is the SendMessage oneof envelope — result.task here, or result.message when no address was found.

Turn 2 — pay

{
  "jsonrpc": "2.0", "id": 2, "method": "SendMessage",
  "params": {"message": {
    "messageId": "m2", "role": "ROLE_USER",
    "taskId": "<task id from turn 1>",
    "parts": [{"text": "payment attached", "mediaType": "text/plain"}],
    "extensions": ["https://github.com/google-agentic-commerce/a2a-x402/blob/main/spec/v0.2"],
    "metadata": {
      "x402.payment.status": "payment-submitted",
      "x402.payment.payload": { /* signed x402 PaymentPayload */ }
    }
  }}
}

Any a2a-x402-capable client works — sign the payload with the x402 SDK (create_payment_payload on the metadata's payment-required JSON) and re-send it as shown above.