{"openapi":"3.1.0","info":{"title":"Suede AI","version":"1.0.0","description":"AI-powered music and video generation, payable with USDC on Base via the x402 protocol.","guidance":"Suede AI generates full-length songs, music videos, and images from text prompts. All endpoints require x402 payment (USDC on Base). Send a POST with a JSON body containing at minimum a 'prompt' field. For music: /create-music ($0.50). For video: /agent/video ($4.99). For images: /agent/image ($0.15). Include a PAYMENT-SIGNATURE header to authorize — either an x402 payment payload or a Skyfire pay/kya-pay token (both rails are accepted on the same endpoints). For async mode, add ?async=true — returns a jobId/songId plus a pollUrl once the job is queued. Music: poll GET /api/songs/{songId} until audio_url is no longer the placeholder. Images: poll GET /agent/image/{jobId} (no additional payment) until status is 'completed' and imageUrl is set. Video: poll GET /agent/video/{jobId} (no additional payment) until status is 'completed' and videoUrl is set."},"servers":[{"url":"https://app.suedeai.ai"}],"tags":[{"name":"AgentCommerce","description":"Agentcommerce related endpoints"},{"name":"SuedeLabs","description":"Suede Labs — onchain AI music platform"},{"name":"SUEDEAI","description":"Suede AI platform services"},{"name":"AISUEDE","description":"AI Suede — generative music and IP"},{"name":"JohnnySuede","description":"Johnnysuede related endpoints"},{"name":"JasonColapietro","description":"Jasoncolapietro related endpoints"},{"name":"SuedeAgent","description":"Suede autonomous music agent"},{"name":"x402","description":"x402 payment protocol endpoints"},{"name":"ACP","description":"Acp related endpoints"},{"name":"AgentCash","description":"AgentCash micropayment integration"},{"name":"AIAgent","description":"AI agent capabilities"},{"name":"music","description":"AI music generation — create full-length songs from text prompts"},{"name":"AIMusic","description":"AI-powered music creation and generative audio"},{"name":"MusicAI","description":"Music intelligence and AI composition"},{"name":"GenerateMusic","description":"Generate an original full-length song from prompts"},{"name":"MusicProduction","description":"Professional music production with AI"},{"name":"song","description":"Song related endpoints"},{"name":"songs","description":"Songs related endpoints"},{"name":"songwriting","description":"Songwriting related endpoints"},{"name":"music generation","description":"Music generation related endpoints"},{"name":"AI music","description":"Ai music related endpoints"},{"name":"video","description":"AI video generation — create music videos from prompts"},{"name":"AIVideo","description":"Aivideo related endpoints"},{"name":"VideoGeneration","description":"Videogeneration related endpoints"},{"name":"GenerateVideo","description":"Generatevideo related endpoints"},{"name":"image","description":"Image related endpoints"},{"name":"AIImage","description":"Aiimage related endpoints"},{"name":"ImageGeneration","description":"Imagegeneration related endpoints"},{"name":"GenerateImage","description":"Generateimage related endpoints"}],"paths":{"/create-music":{"post":{"summary":"Generate a song from a prompt with optional custom lyrics and style inputs. Returns JSON describing the generated track when the request succeeds.","operationId":"create_music","tags":["AgentCommerce","SuedeLabs","SUEDEAI","AISUEDE","JohnnySuede","JasonColapietro","SuedeAgent","x402","ACP","AgentCash","AIAgent","music","AIMusic","MusicAI","GenerateMusic","MusicProduction","song","songs","songwriting","music generation","AI music"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["shareUrl"],"properties":{"shareUrl":{"type":"string","format":"uri","description":"Public URL to listen to and download the track."},"title":{"type":"string","description":"Title of the generated track."},"imageUrl":{"type":"string","format":"uri","description":"Cover art image URL."}}}}}},"402":{"description":"Payment Required — x402 challenge. The response body carries the PaymentRequirements payload (network, asset, maxAmountRequired, payTo, etc.). Re-send the same request with a PAYMENT-SIGNATURE header to authorize.","headers":{"Retry-After":{"description":"RFC 7231 retry hint, in seconds. Always set on 429 and may be set on 402 challenges when the facilitator is back-pressured.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Total request quota for the active window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests in the active window before throttling kicks in.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) at which the rate-limit window resets.","schema":{"type":"integer"}},"WWW-Authenticate":{"description":"Always 'x402' on a payment challenge.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["x402Version","accepts"],"properties":{"x402Version":{"type":"integer","description":"x402 protocol version."},"accepts":{"type":"array","items":{"type":"object"},"description":"Accepted PaymentRequirements (per Coinbase x402 spec)."},"error":{"type":"string","description":"Optional human-readable hint."}}}}}},"429":{"description":"Too Many Requests — rate-limited. Honor `Retry-After` before retrying.","headers":{"Retry-After":{"description":"RFC 7231 retry hint, in seconds. Always set on 429 and may be set on 402 challenges when the facilitator is back-pressured.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Total request quota for the active window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests in the active window before throttling kicks in.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) at which the rate-limit window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string","description":"Human-readable error message."},"code":{"type":"string","description":"Optional machine-readable error code."}}},"example":{"detail":"Too many requests"}}}},"202":{"description":"Accepted — job queued for asynchronous execution. Poll `pollUrl` until the embedded `audio_url`/`video_url` is no longer a placeholder. Returned only when the caller passes `?async=true`.","content":{"application/json":{"schema":{"type":"object","required":["status","pollUrl"],"properties":{"status":{"type":"string","enum":["processing","queued"],"description":"Job lifecycle state at the time the request was accepted."},"shareUrl":{"type":"string","format":"uri","description":"Predicted browser-friendly share URL once the job completes."},"songId":{"type":["string","null"],"description":"Stable id for the placeholder row. May be null when the job is queued before placeholder creation."},"taskId":{"type":"string","description":"Polling identifier for non-songId workloads (musician tools, mastering, etc.)."},"pollUrl":{"type":"string","format":"uri","description":"Absolute URL the client should GET to retrieve the finished asset. Poll until status transitions out of 'processing'/'queued'."}},"additionalProperties":true}}}}},"x-payment-info":{"protocols":["x402","skyfire"],"pricingMode":"fixed","price":"0.50"},"security":[{"SkyfireJWT":[]},{"x402Payment":[]}],"x-bazaar":{"tags":["AgentCommerce","SuedeLabs","SUEDEAI","AISUEDE","JohnnySuede","JasonColapietro","SuedeAgent","x402","ACP","AgentCash","AIAgent","music","AIMusic","MusicAI","GenerateMusic","MusicProduction","song","songs","songwriting","music generation","AI music"],"category":"music","info":{"input":{"type":"http","method":"POST","bodyType":"json","body":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Describe the song you want to create. Include genre, mood, instruments, and any specific vibe. Example: 'Upbeat 80s synthwave with driving bass and neon atmosphere' or 'A melancholic acoustic guitar ballad about rain'."},"style":{"type":"string","description":"Specific musical style or genre tag (e.g., 'Hip Hop', 'Ambient', 'Rock'). Helping the AI focus on a specific sound."},"custom_mode":{"type":"boolean","description":"Set to true to use your own lyrics provided in the 'lyrics' field."},"lyrics":{"type":"string","description":"Your custom lyrics. Required if custom_mode is true."},"make_instrumental":{"type":"boolean","description":"If true, generates a track without vocals."},"vocal_gender":{"type":"string","enum":["m","f"],"description":"Preferred gender for the vocalist ('m' for male, 'f' for female)."},"tags":{"type":"string","description":"Comma-separated keywords to tag the generated file."}}}},"output":{"type":"json","example":{}}},"schema":{"type":"object","properties":{"input":{"type":"object","properties":{"body":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Describe the song you want to create. Include genre, mood, instruments, and any specific vibe. Example: 'Upbeat 80s synthwave with driving bass and neon atmosphere' or 'A melancholic acoustic guitar ballad about rain'."},"style":{"type":"string","description":"Specific musical style or genre tag (e.g., 'Hip Hop', 'Ambient', 'Rock'). Helping the AI focus on a specific sound."},"custom_mode":{"type":"boolean","description":"Set to true to use your own lyrics provided in the 'lyrics' field."},"lyrics":{"type":"string","description":"Your custom lyrics. Required if custom_mode is true."},"make_instrumental":{"type":"boolean","description":"If true, generates a track without vocals."},"vocal_gender":{"type":"string","enum":["m","f"],"description":"Preferred gender for the vocalist ('m' for male, 'f' for female)."},"tags":{"type":"string","description":"Comma-separated keywords to tag the generated file."}}}}},"output":{"type":"object","properties":{"example":{"type":"object","required":["shareUrl"],"properties":{"shareUrl":{"type":"string","format":"uri","description":"Public URL to listen to and download the track."},"title":{"type":"string","description":"Title of the generated track."},"imageUrl":{"type":"string","format":"uri","description":"Cover art image URL."}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Describe the song you want to create. Include genre, mood, instruments, and any specific vibe. Example: 'Upbeat 80s synthwave with driving bass and neon atmosphere' or 'A melancholic acoustic guitar ballad about rain'."},"style":{"type":"string","description":"Specific musical style or genre tag (e.g., 'Hip Hop', 'Ambient', 'Rock'). Helping the AI focus on a specific sound."},"custom_mode":{"type":"boolean","description":"Set to true to use your own lyrics provided in the 'lyrics' field."},"lyrics":{"type":"string","description":"Your custom lyrics. Required if custom_mode is true."},"make_instrumental":{"type":"boolean","description":"If true, generates a track without vocals."},"vocal_gender":{"type":"string","enum":["m","f"],"description":"Preferred gender for the vocalist ('m' for male, 'f' for female)."},"tags":{"type":"string","description":"Comma-separated keywords to tag the generated file."}}}}}},"parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":true,"description":"Signed payment authorization. Accepts either an x402-compatible payment payload (base64 PaymentPayload) or a Skyfire pay or kya-pay JWT. Skyfire tokens are verified against Skyfire's JWKS and charged via the Skyfire charge-token API; x402 payloads settle USDC on Base through the facilitator. Omit on the first call to receive the 402 challenge, then retry with this header to authorize.","schema":{"type":"string"}},{"name":"X-Idempotency-Key","in":"header","required":false,"description":"Client-supplied idempotency token. Re-sending the same key + body within the cache TTL returns the original response without re-charging the payer. Recommended for any POST that triggers a non-idempotent backend job (music/video render, mastering, etc.).","schema":{"type":"string","maxLength":200}},{"name":"async","in":"query","required":false,"description":"When 'true', the server returns 202 Accepted with a polling URL instead of blocking until the job completes. See the 202 response for the callback envelope.","schema":{"type":"string","enum":["true","false"],"default":"false"}}]}},"/agent/video":{"post":{"summary":"Text-to-video generation for agents. Returns an 8-second 720p clip with native audio. Use for short-form video, b-roll, product shots, music-video visuals, and social clips. Audio is generated from the scene, so include sound cues in the prompt (instruments, voices, weather, movement) for an audible result — a still, silent scene renders near-silent by design. PAYMENT-SIGNATURE-authenticated requests default to asynchronous execution. Asynchronous responses return a jobId and pollUrl. Poll GET /agent/video/{jobId} without another payment until status is 'completed' and videoUrl is available.","operationId":"agent_video","tags":["AgentCommerce","SuedeLabs","SUEDEAI","AISUEDE","JohnnySuede","JasonColapietro","SuedeAgent","x402","ACP","AgentCash","AIAgent","video","AIVideo","VideoGeneration","GenerateVideo"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["jobId","status","provider"],"properties":{"jobId":{"type":"string","description":"Job identifier for the render."},"status":{"type":"string","description":"Current render status."},"provider":{"type":"string","description":"Provider handling the render."},"videoUrl":{"type":"string","format":"uri","description":"Generated video URL when the render is complete."},"pollUrl":{"type":"string","format":"uri","description":"URL to poll for asynchronous render status."},"videoId":{"type":"string","description":"Suede video record identifier when available."},"pageUrl":{"type":"string","format":"uri","description":"Suede share-page URL when available."}}}}}},"402":{"description":"Payment Required — x402 challenge. The response body carries the PaymentRequirements payload (network, asset, maxAmountRequired, payTo, etc.). Re-send the same request with a PAYMENT-SIGNATURE header to authorize.","headers":{"Retry-After":{"description":"RFC 7231 retry hint, in seconds. Always set on 429 and may be set on 402 challenges when the facilitator is back-pressured.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Total request quota for the active window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests in the active window before throttling kicks in.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) at which the rate-limit window resets.","schema":{"type":"integer"}},"WWW-Authenticate":{"description":"Always 'x402' on a payment challenge.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["x402Version","accepts"],"properties":{"x402Version":{"type":"integer","description":"x402 protocol version."},"accepts":{"type":"array","items":{"type":"object"},"description":"Accepted PaymentRequirements (per Coinbase x402 spec)."},"error":{"type":"string","description":"Optional human-readable hint."}}}}}},"429":{"description":"Too Many Requests — rate-limited. Honor `Retry-After` before retrying.","headers":{"Retry-After":{"description":"RFC 7231 retry hint, in seconds. Always set on 429 and may be set on 402 challenges when the facilitator is back-pressured.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Total request quota for the active window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests in the active window before throttling kicks in.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) at which the rate-limit window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string","description":"Human-readable error message."},"code":{"type":"string","description":"Optional machine-readable error code."}}},"example":{"detail":"Too many requests"}}}},"202":{"description":"Accepted — job queued for asynchronous execution. Poll `pollUrl` until the embedded `audio_url`/`video_url` is no longer a placeholder. Returned only when the caller passes `?async=true`.","content":{"application/json":{"schema":{"type":"object","required":["status","pollUrl"],"properties":{"status":{"type":"string","enum":["processing","queued"],"description":"Job lifecycle state at the time the request was accepted."},"shareUrl":{"type":"string","format":"uri","description":"Predicted browser-friendly share URL once the job completes."},"songId":{"type":["string","null"],"description":"Stable id for the placeholder row. May be null when the job is queued before placeholder creation."},"taskId":{"type":"string","description":"Polling identifier for non-songId workloads (musician tools, mastering, etc.)."},"pollUrl":{"type":"string","format":"uri","description":"Absolute URL the client should GET to retrieve the finished asset. Poll until status transitions out of 'processing'/'queued'."}},"additionalProperties":true}}}}},"x-payment-info":{"protocols":["x402","skyfire"],"pricingMode":"fixed","price":"4.99"},"security":[{"SkyfireJWT":[]},{"x402Payment":[]}],"x-bazaar":{"tags":["AgentCommerce","SuedeLabs","SUEDEAI","AISUEDE","JohnnySuede","JasonColapietro","SuedeAgent","x402","ACP","AgentCash","AIAgent","video","AIVideo","VideoGeneration","GenerateVideo"],"category":"video","info":{"input":{"type":"http","method":"POST","bodyType":"json","body":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Narrative or visual prompt to drive the video concept."},"durationSeconds":{"type":"integer","description":"Requested clip length in seconds; the service maps it to a supported render length.","default":8,"minimum":3,"maximum":15},"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1"],"description":"Desired frame aspect ratio."}}}},"output":{"type":"json","example":{}}},"schema":{"type":"object","properties":{"input":{"type":"object","properties":{"body":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Narrative or visual prompt to drive the video concept."},"durationSeconds":{"type":"integer","description":"Requested clip length in seconds; the service maps it to a supported render length.","default":8,"minimum":3,"maximum":15},"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1"],"description":"Desired frame aspect ratio."}}}}},"output":{"type":"object","properties":{"example":{"type":"object","required":["jobId","status","provider"],"properties":{"jobId":{"type":"string","description":"Job identifier for the render."},"status":{"type":"string","description":"Current render status."},"provider":{"type":"string","description":"Provider handling the render."},"videoUrl":{"type":"string","format":"uri","description":"Generated video URL when the render is complete."},"pollUrl":{"type":"string","format":"uri","description":"URL to poll for asynchronous render status."},"videoId":{"type":"string","description":"Suede video record identifier when available."},"pageUrl":{"type":"string","format":"uri","description":"Suede share-page URL when available."}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Narrative or visual prompt to drive the video concept."},"durationSeconds":{"type":"integer","description":"Requested clip length in seconds; the service maps it to a supported render length.","default":8,"minimum":3,"maximum":15},"aspectRatio":{"type":"string","enum":["16:9","9:16","1:1"],"description":"Desired frame aspect ratio."}}}}}},"parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":true,"description":"Signed payment authorization. Accepts either an x402-compatible payment payload (base64 PaymentPayload) or a Skyfire pay or kya-pay JWT. Skyfire tokens are verified against Skyfire's JWKS and charged via the Skyfire charge-token API; x402 payloads settle USDC on Base through the facilitator. Omit on the first call to receive the 402 challenge, then retry with this header to authorize.","schema":{"type":"string"}},{"name":"X-Idempotency-Key","in":"header","required":false,"description":"Client-supplied idempotency token. Re-sending the same key + body within the cache TTL returns the original response without re-charging the payer. Recommended for any POST that triggers a non-idempotent backend job (music/video render, mastering, etc.).","schema":{"type":"string","maxLength":200}},{"name":"async","in":"query","required":false,"description":"When 'true', the server returns 202 Accepted with a polling URL instead of blocking until the job completes. See the 202 response for the callback envelope.","schema":{"type":"string","enum":["true","false"],"default":"false"}}]}},"/agent/image":{"post":{"summary":"Generate a still image from a text prompt. PAYMENT-SIGNATURE-authenticated requests default to asynchronous execution. Asynchronous responses return a jobId and pollUrl. Poll GET /agent/image/{jobId} without another payment until status is 'completed' and imageUrl is available.","operationId":"agent_image","tags":["AgentCommerce","SuedeLabs","SUEDEAI","AISUEDE","JohnnySuede","JasonColapietro","SuedeAgent","x402","ACP","AgentCash","AIAgent","image","AIImage","ImageGeneration","GenerateImage"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","required":["jobId","status","provider"],"properties":{"jobId":{"type":"string","description":"Job identifier for the render."},"status":{"type":"string","description":"Current render status."},"provider":{"type":"string","description":"Provider handling the render."},"imageUrl":{"type":"string","format":"uri","description":"Generated image URL when the render is complete."},"pollUrl":{"type":"string","format":"uri","description":"URL to poll for asynchronous render status."}}}}}},"402":{"description":"Payment Required — x402 challenge. The response body carries the PaymentRequirements payload (network, asset, maxAmountRequired, payTo, etc.). Re-send the same request with a PAYMENT-SIGNATURE header to authorize.","headers":{"Retry-After":{"description":"RFC 7231 retry hint, in seconds. Always set on 429 and may be set on 402 challenges when the facilitator is back-pressured.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Total request quota for the active window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests in the active window before throttling kicks in.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) at which the rate-limit window resets.","schema":{"type":"integer"}},"WWW-Authenticate":{"description":"Always 'x402' on a payment challenge.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["x402Version","accepts"],"properties":{"x402Version":{"type":"integer","description":"x402 protocol version."},"accepts":{"type":"array","items":{"type":"object"},"description":"Accepted PaymentRequirements (per Coinbase x402 spec)."},"error":{"type":"string","description":"Optional human-readable hint."}}}}}},"429":{"description":"Too Many Requests — rate-limited. Honor `Retry-After` before retrying.","headers":{"Retry-After":{"description":"RFC 7231 retry hint, in seconds. Always set on 429 and may be set on 402 challenges when the facilitator is back-pressured.","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Total request quota for the active window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Remaining requests in the active window before throttling kicks in.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) at which the rate-limit window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string","description":"Human-readable error message."},"code":{"type":"string","description":"Optional machine-readable error code."}}},"example":{"detail":"Too many requests"}}}},"202":{"description":"Accepted — job queued for asynchronous execution. Poll `pollUrl` until the embedded `audio_url`/`video_url` is no longer a placeholder. Returned only when the caller passes `?async=true`.","content":{"application/json":{"schema":{"type":"object","required":["status","pollUrl"],"properties":{"status":{"type":"string","enum":["processing","queued"],"description":"Job lifecycle state at the time the request was accepted."},"shareUrl":{"type":"string","format":"uri","description":"Predicted browser-friendly share URL once the job completes."},"songId":{"type":["string","null"],"description":"Stable id for the placeholder row. May be null when the job is queued before placeholder creation."},"taskId":{"type":"string","description":"Polling identifier for non-songId workloads (musician tools, mastering, etc.)."},"pollUrl":{"type":"string","format":"uri","description":"Absolute URL the client should GET to retrieve the finished asset. Poll until status transitions out of 'processing'/'queued'."}},"additionalProperties":true}}}}},"x-payment-info":{"protocols":["x402","skyfire"],"pricingMode":"fixed","price":"0.15"},"security":[{"SkyfireJWT":[]},{"x402Payment":[]}],"x-bazaar":{"tags":["AgentCommerce","SuedeLabs","SUEDEAI","AISUEDE","JohnnySuede","JasonColapietro","SuedeAgent","x402","ACP","AgentCash","AIAgent","image","AIImage","ImageGeneration","GenerateImage"],"category":"image","info":{"input":{"type":"http","method":"POST","bodyType":"json","body":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Visual prompt describing the image to generate."},"aspectRatio":{"type":"string","enum":["1:1","9:16","16:9","3:4","4:3","3:2","2:3","5:4","4:5","21:9"],"description":"Desired frame aspect ratio."},"outputFormat":{"type":"string","enum":["png","jpeg"],"description":"Output image format."}}}},"output":{"type":"json","example":{}}},"schema":{"type":"object","properties":{"input":{"type":"object","properties":{"body":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Visual prompt describing the image to generate."},"aspectRatio":{"type":"string","enum":["1:1","9:16","16:9","3:4","4:3","3:2","2:3","5:4","4:5","21:9"],"description":"Desired frame aspect ratio."},"outputFormat":{"type":"string","enum":["png","jpeg"],"description":"Output image format."}}}}},"output":{"type":"object","properties":{"example":{"type":"object","required":["jobId","status","provider"],"properties":{"jobId":{"type":"string","description":"Job identifier for the render."},"status":{"type":"string","description":"Current render status."},"provider":{"type":"string","description":"Provider handling the render."},"imageUrl":{"type":"string","format":"uri","description":"Generated image URL when the render is complete."},"pollUrl":{"type":"string","format":"uri","description":"URL to poll for asynchronous render status."}}}}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["prompt"],"properties":{"prompt":{"type":"string","description":"Visual prompt describing the image to generate."},"aspectRatio":{"type":"string","enum":["1:1","9:16","16:9","3:4","4:3","3:2","2:3","5:4","4:5","21:9"],"description":"Desired frame aspect ratio."},"outputFormat":{"type":"string","enum":["png","jpeg"],"description":"Output image format."}}}}}},"parameters":[{"name":"PAYMENT-SIGNATURE","in":"header","required":true,"description":"Signed payment authorization. Accepts either an x402-compatible payment payload (base64 PaymentPayload) or a Skyfire pay or kya-pay JWT. Skyfire tokens are verified against Skyfire's JWKS and charged via the Skyfire charge-token API; x402 payloads settle USDC on Base through the facilitator. Omit on the first call to receive the 402 challenge, then retry with this header to authorize.","schema":{"type":"string"}},{"name":"X-Idempotency-Key","in":"header","required":false,"description":"Client-supplied idempotency token. Re-sending the same key + body within the cache TTL returns the original response without re-charging the payer. Recommended for any POST that triggers a non-idempotent backend job (music/video render, mastering, etc.).","schema":{"type":"string","maxLength":200}},{"name":"async","in":"query","required":false,"description":"When 'true', the server returns 202 Accepted with a polling URL instead of blocking until the job completes. See the 202 response for the callback envelope.","schema":{"type":"string","enum":["true","false"],"default":"false"}}]}}},"components":{"securitySchemes":{"SkyfireJWT":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Skyfire pay+jwt or kya-pay+jwt token issued by Skyfire and verified against https://app.skyfire.xyz/.well-known/jwks.json. Pass in the PAYMENT-SIGNATURE header.","x-header-name":"PAYMENT-SIGNATURE","x-jwks-uri":"https://app.skyfire.xyz/.well-known/jwks.json"},"x402Payment":{"type":"http","scheme":"bearer","bearerFormat":"x402","description":"x402 USDC payment on Base mainnet (eip155:8453). Pass a signed ERC-3009 transferWithAuthorization payload in the PAYMENT-SIGNATURE header.","x-header-name":"PAYMENT-SIGNATURE","x-facilitator":"https://x402.org/facilitator"}}}}