Policy Check via x402 Wire v2: A Technical Tutorial for the Agent Commerce Gate Decision Endpoint
Call ContextIQ's Policy Check (Agent Commerce Gate) via x402 wire v2 for a pre-payment allow/warn/block decision on identity, reputation, and payment risk.
Policy Check (the Agent Commerce Gate) combines an ERC-8004 identity/reputation lookup with an x402 payment-challenge scan into one pre-payment decision: allow, warn, or block. A prior walkthrough covered the v1 route end to end; this one is focused specifically on the x402 wire v2 endpoint, which as of this writing is confirmed live and indexed in Coinbase's public Bazaar catalog — not just validator-clean, but actually discoverable, with real call traffic.
The Endpoint
POST /api/v1/policy-check/x402-v2
Price: $0.02 per call
Body: { "endpoint": "<x402 URL you're about to pay>", "agentId": "<optional ERC-8004 agent ID>", "network": "<network the agent is registered on>" }
endpoint and network are required; agentId is optional. If you omit it, identity and reputation genuinely aren't evaluated — the response says so explicitly rather than silently attaching an unrelated agent's data to the result.
The 402 Challenge
curl -i -X POST https://contextiq.trango-compute.com/api/v1/policy-check/x402-v2 \
-H "Content-Type: application/json" \
-d '{"endpoint":"https://api.example.com/paid-resource","network":"base"}'
{
"x402Version": 2,
"resource": { "url": "https://contextiq.trango-compute.com/api/v1/policy-check/x402-v2" },
"accepts": [{ "scheme": "exact", "network": "eip155:8453", "amount": "20000", "payTo": "0x4eba5ea3cf0f3fc307099317e17e54390f7a4c58", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" }],
"extensions": {
"bazaar": {
"info": {
"input": {
"type": "http", "method": "POST",
"schema": { "properties": { "endpoint": { "type": "string" }, "agentId": { "type": "string" }, "network": { "type": "string" } }, "required": ["endpoint", "network"] }
}
}
}
}
}
Option A: API Key
curl -X POST https://contextiq.trango-compute.com/api/v1/policy-check/x402-v2 \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"endpoint":"https://api.example.com/paid-resource","agentId":"1","network":"ethereum"}'
Option B: Pay With x402, No API Key
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
import { wrapFetchWithPayment } from "@x402/fetch";
const account = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`);
const client = createWalletClient({ account, transport: http(), chain: base });
const fetchWithPayment = wrapFetchWithPayment(fetch, client);
const res = await fetchWithPayment("https://contextiq.trango-compute.com/api/v1/policy-check/x402-v2", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ endpoint: "https://api.example.com/paid-resource", agentId: "1", network: "ethereum" }),
});
console.log(await res.json());
The Response
{
"decision": "allow",
"score": 45,
"maxScore": 50,
"reasons": [
{ "check": "erc8004_identity_checked", "points": 0, "maxPoints": 0, "detail": "No agent ID supplied — identity and reputation were not evaluated" },
{ "check": "x402_challenge_valid", "points": 20, "maxPoints": 20, "detail": "Payment challenge is well-formed with a usable option" },
{ "check": "no_payment_warnings", "points": 10, "maxPoints": 10, "detail": "No spec-hygiene warnings on the payment challenge" },
{ "check": "recognized_network", "points": 5, "maxPoints": 5, "detail": "Network recognized: Base" },
{ "check": "no_prior_rug_reports", "points": 10, "maxPoints": 10, "detail": "No prior payment to this endpoint has been confirmed but settled to an unexpected recipient or amount" }
],
"identity": { "status": "not_evaluated", "agentId": null, "network": null },
"payment": { "status": "valid", "target": "https://api.example.com/paid-resource" },
"checkId": "8875a324-9577-48f8-b506-877c26500a7e"
}
Two things to note if you're integrating this: maxScore is 50, not 100, whenever agentId is omitted — the identity and reputation checks contribute 0/0 points rather than being silently dropped from the denominator, so a threshold you set against the score should account for whether you're supplying an agent ID or not. And checkId is the value you hold onto — it's what the receipt-verification endpoint uses to bind a later on-chain settlement back to this exact decision, covered in the receipt-verification tutorial.
decision is what you gate on directly. block is reserved for genuine impossibility — a malformed challenge, an unreachable endpoint, or (when an agent ID was supplied) no identity found at all — never for "score too low." Deciding how much reputation is "enough" is left to you.
Try It
Policy Check is a Pro feature explorable from the dashboard, or callable via either route above for wiring a real pre-payment gate into an agent's payment-authorization step.
Follow Trango Compute on LinkedIn
We post updates on new tools, context engineering patterns, and LLM cost research.