{"openapi":"3.1.0","info":{"title":"Fretchen AI Image Generation Service","description":"AI-powered image generation with NFT minting on Optimism/Base, paid via x402 in USDC (or EURC on Base).","version":"1.0.0","x-guidance":"OpenAI images-generation body. POST / with { prompt, size } and no payment header to receive a 402 with x402 v2 payment requirements (accepts[]). Pay with one of the offered entries — USDC on every network, EURC on Base where the 402 lists it — retry with the payment header, and the service returns { created, data: [{ url }], model } — data[0].url is the image. The mint recipient is derived from the payment payload, so there is no recipient field. Unknown request fields are rejected, not ignored. This agent also mints the image as an NFT and reports it under the x_nft response extension; that is a declared capability, not part of the images/v1 contract, and a client that only wants an image can ignore it. A 200 does not by itself mean the NFT was minted — check x_nft.status. Note: payment uses x402, so a stock OpenAI SDK cannot pay this endpoint — the OpenAI shape is for body legibility, not drop-in SDK use. Testnet networks return a placeholder image rather than a generated one.","contact":{"name":"fretchen","url":"https://www.fretchen.eu","email":"fretchen.dev@proton.me"}},"x-discovery":{"ownershipProofs":["0x8af9242b0056decb756ccd803fa791f7bd022f3f4973e9f84fec58ab3ab9160305a35b947c9a817146b91e7b61b49a1eea8eaa5832bc80682fb7b6fbba737e4f1b"]},"x-service-type":"images/v1","x-interop-floor":"A compatible images/v1 agent MUST accept an OpenAI images-generation body ({ prompt, model?, size?, n?, response_format? }), MUST support size 1024x1024 (other sizes are per-agent and advertised in its own schema), MUST return { created, data: [{ url }] } with a fetchable URL rather than base64, and MUST advertise at least one accepts[] entry with asset USDC on network Optimism (eip155:10) or Base (eip155:8453), scheme exact. Request/response schema is defined by this document's ImageGenerationRequest/ImageGenerationResponse. Minting an NFT is NOT part of the floor — see x-capabilities. See README.md.","x-capabilities":["nft-mint"],"servers":[{"url":"https://imagegen-agent.fretchen.eu"}],"tags":[{"name":"Image Generation","description":"AI text-to-image and image editing"},{"name":"NFT","description":"Mints the result as an NFT on Optimism/Base"},{"name":"x402","description":"Paid via x402 stablecoin payments (USDC, or EURC on Base)"}],"paths":{"/":{"post":{"operationId":"genimgX402Token","summary":"Generate AI Image and Mint NFT (x402 stablecoin payment)","description":"Generates an AI image using Black Forest Labs (BFL), uploads it to S3, mints an NFT on Optimism/Base, and transfers it to the payer. Requires an x402 payment: 0.07 USDC, or 0.06 EURC on Base — two separately set prices, not a conversion. An unpaid request is answered with the 402 challenge whatever its body says, so a client can always discover the payment terms; a paid request is validated before anything is verified or settled.","tags":["Image Generation","NFT","x402"],"security":[],"x-payment-info":{"protocols":["x402"],"price":{"mode":"fixed","currency":"USD","amount":"0.07"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageGenerationRequest"}}}},"responses":{"200":{"description":"The image was generated. A 200 does not by itself mean the NFT was minted — check x_nft.status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageGenerationResponse"}}}},"400":{"description":"Request validation failed — missing prompt, an unsupported value, or an unrecognized field. Body is { error: { message, type, code } }."},"402":{"description":"Payment required. Body/headers (Payment-Required, X-Payment) carry the x402 v2 payment requirements to satisfy and retry with."}}}},"/openapi.json":{"get":{"operationId":"openapiSpec","summary":"This document","tags":["x402"],"responses":{"200":{"description":"This OpenAPI document.","content":{"application/json":{"schema":{"type":"object"}}}}}}}},"components":{"schemas":{"ImageGenerationRequest":{"type":"object","properties":{"prompt":{"type":"string","minLength":1,"description":"The text prompt to generate from."},"model":{"description":"Model to generate with. Only the advertised id(s) are served: flux-kontext-pro. Defaults to flux-kontext-pro.","type":"string","enum":["flux-kontext-pro"]},"size":{"description":"Output image dimensions. Defaults to 1024x1024.","type":"string","enum":["1024x1024","1792x1024"]},"n":{"description":"Number of images. Only 1 is supported — pricing and the NFT mint are per-image.","type":"number","const":1},"response_format":{"description":"Only 'url' is supported. Images are served from stable URLs; b64_json would push large bodies through a paid function for no benefit.","type":"string","const":"url"},"mode":{"description":"Vendor extension: 'edit' transforms `referenceImage` instead of generating fresh.","type":"string","enum":["generate","edit"]},"referenceImage":{"description":"Vendor extension: base64-encoded source image. Required when mode is 'edit'.","type":"string"},"network":{"description":"Vendor extension: CAIP-2 network to restrict the 402 payment offer to. One of eip155:10, eip155:8453, eip155:11155420 — the chains where this agent's NFT contract is deployed. Omit it and the 402 offers every mainnet the agent accepts. Drives payment negotiation, not generation.","type":"string","enum":["eip155:10","eip155:8453","eip155:11155420"]},"isListed":{"description":"Vendor extension: list the minted NFT in the public gallery. Alias of x_nft.listed.","type":"boolean"},"x_nft":{"description":"Vendor extension: NFT-specific options. Not part of the images/v1 floor.","type":"object","properties":{"listed":{"description":"List the minted NFT in the public gallery.","type":"boolean"}},"additionalProperties":false},"payment":{"description":"Vendor extension: x402 payment payload, as a body fallback for clients that cannot set the PAYMENT-SIGNATURE / X-PAYMENT header. Passed through as received; validated by @x402/evm, not here."}},"required":["prompt"],"additionalProperties":false,"description":"OpenAI images-generation body plus this agent's vendor extensions. Unknown fields are rejected rather than ignored — see additionalProperties."},"ImageGenerationResponse":{"type":"object","properties":{"created":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Unix timestamp (seconds) when the image was produced."},"data":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"URL of the generated image."},"revised_prompt":{"description":"Always null — this endpoint does not rewrite prompts.","type":["string","null"]}},"required":["url","revised_prompt"],"additionalProperties":false},"description":"The generated images. Always exactly one entry, since only n=1 is supported."},"model":{"type":"string","description":"The model that served the request."},"x_nft":{"type":"object","properties":{"status":{"type":"string","enum":["minted","mint_failed"],"description":"'minted': the NFT exists and belongs to the payer. 'mint_failed': the image was generated and is yours, but the on-chain mint did not complete. The payment settled in that case — settlement precedes the mint, so a failed mint means you were charged for the generation you received, not for the token."},"token_id":{"description":"Token id of the minted NFT.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"contract":{"description":"Address of the NFT contract holding the token.","type":"string"},"network":{"description":"CAIP-2 id of the chain the NFT was minted on.","type":"string"},"metadata_url":{"description":"URL of the NFT metadata JSON.","type":"string"},"mint_tx":{"description":"Hash of the mint transaction.","type":"string"},"transfer_tx":{"description":"Hash of the transfer to the payer.","type":"string"},"listed":{"description":"Whether the NFT was listed in the public gallery.","type":"boolean"},"mint_price":{"description":"Mint price paid on-chain, in wei.","type":"string"},"owner":{"description":"Address the NFT was transferred to, derived from the x402 payment.","type":"string"},"reason":{"description":"Why the mint failed. Only set on 'mint_failed'.","type":"string"}},"required":["status"],"additionalProperties":false,"description":"Vendor extension carrying the NFT receipt. Not part of the images/v1 contract — a client that only wants an image can ignore it entirely."}},"required":["created","data","model","x_nft"],"additionalProperties":false,"description":"OpenAI images-generation response envelope, plus the x_nft vendor extension. A 200 does not by itself mean the NFT was minted — check x_nft.status."}}}}