π³x402 Gateway
Pay-per-call HTTP 402 gateway that fronts write mutations on the Labs API with per-request stablecoin settlement on Base.
Overview
The x402 gateway wraps a small set of Labs API write mutations with the HTTP 402 Payment Required protocol. Callers β typically autonomous AI agents or external services that don't hold a long-lived service token β settle a USDC payment on Base per request, and the gateway forwards the underlying GraphQL mutation to AppSync.
Each successful request costs the configured mutation price in USDC, which is debited directly from the payer wallet via EIP-3009 transferWithAuthorization (or Permit2) and settled through the Coinbase facilitator.
When to use x402
Use the gateway when:
An agent needs write access without provisioning a per-agent service token. The gateway mints a short-lived, scoped service token on the fly after payment is verified.
You want pay-per-call economics. Each mutation has its own price; no subscription or prepaid balance.
You're building third-party tooling that pays for users. The payer wallet is recorded as the mutation author.
Use the standard Labs API with a service token when you have long-lived credentials for a known lab.
Endpoints
The gateway exposes one HTTP endpoint per allow-listed mutation. All endpoints accept POST with a JSON body containing a GraphQL mutation.
POST /x402/labs/{mutation}/x402/labs/initiateCreateOrUpdateFileV2
initiateCreateOrUpdateFileV2
Start a file upload; returns a presigned URL (+ DEK if encryption requested)
/x402/labs/finishCreateOrUpdateFileV2
finishCreateOrUpdateFileV2
Finalise a file upload with metadata
/x402/labs/createAnnouncementV2
createAnnouncementV2
Publish a project announcement
/x402/labs/createProject
createProject
Create a project / data room bound to an IP-NFT
/x402/labs/addProjectOwner
addProjectOwner
Add a wallet as an owner of a project
The path mutation must match the top-level GraphQL mutation field in the request body, otherwise the gateway returns 400.
Payment Flow
The gateway implements the standard x402 three-phase flow: verify β serve β settle.
402 challenge β The gateway returns an x402-standard payment-requirements response describing network, asset, price, and payTo address.
Sign β The client signs an EIP-3009
transferWithAuthorization(or Permit2) for the quoted amount toX402_PAY_TO_ADDRESSon the configured network.Retry with payment β The signed authorization is submitted as a base64 JSON header under any of
Payment-Signature,X-Payment, orPayment.Verify β The gateway calls the Coinbase facilitator's
/verifyendpoint. On failure it returns402with the original requirements.Serve β The gateway mints a scoped, short-lived JWT service token (
allowedMutations: [mutation],authMethod: "x402",ttl = X402_TOKEN_TTL_SECONDS, default300s) with the payer wallet asadminAddress, then forwards the GraphQL mutation to AppSync using that token.Settle β After a
2xxupstream response, the gateway calls the facilitator's/settleendpoint to broadcast the transfer. Settlement headers are merged into the final response.
Payer address resolution
The mutation is executed as if the payer wallet called it. The payer address is resolved from the verified payment payload, in this order:
payload.authorization.from(EIP-3009)payload.permit2Authorization.from(Permit2)payerAddressfield on the JSON request body (fallback only β used when upstream wrappers strip the verified payload)
If none resolves to a valid address the gateway returns 400. Source: lambda/x402-gateway-lambda/index.ts (extractPayerAddress).
Request Format
Constraints enforced by the gateway (validateMutationQuery):
Exactly one GraphQL operation.
Operation kind
mutation.Exactly one top-level selection.
Top-level field name must equal the path
{mutation}.
Pricing & Configuration
Pricing is environment-driven and resolved per-mutation. The gateway evaluates the following env vars in order and uses the first non-empty value:
Values are interpreted as USDC amounts (e.g. "2.50" = $2.50).
X402_NETWORK
base (prod) / base-sepolia (non-prod)
CAIP-2 network (base β eip155:8453)
X402_PAY_TO_ADDRESS
β
Wallet that receives settlement
X402_FACILITATOR_URL
https://api.cdp.coinbase.com/platform/v2/x402
Facilitator base URL
X402_PRICE_* / X402_PRICE_DEFAULT
"1.00"
Per-mutation price in USDC
X402_TOKEN_TTL_SECONDS
300
Lifetime of the minted service token
Facilitator authentication uses Coinbase CDP API keys (CDP_API_KEY_ID_SECRET_ARN / CDP_API_KEY_SECRET_SECRET_ARN in Secrets Manager, or CDP_API_KEY_ID / CDP_API_KEY_SECRET in local mode) to sign the /verify, /settle, and /supported requests.
Response Semantics
200
Payment verified, upstream AppSync returned 2xx. Body is the AppSync response verbatim; settlement headers are merged in.
402
Payment required or payment verification failed. Body includes facilitator hints in headers.
400
Path mutation mismatch, missing query, invalid GraphQL, or unresolvable payer address.
4xx/5xx
Upstream AppSync error β settlement is skipped and the upstream response is returned as-is.
Idempotency
Each minted service token has a unique jti claim, so requests are not idempotent by default β replaying the same signed payment may be rejected by the facilitator's replay protection, and the downstream AppSync call may succeed twice if you retry after a settlement failure. Agents should treat settlement failures as "payment not charged yet" and re-sign.
Agent Usage Pattern
An autonomous agent typically wraps each gateway call in a helper:
See the Developers / AI Agents guide for end-to-end agent integration patterns, and the Labs API reference for the full GraphQL signatures of each gated mutation.
Related
Labs API β full mutation signatures and variable types
Developers / AI Agents β agent integration guide
Last updated