## CAPABILITY: pay-per-call-resize-image description: Resize any image to exact dimensions or social-media presets — Open Graph (1200x630), Twitter card, YouTube thumbnail, Instagram, LinkedIn. Smart fit modes avoid distortion: cover (focal-point crop), contain (padded), blur-fill letterbox (professional OG-image look), stretch. Paid per call via the x402 protocol — no Imagcon account or API key required; payment is the authentication. This is not free for arbitrary uploads: every successful paid call charges $0.02 USDC and must be confirmed with the user before executing. If you already generated the image via this API's generate-image endpoint, use the free companion route instead (see FREE ROUTE below). Call sequence for paid resize: 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 the resized PNG/JPEG/WebP bytes directly. input: - name: image type: file required: true description: Source image (PNG/JPEG/WebP), sent as multipart/form-data field "image" OR as a JSON field "image_base64" (base64-encoded). - name: preset type: string required: false description: Social preset — og, twitter-card, youtube-thumbnail, instagram-square, instagram-portrait, instagram-story, linkedin-post, twitter-header, github-social. Wins over width/height when provided. - name: width type: number required: false description: Target width in pixels (16–4096). Required with height when preset is omitted. - name: height type: number required: false description: Target height in pixels (16–4096). Required with width when preset is omitted. - name: mode type: string required: false description: Fit mode — cover, contain, blur (recommended for OG), or stretch. Default cover. - name: focal type: string required: false description: Crop anchor for cover mode — center, top, bottom, left, right. Default center. - name: background_color type: string required: false description: Hex background for contain mode (default #ffffff). - name: format type: string required: false description: Output format — png, jpeg, or webp. Default png. - name: quality type: number required: false description: JPEG/WebP quality 1–100 (default 90). output: - type: file description: Resized image bytes (image/png, image/jpeg, or image/webp). auth-required: false scope: financial-transaction ### API (paid) method: POST endpoint: https://imagcon.app/routes/x402/resize-image body: image: <> image_base64: <> preset: <> width: <> height: <> mode: <> focal: <
> background_color: <> format: <> quality: <<1-100>> response: image: file (image/png, image/jpeg, or image/webp) 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 "20000" (=$0.02, 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 resized image 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 cannot pay this endpoint. ### FREE ROUTE (no 402 challenge) method: POST endpoint: https://imagcon.app/routes/x402/resize-generated description: Free resize for images you already paid to generate via POST /routes/x402/generate-image. Pass the image_key returned by that endpoint plus the same resize params (preset, width, height, mode, focal, background_color, format, quality). No payment header required — possession of the unguessable image_key is proof of prior payment. body: image_key: generated_images/anonymous/.png preset: <> width: <> height: <> mode: <> focal: <> background_color: <> format: <> quality: <> response: image: file (image/png, image/jpeg, or image/webp) ### 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. ```json { "x402Version": 2, "payload": { "signature": "0x", "authorization": { "from": "0x", "to": "0x1f2A484ef654d49c58c625b09e78B538501D652D", "value": "20000", "validAfter": "0", "validBefore": "", "nonce": "0x" } }, "accepted": { "scheme": "exact", "network": "eip155:8453", "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "amount": "20000", "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. ### EXAMPLE (Python, official x402 SDK) 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) with open("source.png", "rb") as f: resp = session.post( "https://imagcon.app/routes/x402/resize-image", files={"image": ("source.png", f, "image/png")}, data={"preset": "og", "mode": "blur", "format": "png"}, ) assert resp.status_code == 200 with open("resized-og.png", "wb") as out: out.write(resp.content) ``` ### EXAMPLE (free route — prior generate-image payment) ```python import requests resp = requests.post( "https://imagcon.app/routes/x402/resize-generated", json={ "image_key": "generated_images/anonymous/.png", "preset": "og", "mode": "blur", }, ) assert resp.status_code == 200 with open("resized-og.png", "wb") as out: out.write(resp.content) ``` 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.