{
  "openapi": "3.1.0",
  "info": {
    "title": "FastGen Cloud API",
    "version": "1.0.0",
    "summary": "Image and video generation API for developers.",
    "description": "Prepaid, asynchronous image + video generation. Create a job, poll it or receive a webhook, download signed outputs. Prompts are passed to the model verbatim. Minor-safety checks run on every prompt, input and output and cannot be disabled (see the Acceptable Use Policy).",
    "termsOfService": "https://fastgencloud.com/legal/terms",
    "contact": {
      "name": "FastGen Cloud support",
      "email": "support@fastgencloud.com",
      "url": "https://fastgencloud.com/contact"
    }
  },
  "servers": [
    {
      "url": "https://api.fastgencloud.com/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Images"
    },
    {
      "name": "Videos"
    },
    {
      "name": "Jobs"
    },
    {
      "name": "Catalog"
    },
    {
      "name": "Account"
    },
    {
      "name": "Meta"
    }
  ],
  "paths": {
    "/images/generations": {
      "post": {
        "tags": [
          "Images"
        ],
        "operationId": "createImageGeneration",
        "summary": "Text-to-image",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Replays the original job for the same key + body (per account). Reusing a key with a different body returns 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageGenerationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job already finished (fast models / idempotent replay).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted (in flight). Poll GET /jobs/{id} or use webhook_url.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient balance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account paused/suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key reused with a different body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Blocked by content policy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or concurrency limit exceeded (see Retry-After)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily out of capacity / moderation unavailable (retry)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/images/edits": {
      "post": {
        "tags": [
          "Images"
        ],
        "operationId": "createImageEdit",
        "summary": "Instruction-based image edit",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Replays the original job for the same key + body (per account). Reusing a key with a different body returns 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageEditRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job already finished (fast models / idempotent replay).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted (in flight). Poll GET /jobs/{id} or use webhook_url.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient balance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account paused/suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key reused with a different body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Blocked by content policy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or concurrency limit exceeded (see Retry-After)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily out of capacity / moderation unavailable (retry)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/videos/generations": {
      "post": {
        "tags": [
          "Videos"
        ],
        "operationId": "createVideoGeneration",
        "summary": "Image-to-video",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 255
            },
            "description": "Replays the original job for the same key + body (per account). Reusing a key with a different body returns 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VideoGenerationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job already finished (fast models / idempotent replay).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted (in flight). Poll GET /jobs/{id} or use webhook_url.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient balance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Account paused/suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency-Key reused with a different body",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Blocked by content policy",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or concurrency limit exceeded (see Retry-After)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Temporarily out of capacity / moderation unavailable (retry)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "operationId": "listJobs",
        "summary": "List jobs (newest first)",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "queued",
                "processing",
                "succeeded",
                "failed",
                "canceled"
              ]
            }
          },
          {
            "name": "model",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 64
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of jobs",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobList"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or concurrency limit exceeded (see Retry-After)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{id}": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "operationId": "getJob",
        "summary": "Retrieve a job",
        "description": "In-flight jobs that have not been checked in the last 5 seconds are reconciled with the compute provider inline.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or concurrency limit exceeded (see Retry-After)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{id}/cancel": {
      "post": {
        "tags": [
          "Jobs"
        ],
        "operationId": "cancelJob",
        "summary": "Cancel an in-flight job",
        "description": "Refunds the reserved amount. Idempotent: finished jobs are returned unchanged.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit or concurrency limit exceeded (see Retry-After)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/models": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "operationId": "listModels",
        "summary": "List available models",
        "responses": {
          "200": {
            "description": "Enabled models with capabilities, price preview and license",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "object",
                    "data"
                  ],
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Model"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/loras": {
      "get": {
        "tags": [
          "Catalog"
        ],
        "operationId": "listLoras",
        "summary": "List catalog LoRAs",
        "parameters": [
          {
            "name": "model",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Filter to LoRAs accepted by this model."
          }
        ],
        "responses": {
          "200": {
            "description": "LoRAs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "object",
                    "data"
                  ],
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Lora"
                      }
                    },
                    "model": {
                      "type": "string"
                    },
                    "byo_urls": {
                      "type": "boolean",
                      "description": "Whether the model also accepts `loras[].url`."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getAccount",
        "summary": "Account, balance and limits",
        "responses": {
          "200": {
            "description": "The account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getUsage",
        "summary": "Usage aggregates",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "description": "Start (inclusive). Defaults to 30 days ago.",
              "type": "string",
              "maxLength": 40
            },
            "description": "Start (inclusive). Defaults to 30 days ago."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "description": "End (exclusive). Defaults to now.",
              "type": "string",
              "maxLength": 40
            },
            "description": "End (exclusive). Defaults to now."
          },
          {
            "name": "group_by",
            "in": "query",
            "required": false,
            "schema": {
              "default": "day",
              "type": "string",
              "enum": [
                "day",
                "model"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Usage"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/ping": {
      "get": {
        "tags": [
          "Meta"
        ],
        "operationId": "ping",
        "summary": "Liveness check (no auth)",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "service": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    },
                    "time": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "jobEvent": {
      "post": {
        "summary": "Job lifecycle event",
        "description": "Sent to the job's webhook_url when it reaches a terminal state.",
        "parameters": [
          {
            "name": "X-FastGen-Event",
            "in": "header",
            "schema": {
              "type": "string",
              "enum": [
                "job.succeeded",
                "job.failed",
                "job.canceled"
              ]
            }
          },
          {
            "name": "X-FastGen-Delivery",
            "in": "header",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "X-FastGen-Signature",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "t=<unix>,v1=<hex hmac_sha256(secret, `${t}.${body}`)>"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              }
            }
          }
        },
        "responses": {
          "2xx": {
            "description": "Acknowledged. Any non-2xx is retried with backoff."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "fgc_live_…",
        "description": "API key from the console: `Authorization: Bearer fgc_live_…`"
      }
    },
    "headers": {
      "X-Request-Id": {
        "schema": {
          "type": "string"
        },
        "description": "Echo this when contacting support."
      },
      "RateLimit-Limit": {
        "schema": {
          "type": "integer"
        }
      },
      "RateLimit-Remaining": {
        "schema": {
          "type": "integer"
        }
      }
    },
    "schemas": {
      "ImageGenerationRequest": {
        "type": "object",
        "properties": {
          "model": {
            "default": "general-image",
            "description": "Model id from GET /v1/models (t2i-capable).",
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "description": "Text prompt (1–2000 chars)."
          },
          "negative_prompt": {
            "description": "What to avoid. Age-safety terms are always appended server-side.",
            "type": "string",
            "maxLength": 1000
          },
          "size": {
            "description": "Output size \"WxH\". Must be one of the model's supported sizes.",
            "type": "string",
            "pattern": "^\\d{3,4}x\\d{3,4}$"
          },
          "aspect_ratio": {
            "description": "Alternative to size: picks the closest supported size for this ratio.",
            "type": "string",
            "enum": [
              "1:1",
              "4:5",
              "2:3",
              "5:4",
              "3:2",
              "16:9",
              "9:16"
            ]
          },
          "n": {
            "default": 1,
            "description": "Number of images (1–4, model max applies).",
            "type": "integer",
            "minimum": 1,
            "maximum": 4
          },
          "seed": {
            "description": "Seed for reproducible results (0–2147483647). Random when omitted.",
            "type": "integer",
            "minimum": 0,
            "maximum": 2147483647
          },
          "steps": {
            "description": "Sampling steps (bounded per model).",
            "type": "integer",
            "minimum": 1,
            "maximum": 50
          },
          "guidance": {
            "description": "Guidance / CFG scale (bounded per model).",
            "type": "number",
            "minimum": 0,
            "maximum": 20
          },
          "loras": {
            "description": "Up to 3 LoRAs (catalog ids or BYO urls, per model capabilities).",
            "maxItems": 3,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "description": "Catalog LoRA id (see GET /v1/loras).",
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                "url": {
                  "description": "Bring-your-own LoRA: public https URL to a .safetensors file (models with loras=\"url\").",
                  "type": "string",
                  "maxLength": 2048
                },
                "low_url": {
                  "description": "Image-to-video only: the low-noise-expert file of a paired LoRA. If omitted, `url` is applied to both experts.",
                  "type": "string",
                  "maxLength": 2048
                },
                "strength": {
                  "description": "LoRA weight (0.1–1.5). Defaults to the catalog default or 0.8.",
                  "type": "number",
                  "minimum": 0.1,
                  "maximum": 1.5
                }
              }
            }
          },
          "output_format": {
            "default": "png",
            "description": "Output image format.",
            "type": "string",
            "enum": [
              "png",
              "jpeg",
              "webp"
            ]
          },
          "webhook_url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri",
            "description": "Public https URL that receives job.succeeded / job.failed / job.canceled events for this job."
          },
          "metadata": {
            "type": "object",
            "propertyNames": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 256
            },
            "description": "Up to 16 string key/values (≤64/≤256 chars) echoed back on the job and in webhooks."
          }
        },
        "required": [
          "prompt"
        ]
      },
      "ImageEditRequest": {
        "type": "object",
        "properties": {
          "model": {
            "default": "image-edit",
            "description": "Model id from GET /v1/models (edit-capable).",
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "image": {
            "description": "Single reference image (or use images[]).",
            "type": "string",
            "minLength": 1,
            "maxLength": 13981078
          },
          "images": {
            "description": "1–3 reference images.",
            "minItems": 1,
            "maxItems": 3,
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 13981078,
              "description": "Image source: a public https URL, or a base64 data URI (data:image/png;base64,…) up to 10MB. PNG, JPEG or WebP; 64–4096px per side."
            }
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "description": "Edit instruction (1–2000 chars)."
          },
          "negative_prompt": {
            "description": "What to avoid. Age-safety terms are always appended server-side.",
            "type": "string",
            "maxLength": 1000
          },
          "size": {
            "description": "Optional output size \"WxH\". Defaults to the source image size (bounded).",
            "type": "string",
            "pattern": "^\\d{3,4}x\\d{3,4}$"
          },
          "seed": {
            "description": "Seed for reproducible results (0–2147483647). Random when omitted.",
            "type": "integer",
            "minimum": 0,
            "maximum": 2147483647
          },
          "output_format": {
            "default": "png",
            "description": "Output image format.",
            "type": "string",
            "enum": [
              "png",
              "jpeg",
              "webp"
            ]
          },
          "webhook_url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri",
            "description": "Public https URL that receives job.succeeded / job.failed / job.canceled events for this job."
          },
          "metadata": {
            "type": "object",
            "propertyNames": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 256
            },
            "description": "Up to 16 string key/values (≤64/≤256 chars) echoed back on the job and in webhooks."
          }
        },
        "required": [
          "prompt"
        ]
      },
      "VideoGenerationRequest": {
        "type": "object",
        "properties": {
          "model": {
            "default": "image-to-video",
            "description": "Model id from GET /v1/models (i2v-capable).",
            "type": "string",
            "minLength": 1,
            "maxLength": 64
          },
          "image": {
            "type": "string",
            "minLength": 1,
            "maxLength": 13981078,
            "description": "Start frame. Aspect ratio is preserved."
          },
          "prompt": {
            "description": "Motion / scene description (≤1500 chars).",
            "type": "string",
            "maxLength": 1500
          },
          "negative_prompt": {
            "description": "What to avoid. Age-safety terms are always appended server-side.",
            "type": "string",
            "maxLength": 1000
          },
          "duration": {
            "default": 5,
            "description": "Clip length in seconds.",
            "anyOf": [
              {
                "type": "number",
                "const": 5
              },
              {
                "type": "number",
                "const": 8
              }
            ]
          },
          "seed": {
            "description": "Seed for reproducible results (0–2147483647). Random when omitted.",
            "type": "integer",
            "minimum": 0,
            "maximum": 2147483647
          },
          "loras": {
            "description": "Up to 3 LoRAs by URL (high-noise `url` + optional low-noise `low_url`), applied at `strength`.",
            "maxItems": 3,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "description": "Catalog LoRA id (see GET /v1/loras).",
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 128
                },
                "url": {
                  "description": "Bring-your-own LoRA: public https URL to a .safetensors file (models with loras=\"url\").",
                  "type": "string",
                  "maxLength": 2048
                },
                "low_url": {
                  "description": "Image-to-video only: the low-noise-expert file of a paired LoRA. If omitted, `url` is applied to both experts.",
                  "type": "string",
                  "maxLength": 2048
                },
                "strength": {
                  "description": "LoRA weight (0.1–1.5). Defaults to the catalog default or 0.8.",
                  "type": "number",
                  "minimum": 0.1,
                  "maximum": 1.5
                }
              }
            }
          },
          "webhook_url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri",
            "description": "Public https URL that receives job.succeeded / job.failed / job.canceled events for this job."
          },
          "metadata": {
            "type": "object",
            "propertyNames": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 256
            },
            "description": "Up to 16 string key/values (≤64/≤256 chars) echoed back on the job and in webhooks."
          }
        },
        "required": [
          "image"
        ]
      },
      "Job": {
        "type": "object",
        "required": [
          "id",
          "object",
          "status",
          "kind",
          "model",
          "input",
          "output",
          "usage",
          "moderation",
          "error",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "object": {
            "type": "string",
            "const": "job"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "processing",
              "succeeded",
              "failed",
              "canceled"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "image.generation",
              "image.edit",
              "image.variation",
              "image.inpaint",
              "video.generation"
            ]
          },
          "model": {
            "type": "string",
            "example": "general-image"
          },
          "input": {
            "type": "object",
            "additionalProperties": true,
            "description": "Sanitized echo of the request (image bytes replaced by {sha256,width,height,mime})."
          },
          "output": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "required": [
                  "images"
                ],
                "properties": {
                  "images": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ImageOutput"
                    }
                  }
                }
              },
              {
                "type": "object",
                "required": [
                  "video"
                ],
                "properties": {
                  "video": {
                    "$ref": "#/components/schemas/VideoOutput"
                  }
                }
              }
            ],
            "description": "Populated only when status is succeeded."
          },
          "usage": {
            "type": "object",
            "required": [
              "charged_micros",
              "charged_usd",
              "gpu_ms"
            ],
            "properties": {
              "charged_micros": {
                "type": "integer",
                "description": "Micro-USD (1 USD = 1,000,000). Reserved amount while in flight; 0 after a refund."
              },
              "charged_usd": {
                "type": "number"
              },
              "gpu_ms": {
                "type": [
                  "integer",
                  "null"
                ]
              }
            }
          },
          "moderation": {
            "type": "object",
            "required": [
              "status"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "passed",
                  "blocked",
                  "pending"
                ]
              }
            }
          },
          "error": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "required": [
                  "code",
                  "message"
                ],
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              }
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When outputs are deleted (account retention)."
          },
          "metadata": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      },
      "JobList": {
        "type": "object",
        "required": [
          "object",
          "data",
          "has_more",
          "next_cursor"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Job"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ImageOutput": {
        "type": "object",
        "required": [
          "url",
          "mime"
        ],
        "properties": {
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri",
            "description": "Signed download URL (valid up to 7 days, never past expires_at)."
          },
          "width": {
            "type": [
              "integer",
              "null"
            ]
          },
          "height": {
            "type": [
              "integer",
              "null"
            ]
          },
          "mime": {
            "type": "string",
            "example": "image/png"
          },
          "seed": {
            "type": [
              "integer",
              "null"
            ]
          },
          "bytes": {
            "type": "integer"
          }
        }
      },
      "VideoOutput": {
        "type": "object",
        "required": [
          "url",
          "mime"
        ],
        "properties": {
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "duration": {
            "type": [
              "number",
              "null"
            ],
            "description": "Seconds."
          },
          "fps": {
            "type": [
              "number",
              "null"
            ]
          },
          "width": {
            "type": [
              "integer",
              "null"
            ]
          },
          "height": {
            "type": [
              "integer",
              "null"
            ]
          },
          "mime": {
            "type": "string",
            "example": "video/mp4"
          },
          "bytes": {
            "type": "integer"
          }
        }
      },
      "Model": {
        "type": "object",
        "required": [
          "id",
          "object",
          "type",
          "label",
          "capabilities",
          "price",
          "license"
        ],
        "properties": {
          "id": {
            "type": "string",
            "example": "general-image"
          },
          "object": {
            "type": "string",
            "const": "model"
          },
          "type": {
            "type": "string",
            "enum": [
              "image",
              "video"
            ],
            "description": "What the model produces."
          },
          "label": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "capabilities": {
            "type": "object",
            "properties": {
              "t2i": {
                "type": "boolean"
              },
              "edit": {
                "type": "boolean"
              },
              "img2img": {
                "type": "boolean"
              },
              "inpaint": {
                "type": "boolean"
              },
              "i2v": {
                "type": "boolean"
              },
              "sizes": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "durations": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "fps": {
                "type": "number"
              },
              "max_n": {
                "type": "integer"
              },
              "max_refs": {
                "type": "integer"
              },
              "loras": {
                "type": "string",
                "enum": [
                  "url",
                  "catalog"
                ]
              }
            },
            "additionalProperties": true
          },
          "price": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "type": "object",
                "required": [
                  "micros",
                  "usd",
                  "unit",
                  "per"
                ],
                "properties": {
                  "micros": {
                    "type": "integer"
                  },
                  "usd": {
                    "type": "number"
                  },
                  "unit": {
                    "type": "string"
                  },
                  "per": {
                    "type": "string"
                  },
                  "note": {
                    "type": "string"
                  }
                }
              }
            ]
          },
          "license": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Lora": {
        "type": "object",
        "required": [
          "id",
          "object",
          "compatible_models",
          "label",
          "default_strength"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "lora"
          },
          "compatible_models": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Model ids this LoRA can be used with."
          },
          "label": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "default_strength": {
            "type": "number"
          },
          "triggers": {
            "type": [
              "string",
              "null"
            ]
          },
          "license": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "Account": {
        "type": "object",
        "required": [
          "object",
          "id",
          "name",
          "status",
          "balance_micros",
          "balance_usd"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "account"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "suspended",
              "closed"
            ]
          },
          "currency": {
            "type": "string",
            "example": "usd"
          },
          "balance_micros": {
            "type": "integer"
          },
          "balance_usd": {
            "type": "number"
          },
          "rate_limit_rpm": {
            "type": "integer"
          },
          "max_concurrent_jobs": {
            "type": "integer"
          },
          "retention_days": {
            "type": "integer"
          },
          "auto_recharge": {
            "type": "object",
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "threshold_usd": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "amount_usd": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "webhook_signing_configured": {
            "type": "boolean"
          },
          "api_key": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "prefix": {
                "type": "string"
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Usage": {
        "type": "object",
        "required": [
          "object",
          "from",
          "to",
          "group_by",
          "total",
          "data"
        ],
        "properties": {
          "object": {
            "type": "string",
            "const": "usage"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "group_by": {
            "type": "string",
            "enum": [
              "day",
              "model"
            ]
          },
          "total": {
            "type": "object",
            "properties": {
              "jobs": {
                "type": "integer"
              },
              "succeeded": {
                "type": "integer"
              },
              "failed": {
                "type": "integer"
              },
              "canceled": {
                "type": "integer"
              },
              "in_flight": {
                "type": "integer"
              },
              "charged_micros": {
                "type": "integer"
              },
              "charged_usd": {
                "type": "number"
              },
              "gpu_ms": {
                "type": "integer"
              }
            }
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "day": {
                  "type": "string",
                  "format": "date"
                },
                "model": {
                  "type": "string"
                },
                "jobs": {
                  "type": "integer"
                },
                "succeeded": {
                  "type": "integer"
                },
                "failed": {
                  "type": "integer"
                },
                "canceled": {
                  "type": "integer"
                },
                "in_flight": {
                  "type": "integer"
                },
                "charged_micros": {
                  "type": "integer"
                },
                "charged_usd": {
                  "type": "number"
                },
                "gpu_ms": {
                  "type": "integer"
                }
              }
            }
          },
          "truncated": {
            "type": "boolean"
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "required": [
          "id",
          "type",
          "created",
          "data"
        ],
        "description": "Delivered by POST to your webhook_url. Verify `X-FastGen-Signature: t=<unix>,v1=<hex>` where v1 = HMAC-SHA256(webhook_secret, `${t}.${raw_body}`). Retries: 1m, 5m, 30m, 2h, 6h.",
        "properties": {
          "id": {
            "type": "string",
            "example": "evt_0123456789abcdef01234567"
          },
          "type": {
            "type": "string",
            "enum": [
              "job.succeeded",
              "job.failed",
              "job.canceled"
            ]
          },
          "created": {
            "type": "integer",
            "description": "Unix seconds."
          },
          "data": {
            "type": "object",
            "required": [
              "object"
            ],
            "properties": {
              "object": {
                "$ref": "#/components/schemas/Job"
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "type",
              "code",
              "message",
              "request_id"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "invalid_request_error",
                  "authentication_error",
                  "permission_error",
                  "insufficient_balance",
                  "not_found",
                  "idempotency_conflict",
                  "content_blocked",
                  "rate_limit_error",
                  "capacity_error",
                  "api_error"
                ]
              },
              "code": {
                "type": "string",
                "description": "Machine-readable code, e.g. invalid_body, model_unavailable, content_blocked_prompt, concurrency_limit."
              },
              "message": {
                "type": "string"
              },
              "param": {
                "type": "string",
                "description": "The offending request parameter, when applicable."
              },
              "request_id": {
                "type": "string",
                "example": "req_0123456789abcdef01234567"
              }
            }
          }
        }
      }
    }
  }
}