{
    "openapi": "3.1.0",
    "info": {
        "title": "Zappy API",
        "version": "1.0.0",
        "summary": "Create images, edits and video from your own code or from an MCP client.",
        "description": "Zappy's public generation API. One credential, one credit balance: a key spends the credits of the account that created it, and every key carries a daily cap, a per-request ceiling and a rate limit.\n\nGeneration is asynchronous. A creation call answers either 200 with a finished result, when the whole operation completed inside the request, or 202 with a job id to poll. A client must handle both.\n\nEvery response carries an `X-Request-Id` header for your own logs (quote the `job_id` to support). Responses to an authenticated key also carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds) for that key's per-minute window; a 429 adds `Retry-After`. `GET /usage` reports the key's own spend against its daily cap.\n\nCreate and manage keys in Zappy under Account -> Developer.",
        "contact": {
            "name": "Zappy support",
            "url": "https://zappyquote.com/contact.html"
        },
        "termsOfService": "https://zappyquote.com/terms.html"
    },
    "servers": [
        {
            "url": "https://zappyquote.com/api/v1",
            "description": "Production"
        }
    ],
    "externalDocs": {
        "description": "Developer documentation",
        "url": "https://zappyquote.com/developers/"
    },
    "security": [
        {
            "bearerAuth": []
        }
    ],
    "tags": [
        {
            "name": "Account",
            "description": "Balance and pricing. Nothing here spends credits."
        },
        {
            "name": "Generation",
            "description": "Creating images, edits and video. These spend credits."
        },
        {
            "name": "Results",
            "description": "Polling jobs and fetching finished assets."
        },
        {
            "name": "Recipes",
            "description": "Curated Zappy recipes. Listing and quoting spend nothing; running one is an ordinary image generation."
        },
        {
            "name": "Webhooks",
            "description": "Manage signed event delivery to your own HTTPS endpoint. API keys only (never an OAuth connection)."
        },
        {
            "name": "Agent",
            "description": "The Zappy Agent: plan a goal into up to 4 priced image steps, approve a credit budget, advance one step at a time, stop any time. Approving and advancing need the API-key-only agent:write scope."
        }
    ],
    "paths": {
        "/agent/plan": {
            "post": {
                "tags": [
                    "Agent"
                ],
                "operationId": "planAgentRun",
                "summary": "Plan a goal into priced image steps (spends nothing)",
                "description": "Requires `billing:read`. The agent picks the best-matching API-runnable recipe, composes the direction, plans 1-4 variation steps and prices each from the live price list. Deterministic: the same body always gives the same plan.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "goal"
                                ],
                                "properties": {
                                    "goal": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 120,
                                        "description": "What you want made, in a few words. No links or web addresses."
                                    },
                                    "variants": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 4,
                                        "default": 1,
                                        "description": "How many distinct images (one step each)."
                                    },
                                    "recipe": {
                                        "type": "string",
                                        "pattern": "^[a-z0-9-]{1,64}$",
                                        "description": "Optional: an API-runnable recipe slug. Omitted = the agent picks the best match for the goal."
                                    },
                                    "inputs": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string"
                                        },
                                        "description": "Optional: the recipe inputs. Omitted = every input is filled from the goal."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The plan.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "plan",
                                        "credits_quoted"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "plan": {
                                            "type": "object"
                                        },
                                        "credits_quoted": {
                                            "type": "integer"
                                        },
                                        "next": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/agent/runs": {
            "get": {
                "tags": [
                    "Agent"
                ],
                "operationId": "listAgentRuns",
                "summary": "Your agent runs (newest first)",
                "description": "Requires `generation:read`. Works while the agent is closed.",
                "responses": {
                    "200": {
                        "description": "Runs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "runs"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "agent_on": {
                                            "type": "boolean"
                                        },
                                        "runs": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "run_id": {
                                                        "type": "string",
                                                        "pattern": "^ar_[a-f0-9]{16}$"
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "enum": [
                                                            "running",
                                                            "completed",
                                                            "failed",
                                                            "stopped",
                                                            "budget_exhausted"
                                                        ]
                                                    },
                                                    "reason": {
                                                        "type": [
                                                            "string",
                                                            "null"
                                                        ]
                                                    },
                                                    "goal": {
                                                        "type": "string"
                                                    },
                                                    "recipe": {
                                                        "type": "string"
                                                    },
                                                    "why": {
                                                        "type": "string"
                                                    },
                                                    "max_credits_total": {
                                                        "type": "integer"
                                                    },
                                                    "credits_planned": {
                                                        "type": "integer"
                                                    },
                                                    "credits_spent": {
                                                        "type": "integer"
                                                    },
                                                    "next_step": {
                                                        "type": [
                                                            "integer",
                                                            "null"
                                                        ],
                                                        "description": "The step to send to advance next, or null."
                                                    },
                                                    "steps": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object",
                                                            "properties": {
                                                                "n": {
                                                                    "type": "integer"
                                                                },
                                                                "status": {
                                                                    "type": "string",
                                                                    "enum": [
                                                                        "pending",
                                                                        "dispatched",
                                                                        "processing",
                                                                        "succeeded",
                                                                        "failed",
                                                                        "not_admitted",
                                                                        "conflict"
                                                                    ]
                                                                },
                                                                "direction": {
                                                                    "type": "string"
                                                                },
                                                                "credits_quoted": {
                                                                    "type": "integer"
                                                                },
                                                                "credits_charged": {
                                                                    "type": [
                                                                        "integer",
                                                                        "null"
                                                                    ]
                                                                },
                                                                "job_id": {
                                                                    "type": [
                                                                        "string",
                                                                        "null"
                                                                    ]
                                                                }
                                                            }
                                                        }
                                                    },
                                                    "events": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "object"
                                                        }
                                                    },
                                                    "created_at": {
                                                        "type": "string"
                                                    },
                                                    "updated_at": {
                                                        "type": "string"
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    }
                }
            },
            "post": {
                "tags": [
                    "Agent"
                ],
                "operationId": "createAgentRun",
                "summary": "Approve a plan: create a running run within a credit budget",
                "description": "Requires `generation:write` and `agent:write` (API keys only). Re-plans server-side from the same body; refuses a budget below the planned total. One running run per account. The run is bound to this key.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "goal",
                                    "max_credits_total",
                                    "approve"
                                ],
                                "properties": {
                                    "goal": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 120,
                                        "description": "What you want made, in a few words. No links or web addresses."
                                    },
                                    "variants": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 4,
                                        "default": 1,
                                        "description": "How many distinct images (one step each)."
                                    },
                                    "recipe": {
                                        "type": "string",
                                        "pattern": "^[a-z0-9-]{1,64}$",
                                        "description": "Optional: an API-runnable recipe slug. Omitted = the agent picks the best match for the goal."
                                    },
                                    "inputs": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string"
                                        },
                                        "description": "Optional: the recipe inputs. Omitted = every input is filled from the goal."
                                    },
                                    "max_credits_total": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "description": "The most the WHOLE run may spend. Must be at least the planned total."
                                    },
                                    "approve": {
                                        "type": "boolean",
                                        "const": true,
                                        "description": "Your approval of the plan and budget."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Approved and running.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "run"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "run": {
                                            "type": "object",
                                            "properties": {
                                                "run_id": {
                                                    "type": "string",
                                                    "pattern": "^ar_[a-f0-9]{16}$"
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "enum": [
                                                        "running",
                                                        "completed",
                                                        "failed",
                                                        "stopped",
                                                        "budget_exhausted"
                                                    ]
                                                },
                                                "reason": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ]
                                                },
                                                "goal": {
                                                    "type": "string"
                                                },
                                                "recipe": {
                                                    "type": "string"
                                                },
                                                "why": {
                                                    "type": "string"
                                                },
                                                "max_credits_total": {
                                                    "type": "integer"
                                                },
                                                "credits_planned": {
                                                    "type": "integer"
                                                },
                                                "credits_spent": {
                                                    "type": "integer"
                                                },
                                                "next_step": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "description": "The step to send to advance next, or null."
                                                },
                                                "steps": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "n": {
                                                                "type": "integer"
                                                            },
                                                            "status": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "pending",
                                                                    "dispatched",
                                                                    "processing",
                                                                    "succeeded",
                                                                    "failed",
                                                                    "not_admitted",
                                                                    "conflict"
                                                                ]
                                                            },
                                                            "direction": {
                                                                "type": "string"
                                                            },
                                                            "credits_quoted": {
                                                                "type": "integer"
                                                            },
                                                            "credits_charged": {
                                                                "type": [
                                                                    "integer",
                                                                    "null"
                                                                ]
                                                            },
                                                            "job_id": {
                                                                "type": [
                                                                    "string",
                                                                    "null"
                                                                ]
                                                            }
                                                        }
                                                    }
                                                },
                                                "events": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    }
                                                },
                                                "created_at": {
                                                    "type": "string"
                                                },
                                                "updated_at": {
                                                    "type": "string"
                                                }
                                            }
                                        },
                                        "next": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/agent/runs/{run_id}": {
            "get": {
                "tags": [
                    "Agent"
                ],
                "operationId": "getAgentRun",
                "summary": "One run with its steps and audit log",
                "description": "Requires `generation:read`.",
                "parameters": [
                    {
                        "name": "run_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^ar_[a-f0-9]{16}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The run.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "run"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "run": {
                                            "type": "object",
                                            "properties": {
                                                "run_id": {
                                                    "type": "string",
                                                    "pattern": "^ar_[a-f0-9]{16}$"
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "enum": [
                                                        "running",
                                                        "completed",
                                                        "failed",
                                                        "stopped",
                                                        "budget_exhausted"
                                                    ]
                                                },
                                                "reason": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ]
                                                },
                                                "goal": {
                                                    "type": "string"
                                                },
                                                "recipe": {
                                                    "type": "string"
                                                },
                                                "why": {
                                                    "type": "string"
                                                },
                                                "max_credits_total": {
                                                    "type": "integer"
                                                },
                                                "credits_planned": {
                                                    "type": "integer"
                                                },
                                                "credits_spent": {
                                                    "type": "integer"
                                                },
                                                "next_step": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "description": "The step to send to advance next, or null."
                                                },
                                                "steps": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "n": {
                                                                "type": "integer"
                                                            },
                                                            "status": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "pending",
                                                                    "dispatched",
                                                                    "processing",
                                                                    "succeeded",
                                                                    "failed",
                                                                    "not_admitted",
                                                                    "conflict"
                                                                ]
                                                            },
                                                            "direction": {
                                                                "type": "string"
                                                            },
                                                            "credits_quoted": {
                                                                "type": "integer"
                                                            },
                                                            "credits_charged": {
                                                                "type": [
                                                                    "integer",
                                                                    "null"
                                                                ]
                                                            },
                                                            "job_id": {
                                                                "type": [
                                                                    "string",
                                                                    "null"
                                                                ]
                                                            }
                                                        }
                                                    }
                                                },
                                                "events": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    }
                                                },
                                                "created_at": {
                                                    "type": "string"
                                                },
                                                "updated_at": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    }
                }
            }
        },
        "/agent/runs/{run_id}/advance": {
            "post": {
                "tags": [
                    "Agent"
                ],
                "operationId": "advanceAgentRun",
                "summary": "Start step N of a run (spends credits)",
                "description": "Requires `generation:write` and `agent:write`, with the key that approved the run. Send `{\"step\": N}` (the run's `next_step`). Starts step N ONLY, exactly as `POST /images` (same quote, key and daily caps, margin floor) with the remaining budget as its ceiling. **Repeating the same step never starts anything else**: once step N is started, the call answers the run with step N's `job_id` (a lost response is recovered by sending the same step again). Answers the started step's job (`200`/`202`, as `POST /images`) when this call started it. Steps run in order (`409 step_out_of_order`). A failed, not-admitted or conflicting step ends the run - nothing is retried automatically.",
                "parameters": [
                    {
                        "name": "run_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^ar_[a-f0-9]{16}$"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "step"
                                ],
                                "additionalProperties": false,
                                "properties": {
                                    "step": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 4
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The run with step N's job (nothing new started), or the started step's finished job.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "run": {
                                            "type": "object",
                                            "properties": {
                                                "run_id": {
                                                    "type": "string",
                                                    "pattern": "^ar_[a-f0-9]{16}$"
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "enum": [
                                                        "running",
                                                        "completed",
                                                        "failed",
                                                        "stopped",
                                                        "budget_exhausted"
                                                    ]
                                                },
                                                "reason": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ]
                                                },
                                                "goal": {
                                                    "type": "string"
                                                },
                                                "recipe": {
                                                    "type": "string"
                                                },
                                                "why": {
                                                    "type": "string"
                                                },
                                                "max_credits_total": {
                                                    "type": "integer"
                                                },
                                                "credits_planned": {
                                                    "type": "integer"
                                                },
                                                "credits_spent": {
                                                    "type": "integer"
                                                },
                                                "next_step": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "description": "The step to send to advance next, or null."
                                                },
                                                "steps": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "n": {
                                                                "type": "integer"
                                                            },
                                                            "status": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "pending",
                                                                    "dispatched",
                                                                    "processing",
                                                                    "succeeded",
                                                                    "failed",
                                                                    "not_admitted",
                                                                    "conflict"
                                                                ]
                                                            },
                                                            "direction": {
                                                                "type": "string"
                                                            },
                                                            "credits_quoted": {
                                                                "type": "integer"
                                                            },
                                                            "credits_charged": {
                                                                "type": [
                                                                    "integer",
                                                                    "null"
                                                                ]
                                                            },
                                                            "job_id": {
                                                                "type": [
                                                                    "string",
                                                                    "null"
                                                                ]
                                                            }
                                                        }
                                                    }
                                                },
                                                "events": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    }
                                                },
                                                "created_at": {
                                                    "type": "string"
                                                },
                                                "updated_at": {
                                                    "type": "string"
                                                }
                                            }
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string"
                                        },
                                        "next": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "The started step's job, accepted. Poll it or advance again later.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "job_id",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "402": {
                        "$ref": "#/components/responses/E402"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "502": {
                        "$ref": "#/components/responses/E502"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/agent/runs/{run_id}/stop": {
            "post": {
                "tags": [
                    "Agent"
                ],
                "operationId": "stopAgentRun",
                "summary": "Stop a run now",
                "description": "Requires `agent:write`. Always available, even while the agent is closed. A step already admitted finishes and settles as usual.",
                "parameters": [
                    {
                        "name": "run_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^ar_[a-f0-9]{16}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Stopped (or already finished).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "run"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "run": {
                                            "type": "object",
                                            "properties": {
                                                "run_id": {
                                                    "type": "string",
                                                    "pattern": "^ar_[a-f0-9]{16}$"
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "enum": [
                                                        "running",
                                                        "completed",
                                                        "failed",
                                                        "stopped",
                                                        "budget_exhausted"
                                                    ]
                                                },
                                                "reason": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ]
                                                },
                                                "goal": {
                                                    "type": "string"
                                                },
                                                "recipe": {
                                                    "type": "string"
                                                },
                                                "why": {
                                                    "type": "string"
                                                },
                                                "max_credits_total": {
                                                    "type": "integer"
                                                },
                                                "credits_planned": {
                                                    "type": "integer"
                                                },
                                                "credits_spent": {
                                                    "type": "integer"
                                                },
                                                "next_step": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "description": "The step to send to advance next, or null."
                                                },
                                                "steps": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "n": {
                                                                "type": "integer"
                                                            },
                                                            "status": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "pending",
                                                                    "dispatched",
                                                                    "processing",
                                                                    "succeeded",
                                                                    "failed",
                                                                    "not_admitted",
                                                                    "conflict"
                                                                ]
                                                            },
                                                            "direction": {
                                                                "type": "string"
                                                            },
                                                            "credits_quoted": {
                                                                "type": "integer"
                                                            },
                                                            "credits_charged": {
                                                                "type": [
                                                                    "integer",
                                                                    "null"
                                                                ]
                                                            },
                                                            "job_id": {
                                                                "type": [
                                                                    "string",
                                                                    "null"
                                                                ]
                                                            }
                                                        }
                                                    }
                                                },
                                                "events": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    }
                                                },
                                                "created_at": {
                                                    "type": "string"
                                                },
                                                "updated_at": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/assets/{asset_id}": {
            "get": {
                "tags": [
                    "Results"
                ],
                "operationId": "getAsset",
                "summary": "A short-lived signed URL for a finished asset",
                "description": "Requires `assets:read`. The asset must exist, belong to you, be durable and still match its recorded digest. A missing asset and another account's asset answer identically, so this is not an id oracle. The URL is short-lived: fetch it, do not store it.",
                "parameters": [
                    {
                        "name": "asset_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The signed delivery.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "asset_id",
                                        "url"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "asset_id": {
                                            "type": "string"
                                        },
                                        "url": {
                                            "type": "string",
                                            "format": "uri"
                                        },
                                        "expires_at": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/balance": {
            "get": {
                "tags": [
                    "Account"
                ],
                "operationId": "getBalance",
                "summary": "Credits available to this account",
                "description": "Requires the `billing:read` scope. `daily_free` is the free allowance included today.",
                "responses": {
                    "200": {
                        "description": "The account balance.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "balance"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "balance": {
                                            "type": "integer",
                                            "minimum": 0
                                        },
                                        "daily_free": {
                                            "type": "integer",
                                            "minimum": 0
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/capabilities": {
            "get": {
                "tags": [
                    "Account"
                ],
                "operationId": "listCapabilities",
                "summary": "What this API can make, and what each one costs right now",
                "description": "Returns only capabilities that have an API operation, each naming the operation that buys it. Credit costs are live: read them here rather than hard-coding them.",
                "responses": {
                    "200": {
                        "description": "The callable capability catalogue.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "capabilities"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "capabilities": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "required": [
                                                    "capability",
                                                    "credits",
                                                    "unit",
                                                    "operation",
                                                    "callable",
                                                    "async"
                                                ],
                                                "properties": {
                                                    "capability": {
                                                        "type": "string",
                                                        "enum": [
                                                            "zappy-image-pro",
                                                            "zappy-image-edit"
                                                        ]
                                                    },
                                                    "credits": {
                                                        "type": "integer",
                                                        "minimum": 0
                                                    },
                                                    "unit": {
                                                        "type": "string",
                                                        "examples": [
                                                            "per_generation"
                                                        ]
                                                    },
                                                    "operation": {
                                                        "type": "string",
                                                        "examples": [
                                                            "POST /api/v1/images"
                                                        ]
                                                    },
                                                    "callable": {
                                                        "type": "boolean"
                                                    },
                                                    "async": {
                                                        "type": "boolean"
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/creations": {
            "get": {
                "tags": [
                    "Results"
                ],
                "operationId": "listCreations",
                "summary": "This account's recent creations",
                "description": "Requires `generation:read`.",
                "responses": {
                    "200": {
                        "description": "The creations page.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "creations"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "creations": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "asset_id": {
                                                        "type": "string"
                                                    },
                                                    "capability": {
                                                        "type": "string"
                                                    },
                                                    "created_at": {
                                                        "type": "string",
                                                        "format": "date-time"
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/images": {
            "post": {
                "tags": [
                    "Generation"
                ],
                "operationId": "createImages",
                "summary": "Create with `zappy-image-pro`",
                "description": "Spends credits. Requires `generation:write`.\n\n**Send `Idempotency-Key`.** A retry carrying the same key returns the original job instead of dispatching a second generation, so a network timeout or an agent retry cannot charge you twice. Reusing a key with a different body is refused with `idempotency_conflict`.\n\nAnswers 200 when the whole operation finished inside the request, 202 otherwise - handle both. A failed generation is not charged.",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "description": "One unique value per logical request; retries of that request reuse it.",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100,
                            "pattern": "^[A-Za-z0-9._:\\-]{1,100}$"
                        }
                    },
                    {
                        "name": "X-Zappy-Client-Type",
                        "in": "header",
                        "required": false,
                        "description": "Optional attribution only. Authenticates nothing and changes no price, cap, scope or route.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "api",
                                "mcp",
                                "cli",
                                "sdk"
                            ]
                        }
                    },
                    {
                        "name": "X-Zappy-Client-Name",
                        "in": "header",
                        "required": false,
                        "description": "Optional attribution only.",
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "prompt"
                                ],
                                "properties": {
                                    "prompt": {
                                        "type": "string",
                                        "minLength": 1,
                                        "description": "What to make."
                                    },
                                    "max_credits": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "description": "Refuse the call if the quote exceeds this. It can only LOWER your key ceiling, never raise it."
                                    }
                                },
                                "additionalProperties": false
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Finished inside the request. There is nothing to poll.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "job_id",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "succeeded"
                                            ]
                                        },
                                        "capability": {
                                            "type": "string",
                                            "enum": [
                                                "zappy-image-pro"
                                            ]
                                        },
                                        "credits_quoted": {
                                            "type": "integer"
                                        },
                                        "credits_charged": {
                                            "type": "integer"
                                        },
                                        "asset_id": {
                                            "type": "string"
                                        },
                                        "created_at": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "Accepted. Poll `GET /jobs/{job_id}` and honour `Retry-After`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "job_id",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "accepted",
                                                "processing"
                                            ]
                                        },
                                        "capability": {
                                            "type": "string",
                                            "enum": [
                                                "zappy-image-pro"
                                            ]
                                        },
                                        "credits_quoted": {
                                            "type": "integer"
                                        },
                                        "created_at": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "402": {
                        "$ref": "#/components/responses/E402"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "502": {
                        "$ref": "#/components/responses/E502"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/images/edit": {
            "post": {
                "tags": [
                    "Generation"
                ],
                "operationId": "createImagesEdit",
                "summary": "Create with `zappy-image-edit`",
                "description": "Spends credits. Requires `generation:write`.\n\n**Send `Idempotency-Key`.** A retry carrying the same key returns the original job instead of dispatching a second generation, so a network timeout or an agent retry cannot charge you twice. Reusing a key with a different body is refused with `idempotency_conflict`.\n\nAnswers 200 when the whole operation finished inside the request, 202 otherwise - handle both. A failed generation is not charged.",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "description": "One unique value per logical request; retries of that request reuse it.",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100,
                            "pattern": "^[A-Za-z0-9._:\\-]{1,100}$"
                        }
                    },
                    {
                        "name": "X-Zappy-Client-Type",
                        "in": "header",
                        "required": false,
                        "description": "Optional attribution only. Authenticates nothing and changes no price, cap, scope or route.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "api",
                                "mcp",
                                "cli",
                                "sdk"
                            ]
                        }
                    },
                    {
                        "name": "X-Zappy-Client-Name",
                        "in": "header",
                        "required": false,
                        "description": "Optional attribution only.",
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-z0-9][a-z0-9._-]{0,63}$"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "prompt",
                                    "source_asset_id"
                                ],
                                "properties": {
                                    "prompt": {
                                        "type": "string",
                                        "minLength": 1,
                                        "description": "The change to make."
                                    },
                                    "source_asset_id": {
                                        "type": "string",
                                        "description": "An asset this account owns."
                                    },
                                    "max_credits": {
                                        "type": "integer",
                                        "minimum": 1
                                    }
                                },
                                "additionalProperties": false
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Finished inside the request. There is nothing to poll.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "job_id",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "succeeded"
                                            ]
                                        },
                                        "capability": {
                                            "type": "string",
                                            "enum": [
                                                "zappy-image-edit"
                                            ]
                                        },
                                        "credits_quoted": {
                                            "type": "integer"
                                        },
                                        "credits_charged": {
                                            "type": "integer"
                                        },
                                        "asset_id": {
                                            "type": "string"
                                        },
                                        "created_at": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "Accepted. Poll `GET /jobs/{job_id}` and honour `Retry-After`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "job_id",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "accepted",
                                                "processing"
                                            ]
                                        },
                                        "capability": {
                                            "type": "string",
                                            "enum": [
                                                "zappy-image-edit"
                                            ]
                                        },
                                        "credits_quoted": {
                                            "type": "integer"
                                        },
                                        "created_at": {
                                            "type": "string",
                                            "format": "date-time"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "402": {
                        "$ref": "#/components/responses/E402"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "502": {
                        "$ref": "#/components/responses/E502"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/jobs/{job_id}": {
            "get": {
                "tags": [
                    "Results"
                ],
                "operationId": "getJob",
                "summary": "Poll an asynchronous generation",
                "description": "Requires `generation:read`. While work is in flight the response carries `Retry-After`; honour it rather than polling in a tight loop. A job whose provider finished but whose asset is not yet contained reports `processing` with reason `delivery_pending` - it is not failed, and must not be retried as a new call.",
                "parameters": [
                    {
                        "name": "job_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The job.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "job_id",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "accepted",
                                                "processing",
                                                "succeeded",
                                                "failed",
                                                "cancelled"
                                            ]
                                        },
                                        "reason": {
                                            "type": "string",
                                            "enum": [
                                                "delivery_pending"
                                            ],
                                            "description": "Present only while `status` is `processing` and the asset is still being contained."
                                        },
                                        "capability": {
                                            "type": "string",
                                            "enum": [
                                                "zappy-image-pro",
                                                "zappy-image-edit"
                                            ]
                                        },
                                        "credits_quoted": {
                                            "type": "integer"
                                        },
                                        "credits_charged": {
                                            "type": "integer",
                                            "description": "Present once the job settled. A failed generation is not charged."
                                        },
                                        "asset_id": {
                                            "type": "string",
                                            "description": "Present once a durable asset exists."
                                        },
                                        "created_at": {
                                            "type": "string",
                                            "format": "date-time"
                                        },
                                        "error": {
                                            "type": "object",
                                            "properties": {
                                                "code": {
                                                    "type": "string"
                                                },
                                                "message": {
                                                    "type": "string"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/quote": {
            "post": {
                "tags": [
                    "Account"
                ],
                "operationId": "quote",
                "summary": "What a call would cost, without spending anything",
                "description": "The one paid-shaped route that spends nothing. Quote before you generate when the cost matters. Requires the `billing:read` scope.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "capability"
                                ],
                                "properties": {
                                    "capability": {
                                        "type": "string",
                                        "enum": [
                                            "zappy-image-pro",
                                            "zappy-image-edit"
                                        ]
                                    },
                                    "duration": {
                                        "type": "integer",
                                        "description": "Seconds, for a video capability that prices by duration."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The quote.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "capability",
                                        "credits_quoted"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "capability": {
                                            "type": "string",
                                            "enum": [
                                                "zappy-image-pro",
                                                "zappy-image-edit"
                                            ]
                                        },
                                        "credits_quoted": {
                                            "type": "integer",
                                            "minimum": 0
                                        },
                                        "balance": {
                                            "type": "integer",
                                            "minimum": 0
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/recipes": {
            "get": {
                "tags": [
                    "Recipes"
                ],
                "operationId": "listRecipes",
                "summary": "The live recipe catalogue",
                "description": "Any valid key. Each recipe says whether it runs through this API (`api.runnable`); a recipe that does not runs in the Zappy Studio at `studio_url`.",
                "responses": {
                    "200": {
                        "description": "The catalogue.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "recipes"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "recipes": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "slug": {
                                                        "type": "string"
                                                    },
                                                    "version": {
                                                        "type": "integer"
                                                    },
                                                    "title": {
                                                        "type": "string"
                                                    },
                                                    "summary": {
                                                        "type": "string"
                                                    },
                                                    "category": {
                                                        "type": "string"
                                                    },
                                                    "outputs": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "string"
                                                        }
                                                    },
                                                    "from_credits": {
                                                        "type": [
                                                            "integer",
                                                            "null"
                                                        ]
                                                    },
                                                    "url": {
                                                        "type": "string"
                                                    },
                                                    "studio_url": {
                                                        "type": "string"
                                                    },
                                                    "inputs": {
                                                        "type": "object",
                                                        "additionalProperties": {
                                                            "type": "string"
                                                        },
                                                        "description": "input key -> human label"
                                                    },
                                                    "api": {
                                                        "type": "object",
                                                        "properties": {
                                                            "runnable": {
                                                                "type": "boolean"
                                                            },
                                                            "capability": {
                                                                "type": [
                                                                    "string",
                                                                    "null"
                                                                ]
                                                            },
                                                            "aspect_ratio": {
                                                                "type": [
                                                                    "string",
                                                                    "null"
                                                                ]
                                                            },
                                                            "note": {
                                                                "type": "string"
                                                            },
                                                            "inputs": {
                                                                "type": "object",
                                                                "additionalProperties": {
                                                                    "type": "string"
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/recipes/{slug}": {
            "get": {
                "tags": [
                    "Recipes"
                ],
                "operationId": "getRecipe",
                "summary": "One recipe",
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-z0-9-]{1,64}$"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The recipe.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "recipe"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "recipe": {
                                            "type": "object",
                                            "properties": {
                                                "slug": {
                                                    "type": "string"
                                                },
                                                "version": {
                                                    "type": "integer"
                                                },
                                                "title": {
                                                    "type": "string"
                                                },
                                                "summary": {
                                                    "type": "string"
                                                },
                                                "category": {
                                                    "type": "string"
                                                },
                                                "outputs": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    }
                                                },
                                                "from_credits": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ]
                                                },
                                                "url": {
                                                    "type": "string"
                                                },
                                                "studio_url": {
                                                    "type": "string"
                                                },
                                                "inputs": {
                                                    "type": "object",
                                                    "additionalProperties": {
                                                        "type": "string"
                                                    },
                                                    "description": "input key -> human label"
                                                },
                                                "api": {
                                                    "type": "object",
                                                    "properties": {
                                                        "runnable": {
                                                            "type": "boolean"
                                                        },
                                                        "capability": {
                                                            "type": [
                                                                "string",
                                                                "null"
                                                            ]
                                                        },
                                                        "aspect_ratio": {
                                                            "type": [
                                                                "string",
                                                                "null"
                                                            ]
                                                        },
                                                        "note": {
                                                            "type": "string"
                                                        },
                                                        "inputs": {
                                                            "type": "object",
                                                            "additionalProperties": {
                                                                "type": "string"
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/recipes/{slug}/quote": {
            "post": {
                "tags": [
                    "Recipes"
                ],
                "operationId": "quoteRecipe",
                "summary": "Compose a recipe with your inputs and quote it (spends nothing)",
                "description": "Requires `billing:read`. Returns the composed direction and the credits a run would be quoted at.",
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-z0-9-]{1,64}$"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "inputs"
                                ],
                                "additionalProperties": false,
                                "properties": {
                                    "inputs": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string",
                                            "maxLength": 120
                                        },
                                        "description": "One value per recipe input (see the recipe's `api.inputs`). Every input is required."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The quote.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "recipe",
                                        "credits_quoted"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "recipe": {
                                            "type": "string"
                                        },
                                        "capability": {
                                            "type": "string"
                                        },
                                        "credits_quoted": {
                                            "type": "integer"
                                        },
                                        "direction": {
                                            "type": "string"
                                        },
                                        "aspect_ratio": {
                                            "type": [
                                                "string",
                                                "null"
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/recipes/{slug}/run": {
            "post": {
                "tags": [
                    "Recipes"
                ],
                "operationId": "runRecipe",
                "summary": "Run a recipe (spends credits)",
                "description": "Requires `generation:write`. Exactly `POST /images` with the recipe's direction and framing: the same quote, ceilings, daily cap, idempotency and job polling. You cannot send your own prompt. **Send `Idempotency-Key`.**",
                "parameters": [
                    {
                        "name": "slug",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-z0-9-]{1,64}$"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 100,
                            "pattern": "^[A-Za-z0-9._:\\-]{1,100}$"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "inputs",
                                    "max_credits"
                                ],
                                "additionalProperties": false,
                                "properties": {
                                    "inputs": {
                                        "type": "object",
                                        "additionalProperties": {
                                            "type": "string",
                                            "maxLength": 120
                                        },
                                        "description": "One value per recipe input (see the recipe's `api.inputs`). Every input is required."
                                    },
                                    "max_credits": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "description": "Required. Refuse the run if the quote exceeds this."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Finished inside the request.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "job_id",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string"
                                        },
                                        "asset_id": {
                                            "type": "string"
                                        },
                                        "credits_charged": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "Accepted. Poll `GET /jobs/{job_id}`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "job_id",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "job_id": {
                                            "type": "string"
                                        },
                                        "status": {
                                            "type": "string"
                                        },
                                        "credits_quoted": {
                                            "type": "integer"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "402": {
                        "$ref": "#/components/responses/E402"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "502": {
                        "$ref": "#/components/responses/E502"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/usage": {
            "get": {
                "tags": [
                    "Account"
                ],
                "operationId": "getUsage",
                "summary": "This key's usage today, against its own limits",
                "description": "Requires the `billing:read` scope. Describes only the key that made the call. `credits_spent_today` is the figure the daily cap is enforced against (charges plus outstanding reservations). A figure that cannot be read right now is `null`, never 0; a limit that is not set is `null`.",
                "responses": {
                    "200": {
                        "description": "Usage for the calling key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "usage"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "usage": {
                                            "type": "object",
                                            "required": [
                                                "key_prefix",
                                                "credits_spent_today",
                                                "daily_credits_cap",
                                                "credits_remaining_today",
                                                "max_credits_per_request",
                                                "rate_limit_per_min",
                                                "jobs_today"
                                            ],
                                            "properties": {
                                                "key_prefix": {
                                                    "type": "string",
                                                    "description": "The non-secret start of the key, as shown in Account -> Developer."
                                                },
                                                "credits_spent_today": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "minimum": 0
                                                },
                                                "daily_credits_cap": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "minimum": 0
                                                },
                                                "credits_remaining_today": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "minimum": 0
                                                },
                                                "max_credits_per_request": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "minimum": 0
                                                },
                                                "rate_limit_per_min": {
                                                    "type": [
                                                        "integer",
                                                        "null"
                                                    ],
                                                    "minimum": 0
                                                },
                                                "jobs_today": {
                                                    "type": [
                                                        "object",
                                                        "null"
                                                    ],
                                                    "properties": {
                                                        "succeeded": {
                                                            "type": "integer",
                                                            "minimum": 0
                                                        },
                                                        "failed": {
                                                            "type": "integer",
                                                            "minimum": 0
                                                        },
                                                        "processing": {
                                                            "type": "integer",
                                                            "minimum": 0
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/webhooks": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "listWebhooks",
                "summary": "Your webhook endpoints and recent deliveries",
                "description": "Requires `webhooks:read` (API keys only).",
                "responses": {
                    "200": {
                        "description": "Webhook state.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "endpoints"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "webhooks_on": {
                                            "type": "boolean"
                                        },
                                        "event_types": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            }
                                        },
                                        "max_endpoints": {
                                            "type": "integer"
                                        },
                                        "endpoints": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "id": {
                                                        "type": "string",
                                                        "pattern": "^we_[a-f0-9]{16}$"
                                                    },
                                                    "destination_url": {
                                                        "type": "string",
                                                        "format": "uri"
                                                    },
                                                    "events": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "string",
                                                            "enum": [
                                                                "job.completed",
                                                                "job.failed",
                                                                "asset.ready",
                                                                "request.refunded"
                                                            ]
                                                        }
                                                    },
                                                    "status": {
                                                        "type": "string",
                                                        "enum": [
                                                            "active",
                                                            "paused",
                                                            "revoked"
                                                        ]
                                                    },
                                                    "fingerprint": {
                                                        "type": "string"
                                                    },
                                                    "created_at": {
                                                        "type": "string"
                                                    },
                                                    "updated_at": {
                                                        "type": "string"
                                                    }
                                                }
                                            }
                                        },
                                        "deliveries": {
                                            "type": "array",
                                            "items": {
                                                "type": "object"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            },
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "createWebhook",
                "summary": "Add an endpoint (the signing secret is returned once)",
                "description": "Requires `webhooks:write` (API keys only). The destination must be a public `https://` URL. A second create for a URL a live endpoint already uses answers `409 endpoint_exists`.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "url",
                                    "events"
                                ],
                                "additionalProperties": false,
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "format": "uri"
                                    },
                                    "events": {
                                        "type": "array",
                                        "minItems": 1,
                                        "items": {
                                            "type": "string",
                                            "enum": [
                                                "job.completed",
                                                "job.failed",
                                                "asset.ready",
                                                "request.refunded"
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "endpoint",
                                        "secret"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "endpoint": {
                                            "type": "object",
                                            "properties": {
                                                "id": {
                                                    "type": "string",
                                                    "pattern": "^we_[a-f0-9]{16}$"
                                                },
                                                "destination_url": {
                                                    "type": "string",
                                                    "format": "uri"
                                                },
                                                "events": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string",
                                                        "enum": [
                                                            "job.completed",
                                                            "job.failed",
                                                            "asset.ready",
                                                            "request.refunded"
                                                        ]
                                                    }
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "enum": [
                                                        "active",
                                                        "paused",
                                                        "revoked"
                                                    ]
                                                },
                                                "fingerprint": {
                                                    "type": "string"
                                                },
                                                "created_at": {
                                                    "type": "string"
                                                },
                                                "updated_at": {
                                                    "type": "string"
                                                }
                                            }
                                        },
                                        "secret": {
                                            "type": "string"
                                        },
                                        "secret_note": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "409": {
                        "$ref": "#/components/responses/E409"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/webhooks/{endpoint_id}/redeliver": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "redeliverWebhook",
                "summary": "Queue one event for redelivery to an endpoint",
                "description": "Requires `webhooks:write`. Rate limited.",
                "parameters": [
                    {
                        "name": "endpoint_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^we_[a-f0-9]{16}$"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "event_id"
                                ],
                                "properties": {
                                    "event_id": {
                                        "type": "string"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Queued.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "status": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        },
        "/webhooks/{endpoint_id}/{action}": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "changeWebhook",
                "summary": "Pause, resume, rotate (new secret, once) or revoke an endpoint",
                "description": "Requires `webhooks:write`. Revoke is final.",
                "parameters": [
                    {
                        "name": "endpoint_id",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "pattern": "^we_[a-f0-9]{16}$"
                        }
                    },
                    {
                        "name": "action",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pause",
                                "resume",
                                "rotate",
                                "revoke"
                            ]
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Applied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "status"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ]
                                        },
                                        "status": {
                                            "type": "string"
                                        },
                                        "endpoint": {
                                            "type": "object",
                                            "properties": {
                                                "id": {
                                                    "type": "string",
                                                    "pattern": "^we_[a-f0-9]{16}$"
                                                },
                                                "destination_url": {
                                                    "type": "string",
                                                    "format": "uri"
                                                },
                                                "events": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string",
                                                        "enum": [
                                                            "job.completed",
                                                            "job.failed",
                                                            "asset.ready",
                                                            "request.refunded"
                                                        ]
                                                    }
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "enum": [
                                                        "active",
                                                        "paused",
                                                        "revoked"
                                                    ]
                                                },
                                                "fingerprint": {
                                                    "type": "string"
                                                },
                                                "created_at": {
                                                    "type": "string"
                                                },
                                                "updated_at": {
                                                    "type": "string"
                                                }
                                            }
                                        },
                                        "secret": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "400": {
                        "$ref": "#/components/responses/E400"
                    },
                    "401": {
                        "$ref": "#/components/responses/E401"
                    },
                    "403": {
                        "$ref": "#/components/responses/E403"
                    },
                    "404": {
                        "$ref": "#/components/responses/E404"
                    },
                    "429": {
                        "$ref": "#/components/responses/E429"
                    },
                    "503": {
                        "$ref": "#/components/responses/E503"
                    }
                }
            }
        }
    },
    "components": {
        "securitySchemes": {
            "bearerAuth": {
                "type": "http",
                "scheme": "bearer",
                "description": "Your Zappy API key: `Authorization: Bearer zp_live_...`. A website session cookie is never accepted."
            }
        },
        "schemas": {
            "Error": {
                "type": "object",
                "required": [
                    "ok",
                    "error"
                ],
                "properties": {
                    "ok": {
                        "type": "boolean",
                        "enum": [
                            false
                        ]
                    },
                    "error": {
                        "type": "object",
                        "required": [
                            "code",
                            "message"
                        ],
                        "properties": {
                            "code": {
                                "type": "string",
                                "enum": [
                                    "agent_unavailable",
                                    "approval_required",
                                    "balance_unavailable",
                                    "budget_below_plan",
                                    "busy",
                                    "capability_retired",
                                    "connection_busy",
                                    "daily_cap_reached",
                                    "delivery_unavailable",
                                    "endpoint_exists",
                                    "goal_required",
                                    "idempotency_conflict",
                                    "idempotency_key_required",
                                    "insufficient_credits",
                                    "insufficient_scope",
                                    "invalid_events",
                                    "invalid_input",
                                    "invalid_step",
                                    "invalid_variants",
                                    "key_busy",
                                    "key_misconfigured",
                                    "max_credits_required",
                                    "not_available",
                                    "not_found",
                                    "pilot_closed",
                                    "rate_limited",
                                    "recipe_inputs_required",
                                    "recipe_not_api_runnable",
                                    "request_exceeds_key_ceiling",
                                    "request_key_retired",
                                    "run_active",
                                    "run_busy",
                                    "spend_check_unavailable",
                                    "step_out_of_order",
                                    "step_required",
                                    "too_many_endpoints",
                                    "too_many_runs",
                                    "transition_refused",
                                    "unauthorized",
                                    "unknown_input",
                                    "unsupported_duration",
                                    "unsupported_parameter",
                                    "wrong_key"
                                ]
                            },
                            "message": {
                                "type": "string",
                                "description": "Human-readable and safe to show a customer. Never carries upstream provider text."
                            }
                        }
                    }
                }
            }
        },
        "responses": {
            "E400": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E401": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E402": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E403": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E404": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E409": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E429": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E502": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            },
            "E503": {
                "description": "Refused. `error.code` says which rule applied.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/Error"
                        }
                    }
                }
            }
        }
    }
}
