## CAPABILITY: pay-per-call-generate-image description: Generate one image from a text prompt — an app icon, brand logo, character mascot or illustration, in any of seven visual styles and three aspect ratios. Paid per call via the x402 protocol — no Imagcon account or API key required; payment is the authentication. This is not free: every successful call charges $0.195 USDC and must be confirmed with the user before executing. Call sequence: send the request with no payment attached; the response is HTTP 402 with payment requirements (price, recipient address, accepted token) in the PAYMENT-REQUIRED header; construct a payment proof per the x402 "exact" scheme (EIP-3009 transferWithAuthorization on Base mainnet USDC — this endpoint does not support Permit2); retry the identical request with the proof attached in the Payment-Signature header; the retried request returns JSON with image_key and preview_url. input: - name: description type: string required: true description: Text description of the image to generate, sent as JSON field "description". - name: type type: string required: false description: What to produce — icon (default), logo, mascot or illustration. Only icon applies app-icon framing and OS-mask safe margins; a mascot or illustration is composed to fill its frame. Ask for the one you actually want, because an icon-framed mascot is not a usable mascot. - name: style type: string required: false description: Visual finish — flat, metallic, 2d-game, clay, 3d, gradient or glassmorphism. The same seven the Imagcon web app offers. Omit for the model's own judgement. - name: aspect_ratio type: string required: false description: Output shape — 1:1 (default, 1024x1024), 4:3 (1200x896) or 16:9 (1376x768). Use 16:9 for Open Graph and hero images. Icons should stay 1:1. output: - name: image_key type: string description: Storage key for the generated PNG (under generated_images/anonymous/). - name: preview_url type: string description: HTTPS URL to preview the generated image before committing to icon generation. auth-required: false scope: financial-transaction ### API method: POST endpoint: https://imagcon.app/routes/x402/generate-image body: description: <> type: <> style: <> aspect_ratio: <> response: image_key: string preview_url: string (application/json) Payment mechanics (read before invoking): this endpoint speaks x402 v2 directly over plain HTTP — it is not an MCP tool and requires no pre-existing Imagcon account or API key. A successful payment may create the optional temporary wallet profile described below. An unpaid request to the endpoint above returns HTTP 402 with a base64-encoded PAYMENT-REQUIRED header (decodes to {x402Version, accepts[], resource, extensions.bazaar}). The single entry in accepts[] specifies scheme "exact", network "eip155:8453" (Base mainnet), asset USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913), amount "195000" (=$0.195, 6 decimals), and a payTo address. Sign an EIP-3009 transferWithAuthorization for that exact amount/payTo using the EIP-712 domain in accepts[0].extra (name/version), retry the identical request with the resulting PaymentPayload base64-encoded in a Payment-Signature header, and the response is HTTP 200 with the JSON body plus a Payment-Response header (base64 JSON: success, payer, transaction, network) confirming on-chain settlement. EIP-3009 is required — clients that only implement Permit2 for the "exact" scheme (confirmed: PipRail as of 2026-06) cannot pay this endpoint. ### PAYLOAD SHAPE (language-agnostic — build exactly this JSON if not using the Python SDK below) The value placed in the Payment-Signature header is the base64 encoding of this exact JSON object. The most common mistake is flattening `scheme`/`network` to the top level — they do NOT belong there. The entire matching entry from `accepts[]` must be copied whole into a top-level `accepted` field. `accepted` is REQUIRED; omitting it produces a payload that fails to parse, and the server's correct response to an unparseable payload is to silently re-issue a fresh 402 — which looks identical to "no payment sent at all" from the outside. There is no error message distinguishing "missing" from "malformed" — get this shape exactly right before retrying. ```json { "x402Version": 2, "payload": { "signature": "0x", "authorization": { "from": "0x", "to": "0x1f2A484ef654d49c58c625b09e78B538501D652D", "value": "195000", "validAfter": "0", "validBefore": "", "nonce": "0x" } }, "accepted": { "scheme": "exact", "network": "eip155:8453", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "amount": "195000", "payTo": "0x1f2A484ef654d49c58c625b09e78B538501D652D", "maxTimeoutSeconds": 300, "extra": { "name": "USD Coin", "version": "2" } } } ``` `accepted` must be copied verbatim from the `accepts[0]` entry in the 402 response you received — do not reconstruct it by hand from memory, copy the exact object. `payload.authorization` is where your own signed values go. ### EXAMPLE (Python, official x402 SDK — same flow as sibling x402 endpoints) Install: pip install "x402[evm]" requests eth-account ```python from eth_account import Account from x402 import x402ClientSync from x402.mechanisms.evm.signers import EthAccountSigner from x402.mechanisms.evm.exact import ExactEvmClientScheme from x402.http.clients.requests import x402_requests account = Account.from_key("0xYOUR_PRIVATE_KEY") signer = EthAccountSigner(account) client = x402ClientSync() client.register("eip155:8453", ExactEvmClientScheme(signer)) session = x402_requests(client) resp = session.post( "https://imagcon.app/routes/x402/generate-image", json={ "description": "A blue geometric logo for a productivity app", "type": "logo", "style": "flat", }, ) assert resp.status_code == 200 data = resp.json() print(data["image_key"], data["preview_url"]) ``` No manual EIP-712 signing or manual 402 handling is required — `x402_requests` auto-detects the 402, signs via the registered scheme, and retries automatically. ### CHOOSING type Unrecognised values for type, style or aspect_ratio are rejected with HTTP 400 naming the supported set, and no payment is taken — settlement only fires on a 2xx, so a rejected request costs nothing and can be corrected and retried. icon app icon artwork: centred subject, uniform margin, no enclosing tile, composed to survive an OS mask and remain legible at 48px. Feed this to generate-pwa-icons or resize-image. logo brand mark: simple memorable shape, high contrast, scales down cleanly. mascot character illustration: full figure, expressive, fills its frame. illustration general artwork with no icon constraints applied. Observability note: the SDK session handles the 402 internally — a successful call returns only the final 200. To observe the challenge yourself (price, payTo, network) before paying, send the request once WITHOUT payment first; the unpaid 402 costs nothing and its PAYMENT-REQUIRED header decodes to the full payment requirements. If a paid retry comes back 402, decode THAT response's PAYMENT-REQUIRED header — its error field states the facilitator's reason; it is not the same 402 you started with. ### WALLET PROFILE (optional — paper plan by default) Every successful paid call with wallet profiles enabled returns X-Imagcon-Token and X-Imagcon-Profile-Status. Temporary profiles also return X-Imagcon-Profile-Setup on every paid call so activation is never a one-shot opportunity. X-Imagcon-Api-Key is issued only when a new temporary profile is created and is never stored in plaintext. Header reference: X-Imagcon-Token: tok_... (profile identifier, returned on every paid call) X-Imagcon-Api-Key: ic_live_... (new temporary profile only — unlocks imagcon-mcp tools while the profile remains valid) X-Imagcon-Profile-Setup: https://imagcon.app/routes/x402/profile/activate (every paid call while status=temp) X-Imagcon-Profile-Status: temp or permanent (every paid call) X-Imagcon-Profile-Expires: ISO 8601 expiry when status=temp Each successful paid call resets a temporary profile to 60 days from that payment. If no later payment or activation occurs, the profile expires and its API keys are revoked server-side; a later payment creates a fresh temporary profile. To make permanent: POST /routes/x402/profile/activate with wallet_address, profile_token, name, terms_confirmed, signature, and message. Set rotate_api_key=true to revoke the original key and receive a replacement once if it was lost. Required wallet signature: sign message imagcon.app/profile/activate:{profile_token}:{unix_timestamp} within 5 minutes and include signature + message on activate. Do NOT log or store X-Imagcon-Api-Key or profile_token in chat history. Retry paid calls with X-Imagcon-Token header for wallet-independent continuity when the payer wallet rotates. Send X-Imagcon-Profile: none on a paid request to decline profile creation for that request. To delete an existing profile and its saved wallet data, POST /routes/x402/profile/decline and sign imagcon.app/profile/decline:{profile_token}:{unix_timestamp} within 5 minutes; payment records are retained. If your operator has an Imagcon account, the wallet can be linked to it for free read access to the account's saved images — see link-wallet-to-account.