{
  "openapi": "3.1.0",
  "info": {
    "title": "Mangii Headless API",
    "version": "1.0.0",
    "description": "Agent-consumable creation API. Auth is Authorization Bearer mangii_sk_. Generation POSTs default to async 202 + job_id. Debit is useApiCredit: apiPackCredits first, then purchase-backed packCredits. weeklyCredits never.\n"
  },
  "servers": [
    {
      "url": "https://api.mangii.ai",
      "description": "Generation host (Functions custom domain or Cloud Run)"
    }
  ],
  "security": [
    {
      "mangiiKey": []
    }
  ],
  "tags": [
    {
      "name": "stories"
    },
    {
      "name": "images"
    },
    {
      "name": "catalog"
    },
    {
      "name": "billing"
    },
    {
      "name": "jobs"
    }
  ],
  "paths": {
    "/v1/stories": {
      "get": {
        "operationId": "listStories",
        "tags": [
          "stories"
        ],
        "summary": "List own stories",
        "responses": {
          "200": {
            "description": "Paginated stories",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryList"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createStory",
        "tags": [
          "stories"
        ],
        "summary": "Create a story (async by default)",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateStoryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync completion (opt-in, long-timeout host only)",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerationResult"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAccepted"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyCollision"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/stories/{id}": {
      "get": {
        "operationId": "getStory",
        "tags": [
          "stories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/StoryId"
          }
        ],
        "responses": {
          "200": {
            "description": "Story",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Story"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "patch": {
        "operationId": "patchStory",
        "tags": [
          "stories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/StoryId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "visibility": {
                    "type": "string",
                    "enum": [
                      "private",
                      "public"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Story"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "delete": {
        "operationId": "deleteStory",
        "tags": [
          "stories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/StoryId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/stories/{id}/panels": {
      "get": {
        "operationId": "listStoryPanels",
        "tags": [
          "stories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/StoryId"
          }
        ],
        "responses": {
          "200": {
            "description": "Panels",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "continueStory",
        "tags": [
          "stories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/StoryId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContinueStoryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync completion (opt-in, long-timeout host only)",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerationResult"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAccepted"
                }
              }
            }
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyCollision"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/stories/{id}/panels/{pid}": {
      "delete": {
        "operationId": "deletePanel",
        "tags": [
          "stories"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/StoryId"
          },
          {
            "$ref": "#/components/parameters/PanelId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/stories/{id}/panels/{pid}/regenerate": {
      "post": {
        "operationId": "regeneratePanel",
        "tags": [
          "stories"
        ],
        "description": "Optional prompt and quality only. Style is locked after panel 0.",
        "parameters": [
          {
            "$ref": "#/components/parameters/StoryId"
          },
          {
            "$ref": "#/components/parameters/PanelId"
          },
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegeneratePanelRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync completion (opt-in, long-timeout host only)",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerationResult"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAccepted"
                }
              }
            }
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyCollision"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/images": {
      "post": {
        "operationId": "createImage",
        "tags": [
          "images"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateImageRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sync completion (opt-in, long-timeout host only)",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GenerationResult"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAccepted"
                }
              }
            }
          },
          "402": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/IdempotencyCollision"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/styles": {
      "get": {
        "operationId": "listStyles",
        "tags": [
          "catalog"
        ],
        "summary": "Canonical styles excluding experimental",
        "responses": {
          "200": {
            "description": "Style catalog",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/credits": {
      "get": {
        "operationId": "getCredits",
        "tags": [
          "billing"
        ],
        "responses": {
          "200": {
            "description": "Balances. weeklyCredits is display-only. spendableCredits is apiPackCredits plus current packCredits after the account has ever purchased. Later ad/referral grants on that pack pool also spend.",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Credits"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "tags": [
          "billing"
        ],
        "responses": {
          "200": {
            "description": "Per-day usage",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "tags": [
          "jobs"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job status",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/checkout/credits": {
      "post": {
        "operationId": "checkoutCredits",
        "tags": [
          "billing"
        ],
        "description": "Requires billing:write scope or dashboard session. Not on generate-scoped keys.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Stripe Checkout URL for a human",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/checkout/subscription": {
      "post": {
        "operationId": "checkoutSubscription",
        "tags": [
          "billing"
        ],
        "description": "Requires billing:write scope or dashboard session.",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "responses": {
          "200": {
            "description": "Stripe Checkout URL for a human",
            "headers": {
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/XRateLimitLimit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/XRateLimitRemaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/XRateLimitReset"
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "mangiiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "mangii_sk_",
        "description": "API key mangii_sk_<32 bytes base62>"
      }
    },
    "parameters": {
      "StoryId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "PanelId": {
        "name": "pid",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string"
        }
      }
    },
    "headers": {
      "XRateLimitLimit": {
        "description": "Requests this key may make in the current minute bucket.",
        "schema": {
          "type": "integer"
        },
        "example": 60
      },
      "XRateLimitRemaining": {
        "description": "Requests left in the current minute bucket. Floored at 0, so a 429 always reports 0.",
        "schema": {
          "type": "integer"
        },
        "example": 59
      },
      "XRateLimitReset": {
        "description": "Unix seconds at the start of the next minute bucket, when the allowance rolls over.",
        "schema": {
          "type": "integer"
        },
        "example": 1755600120
      },
      "RetryAfter": {
        "description": "Seconds to wait before retrying. Always the full bucket width.",
        "schema": {
          "type": "integer"
        },
        "example": 60
      }
    },
    "responses": {
      "Error": {
        "description": "Uniform error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "IdempotencyCollision": {
        "description": "Idempotency-Key is already in flight (idempotency_in_progress — retry the same key) or was reused with a different body (idempotency_conflict — pick a new key).\n",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/XRateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/XRateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/XRateLimitReset"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Per-key rate limit exceeded for the current minute bucket. Every /v1 operation shares one per-key limiter, so any of them can return this.\n",
        "headers": {
          "X-RateLimit-Limit": {
            "$ref": "#/components/headers/XRateLimitLimit"
          },
          "X-RateLimit-Remaining": {
            "$ref": "#/components/headers/XRateLimitRemaining"
          },
          "X-RateLimit-Reset": {
            "$ref": "#/components/headers/XRateLimitReset"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "code",
              "message",
              "request_id"
            ],
            "properties": {
              "type": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "enum": [
                  "invalid_key",
                  "insufficient_credits",
                  "budget_exceeded",
                  "content_blocked",
                  "gone",
                  "idempotency_conflict",
                  "idempotency_in_progress"
                ]
              },
              "message": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              },
              "buy_url": {
                "type": "string"
              }
            }
          }
        }
      },
      "Credits": {
        "type": "object",
        "required": [
          "weeklyCredits",
          "packCredits",
          "apiPackCredits"
        ],
        "properties": {
          "weeklyCredits": {
            "type": "integer"
          },
          "packCredits": {
            "type": "integer"
          },
          "apiPackCredits": {
            "type": "integer"
          },
          "spendableCredits": {
            "type": "integer",
            "description": "apiPackCredits plus current packCredits when hasEverPurchasedCredits is true. Later ad/referral grants on that pack pool also spend. Same pools useApiCredit spends."
          },
          "notes": {
            "type": "string",
            "description": "weeklyCredits is display-only and never spends on API/MCP. spendableCredits is apiPackCredits plus the current packCredits balance when hasEverPurchasedCredits is true. After a purchase, later grants into packCredits (including ad/referral) share that spendable pool. Never-purchased accounts cannot spend packCredits."
          }
        }
      },
      "JobAccepted": {
        "type": "object",
        "required": [
          "job_id",
          "request_id"
        ],
        "properties": {
          "job_id": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "credits_charged": {
            "type": "integer"
          },
          "credits_remaining": {
            "type": "integer"
          },
          "quality": {
            "type": "string"
          },
          "next_step": {
            "type": "string",
            "description": "What to call next. Follow this instead of guessing."
          }
        }
      },
      "GenerationResult": {
        "type": "object",
        "required": [
          "credits_charged",
          "credits_remaining",
          "quality",
          "request_id"
        ],
        "properties": {
          "credits_charged": {
            "type": "integer"
          },
          "credits_remaining": {
            "type": "integer"
          },
          "quality": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          },
          "job_id": {
            "type": "string"
          },
          "story_id": {
            "type": "string"
          },
          "panel_id": {
            "type": "string"
          },
          "image_url": {
            "type": "string",
            "description": "HTTPS URL of the finished panel."
          },
          "next_step": {
            "type": "string",
            "description": "What to call next."
          }
        }
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "running",
              "succeeded",
              "failed"
            ]
          },
          "credits_charged": {
            "type": "integer"
          },
          "credits_remaining": {
            "type": "integer"
          },
          "quality": {
            "type": "string"
          },
          "request_id": {
            "type": "string"
          }
        }
      },
      "Story": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "visibility": {
            "type": "string"
          },
          "panelCount": {
            "type": "integer",
            "description": "How many panels this story currently has."
          },
          "language": {
            "type": [
              "string",
              "null"
            ],
            "description": "Story language code when stored."
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ]
          },
          "style_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "cover_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "StoryList": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Story"
            }
          }
        }
      },
      "CreateStoryRequest": {
        "type": "object",
        "required": [
          "prompt",
          "style_id"
        ],
        "properties": {
          "prompt": {
            "type": "string",
            "maxLength": 2000
          },
          "style_id": {
            "type": "string"
          },
          "color_mode": {
            "type": "string"
          },
          "quality": {
            "type": "string",
            "enum": [
              "standard",
              "hd",
              "ultra"
            ]
          },
          "language": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "reference_image": {
            "type": "string",
            "description": "Optional identity photo. https URL or data URI. Alias of identity_image."
          },
          "identity_image": {
            "type": "string",
            "description": "Optional identity photo. https URL or data URI."
          },
          "visibility": {
            "type": "string",
            "enum": [
              "private",
              "public"
            ],
            "default": "private"
          },
          "async": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "ContinueStoryRequest": {
        "type": "object",
        "required": [
          "prompt"
        ],
        "properties": {
          "prompt": {
            "type": "string",
            "maxLength": 2000
          },
          "quality": {
            "type": "string",
            "enum": [
              "standard",
              "hd",
              "ultra"
            ]
          },
          "identity_panel_id": {
            "type": "string",
            "description": "Override Image 1 (identity) with this panel id from GET /v1/stories/{id}/panels."
          },
          "identity_image": {
            "type": "string",
            "description": "Override Image 1 with an https URL or data URI. Do not also send identity_panel_id."
          },
          "reference_image": {
            "type": "string",
            "description": "Alias for identity_image on continue and regenerate."
          },
          "continuity_panel_id": {
            "type": "string",
            "description": "Override Image 2 (scene) with this panel id. Do not also send continuity_image."
          },
          "continuity_image": {
            "type": "string",
            "description": "Override Image 2 with an https URL or data URI."
          },
          "context_panel_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Legacy [identity, scene] list. Ignored when named identity_* or continuity_* fields are set."
          },
          "async": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "RegeneratePanelRequest": {
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string",
            "maxLength": 2000
          },
          "quality": {
            "type": "string",
            "enum": [
              "standard",
              "hd",
              "ultra"
            ]
          },
          "identity_panel_id": {
            "type": "string"
          },
          "identity_image": {
            "type": "string"
          },
          "reference_image": {
            "type": "string"
          },
          "continuity_panel_id": {
            "type": "string"
          },
          "continuity_image": {
            "type": "string"
          },
          "context_panel_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "async": {
            "type": "boolean",
            "default": true
          }
        }
      },
      "CreateImageRequest": {
        "type": "object",
        "required": [
          "prompt",
          "style_id"
        ],
        "properties": {
          "prompt": {
            "type": "string",
            "maxLength": 2000
          },
          "style_id": {
            "type": "string"
          },
          "quality": {
            "type": "string",
            "enum": [
              "standard",
              "hd",
              "ultra"
            ]
          },
          "reference_image": {
            "type": "string"
          },
          "async": {
            "type": "boolean",
            "default": true
          }
        }
      }
    }
  }
}
