# AgentMillionDollarHomepage.com This site sells pixels exclusively through an HTTP x402 v2 API. There are no accounts, API keys, cookies, forms, or human checkout. The homepage also exposes WebMCP site tools so a human and agent can inspect and preview the same live canvas before purchasing. Use the origin serving this file as BASE_URL. ## Product - Canvas: 1000 by 1000 pixels. - Coordinates start at the top-left: x=0, y=0. - x, y, width, and height must be multiples of 10. - Minimum placement: 10 by 10 pixels. - Price: $1.00 USDC per pixel. - Network: Base mainnet (`eip155:8453`). - Scheme: x402 v2 `exact`. - Facilitator: PayAI's public facilitator; buyers need no facilitator account or API key. - Creating an offer never reserves pixels and never charges a fee. Offers expire after 5 minutes. - Creating an offer returns a proposal-bound `preview_url` comparing the current canvas with the exact normalized proposal. - Each payment URL includes a SHA-256 proposal hash committing to the board, coordinates, content, target, full price, and normalized artwork. - Cells are claimed atomically only after a full-price payment authorization is verified. If another buyer wins first, the authorization is not settled. ## Agent operating rules - Always use the live mainnet canvas and real Base USDC by default. Do not ask whether to use mainnet or testnet. - Use the Base Sepolia testnet canvas only when the user explicitly asks for testnet, Base Sepolia, or a test-funds transaction. Do not infer testnet merely because the user says they are trying, testing, previewing, or experimenting with the product. - Never execute payment until the user has explicitly approved both the full price and the exact proposal. - After creating an offer, open or present its `preview_url` and wait for the user to approve that exact normalized proposal before paying. A prior description or source-image preview is not final approval. - If the requested pixels overlap a live placement, proactively inspect nearby free space and suggest the closest suitable alternative. Preview the new coordinates and wait for approval; never relocate and pay without telling the user. - Translate requests such as “center,” “top-left,” or “near this placement” into exact coordinates, snap them to the 10-pixel grid, and report the resulting x, y, width, and height. - For artwork, inspect its intrinsic width and height when possible and preserve its aspect ratio by default. If the user provides only width or height, calculate the other dimension, snap it to the 10-pixel grid, and disclose the resulting dimensions, estimated crop, upscaling risk, and full price before creating an offer. - The purchase API always requires both final `width` and `height`. Deriving a missing dimension is agent behavior, not an alternate API shape. - Recheck live availability immediately before payment. The preview background is live and the unpaid offer does not hold pixels. - If payment returns HTTP 409 because the pixels were claimed, do not retry that conflicting proposal. Find a suitable free location, create a new offer, show its preview, and request approval again. - Never change the approved board, coordinates, dimensions, text, target URL, artwork, price, or proposal hash. Any change requires a new preview and explicit approval. ## Base Sepolia test canvas (explicit requests only) Never select or suggest testnet as the default. Use `/testnet` only after the user explicitly requests testnet, Base Sepolia, or a test-funds transaction. It exercises the same canvas, purchase, image-normalization, x402 settlement, and publication flow with Base Sepolia test USDC (`eip155:84532`). The test canvas is independent from the main canvas even when coordinates overlap. Testnet pixels cost $0.01 test USDC each, so the minimum 10 by 10 placement costs $1.00. Mainnet pixels remain $1.00 USDC each. When using REST directly: - Inspect it with `GET /api/placements?testnet=true`. - Include `"testnet": true` in `POST /api/purchases`. - Use the returned payment URL unchanged. Its x402 offer selects Base Sepolia and the configured test recipient. Published test placements remain visible for 10 minutes after settlement, then disappear from the test canvas. Their D1 placement, claimed cells, and normalized image are deleted lazily by subsequent API requests. Expired unpaid offers and their normalized images are also deleted lazily; they never own cells. Obtain test USDC from a Base-listed faucet before creating a purchase offer: https://docs.base.org/base-chain/network-information/network-faucets. The exact EVM x402 payment is gasless for the buyer; the facilitator submits the settlement transaction, so this purchase flow does not require the buyer to hold Base Sepolia ETH. ### Quick testnet example with `purl` 1. Install the [purl.dev CLI](https://purl.dev), create an EVM wallet, and print its public address: brew install stripe/purl/purl purl wallet add --type evm purl wallet list purl wallet show Copy only the public `0x` address. Never share the private key, password, or keystore. 2. Open the [Circle Testnet Faucet](https://faucet.circle.com), select **USDC** and **Base Sepolia**, and paste the public address. Faucet amounts and limits can change. Check that the test USDC arrived: purl balance --network base-sepolia 3. Find an available 10 by 10 region and create its test purchase offer: curl -sS "$BASE_URL/api/placements?testnet=true" curl -sS --request POST "$BASE_URL/api/purchases" \ --header "Content-Type: application/json" \ --data '{"testnet":true,"x":0,"y":0,"width":10,"height":10,"text":"My test ad","target_url":"https://example.com"}' Replace `x` and `y` with free coordinates. The example placement costs $1.00 total. Open or present the returned `preview_url`, state the exact price and coordinates, and wait for the user to approve that normalized proposal. Only after that approval, copy `payment.url` and `payment.max_amount_usdc_atomic`, preview the payment, and confirm it before the five-minute offer expires: purl --dry-run --request POST --network base-sepolia --max-amount "" purl --confirm --request POST --network base-sepolia --max-amount "" Do not pass a request body to the payment URL. After settlement succeeds, the ad appears at `$BASE_URL/testnet` for 10 minutes. ## 1. Inspect live placements GET /api/placements This endpoint inspects the mainnet canvas by default. Append `?testnet=true` only for an explicitly requested testnet operation. The response contains board metadata and every live placement: { "board": { "width": 1000, "height": 1000, "sold_pixels": 100, "available_pixels": 999900, "price_per_pixel": "$1.00", "price_per_pixel_usd_cents": 100, "testnet": false }, "placements": [ { "id": "offer_...", "testnet": false, "x": 0, "y": 0, "width": 10, "height": 10, "text": "My agent", "logo_url": "https://example.com/api/placements/offer_.../image/{hash}.webp", "target_url": "https://example.com", "status": "live", "proposal_hash": "64 lowercase hex characters", "price": "$100.00", "offer_expires_at": null, "paid_at": "2026-08-27T12:00:00.000Z", "payer_address": "0x...", "transaction": "0x..." } ] } Use the rectangles in `placements` to detect overlap and find nearby free space. A rectangle occupies `[x, x + width)` horizontally and `[y, y + height)` vertically. ## 2. Create a full-price purchase offer POST /api/purchases Content-Type: application/json Example body: { "x": 0, "y": 0, "width": 10, "height": 10, "text": "My agent", "logo_url": "https://example.com/logo.png", "target_url": "https://example.com" } Omit `testnet` for normal purchases; it defaults to `false` and charges real Base USDC. Never ask the user which network to use. Set `testnet` to `true` only when the user explicitly requested testnet, Base Sepolia, or test funds. Input requirements: - `x` and `y` must be integers from 0 through 990 and multiples of 10. - `width` and `height` must be integers from 10 through 1000 and multiples of 10. - The complete rectangle must fit within the 1000 by 1000 canvas: `x + width <= 1000` and `y + height <= 1000`. - `target_url` is required, must be HTTPS, and may contain at most 2,048 characters. - `text` is trimmed, may contain at most 120 characters, and defaults to an empty string. - Supply non-empty `text`, `logo_url`, or both. ### Artwork sizing and crop planning Before calling `preview_ad_placement` or `POST /api/purchases` with artwork: 1. Inspect the source image's intrinsic pixel width and height when possible. Use those values to determine aspect ratio and likely upscaling; do not treat them as the number of canvas pixels the user must buy. 2. If the user provides only `height`, keep it fixed and calculate `raw_width = height * source_width / source_height`. If the user provides only `width`, keep it fixed and calculate `raw_height = width * source_height / source_width`. If the supplied dimension is not itself a valid multiple of 10 from 10 through 1000, propose a nearby valid value and obtain approval before using it; never adjust it silently. 3. The calculated dimension must still be an integer multiple of 10. Compare the valid 10-pixel grid values immediately below and above the raw result, discard any that fall outside the canvas or available region, and prefer the one that loses the least source area under centered `cover` cropping. Never silently change the one dimension the user explicitly supplied. 4. Calculate and state the full estimated price before creating the offer: `width * height * $1.00` in real USDC on the default mainnet canvas, or `width * height * $0.01` in test USDC only after an explicit testnet request. 5. Tell the user the source dimensions and aspect ratio, proposed canvas dimensions, full price, whether cropping is expected, and whether the source must be enlarged. Then render the draft preview and obtain approval before creating the offer. If the user supplies both dimensions and their aspect ratio differs from the artwork, do not silently override them. Explain that centered `cover` will crop the source, quantify the approximate retained or cropped fraction when possible, and suggest at least one grid-aligned aspect-preserving alternative with its full price. Honor the user's original dimensions only after they choose them knowingly. For example, square artwork placed in a 200 by 100 rectangle retains only about half of its source area and costs $20,000 on mainnet; 200 by 200 avoids the crop for $40,000, while 140 by 140 is a near-budget square alternative at $19,600. If the source dimensions cannot be determined, say so and do not claim the artwork is crop-safe. Continue only with proposed explicit dimensions, and rely on the exact normalized `preview_url` for final review. Text-only placements have no artwork aspect ratio, so both dimensions must be chosen explicitly. Pass `logo_url` in exactly one of these forms; the server detects the form automatically: - An HTTPS image URL, for example `https://example.com/logo.png`. - An inline PNG data URL, for example `data:image/png;base64,iVBORw0KGgo...`. HTTPS `logo_url` values may contain at most 2,048 characters. Inline data must use the exact `data:image/png;base64,` prefix, contain valid standard base64, decode to a PNG, and be no larger than 2 MB. HTTPS image responses are also capped at 2 MB and must use an `image/*` content type. When the offer is created, the Cloudflare Images binding applies a centered `cover` transform to exactly the placement width and height. This preserves aspect ratio but crops overflow when the source and placement aspect ratios differ, and it may upscale a smaller source. It disables animation, encodes a quality-82 WebP, and stores only that normalized result in D1. The inline base64 source is never stored. Offer creation fails with HTTP 422 if the image cannot be fetched, decoded, or processed, or if the normalized result exceeds 1 MB. Always use `preview_url` to show the user the exact normalized crop that will be published. A successful response is HTTP 201 and includes `purchase`, absolute `preview_url` and `payment_url` values, and a structured `payment` object: { "purchase": { "id": "offer_...", "testnet": false, "price": "$100.00", "proposal_hash": "64 lowercase hex characters", "offer_expires_at": "2026-08-27T12:00:00.000Z" }, "preview_url": "https://example.com/preview/offer_.../{proposal_hash}", "payment_url": "https://example.com/api/purchases/offer_.../{proposal_hash}", "payment": { "protocol": "x402", "version": 2, "method": "POST", "url": "https://example.com/api/purchases/offer_.../{proposal_hash}", "body": null, "network": "eip155:8453", "asset": "USDC", "scheme": "exact", "price": "$100.00", "max_amount_usdc_atomic": "100000000", "expires_at": "2026-08-27T12:00:00.000Z", "proposal_hash": "64 lowercase hex characters", "prompt": "Make an x402 v2 POST request..." } } The example omits unchanged purchase fields for brevity. Open `preview_url` for a side-by-side comparison of the live canvas and the canvas with this exact proposal. Its canvas background reflects live placements when the page is opened; the proposal coordinates, content, and normalized artwork are bound to `proposal_hash`. A successful offer returns a first-party, hash-versioned `logo_url`; later changes to an HTTPS source do not affect the committed artwork. `proposal_hash` is calculated from the exact normalized proposal and embedded in both the preview and protected resource URLs. `max_amount_usdc_atomic` uses six-decimal USDC units and is a safety ceiling for wallet clients. The live HTTP 402 offer is authoritative. An unpaid `preview_url` remains usable only while its offer exists, normally until `offer_expires_at`; after lazy expiry cleanup it returns HTTP 404. After successful settlement, a mainnet preview remains available with its live placement. A testnet preview disappears when its live test placement is lazily deleted 10 minutes after settlement. Preview URLs are transient review artifacts, not permanent image hosting. Creating the offer stores immutable content and normalized artwork but inserts no `placement_cells`, so it cannot block the canvas. Availability can change after offer creation. The paid request verifies authorization first and then atomically claims every cell. If the cells are no longer free, it returns HTTP 409 and does not settle the payment. ## 3. Request the x402 offer POST the returned `payment_url` with no body and no payment header: POST /api/purchases/{purchase_id}/{proposal_hash} The server responds HTTP 402 with a standard base64-encoded `PAYMENT-REQUIRED` header. The JSON body repeats the immutable purchase proposal and full price. ## 4. Pay and publish Use an x402 v2-compatible wallet client to decode `PAYMENT-REQUIRED`, select the Base USDC `exact` offer whose network exactly matches `payment.network`, and sign it. For the normal default flow this is Base mainnet (`eip155:8453`); Base Sepolia (`eip155:84532`) is valid only when the user explicitly requested testnet. Repeat the same POST before `expires_at` with: PAYMENT-SIGNATURE: {base64-encoded signed x402 payload} Do not send a JSON body to the payment endpoint. The offer identifies the immutable proposal hash, amount, recipient, network, and resource URL. Do not send USDC directly to the recipient address. A direct transfer cannot atomically identify and publish the committed placement. Give `payment.prompt` or, preferably, the structured `payment` object to the agent's x402 wallet tool. After the facilitator verifies and settles the USDC transfer, the response is HTTP 200, includes a standard `PAYMENT-RESPONSE` header, and returns `purchase` with `status: "live"`, its payer, and transaction hash. The placement becomes visible through GET /api/placements immediately. Handle non-success responses conservatively: - HTTP 409 with `error: "spot_unavailable"`: payment was not settled. Inspect the canvas, propose nearby free coordinates, create a new offer, show its exact preview, and obtain fresh approval. - HTTP 409 saying the purchase is already processing: do not create or sign another payment. Check the same purchase status and retry only after the in-flight attempt resolves. - HTTP 500 saying payment settled but publication is pending: treat the payment as completed. Save the returned purchase ID and transaction, poll that same purchase, and never create or authorize a replacement payment for it. - HTTP 502 saying settlement is uncertain: do not create a new offer or signature. Retry the identical signed request for the same purchase as instructed, then check that purchase and transaction before taking any other payment action. - HTTP 502 saying payment processing failed, or a facilitator payment-error response: do not generate a different authorization for the same purchase. Retry the same signed request only while the offer remains valid; otherwise stop and report the unresolved purchase rather than risk a duplicate payment. ## 5. Check status GET /api/purchases/{purchase_id} Possible returned statuses are `offered`, `paying`, and `live`. Expired unpaid offers are deleted and return HTTP 404. An unpaid offer owns no cells. If it expires before a valid payment begins, make a new offer. A short internal `paying` lock exists only after verification while claim and settlement are in progress. ## WebMCP site tools When the homepage is open in a compatible browser, prefer this collaborative flow: 1. `inspect_ad_canvas` reads current totals and occupied rectangles in pages of up to 10. Continue with the returned `next_offset` until it is `null`. 2. For artwork, inspect its aspect ratio, derive any missing dimension, snap both dimensions to the grid, disclose the crop estimate and full price, then call `preview_ad_placement`. It renders the proposed placement on the shared canvas without reserving or charging. 3. Wait for the human to approve this draft placement before creating an offer. 4. `create_ad_purchase` creates the immutable full-price offer and returns `preview_url` plus the structured `payment` object without holding pixels. It uses mainnet unless the user explicitly requested testnet. 5. Open or present `preview_url`, state the exact full price, board, coordinates, dimensions, target, text, and artwork, and wait for the human to approve this exact normalized proposal. Draft-preview approval from step 3 is not payment approval. 6. Recheck availability. After final approval, use a separately configured x402 wallet to make the empty POST to `payment.url` without changing any proposal field. 7. `check_ad_purchase` reads status and refreshes the canvas after publication. ## Wallet clients and compatibility Verified on 2026-08-27 for this site's default payment route: x402 v2 `exact`, real USDC on Base mainnet (`eip155:8453`), sent as an empty HTTPS POST with the `PAYMENT-SIGNATURE` header. Use this mainnet route without asking about networks. The only exception is an explicit user request for testnet, which selects Base Sepolia test USDC (`eip155:84532`). Always use the purchase response's `payment.url`, `payment.method`, `payment.max_amount_usdc_atomic`, `payment.proposal_hash`, and `payment.expires_at`. Request the live HTTP 402 offer before signing. Never replace this flow with a direct token transfer. ### Fund the wallet before creating an offer Offers expire after 5 minutes. Complete wallet authentication, funding, and spending-limit setup before calling the purchase endpoint. The wallet must hold enough native USDC on Base mainnet to cover the previewed price after any onramp or withdrawal fees; USDC held on Ethereum, Polygon, Solana, or another network cannot pay this offer. When funding from an exchange or external onramp, select both USDC and the Base network (`eip155:8453`), verify the destination address, and check the wallet balance after the transfer. Share only the wallet's public address. Never enter its private key, seed phrase, or recovery phrase into an onramp, website, prompt, or chat. ### Required compatibility check for every wallet Before signing, decode or preview the live HTTP 402 response and verify all of these values: - `x402Version` is exactly `2`. - The selected offer uses scheme `exact` and Base USDC. Its network must equal `payment.network`: `eip155:8453` for the default mainnet purchase or `eip155:84532` only for an explicitly requested testnet purchase. - The offer's atomic `amount` does not exceed `payment.max_amount_usdc_atomic`. - The offer's resource URL is exactly `payment.url` and contains `payment.proposal_hash`. - The client replays the original empty POST using `PAYMENT-SIGNATURE`. Stop if the client expects `X-PAYMENT`, `maxAmountRequired`, a non-CAIP network such as plain `base` or `base-sepolia` inside the challenge, or an MPP `WWW-Authenticate: Payment` challenge. Those are not this site's x402 v2 wire protocol. An HTTP 402 response by itself does not establish compatibility. ### Coinbase Agentic Wallet MCP (recommended for MCP clients) Install and choose your MCP client when prompted: npx @coinbase/payments-mcp Restart the client, ask `Show me my wallet`, and authenticate by email. In the wallet UI, click **Fund** to buy Base USDC through Coinbase Pay, or click **Receive** to transfer existing Base USDC to the displayed public address. Available card, bank, Apple Pay, and Coinbase payment methods vary by region. Confirm the balance covers the previewed price after fees. This site's minimum 10×10 placement costs $100, so set both the per-call limit and remaining session limit to at least the previewed price before creating an offer. Then give the agent the returned `payment.prompt`, or say: Make an x402 POST request with no body to . Do not pay more than , and require Base mainnet USDC. Docs: - https://docs.cdp.coinbase.com/agentic-wallet/mcp/quickstart - https://docs.cdp.coinbase.com/agentic-wallet/mcp/mcp-tools/make-x402-request - https://docs.cdp.coinbase.com/agentic-wallet/cli/skills/fund ### Coinbase Agentic Wallet CLI (`awal`) Authenticate once: npx awal@latest auth login you@example.com npx awal@latest auth verify Open the wallet UI, click **Fund** to buy Base USDC through Coinbase Pay, or transfer existing Base USDC to the address shown by `npx awal@latest address`. Then verify the balance and configure limits: npx awal@latest show npx awal@latest balance This site's minimum 10×10 placement costs $100, so the Base USDC balance, per-transaction limit, and remaining session limit must all be at least the previewed price before creating an offer. Pay the purchase. Substitute both values from the structured `payment` object: npx awal@latest x402 pay "" -X POST --max-amount --json Do not pass a request body. Docs: https://docs.cdp.coinbase.com/agentic-wallet/cli/skills/pay-for-service ### Stripe `purl` CLI `purl` is Stripe's official curl-like x402 payment client; it is separate from the normal `stripe` developer CLI. Install it and create a dedicated EVM wallet: brew install stripe/purl/purl purl wallet add --type evm purl wallet list purl wallet show `purl` does not include a fiat onramp. Copy only the public `0x` address printed by `purl wallet show`, then fund it through either hosted checkout: - Transak: https://global.transak.com/ - MoonPay: https://www.moonpay.com/buy/usdc In the checkout, choose **USDC** on the **Base** network, enter enough fiat for the quoted amount received to cover the previewed price after fees, and paste the `purl` public address as the destination. Complete the provider's card payment and any required email, identity, or card verification. Do not select Ethereum, Polygon, or another USDC network, and never enter the `purl` private key or wallet password. After the wallet funding purchase settles, verify the Base USDC balance before creating the placement offer: purl balance --network base Preview the exact empty POST without paying: purl --dry-run --request POST --network base --max-amount "" After checking the v2 offer against the requirements above, pay with an explicit confirmation prompt: purl --confirm --request POST --network base --max-amount "" Do not pass `--data` or `--json`. Linux users can install from source using the repository instructions. Docs: - https://github.com/stripe/purl - https://github.com/stripe/purl/blob/main/skills/pay-for-http-request/SKILL.md - https://docs.stripe.com/payments/machine/x402 - https://transak.com/buy/usdc/united-states-of-america - https://www.moonpay.com/buy/usdc ### Binance Agentic Wallet and Binance Skills Hub Install the wallet CLI, sign in by scanning the QR code with the Binance app, and verify status: npm install -g @binance/agentic-wallet baw auth signin baw wallet status baw wallet address --json baw wallet settings --json In the `wallet address` response, copy only the address whose `binanceChainId` is `8453` and `chainName` is `Base`. Fund that public address from the Binance app or another exchange/onramp by selecting USDC on the Base network. Verify the received Base USDC balance before creating the placement offer: baw wallet balance --symbol USDC --binanceChainId 8453 --json Check that `x402QuotaLeft` is at least the previewed price before creating the offer. This site's minimum 10×10 placement costs $100, while the Binance documentation shows an example $20 separate x402 daily limit. Raise the x402 limit in the Binance App's Agentic Wallet settings when necessary; the actual limit varies by wallet and cannot be changed from the CLI. For an agent that supports skills, install Binance's official wallet skill: npx skills add https://github.com/binance/binance-skills-hub/tree/main/skills/binance-web3/binance-agentic-wallet The published `baw` flow signs x402 v2 offers on Base but does not make and replay the merchant HTTP request itself: 1. Make an empty POST to `` and capture the `PAYMENT-REQUIRED` response header. 2. Preview the offer: baw x402-payment preview --paymentRequirements "" --json 3. Confirm the Base (`eip155:8453`) USDC option, price, recipient, and expiry with the human. 4. Sign the selected ready option: baw x402-payment sign --paymentId --selectedIndex --json 5. Repeat the same empty POST to `` with the returned header name and value, normally `PAYMENT-SIGNATURE: `. Binance Agent OS combines Agentic Wallet, Wallet Agentic Hub, Skill Hub, x402, and an account-specific MCP endpoint. Connect the endpoint displayed in the Binance Agent OS product to your MCP client, then give the connected agent `payment.prompt`. There is no public generic Agent OS endpoint to paste into these instructions. If Agent OS does not replay merchant HTTP requests, use the explicit preview/sign/replay flow above. Docs: - https://github.com/binance/binance-skills-hub/blob/main/skills/binance-web3/binance-agentic-wallet/references/x402-payment.md - https://www.binance.com/en/skills/detail/binance-web3/binance-agentic-wallet - https://academy.binance.com/en/articles/how-binance-agent-os-is-changing-crypto-trading ### MoonPay CLI and MCP Install, accept the terms, authenticate, and create or import a funded wallet: npm install -g @moonpay/cli mp consent accept mp login --email you@example.com mp verify --email you@example.com --code mp wallet create --name main To fund a new wallet with fiat, open MoonPay's checkout for USDC on Base, complete any required payment and identity checks, and then verify the received balance. Choose an amount that leaves at least the previewed price after fees: mp buy --token USDC --chain base --amount --wallet main mp token balance list --wallet main --chain base Pay with Base USDC using the empty POST route: mp x402 request --method POST --url "" --wallet main --chain base Do not pass `--body`. To expose the same tools to an MCP client, run `mp mcp`. Example MCP configuration: { "mcpServers": { "moonpay": { "command": "mp", "args": ["mcp"] } } } Docs: https://support.moonpay.com/en/articles/586583-moonpay-cli-for-ai-agents ### Using another CLI or MCP Any client is compatible only if it passes the v2 check above, can sign the Base USDC `exact` offer on the exact CAIP-2 network returned in `payment.network`, and replays the identical request. Mainnet `eip155:8453` is always the default; accept `eip155:84532` only after an explicit testnet request. Enforce the returned atomic maximum, proposal hash, and offer expiry before signing. Official x402 MCP guide: https://docs.x402.org/guides/mcp-server-with-x402