# CryptoAd Network > A self-serve crypto advertising platform with an HTTP API for AI agents. An agent with an HTTP client and a wallet holding USDC on Base can get a quote, pay through the x402 protocol and place an ad in one short exchange, without an account, an email address or a browser. Ad formats: PTC and Sponsored Listing run on FaucetPay; Banner, Native, Paid Visits run on publisher sites in the network. Every ad is reviewed before it goes live. Prices, fields and limits of every format are in the formats document below. ## Agent API - [API index](https://cryptoadvertising.net/api/v1): name, version, whether payments are available, and the endpoint list - [OpenAPI 3.1 document](https://cryptoadvertising.net/api/v1/openapi.json): every endpoint with schemas, error codes and examples - [Formats and prices](https://cryptoadvertising.net/api/v1/formats): every ad format with its fields, limits, pricing models, minimum bids and an example order ## How to place an ad 1. Read `GET /api/v1/formats` and build an order. Field names are snake_case. Money is a decimal string in USD. 2. `POST /api/v1/quote` with the order returns its exact price and creates nothing. 3. `POST /api/v1/ads` with the same order and an `Idempotency-Key` header: a freshly generated random UUID (128 random bits). Without an API key, or with a key whose balance does not cover the price, the answer is `402 Payment Required` with an x402 version 2 payment requirement for the exact price, in the `PAYMENT-REQUIRED` header and in the body. 4. Sign that payment (USDC on Base, scheme `exact`, EIP-3009 `transferWithAuthorization`) and repeat the same request, same body and same `Idempotency-Key`, with the `PAYMENT-SIGNATURE` header. The answer is `201` with the ad, the transaction hash and, for a request made without a key, an API key. 5. Store the API key from that answer immediately: it is the only credential of the account that owns the ad. Send it as `Authorization: Bearer `, and make one call with it (`GET /api/v1/balance`) straight away: the first key that is used becomes the account's only key. 6. Poll `GET /api/v1/ads/{id}`. The status goes from `in_review` to `active` or `rejected`. There are no webhooks. ## Rules an agent should know - Nothing is created before a payment is confirmed on chain. A quote and a 402 answer create nothing. - Repeating a request with the same `Idempotency-Key` and the same body is always safe: it never pays twice and never places a second ad. If an answer was lost, repeat the request exactly. - Without an API key, the `Idempotency-Key` is a bearer secret. Generate 128 random bits (a random UUID) for every new request, never reuse it, never log it. A counter, a timestamp or a patterned value is refused (`idempotency_key_weak`). - If the answer carrying the API key was lost: repeat the same request with the same body, the same `Idempotency-Key` and the same `PAYMENT-SIGNATURE` header, within 24 hours and before any key of the account has been used. That repeat returns the stored answer with a key. Any other repeat returns the stored answer with `"api_key": null` and `api_key_recovery`: `repeat_with_payment_header` (send the header that paid) or `support_wallet_proof` (recovery is only possible through support, with a message signed by the paying wallet). - `POST /api/v1/keys` shows its key once. A repeat with the same `Idempotency-Key` answers `409 key_already_issued` and no key; call again with a new `Idempotency-Key` to get a new empty account. An empty account whose key is never used is removed after 7 days. - A signed payment header is a bearer instrument until it is settled: send it only over TLS, only to this origin. One signed payment pays for exactly one request. - 1 USDC is credited as $1.00. A payment goes from the payer's wallet straight to the platform's wallet; the platform holds no keys. - If an ad is rejected in review, its whole budget returns to the balance of the API key and can pay for another order. What an ad has not spent returns to the balance when it ends. - Balance is not refunded to a wallet automatically. A refund is a manual transfer on request. - Losing the API key loses access to the account. There is no recovery by email, because there is no email. - A Paid Visits ad needs an image (`image_id`), and an image belongs to an API key. So that order takes three calls: `POST /api/v1/keys`, `POST /api/v1/images` with the key, then `POST /api/v1/ads` with the key and `image_id`; the 402 answer asks for the price as usual. No other format takes an image. - Landing URLs must be https. The API has no webhooks and no callbacks: it never calls a URL an agent supplies. Poll for status. ## Fetching these documents The index, the OpenAPI document and the formats document may be fetched and indexed by anyone: the site's robots.txt allows exactly those three under `/api/`, and nothing else there. The OpenAPI document is also at `/openapi.json`, and `/.well-known/x402` lists the paid resources. A 402 answer of this API carries the x402 `bazaar` extension, which describes how to call the resource. ## Endpoints - `GET /api/v1` (no key): Index: name, version, links to every document, and whether payments are available. - `GET /api/v1/openapi.json` (no key): This API as an OpenAPI 3.1 document, with examples. - `GET /api/v1/formats` (no key): The catalog: every ad format with its fields, limits, pricing models and prices. - `POST /api/v1/quote` (no key): Validate an order and return its exact price and breakdown. Creates nothing. - `POST /api/v1/keys` (no key): Create an anonymous account with a zero balance and return its API key. - `POST /api/v1/ads` (API key, or an x402 payment): Place an order. Paid from the key's balance, or with an x402 payment in the same exchange. - `GET /api/v1/ads` (API key): The key's ads, newest first. - `GET /api/v1/ads/{id}` (API key): One ad: status, spend, what remains, and the reason if it was rejected. - `GET /api/v1/ads/{id}/stats` (API key): Delivery of one ad: totals and a daily series. - `POST /api/v1/ads/{id}/pause` (API key): Pause an active ad (Banner, Native, Paid Visits). - `POST /api/v1/ads/{id}/resume` (API key): Resume a paused ad. - `POST /api/v1/ads/{id}/archive` (API key): End an ad. What it has not spent returns to the balance. - `POST /api/v1/images` (API key): Upload an image for a Paid Visits ad. - `GET /api/v1/balance` (API key): The key's balance: available, reserved, total. - `POST /api/v1/balance/topup` (API key and an x402 payment): Add funds to the key's balance with an x402 payment. - `DELETE /api/v1/keys/current` (API key): Revoke the key that makes this request.