{"openapi":"3.1.0","info":{"title":"Spicy API","version":"1.0.0","description":"Spicy API is one REST API for uncensored image, image-editing, video and chat generation, sold per generation from a prepaid US-dollar balance: no subscription, no GPUs to run. It is OpenAI-compatible (point the OpenAI SDK at https://api.spicyapi.com/v1 with a Spicy API key) and includes our own POV video fine-tunes. Not to be confused with spicyapi.ai, an unrelated model aggregator. Images from $0.06, video from $0.10 per second. OPENAI-COMPATIBLE: point the OpenAI SDK at https://api.spicyapi.com/v1 with a Spicy API key; client.images.generate maps onto POST /v1/images/generations and client.chat.completions.create onto POST /v1/chat/completions (streaming included). Image edits take JSON with image_url (not the SDK's multipart upload) and video is a plain HTTP task you poll. Every response carries cost_usd, the exact amount debited. Prompts are screened before any charge (422, never billed); failed generations are refunded. Sandbox keys (created with sandbox: true) answer every endpoint from fixtures flagged sandbox: true and bill nothing. Machine-readable overview: https://www.spicyapi.com/llms.txt. MCP server for agents: https://www.spicyapi.com/api/mcp.","contact":{"name":"Spicy API support","email":"support@spicyapi.com","url":"https://www.spicyapi.com/docs"},"termsOfService":"https://www.spicyapi.com/terms-of-service"},"servers":[{"url":"https://api.spicyapi.com","description":"Public API host (also reachable at https://www.spicyapi.com/api)."}],"x-openai-compatible":{"baseUrl":"https://api.spicyapi.com/v1","compatible":["/v1/chat/completions","/v1/images/generations","/v1/models"],"notes":"Image sizes use width*height (1024*1024). Edits and video are Spicy API specific."},"x-mcp":{"endpoint":"https://www.spicyapi.com/api/mcp","transport":"streamable-http","auth":"Authorization: Bearer sk-spicy-...","docs":"https://www.spicyapi.com/docs","llms":"https://www.spicyapi.com/llms.txt","skills":"https://www.spicyapi.com/skills/index.json"},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"sk-spicy-...","description":"Per-account API key from https://www.spicyapi.com/dashboard/api-keys (shown once, stored hashed). Sandbox keys bill nothing."}}},"tags":[{"name":"Core"},{"name":"Images"},{"name":"Video"},{"name":"Chat"},{"name":"Agent tools","description":"REST mirror of the MCP server at https://www.spicyapi.com/api/mcp: same key, same handlers, same guardrails."},{"name":"default","description":"Always available with a valid key."},{"name":"guarded","description":"Spending and credential tools: need approval_token unless the account turned approvals off."}],"paths":{"/v1/models":{"get":{"operationId":"listModels","summary":"List Models","description":"List every model available to your account. Returns the live catalogue: ids, pricing, limits, and, for our own fine-tunes, the trigger word the gateway injects for you.","tags":["Core"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"The models your key can call.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"The model id you pass as `model`."},"kind":{"type":"string","description":"One of `image`, `image-edit`, `video`, `chat`."},"label":{"type":"string","description":"Human-readable name."},"description":{"type":"string","description":"What the model is good for."},"featured":{"type":"boolean","description":"True for our own fine-tunes."},"requires_image":{"type":"boolean","description":"True when the model needs an `image_url` input."},"accepts_image":{"type":"boolean","description":"True when `image_url` is allowed. False on pure text-to-video models, which reject one."},"pricing":{"type":"object","description":"Unit and USD rate. Video models price per second, by resolution."},"lora_trigger":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Trigger word for a fine-tune. Injected automatically, you do not need to include it."},"limits":{"type":"object","description":"Sizes, resolutions, max duration, max outputs."},"examples":{"type":"array","items":{"type":"string"},"description":"Example output URLs for this model."}},"required":["id","kind","label","description","featured","requires_image","accepts_image","pricing"]},"description":"Every model available to you."}},"required":["data"]},"example":{"data":[{"id":"spicy-pov-missionary-1","kind":"video","label":"Spicy POV Missionary","featured":true,"requires_image":true,"accepts_image":true,"pricing":{"unit":"second","usd_by_resolution":{"720P":0.175,"1080P":0.29}},"lora_trigger":"sg_povmis1","limits":{"resolutions":["720P","1080P"],"maxDuration":15}}]}}}},"400":{"description":"Invalid parameters. Body: {error: {message, type: 'invalid_request_error'}}."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance. Top up in the dashboard or through the get_topup_link tool; nothing was charged."},"422":{"description":"Prompt blocked by moderation (acceptable use policy). Never charged."},"429":{"description":"Model at capacity; retry in a few seconds."}}}},"/v1/account":{"get":{"operationId":"getAccount","summary":"Get Account","description":"Read your balance and account status.","tags":["Core"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","description":"The account this key belongs to."},"balance_usd":{"type":"number","description":"Remaining balance in US dollars."}},"required":["email","balance_usd"]},"example":{"email":"you@example.com","balance_usd":42.75}}}},"400":{"description":"Invalid parameters. Body: {error: {message, type: 'invalid_request_error'}}."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance. Top up in the dashboard or through the get_topup_link tool; nothing was charged."},"422":{"description":"Prompt blocked by moderation (acceptable use policy). Never charged."},"429":{"description":"Model at capacity; retry in a few seconds."}}}},"/v1/images/generations":{"post":{"operationId":"createImage","summary":"Create Image","description":"Generate one or more images from a text prompt. Billed per output image. Prompts are screened before anything is charged, and every request is steered to depict adults only.","tags":["Images"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Request id, useful for support."},"object":{"type":"string","description":"Always `image.generation`."},"model":{"type":"string","description":"The model that produced the images."},"created":{"type":"integer","description":"Unix timestamp."},"data":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"Durable CDN URL. Reusable as an input to edits and video."}},"required":["url"]},"description":"One entry per generated image."},"cost_usd":{"type":"number","description":"What this request cost, in US dollars, already debited from your balance."}},"required":["id","object","model","created","data","cost_usd"]},"example":{"id":"req_8f2a91c4","object":"image.generation","model":"spicy-image-1","created":1755950400,"data":[{"url":"https://cdn.spicyapi.com/outputs/a1b2/req_8f2a91c4-0.png"}],"cost_usd":0.06}}}},"400":{"description":"Invalid parameters. Body: {error: {message, type: 'invalid_request_error'}}."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance. Top up in the dashboard or through the get_topup_link tool; nothing was charged."},"422":{"description":"Prompt blocked by moderation (acceptable use policy). Never charged."},"429":{"description":"Model at capacity; retry in a few seconds."}},"requestBody":{"required":true,"description":"Outputs are persisted to our CDN and returned as durable URLs. Those URLs are the only images accepted as inputs to `/v1/images/edits` and `/v1/videos/generations`.","content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"A model id from `GET /v1/models`, e.g. `spicy-image-1`."},"prompt":{"type":"string","description":"What to generate."},"negative_prompt":{"type":"string","description":"What to avoid. Our own safety terms are always appended."},"size":{"type":"string","description":"`width*height`, e.g. `1024*1024`. Defaults to the model's first supported size."},"n":{"type":"integer","description":"How many images to return. Clamped to the model's maximum. Defaults to 1."},"seed":{"type":"integer","description":"Reuse a seed to reproduce a result. Random when omitted."}},"required":["model","prompt"]}}}}}},"/v1/images/edits":{"post":{"operationId":"editImage","summary":"Edit Image","description":"Edit an image you generated earlier, guided by a prompt. Every `image_url` must be an image your own account generated. Uploads and external URLs are rejected before you are charged.","tags":["Images"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Request id."},"object":{"type":"string","description":"Always `image.edit`."},"data":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"Durable CDN URL."}},"required":["url"]},"description":"The edited image."},"cost_usd":{"type":"number","description":"What this request cost, in US dollars, already debited from your balance."}},"required":["id","object","data","cost_usd"]},"example":{"id":"req_31c7de05","object":"image.edit","data":[{"url":"https://cdn.spicyapi.com/outputs/a1b2/req_31c7de05-0.png"}],"cost_usd":0.15}}}},"400":{"description":"Invalid parameters. Body: {error: {message, type: 'invalid_request_error'}}."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance. Top up in the dashboard or through the get_topup_link tool; nothing was charged."},"422":{"description":"Prompt blocked by moderation (acceptable use policy). Never charged."},"429":{"description":"Model at capacity; retry in a few seconds."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"An image-edit model id, e.g. `spicy-image-edit-1`."},"prompt":{"type":"string","description":"The change to make."},"image_url":{"type":"string","description":"A single source image. Use this or `image_urls`."},"image_urls":{"type":"array","items":{"type":"string"},"description":"Up to 3 source images, all owned by your account."},"negative_prompt":{"type":"string","description":"What to avoid."},"size":{"type":"string","description":"Output size as `width*height`."},"seed":{"type":"integer","description":"Reproducibility seed."}},"required":["model","prompt"]}}}}}},"/v1/images":{"get":{"operationId":"listImages","summary":"List Images","description":"List the images your account has generated. These are exactly the URLs accepted as inputs elsewhere in the API. Use this to look up what you can edit or animate.","tags":["Images"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string","description":"Durable CDN URL."},"source":{"type":"string","description":"`image` or `image-edit`."},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 timestamp."}},"required":["url","source"]},"description":"Your generated images, newest first."}},"required":["data"]},"example":{"data":[{"url":"https://cdn.spicyapi.com/outputs/a1b2/req_8f2a91c4-0.png","source":"image","created_at":"2026-08-23T10:14:02.000Z"}]}}}},"400":{"description":"Invalid parameters. Body: {error: {message, type: 'invalid_request_error'}}."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance. Top up in the dashboard or through the get_topup_link tool; nothing was charged."},"422":{"description":"Prompt blocked by moderation (acceptable use policy). Never charged."},"429":{"description":"Model at capacity; retry in a few seconds."}},"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, newest first. Defaults to 50.","schema":{"type":"integer","description":"How many to return, newest first. Defaults to 50."}}]}},"/v1/videos/generations":{"post":{"operationId":"createVideo","summary":"Create Video","description":"Start a video generation. Returns a task to poll. Video is asynchronous: this call returns immediately with a task id, and you poll `GET /v1/videos/tasks/{id}` until it succeeds or fails. Image-to-video models need an `image_url` your account generated. Failed generations are refunded automatically.","tags":["Video"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"A task you can poll.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Task id. Pass it to `GET /v1/videos/tasks/{id}`."},"object":{"type":"string","description":"Always `task`."},"type":{"type":"string","description":"Always `video`."},"model":{"type":"string","description":"The model generating the clip."},"status":{"type":"string","description":"`queued`, `processing`, `finalizing`, `succeeded`, or `failed`."},"output":{"anyOf":[{"type":"object","properties":{"video_url":{"type":"string","description":"Durable CDN URL of the finished clip."}},"required":["video_url"]},{"type":"null"}],"description":"Null until the task succeeds."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Why the task failed, when it did."},"cost_usd":{"type":"number","description":"What this request cost, in US dollars, already debited from your balance."}},"required":["id","object","type","model","status","cost_usd"]},"example":{"id":"task_5d9e2f10","object":"task","type":"video","model":"spicy-pov-missionary-1","status":"queued","output":null,"error":null,"cost_usd":0.875}}}},"400":{"description":"Invalid parameters. Body: {error: {message, type: 'invalid_request_error'}}."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance. Top up in the dashboard or through the get_topup_link tool; nothing was charged."},"422":{"description":"Prompt blocked by moderation (acceptable use policy). Never charged."},"429":{"description":"Model at capacity; retry in a few seconds."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"A video model id, e.g. `spicy-pov-missionary-1`."},"prompt":{"type":"string","description":"What should happen in the clip."},"image_url":{"type":"string","description":"First frame; must be one of your generated images. Required where `requires_image` is true. Optional on `spicy-motion-3` and `spicy-motion-3-fast`, which generate from text alone when it is omitted."},"resolution":{"type":"string","description":"One of the model's `limits.resolutions` from `GET /v1/models`: `720P` or `1080P` on the wan2.x models, `480P`, `720P` or `1080P` on `spicy-motion-3` and `spicy-motion-3-fast`. Defaults to `720P`."},"duration":{"type":"integer","description":"Seconds, between the model's `minDuration` and `maxDuration` (2 to 15 on the wan2.x models, 2 to 30 on `spicy-motion-3` and `spicy-motion-3-fast`). Defaults to 5."},"negative_prompt":{"type":"string","description":"What to avoid."},"audio":{"type":"boolean","description":"Generate audio where the model supports it."},"seed":{"type":"integer","description":"Reproducibility seed."}},"required":["model","prompt"]}}}}}},"/v1/videos/tasks/{id}":{"get":{"operationId":"getVideoTask","summary":"Get Video Task","description":"Check a video task and collect the finished clip. Poll every 10 to 15 seconds. When `status` is `succeeded`, `output.video_url` holds a durable CDN URL.","tags":["Video"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"The task id."},"status":{"type":"string","description":"`queued`, `processing`, `finalizing`, `succeeded`, or `failed`."},"output":{"anyOf":[{"type":"object","properties":{"video_url":{"type":"string","description":"Durable CDN URL of the clip."}},"required":["video_url"]},{"type":"null"}],"description":"Present once finished."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Failure reason, if any. Failed tasks are refunded."},"cost_usd":{"type":"number","description":"What this request cost, in US dollars, already debited from your balance."}},"required":["id","status","cost_usd"]},"example":{"id":"task_5d9e2f10","object":"task","type":"video","model":"spicy-pov-missionary-1","status":"succeeded","output":{"video_url":"https://cdn.spicyapi.com/outputs/a1b2/task_5d9e2f10.mp4"},"error":null,"cost_usd":0.875}}}},"400":{"description":"Invalid parameters. Body: {error: {message, type: 'invalid_request_error'}}."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance. Top up in the dashboard or through the get_topup_link tool; nothing was charged."},"422":{"description":"Prompt blocked by moderation (acceptable use policy). Never charged."},"429":{"description":"Model at capacity; retry in a few seconds."}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task id from POST /v1/videos/generations."}]}},"/v1/chat/completions":{"post":{"operationId":"chatCompletions","summary":"Create Chat Completion","description":"OpenAI-compatible uncensored chat, with streaming. Drop-in compatible with the OpenAI SDK: point `baseURL` at `https://api.spicyapi.com/v1` and pass your SpicyAPI key. Billed on total tokens.","tags":["Chat"],"security":[{"apiKey":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Completion id."},"choices":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","description":"Position in the list."},"message":{"type":"object","properties":{"role":{"type":"string","description":"Always `assistant`."},"content":{"type":"string","description":"Reply text."}},"required":["role","content"],"description":"The reply."},"finish_reason":{"type":"string","description":"Why generation stopped."}},"required":["index","message"]},"description":"Generated replies."},"usage":{"type":"object","properties":{"prompt_tokens":{"type":"integer","description":"Tokens in the request."},"completion_tokens":{"type":"integer","description":"Tokens generated."},"total_tokens":{"type":"integer","description":"Sum, what you are billed on."}},"required":["prompt_tokens","completion_tokens","total_tokens"],"description":"Token counts."},"cost_usd":{"type":"number","description":"What this request cost, in US dollars, already debited from your balance."}},"required":["id","choices","cost_usd"]},"example":{"id":"chatcmpl_7b3f","object":"chat.completion","model":"spicy-chat-1","choices":[{"index":0,"message":{"role":"assistant","content":"<string>"},"finish_reason":"stop"}],"usage":{"prompt_tokens":12,"completion_tokens":84,"total_tokens":96},"cost_usd":0.000055}}}},"400":{"description":"Invalid parameters. Body: {error: {message, type: 'invalid_request_error'}}."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance. Top up in the dashboard or through the get_topup_link tool; nothing was charged."},"422":{"description":"Prompt blocked by moderation (acceptable use policy). Never charged."},"429":{"description":"Model at capacity; retry in a few seconds."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"A chat model id, e.g. `spicy-chat-1`."},"messages":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","description":"`system`, `user`, or `assistant`."},"content":{"type":"string","description":"Message text."}},"required":["role","content"]},"description":"The conversation so far."},"temperature":{"type":"number","description":"Sampling temperature, 0 to 2."},"max_tokens":{"type":"integer","description":"Cap on generated tokens."},"stream":{"type":"boolean","description":"Stream back server-sent events. Usage arrives in the final chunk."}},"required":["model","messages"]}}}}}},"/api/v1/tools":{"get":{"operationId":"listTools","summary":"List every agent tool with its argument schema, whether it is guarded (needs approval_token) and whether it works with no balance.","tags":["Agent tools"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"responses":{"200":{"description":"Tool catalog","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/tools/list_models":{"post":{"operationId":"tool_list_models","summary":"List models","description":"Every model with its kind (image, image-edit, video, chat), USD price (per image, per second by resolution, or per 1M tokens), limits (sizes, resolutions, 2 to 30 seconds, outputs per call), whether it needs or accepts an input image, and example clips. Prices here are exactly what the API bills. Works with a $0 balance. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"description":"Filter by kind.","type":"string","enum":["image","image-edit","video","chat"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/estimate_cost":{"post":{"operationId":"tool_estimate_cost","summary":"Estimate cost","description":"USD cost of a request before making it, from the same price table the gateway bills: images by count, video by seconds and resolution, chat by tokens. Use it to quote the user and to check against get_account before a spend. Works with a $0 balance. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"A model id from list_models, e.g. spicy-image-1, spicy-image-1-pro, spicy-image-edit-1."},"n":{"description":"Images per call (image models). Clamped to the model's maximum.","type":"integer","minimum":1,"maximum":10},"resolution":{"description":"Video resolution, e.g. 720P (default) or 1080P.","type":"string"},"duration":{"description":"Video seconds, default 5.","type":"integer","minimum":1,"maximum":60},"tokens":{"description":"Total tokens for chat models, default 1000.","type":"integer","minimum":0,"maximum":9007199254740991},"count":{"description":"How many such requests, default 1.","type":"integer","minimum":1,"maximum":100000}},"required":["model"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/get_account":{"post":{"operationId":"tool_get_account","summary":"Get account","description":"Balance in USD, spend this calendar month, the monthly spend limit if set, whether approvals are skipped for agents, whether the account has ever topped up, the webhook URL, and whether this key is a sandbox key. Call it first and before any spend. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/list_images":{"post":{"operationId":"tool_list_images","summary":"List images","description":"The account's generated images, newest first. These are the only URLs accepted as image_url by edit_image and generate_video (no uploads, no third-party URLs). Use it to pick a first frame to animate. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"description":"Default 20.","type":"integer","minimum":1,"maximum":100}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/generate_image":{"post":{"operationId":"tool_generate_image","summary":"Generate image","description":"Text to image, synchronous (10 to 30 seconds), returns durable CDN URLs reusable as image_url for edits and video. Billed per image at the model's rate; the exact amount is cost_usd in the result. Prompts are screened first; blocked prompts cost nothing. Every request depicts adults only. Guarded: without approval_token it returns {error: \"approval_required\", summary, approval_token}; show the summary (it carries the cost), get the user's yes, call again with the token. GUARDED: without approval_token it returns {error: 'approval_required', summary, approval_token}; show the summary to the user, get a yes, call again with the token (or the account turns approvals off in the dashboard).","tags":["Agent tools","guarded"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"An image model id, e.g. spicy-image-1 (fast) or spicy-image-1-pro (best prompt adherence)."},"prompt":{"type":"string","minLength":1,"maxLength":4000},"negative_prompt":{"type":"string","maxLength":2000},"size":{"description":"width*height from the model's limits, e.g. 1024*1024 (default), 832*1216, 1216*832.","type":"string"},"n":{"description":"Images to return, default 1, clamped to the model's maximum.","type":"integer","minimum":1,"maximum":4},"seed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"approval_token":{"description":"Approval token from a previous approval_required response, after the user said yes.","type":"string"}},"required":["model","prompt"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/edit_image":{"post":{"operationId":"tool_edit_image","summary":"Edit image","description":"Prompt-driven edit of one to three images the account generated (list_images), for outfit, pose and scene changes. Synchronous; returns a durable CDN URL. Billed per edit. Guarded: without approval_token it returns {error: \"approval_required\", summary, approval_token}; show the summary (it carries the cost), get the user's yes, call again with the token. GUARDED: without approval_token it returns {error: 'approval_required', summary, approval_token}; show the summary to the user, get a yes, call again with the token (or the account turns approvals off in the dashboard).","tags":["Agent tools","guarded"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"An image-edit model id, e.g. spicy-image-edit-1."},"prompt":{"type":"string","minLength":1,"maxLength":4000,"description":"The change to make."},"image_urls":{"minItems":1,"maxItems":3,"type":"array","items":{"type":"string","format":"uri"},"description":"Source images, all from this account's own generations."},"negative_prompt":{"type":"string","maxLength":2000},"size":{"description":"Output width*height.","type":"string"},"seed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"approval_token":{"description":"Approval token from a previous approval_required response, after the user said yes.","type":"string"}},"required":["model","prompt","image_urls"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/generate_video":{"post":{"operationId":"tool_generate_video","summary":"Generate video","description":"Image to video (or text to video on spicy-motion-3 and spicy-motion-3-fast). Asynchronous: returns a task id at once with the price already debited; poll get_job every 10 to 15 seconds until succeeded (output.video_url) or failed (refunded). image_url must be one of the account's own generated images. Price = seconds x the per-second rate for the resolution. Our POV fine-tunes (spicy-pov-*) need a first frame already in position. Guarded: without approval_token it returns {error: \"approval_required\", summary, approval_token}; show the summary (it carries the cost), get the user's yes, call again with the token. GUARDED: without approval_token it returns {error: 'approval_required', summary, approval_token}; show the summary to the user, get a yes, call again with the token (or the account turns approvals off in the dashboard).","tags":["Agent tools","guarded"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"model":{"type":"string","description":"A video model id, e.g. spicy-motion-2, spicy-motion-3, spicy-pov-missionary-1."},"prompt":{"type":"string","minLength":1,"maxLength":4000,"description":"What should happen in the clip."},"image_url":{"description":"First frame, from list_images or a generate_image result. Required unless the model is text-to-video capable.","type":"string","format":"uri"},"resolution":{"description":"480P, 720P (default) or 1080P, within the model's limits.","type":"string"},"duration":{"description":"Seconds, default 5, within the model's limits.","type":"integer","minimum":2,"maximum":30},"negative_prompt":{"type":"string","maxLength":2000},"audio":{"description":"Generate audio where the model supports it.","type":"boolean"},"seed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"approval_token":{"description":"Approval token from a previous approval_required response, after the user said yes.","type":"string"}},"required":["model","prompt"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/get_job":{"post":{"operationId":"tool_get_job","summary":"Get job","description":"Status of a video task (queued, processing, finalizing, succeeded with output.video_url, or failed and refunded) or of a logged image or chat request by id. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Task or request id, e.g. sj_..."}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/list_jobs":{"post":{"operationId":"tool_list_jobs","summary":"List jobs","description":"Recent requests on the account (images, edits, video tasks, chat), newest first: id, type, model, status, cost_usd, output URL when finished, error when failed, and whether it came from the playground, the API or an agent. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"limit":{"description":"Default 20.","type":"integer","minimum":1,"maximum":100},"type":{"type":"string","enum":["image","image-edit","video","chat"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/get_usage":{"post":{"operationId":"tool_get_usage","summary":"Get usage","description":"Spend and request counts over the last N days, totalled and broken down by model, type and source (playground, api, agent), with the error count. Reads the account's request log. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"days":{"description":"Default 7.","type":"integer","minimum":1,"maximum":90}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/create_api_key":{"post":{"operationId":"tool_create_api_key","summary":"Create API key","description":"Mint a new key for this account (plaintext returned once, stored hashed; at most 20 active keys). sandbox: true makes a key that answers everything from fixtures and bills nothing. Keys made with a sandbox key are always sandbox keys. Keep keys in environment variables, never in chat. Guarded: without approval_token it returns {error: \"approval_required\", summary, approval_token}; show the summary (it carries the cost), get the user's yes, call again with the token. GUARDED: without approval_token it returns {error: 'approval_required', summary, approval_token}; show the summary to the user, get a yes, call again with the token (or the account turns approvals off in the dashboard).","tags":["Agent tools","guarded"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60,"description":"A label, e.g. Production or Agent."},"sandbox":{"description":"Fixture-only key, nothing billed. Default false.","type":"boolean"},"approval_token":{"description":"Approval token from a previous approval_required response, after the user said yes.","type":"string"}},"required":["name"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/revoke_api_key":{"post":{"operationId":"tool_revoke_api_key","summary":"Revoke API key","description":"Permanently revoke a key by id (the id is returned by create_api_key and shown on the API keys page). Applications using it stop working at once. Guarded: without approval_token it returns {error: \"approval_required\", summary, approval_token}; show the summary (it carries the cost), get the user's yes, call again with the token. GUARDED: without approval_token it returns {error: 'approval_required', summary, approval_token}; show the summary to the user, get a yes, call again with the token (or the account turns approvals off in the dashboard).","tags":["Agent tools","guarded"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","minLength":1,"description":"Key id (sha256 hash)."},"approval_token":{"description":"Approval token from a previous approval_required response, after the user said yes.","type":"string"}},"required":["id"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/get_topup_link":{"post":{"operationId":"tool_get_topup_link","summary":"Get top-up link","description":"Checkout URL to add funds by card (hosted checkout) or crypto for a preset amount ($50, $100, $250, $500, $1000; minimum $50). The USER opens it and pays in the browser; never enter payment details yourself. The balance is credited by the payment webhook; call get_account afterwards. Works with a $0 balance. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"amount_usd":{"description":"One of 50, 100, 250, 500, 1000. Default 50.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"method":{"description":"Default card.","type":"string","enum":["card","crypto"]}},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/set_spend_limit":{"post":{"operationId":"tool_set_spend_limit","summary":"Set spend limit","description":"Cap what this account can spend per calendar month (UTC), enforced at debit time on every surface: requests past the cap return 402 without charging. Lowering or setting a limit never needs approval; raising or removing one does. null removes the limit. GUARDED: without approval_token it returns {error: 'approval_required', summary, approval_token}; show the summary to the user, get a yes, call again with the token (or the account turns approvals off in the dashboard).","tags":["Agent tools","guarded"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"monthly_usd":{"anyOf":[{"type":"number","minimum":1,"maximum":1000000},{"type":"null"}],"description":"Monthly cap in USD, or null to remove it."},"approval_token":{"description":"Approval token from a previous approval_required response, after the user said yes.","type":"string"}},"required":["monthly_usd"],"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}},"/api/v1/tools/read_acceptable_use":{"post":{"operationId":"tool_read_acceptable_use","summary":"Read acceptable use policy","description":"The acceptable use policy as markdown: prohibited content (minors in any form, real people without consent, non-consensual scenarios and the rest), age-verification duties for the customer's product, enforcement. Read it before the first generation and tell the user what their product must do. Works with a $0 balance. Works with a $0 balance.","tags":["Agent tools","default"],"security":[{"apiKey":[]}],"servers":[{"url":"https://www.spicyapi.com"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"The tool's JSON result (same payload the MCP tool returns)."},"400":{"description":"Arguments failed validation; body lists the issues."},"401":{"description":"Missing or invalid API key."},"402":{"description":"Insufficient balance."},"403":{"description":"Guarded tool without a valid approval_token (body carries a fresh one)."},"429":{"description":"Rate limited (60 requests per minute per key)."}}}}}}