{
  "openapi": "3.1.0",
  "info": {
    "title": "FreeInd API",
    "version": "1.0.0",
    "description": "Multi-provider AI generation API for text, images, video, audio, and speech. Authenticate with a scoped API key, submit idempotent generations, and receive signed webhooks.\n\nAuthentication: `Authorization: Bearer fi_live_...` with a scoped API key created in the dashboard.\nErrors use a stable envelope: `{ \"error\": { \"code\", \"message\", \"requestId\" } }`.\nRate limits are per key and reported in `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`.",
    "contact": {
      "name": "FreeInd",
      "url": "https://free.ind.in/docs"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://free.ind.in",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Meta & discovery",
      "description": "Unauthenticated endpoints for service health, plans, and the public model catalog. Safe to call from the browser or a startup probe."
    },
    {
      "name": "Models",
      "description": "Plan-aware model discovery. Always read the catalog before submitting a generation — it carries the credit price and the per-model `parameterSchema` used to validate params."
    },
    {
      "name": "Generations",
      "description": "Create and track generation jobs. Submission is asynchronous: a 201 means the job is queued, not finished. Poll the detail endpoint or subscribe to webhooks for terminal states."
    },
    {
      "name": "Files & assets",
      "description": "Two ways to feed media into a generation: upload it (private, stored on the platform) or pass a direct http(s)/base64 URL. Uploads use presigned PUT URLs so file bytes never touch the API."
    },
    {
      "name": "Usage & credits",
      "description": "Report on consumption and credit balances. Usage records are written when a generation settles, so totals lag terminal states by seconds."
    },
    {
      "name": "Wallet",
      "description": "Pay-as-you-go wallet. Deposit once, then generate at live model prices. Top-ups require a dashboard session; reads and threshold updates work with an API key."
    },
    {
      "name": "Webhooks",
      "description": "Subscribe to terminal generation and workflow events. Deliveries are signed with HMAC-SHA256 in the `X-FreeInd-Signature` header and retried with backoff."
    },
    {
      "name": "Dashboard & account",
      "description": "Key, billing, workspace, and account management. These endpoints authenticate with the dashboard session cookie rather than an API key, and are not part of the Postman collection."
    },
    {
      "name": "free.flow · Workflows",
      "description": "Build, activate, and run multi-step pipelines. A workflow is a DAG of generation nodes with typed flow inputs; a run walks the nodes in order and passes outputs downstream. Pipelines can be one-shot or reusable templates."
    },
    {
      "name": "free.flow · Reference templates",
      "description": "Turn a reference image or video into a reusable workflow: analyze its look, structure, and audio feel, then adopt the generated template. Analyses are metered on vision tokens and cached by asset bytes."
    },
    {
      "name": "free.slides · Presentations",
      "description": "Turn a brief into a designed deck: the planner writes an outline and one image generation runs per slide. Export to PPTX or PDF when every slide is ready."
    },
    {
      "name": "free.podcast · Episodes",
      "description": "Write a multi-speaker script, render each turn with a different voice, and mix the episode with an optional music bed and outro. Rendering runs on free.flow under the hood."
    },
    {
      "name": "free.audiobook · Narration",
      "description": "Turn long text into a single narrated audiobook. The text is chunked, each chunk is rendered with the chosen voice model, and the final mix is assembled on demand."
    },
    {
      "name": "free.speech · Voices",
      "description": "Clone a voice from uploaded samples, then pass the returned `providerVoiceId` as the `voice` param on any text-to-audio generation. Cloning needs a paid plan and explicit consent."
    },
    {
      "name": "free.studio · Storyboard to video",
      "description": "The ad/studio pipeline: a brief becomes a storyboard of shots, the storyboard runs as a workflow, and captions come back as SRT. Effects and transitions are catalogued for the UI."
    },
    {
      "name": "free.boards · Moodboards",
      "description": "Collect assets into ordered boards for review and iteration. Items reference assets; resolve previews with `GET /v1/assets?assetIds=…`. Paid plans only."
    },
    {
      "name": "Presets",
      "description": "Saved generator setups: a mode, an optional model, and the raw form params. Re-apply a preset by sending its params to `POST /v1/generations`."
    },
    {
      "name": "Projects",
      "description": "Group generations and assets into projects for the library. Filter generations and assets by `projectId` once assigned."
    },
    {
      "name": "free.chat · OpenAI-compatible",
      "description": "Send chat completions with an API key using the OpenAI wire format. Models and quota are exposed alongside, so SDKs can point at this base URL unchanged."
    },
    {
      "name": "free.logo · Brand kit",
      "description": "Generate names, taglines, and a colour palette before rendering logo marks with an image model."
    }
  ],
  "paths": {
    "/v1/health/ready": {
      "get": {
        "operationId": "health-ready",
        "summary": "Readiness probe",
        "description": "Reports the health of the database, Redis, storage, providers, and workers. Returns 200 when the API can serve traffic and 503 when a critical dependency is unavailable.",
        "tags": [
          "Meta & discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Service is ready",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "ok",
                  "checks": {
                    "database": {
                      "status": "ok",
                      "latencyMs": 1
                    },
                    "redis": {
                      "status": "ok",
                      "latencyMs": 1
                    },
                    "storage": {
                      "status": "ok",
                      "latencyMs": 299
                    },
                    "providers": {
                      "status": "ok",
                      "latencyMs": 3824
                    },
                    "workerHeartbeat": {
                      "status": "ok",
                      "latencyMs": 1200
                    }
                  },
                  "version": "1.4.0",
                  "commit": "1ed362c8",
                  "uptime": 48213.2,
                  "time": "2026-10-24T12:00:00.000Z"
                }
              }
            }
          },
          "503": {
            "description": "A critical dependency is unhealthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "unavailable",
                  "checks": {
                    "database": {
                      "status": "unavailable",
                      "latencyMs": 30000
                    }
                  },
                  "version": "1.4.0",
                  "time": "2026-10-24T12:00:00.000Z"
                }
              }
            }
          }
        }
      }
    },
    "/v1/plans": {
      "get": {
        "operationId": "plans",
        "summary": "List public plans",
        "description": "Active subscription and one-time plans with their entitlements and the latest approved price. Prices are returned in USD; `GET /v1/billing/fx` exposes the live USD→INR rate.",
        "tags": [
          "Meta & discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Plan catalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000010",
                      "slug": "starter",
                      "name": "Starter",
                      "kind": "subscription",
                      "price": {
                        "amountUsd": 9,
                        "currency": "USD",
                        "interval": "month"
                      },
                      "entitlements": {
                        "credits_per_month": 1000,
                        "api_rate_per_minute": 60,
                        "api_rate_daily": 1000,
                        "storage_bytes": 5368709120
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/models/public": {
      "get": {
        "operationId": "models-public",
        "summary": "Public model showcase",
        "description": "Every active model with its provider, modality, supported modes, and credit price. No auth and no workspace context, so plan-specific availability is not applied.",
        "tags": [
          "Meta & discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Model list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000001",
                      "name": "OpenAI: GPT Image 1",
                      "slug": "openai-gpt-image-1",
                      "modality": "image",
                      "supportedModes": [
                        "text_to_image"
                      ],
                      "creditsPerGeneration": 40,
                      "providerName": "OpenAI",
                      "providerKey": "openai",
                      "isFreeTier": false
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/catalog/public": {
      "get": {
        "operationId": "catalog-public",
        "summary": "Public catalog with samples",
        "description": "Makers, generation modes, and active models with sample outputs. This powers the public model pages and is cached in Redis.",
        "tags": [
          "Meta & discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Catalog payload",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "makers": [
                    {
                      "name": "OpenAI",
                      "slug": "openai",
                      "modelCount": 6
                    }
                  ],
                  "modes": [
                    {
                      "id": "text_to_image",
                      "label": "Text to image",
                      "modelCount": 42
                    }
                  ],
                  "models": [
                    {
                      "id": "00000000-0000-4000-8000-000000000001",
                      "name": "GPT Image 1"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/stats/public": {
      "get": {
        "operationId": "stats-public",
        "summary": "Public platform stats",
        "description": "Aggregate count of successfully completed generations across the platform.",
        "tags": [
          "Meta & discovery"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Stats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "generationsCompleted": 1284390
                }
              }
            }
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "list-models",
        "summary": "List models available to a workspace",
        "description": "Active models filtered by the workspace's plan. Each model includes `creditsPerGeneration`, `supportedModes`, `parameterSchema`, input requirements, and limits. Params sent to `POST /v1/generations` are validated against `parameterSchema`.",
        "tags": [
          "Models"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to resolve plan availability for.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to resolve plan availability for.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Grouped model list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000001",
                      "name": "OpenAI: GPT Image 1",
                      "slug": "openai-gpt-image-1",
                      "modality": "image",
                      "supportedModes": [
                        "text_to_image"
                      ],
                      "creditsPerGeneration": 40,
                      "parameterSchema": {
                        "prompt": {
                          "type": "string",
                          "required": true,
                          "maxLength": 4000
                        },
                        "aspectRatio": {
                          "type": "string",
                          "enum": [
                            "1:1",
                            "16:9",
                            "9:16"
                          ]
                        },
                        "seed": {
                          "type": "integer"
                        }
                      },
                      "maxResolution": "1536x1024",
                      "maxFileSizeBytes": 52428800
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read",
        "x-notes": [
          "Cache the response for a few minutes — the catalog changes only when models are added or re-priced."
        ]
      }
    },
    "/v1/generations": {
      "post": {
        "operationId": "create-generation",
        "summary": "Create a generation",
        "description": "Submit a text, image, video, audio, transcription, or editing job. `workspaceId` and `modelId` are required; `params.mode` selects the parameter set and must be supported by the model. Send an `Idempotency-Key` header to make retries safe.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Optional. 8–128 chars of `[A-Za-z0-9._:-]`. Reusing a key in the same workspace returns 409 `idempotency_conflict` instead of creating a second job.",
            "schema": {
              "type": "string",
              "description": "Optional. 8–128 chars of `[A-Za-z0-9._:-]`. Reusing a key in the same workspace returns 409 `idempotency_conflict` instead of creating a second job.",
              "example": "fox-portrait-001"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace that pays for the generation. Must match the API key workspace."
                  },
                  "modelId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Model id from `GET /v1/models`."
                  },
                  "params": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Mode-specific params. `mode` is required — one of `text_to_text`, `text_to_image`, `text_to_video`, `text_to_audio`, `image_to_image`, `image_to_video`, `video_to_video`, `audio_to_text`, `video_to_text`, `video_join`, `video_audio_mix`, `audio_concat`, `audio_mix`, `image_compose`, `video_frame_extract`."
                  },
                  "inputs": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Source media for edit/transcription/animation modes: `imageAssetIds`, `videoAssetIds`, `audioAssetIds`, or direct `imageUrls` / `videoUrls` / `audioUrls` (http(s) or base64 data URLs)."
                  },
                  "projectId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Optional project to group the generation under."
                  },
                  "paymentMode": {
                    "type": "string",
                    "description": "`credits` (default), `wallet`, or `direct` for a one-time checkout.",
                    "default": "credits"
                  },
                  "enhancePrompt": {
                    "type": "boolean",
                    "description": "Opt into prompt enhancement for eligible audio models. Charges an extra fee, reserved separately.",
                    "default": false
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Body alternative to the `Idempotency-Key` header."
                  }
                },
                "required": [
                  "workspaceId",
                  "modelId",
                  "params"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "modelId": "00000000-0000-4000-8000-000000000001",
                "params": {
                  "mode": "text_to_image",
                  "prompt": "a red fox in fresh snow, golden hour, 85mm photograph",
                  "aspectRatio": "16:9",
                  "seed": 42
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Job accepted and queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000aa",
                  "workspaceId": "00000000-0000-4000-8000-000000000000",
                  "modelId": "00000000-0000-4000-8000-000000000001",
                  "mode": "text_to_image",
                  "status": "queued",
                  "params": {
                    "mode": "text_to_image",
                    "prompt": "a red fox in fresh snow, golden hour, 85mm photograph",
                    "aspectRatio": "16:9",
                    "seed": 42
                  },
                  "input": {},
                  "estimatedCredits": 40,
                  "paymentMode": "credits",
                  "idempotencyKey": "fox-portrait-001",
                  "createdAt": "2026-10-24T12:00:00.000Z"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits or wallet balance",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "error": {
                    "code": "insufficient_credits",
                    "message": "Not enough credits for this generation",
                    "requestId": "req_01J9Z8K2"
                  }
                }
              }
            }
          },
          "409": {
            "description": "Idempotency key already used",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "error": {
                    "code": "idempotency_conflict",
                    "message": "A generation with this idempotency key already exists",
                    "requestId": "req_01J9Z8K2"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Invalid params for the selected mode or model",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "error": {
                    "code": "validation_error",
                    "message": "Invalid request body",
                    "details": [
                      {
                        "field": "params.aspectRatio",
                        "message": "Unsupported value"
                      }
                    ],
                    "requestId": "req_01J9Z8K2"
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write",
        "x-notes": [
          "The request holds a credit reservation at submit time and settles to the actual cost when the provider reports usage."
        ]
      },
      "get": {
        "operationId": "list-generations",
        "summary": "List generations",
        "description": "Paginated generation history for a workspace, newest first. Filter by mode, status, model, project, or attributed member.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          },
          {
            "name": "perPage",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "description": "Page size.",
              "default": 20
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "Filter by generation mode.",
            "schema": {
              "type": "string",
              "description": "Filter by generation mode."
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by status (`queued`, `running`, `succeeded`, …).",
            "schema": {
              "type": "string",
              "description": "Filter by status (`queued`, `running`, `succeeded`, …)."
            }
          },
          {
            "name": "modelId",
            "in": "query",
            "required": false,
            "description": "Filter by model.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Filter by model."
            }
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "description": "Filter by project.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Filter by project."
            }
          },
          {
            "name": "createdById",
            "in": "query",
            "required": false,
            "description": "Filter by the member the job is attributed to.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Filter by the member the job is attributed to."
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Created after.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Created after."
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Created before.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Created before."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000aa",
                      "status": "succeeded",
                      "mode": "text_to_image",
                      "modelName": "OpenAI: GPT Image 1",
                      "estimatedCredits": 40,
                      "actualCredits": 40,
                      "thumbnail": "https://cdn.free.ind.in/.../thumb.webp",
                      "createdAt": "2026-10-24T12:00:00.000Z",
                      "completedAt": "2026-10-24T12:00:18.000Z"
                    }
                  ],
                  "meta": {
                    "hasNextPage": false,
                    "nextCursor": null,
                    "total": null
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/generations/batch": {
      "post": {
        "operationId": "batch-generations",
        "summary": "Create up to 25 generations",
        "description": "Runs the single-generation path once per item and returns per-item outcomes. Items are independent: one bad item does not roll back the others.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "items": {
                    "type": "array",
                    "items": {},
                    "description": "1–25 items. Each item is validated exactly like a single generation request (`modelId` + `params` + optional `inputs`)."
                  },
                  "paymentMode": {
                    "type": "string",
                    "description": "Applied to every item unless the item overrides it."
                  },
                  "projectId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Default project for the batch."
                  }
                },
                "required": [
                  "workspaceId",
                  "items"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "items": [
                  {
                    "modelId": "00000000-0000-4000-8000-000000000001",
                    "params": {
                      "mode": "text_to_image",
                      "prompt": "a red fox in snow"
                    }
                  },
                  {
                    "modelId": "00000000-0000-4000-8000-000000000001",
                    "params": {
                      "mode": "text_to_image",
                      "prompt": "a snowy owl at dusk"
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Per-item results",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "index": 0,
                      "status": "created",
                      "generationId": "00000000-0000-4000-8000-0000000000aa"
                    },
                    {
                      "index": 1,
                      "status": "error",
                      "error": {
                        "code": "insufficient_credits",
                        "message": "Not enough credits"
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/generations/{generationId}": {
      "get": {
        "operationId": "get-generation",
        "summary": "Retrieve a generation",
        "description": "Current state of a job plus its full event timeline (`queued` → `reserved` → `submitted` → `running` → terminal). Poll this until `status` is terminal. Use `/raw` to fetch output assets in the same call.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "generationId",
            "in": "path",
            "required": true,
            "description": "Generation id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Generation id.",
              "example": "00000000-0000-4000-8000-0000000000aa"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace the job belongs to.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace the job belongs to.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Generation with events",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000aa",
                  "status": "succeeded",
                  "mode": "text_to_image",
                  "modelId": "00000000-0000-4000-8000-000000000001",
                  "modelName": "OpenAI: GPT Image 1",
                  "textOutput": null,
                  "errorCode": null,
                  "errorMessage": null,
                  "estimatedCredits": 40,
                  "actualCredits": 40,
                  "createdAt": "2026-10-24T12:00:00.000Z",
                  "completedAt": "2026-10-24T12:00:18.000Z",
                  "events": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000e1",
                      "status": "queued",
                      "message": "Job queued",
                      "createdAt": "2026-10-24T12:00:00.100Z"
                    },
                    {
                      "id": "00000000-0000-4000-8000-0000000000e2",
                      "status": "succeeded",
                      "message": "Generation completed",
                      "createdAt": "2026-10-24T12:00:18.000Z"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Unknown generation in this workspace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "error": {
                    "code": "not_found",
                    "message": "Generation not found",
                    "requestId": "req_01J9Z8K2"
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/generations/{generationId}/raw": {
      "get": {
        "operationId": "get-generation-raw",
        "summary": "Retrieve a generation with outputs",
        "description": "Everything on the detail endpoint plus the generated assets and the provider request/response trace. Best endpoint for a worker that needs the finished file.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "generationId",
            "in": "path",
            "required": true,
            "description": "Generation id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Generation id.",
              "example": "00000000-0000-4000-8000-0000000000aa"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace the job belongs to.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace the job belongs to.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Generation, outputs, and provider trace",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "input": {},
                  "params": {
                    "mode": "text_to_image",
                    "prompt": "a red fox in fresh snow"
                  },
                  "outputs": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000f1",
                      "mediaType": "image",
                      "mimeType": "image/png",
                      "sizeBytes": 2411220,
                      "width": 1536,
                      "height": 1024,
                      "storageKey": "ws/.../generated.png"
                    }
                  ],
                  "rawRequest": {
                    "model": "gpt-image-1",
                    "prompt": "a red fox in fresh snow"
                  },
                  "rawResponse": {
                    "created": 1761307218,
                    "data": [
                      {
                        "b64_json": "…"
                      }
                    ]
                  },
                  "record": {
                    "id": "00000000-0000-4000-8000-0000000000aa",
                    "status": "succeeded"
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/generations/{generationId}/cancel": {
      "post": {
        "operationId": "cancel-generation",
        "summary": "Cancel a generation",
        "description": "Requests cancellation for a job in `queued`, `reserved`, `submitted`, or `running`. Returns `cancel_requested`; the worker moves it to `cancelled` and releases the credit reservation.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "generationId",
            "in": "path",
            "required": true,
            "description": "Generation id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Generation id.",
              "example": "00000000-0000-4000-8000-0000000000aa"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace the job belongs to.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace the job belongs to.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "Optional human-readable cancellation reason, stored in the audit log."
                  }
                },
                "required": []
              },
              "example": {
                "reason": "Prompt was wrong"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cancellation accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "cancel_requested"
                }
              }
            }
          },
          "409": {
            "description": "Job is already in a terminal state",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "error": {
                    "code": "conflict",
                    "message": "Generation cannot be cancelled in state succeeded",
                    "requestId": "req_01J9Z8K2"
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/generations/{generationId}/payment": {
      "post": {
        "operationId": "generation-payment",
        "summary": "Open the checkout for a direct-payment job",
        "description": "For a job created with `paymentMode: \"direct\"`, creates or resumes the one-time checkout and returns the hosted checkout URL.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "generationId",
            "in": "path",
            "required": true,
            "description": "Generation id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Generation id.",
              "example": "00000000-0000-4000-8000-0000000000aa"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "provider": {
                    "type": "string",
                    "description": "`creem`, `atlos`, `razorpay`, or `cashfree`. Defaults to the enabled provider."
                  },
                  "tosAccepted": {
                    "type": "boolean",
                    "description": "Required by gateways that need an explicit terms acceptance."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "provider": "creem",
                "tosAccepted": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout ready",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "payment": {
                    "checkoutUrl": "https://checkout.creem.io/ch/...",
                    "paymentSessionId": "ps_01J9Z8K2",
                    "amountUsd": 0.4,
                    "credits": 40,
                    "chargedAmount": 35.6,
                    "chargedCurrency": "INR",
                    "fxRate": 89
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/generations/emergency-stop": {
      "get": {
        "operationId": "emergency-stop",
        "summary": "Platform generation pause status",
        "description": "Whether generation is paused platform-wide by an operator. Automation should check this before submitting large batches.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Pause status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "stopped": false,
                  "reason": null
                }
              }
            }
          }
        },
        "x-required-scope": "all"
      }
    },
    "/v1/speech/script": {
      "post": {
        "operationId": "write-speech-script",
        "summary": "Write a voiceover script",
        "description": "Turns a short brief into a spoken-word script sized to a target duration. Requires a paid plan. Uses the platform enhancer model and is metered separately.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace to bill."
                  },
                  "brief": {
                    "type": "string",
                    "description": "What the voiceover is about."
                  },
                  "tone": {
                    "type": "string",
                    "description": "e.g. warm, confident, playful."
                  },
                  "audience": {
                    "type": "string",
                    "description": "Who is listening."
                  },
                  "language": {
                    "type": "string",
                    "description": "BCP-47 language tag or English name."
                  },
                  "durationSeconds": {
                    "type": "integer",
                    "description": "Target spoken duration."
                  }
                },
                "required": [
                  "workspaceId",
                  "brief"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "brief": "A 30-second product intro for an AI image generator",
                "tone": "confident",
                "audience": "small business owners",
                "durationSeconds": 30
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Script",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "script": "Meet FreeInd — the fastest way to turn an idea into a finished image…"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/music/lyrics": {
      "post": {
        "operationId": "write-music-lyrics",
        "summary": "Write song lyrics",
        "description": "Writes lyrics for a free.music track from an idea, genre, mood, and vocal style. Requires a paid plan. Instrumental tracks have no lyrics and return a validation error.",
        "tags": [
          "Generations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace to bill."
                  },
                  "idea": {
                    "type": "string",
                    "description": "What the song is about."
                  },
                  "vocal": {
                    "type": "string",
                    "description": "Vocal type; `instrumental` is rejected."
                  },
                  "genre": {
                    "type": "string",
                    "description": "Musical genre."
                  },
                  "mood": {
                    "type": "string",
                    "description": "Emotional tone."
                  },
                  "language": {
                    "type": "string",
                    "description": "Lyric language."
                  }
                },
                "required": [
                  "workspaceId",
                  "idea"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "idea": "a night drive through neon-lit streets",
                "vocal": "female",
                "genre": "synthwave",
                "mood": "nostalgic"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Lyrics",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "lyrics": "[Verse 1]\nStreetlights bleed into the rain…\n\n[Chorus]\nDrive on, drive on…"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/files/upload-url": {
      "post": {
        "operationId": "upload-url",
        "summary": "Request a presigned upload URL",
        "description": "Creates a pending asset and returns a presigned URL. PUT the raw file bytes to `uploadUrl`, then call `POST /v1/files/upload-complete` with the returned `assetId`.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace that owns the asset."
                  },
                  "mimeType": {
                    "type": "string",
                    "description": "Exact MIME type of the file being uploaded."
                  },
                  "sizeBytes": {
                    "type": "integer",
                    "description": "File size in bytes; checked against the storage quota."
                  },
                  "filename": {
                    "type": "string",
                    "description": "Original filename, stored for display."
                  },
                  "purpose": {
                    "type": "string",
                    "description": "`upload` (default), `generated`, `preview`, `temp`, `chat_input`, `support_attachment`.",
                    "default": "upload"
                  },
                  "projectId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Optional project to file the asset under."
                  }
                },
                "required": [
                  "workspaceId",
                  "mimeType"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "mimeType": "image/png",
                "sizeBytes": 1048576,
                "filename": "fox.png",
                "purpose": "upload"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Upload session created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "assetId": "00000000-0000-4000-8000-0000000000b1",
                  "uploadUrl": "https://storage.example.com/ws/.../fox.png?X-Amz-Signature=...",
                  "expiresInSeconds": 900,
                  "storageKey": "ws/00000000-0000-4000-8000-000000000000/upload/fox.png"
                }
              }
            }
          }
        },
        "x-required-scope": "files.write",
        "x-notes": [
          "The presigned URL is short-lived. Upload immediately and never log it — it grants write access to that object key."
        ]
      }
    },
    "/v1/files/upload-complete": {
      "post": {
        "operationId": "upload-complete",
        "summary": "Finalize an upload",
        "description": "Verifies the object exists in storage, marks the asset `ready`, and returns the asset record. Pass the asset id in `inputs.imageAssetIds` / `videoAssetIds` / `audioAssetIds` on the generation.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "assetId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The `assetId` returned by `POST /v1/files/upload-url`."
                  }
                },
                "required": [
                  "assetId"
                ]
              },
              "example": {
                "assetId": "00000000-0000-4000-8000-0000000000b1"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Asset is ready",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000b1",
                  "kind": "input",
                  "mediaType": "image",
                  "mimeType": "image/png",
                  "sizeBytes": 1048576,
                  "status": "ready",
                  "createdAt": "2026-10-24T12:00:00.000Z"
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      }
    },
    "/v1/assets": {
      "get": {
        "operationId": "list-assets",
        "summary": "List assets",
        "description": "Workspace asset library, newest first. Filter by kind, media type, favorite, project, or the generation that produced the asset.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "Comma-separated kinds, e.g. `generated,input`.",
            "schema": {
              "type": "string",
              "description": "Comma-separated kinds, e.g. `generated,input`."
            }
          },
          {
            "name": "mediaType",
            "in": "query",
            "required": false,
            "description": "`image`, `video`, or `audio`.",
            "schema": {
              "type": "string",
              "description": "`image`, `video`, or `audio`."
            }
          },
          {
            "name": "favorite",
            "in": "query",
            "required": false,
            "description": "Only favorited assets.",
            "schema": {
              "type": "boolean",
              "description": "Only favorited assets."
            }
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "description": "Filter by project.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Filter by project."
            }
          },
          {
            "name": "sourceGenerationId",
            "in": "query",
            "required": false,
            "description": "Outputs of a specific generation.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Outputs of a specific generation."
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Search filenames, MIME types, and model names.",
            "schema": {
              "type": "string",
              "description": "Search filenames, MIME types, and model names."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          },
          {
            "name": "perPage",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "description": "Page size.",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated asset list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000f1",
                      "kind": "generated",
                      "mediaType": "image",
                      "mimeType": "image/png",
                      "sizeBytes": 2411220,
                      "width": 1536,
                      "height": 1024,
                      "favorite": false,
                      "sourceGenerationId": "00000000-0000-4000-8000-0000000000aa",
                      "createdAt": "2026-10-24T12:00:18.000Z"
                    }
                  ],
                  "meta": {
                    "hasNextPage": false,
                    "nextCursor": null,
                    "total": 1
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "assets.read"
      }
    },
    "/v1/assets/{assetId}": {
      "get": {
        "operationId": "get-asset",
        "summary": "Retrieve an asset",
        "description": "Metadata for one asset. Use `/download` to get a short-lived file URL.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "assetId",
            "in": "path",
            "required": true,
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Asset id.",
              "example": "00000000-0000-4000-8000-0000000000f1"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace the asset belongs to.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace the asset belongs to.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asset record",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000f1",
                  "kind": "generated",
                  "mediaType": "image",
                  "mimeType": "image/png",
                  "sizeBytes": 2411220,
                  "status": "ready",
                  "favorite": false,
                  "createdAt": "2026-10-24T12:00:18.000Z"
                }
              }
            }
          }
        },
        "x-required-scope": "assets.read"
      },
      "patch": {
        "operationId": "update-asset",
        "summary": "Update asset metadata",
        "description": "Rename an asset, mark it favorite, or move it to a project.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "assetId",
            "in": "path",
            "required": true,
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Asset id.",
              "example": "00000000-0000-4000-8000-0000000000f1"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace the asset belongs to.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace the asset belongs to.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "favorite": {
                    "type": "boolean",
                    "description": "Favorite flag."
                  },
                  "projectId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Project to move the asset into."
                  }
                },
                "required": []
              },
              "example": {
                "favorite": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated asset",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000f1",
                  "favorite": true
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      },
      "delete": {
        "operationId": "delete-asset",
        "summary": "Delete an asset",
        "description": "Soft-deletes the asset. Storage is reclaimed asynchronously; the asset stops appearing in lists immediately.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "assetId",
            "in": "path",
            "required": true,
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Asset id.",
              "example": "00000000-0000-4000-8000-0000000000f1"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace the asset belongs to.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace the asset belongs to.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "deleted"
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      }
    },
    "/v1/assets/{assetId}/download": {
      "get": {
        "operationId": "download-asset",
        "summary": "Get a download URL",
        "description": "Returns a short-lived presigned URL for the asset bytes. The URL is time-limited — request a fresh one instead of caching it.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "assetId",
            "in": "path",
            "required": true,
            "description": "Asset id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Asset id.",
              "example": "00000000-0000-4000-8000-0000000000f1"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace the asset belongs to.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace the asset belongs to.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "disposition",
            "in": "query",
            "required": false,
            "description": "Set to `attachment` to force a download filename.",
            "schema": {
              "type": "string",
              "description": "Set to `attachment` to force a download filename."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Presigned download URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "url": "https://storage.example.com/ws/.../generated.png?X-Amz-Signature=...",
                  "expiresInSeconds": 900
                }
              }
            }
          }
        },
        "x-required-scope": "assets.read"
      }
    },
    "/v1/assets/bulk-delete": {
      "post": {
        "operationId": "bulk-delete-assets",
        "summary": "Delete assets in bulk",
        "description": "Soft-delete up to 100 assets in one request.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "assetIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "1–100 asset ids."
                  }
                },
                "required": [
                  "workspaceId",
                  "assetIds"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "assetIds": [
                  "00000000-0000-4000-8000-0000000000f1"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deleted ids",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "deleted": 1
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      }
    },
    "/v1/assets/bulk-favorite": {
      "post": {
        "operationId": "bulk-favorite-assets",
        "summary": "Favorite assets in bulk",
        "description": "Set the favorite flag on up to 100 assets.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "assetIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "1–100 asset ids."
                  },
                  "favorite": {
                    "type": "boolean",
                    "description": "Value to apply."
                  }
                },
                "required": [
                  "workspaceId",
                  "assetIds",
                  "favorite"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "assetIds": [
                  "00000000-0000-4000-8000-0000000000f1"
                ],
                "favorite": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated count",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "updated": 1
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      }
    },
    "/v1/assets/bulk-project": {
      "post": {
        "operationId": "bulk-project-assets",
        "summary": "Move assets to a project",
        "description": "Assign up to 100 assets to a project, or clear the project with `projectId: null`.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "assetIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "1–100 asset ids."
                  },
                  "projectId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "uuid",
                    "description": "Target project or null."
                  }
                },
                "required": [
                  "workspaceId",
                  "assetIds",
                  "projectId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "assetIds": [
                  "00000000-0000-4000-8000-0000000000f1"
                ],
                "projectId": "00000000-0000-4000-8000-000000000020"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated count",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "updated": 1
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      }
    },
    "/v1/assets/bulk-download": {
      "post": {
        "operationId": "bulk-download-assets",
        "summary": "Resolve download URLs in bulk",
        "description": "Returns one short-lived presigned URL per asset so a client can download a selection without N round-trips. The manifest omits ids the caller cannot access.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "assetIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "1–100 asset ids."
                  }
                },
                "required": [
                  "workspaceId",
                  "assetIds"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "assetIds": [
                  "00000000-0000-4000-8000-0000000000f1"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Download manifest",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000f1",
                      "filename": "generated.png",
                      "url": "https://storage.example.com/ws/.../generated.png?X-Amz-Signature=...",
                      "expiresInSeconds": 900
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "assets.read"
      }
    },
    "/v1/workspaces/{workspaceId}/storage": {
      "get": {
        "operationId": "workspace-storage",
        "summary": "Workspace storage usage",
        "description": "Bytes used, quota, and a per-media-type breakdown.",
        "tags": [
          "Files & assets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "required": true,
            "description": "Workspace id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace id.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Storage report",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "usageBytes": 104857600,
                  "quotaBytes": 5368709120,
                  "remainingBytes": 5263851520,
                  "byMediaType": [
                    {
                      "mediaType": "image",
                      "bytes": 94371840,
                      "assets": 41
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "usage.read"
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "get-usage",
        "summary": "Usage summary",
        "description": "Credits, provider cost, generation count, and output bytes for a workspace and date range.",
        "tags": [
          "Usage & credits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to report on.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to report on.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Start of the window.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of the window."
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "End of the window.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of the window."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage summary",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "workspaceId": "00000000-0000-4000-8000-000000000000",
                  "creditsUsed": 3280,
                  "providerCostUsd": 12.84,
                  "customerCostUsd": 32.8,
                  "grossMarginUsd": 19.96,
                  "generationsCount": 82,
                  "outputBytes": 184320000
                }
              }
            }
          }
        },
        "x-required-scope": "usage.read"
      }
    },
    "/v1/usage/breakdown": {
      "get": {
        "operationId": "usage-breakdown",
        "summary": "Usage breakdown",
        "description": "Per-model and per-day usage breakdown for charts and internal cost reporting.",
        "tags": [
          "Usage & credits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to report on.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to report on.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Start of the window.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Start of the window."
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "End of the window.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "End of the window."
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "Length of the daily series (max 365).",
            "schema": {
              "type": "integer",
              "description": "Length of the daily series (max 365).",
              "default": 30
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Breakdown",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "range": {
                    "days": 30,
                    "from": "2026-09-25"
                  },
                  "totals": {
                    "credits": 3280,
                    "generationsCount": 82,
                    "outputBytes": 184320000,
                    "customerCostUsd": 32.8
                  },
                  "byDay": [
                    {
                      "day": "2026-10-23",
                      "credits": 480,
                      "generations": 12,
                      "customerCostUsd": 4.8
                    }
                  ],
                  "byModel": [
                    {
                      "modelId": "00000000-0000-4000-8000-000000000001",
                      "modelName": "GPT Image 1",
                      "credits": 1600,
                      "generations": 40
                    }
                  ],
                  "byStatus": [
                    {
                      "status": "succeeded",
                      "count": 80
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "usage.read"
      }
    },
    "/v1/workspaces/{workspaceId}/credits": {
      "get": {
        "operationId": "credits-balance",
        "summary": "Credit balance and ledger",
        "description": "Available credits plus the paginated credit ledger (grants, reservations, settlements, refunds).",
        "tags": [
          "Usage & credits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "required": true,
            "description": "Workspace id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace id.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size (max 100).",
            "schema": {
              "type": "integer",
              "description": "Page size (max 100).",
              "default": 25
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter by ledger entry type.",
            "schema": {
              "type": "string",
              "description": "Filter by ledger entry type."
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "`newest` or `oldest`.",
            "schema": {
              "type": "string",
              "description": "`newest` or `oldest`.",
              "default": "newest"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Balance and ledger",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "workspaceId": "00000000-0000-4000-8000-000000000000",
                  "availableCredits": 720,
                  "ledger": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000c1",
                      "type": "settlement",
                      "credits": -40,
                      "description": "GPT Image 1 generation",
                      "createdAt": "2026-10-24T12:00:18.000Z"
                    }
                  ],
                  "total": 1,
                  "page": 1,
                  "limit": 25
                }
              }
            }
          }
        },
        "x-required-scope": "usage.read"
      }
    },
    "/v1/credits/top-ups": {
      "post": {
        "operationId": "create-credit-topup",
        "summary": "Create a credit top-up order",
        "description": "Creates a pending credit top-up. Dashboard-session only — API keys cannot start a purchase. Idempotent on `idempotencyKey`.",
        "tags": [
          "Usage & credits"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace to top up."
                  },
                  "credits": {
                    "type": "integer",
                    "description": "Credits to purchase."
                  },
                  "amountUsd": {
                    "type": "number",
                    "description": "Charge amount in USD."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Unique order key."
                  },
                  "tosAccepted": {
                    "type": "boolean",
                    "description": "Must be literally `true`; the acceptance is recorded with the order."
                  }
                },
                "required": [
                  "workspaceId",
                  "credits",
                  "amountUsd",
                  "idempotencyKey",
                  "tosAccepted"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "credits": 1000,
                "amountUsd": 10,
                "idempotencyKey": "topup-2026-10-24",
                "tosAccepted": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pending top-up",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000c2",
                  "status": "pending",
                  "credits": 1000
                }
              }
            }
          }
        },
        "x-required-scope": "wallet.write"
      },
      "get": {
        "operationId": "list-credit-topups",
        "summary": "List credit top-ups",
        "description": "Paginated credit top-up orders with status and date filters.",
        "tags": [
          "Usage & credits"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by order status.",
            "schema": {
              "type": "string",
              "description": "Filter by order status."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Top-up list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000c2",
                      "status": "succeeded",
                      "credits": 1000
                    }
                  ],
                  "total": 1
                }
              }
            }
          }
        },
        "x-required-scope": "usage.read"
      }
    },
    "/v1/wallet": {
      "get": {
        "operationId": "get-wallet",
        "summary": "Wallet balance",
        "description": "Balance, deposit totals, minimum deposit, status, and the next token expiry.",
        "tags": [
          "Wallet"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet view",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "workspaceId": "00000000-0000-4000-8000-000000000000",
                  "currency": "USD",
                  "availableBalanceUsd": 42.18,
                  "totalDepositedUsd": 50,
                  "totalRefundedUsd": 0,
                  "minimumDepositUsd": 10,
                  "status": "active",
                  "enabled": true,
                  "lowBalanceThresholdUsd": 10,
                  "tokensExpireAfterDays": 365,
                  "nextExpiryAt": "2027-01-01T00:00:00.000Z"
                }
              }
            }
          }
        },
        "x-required-scope": "wallet.read"
      },
      "patch": {
        "operationId": "update-wallet",
        "summary": "Update wallet settings",
        "description": "Set the low-balance notification threshold. Requires the billing role.",
        "tags": [
          "Wallet"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to update.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to update.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "lowBalanceThresholdUsd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "Email/notification threshold; null disables it."
                  }
                },
                "required": []
              },
              "example": {
                "lowBalanceThresholdUsd": 10
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated wallet view",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "active"
                }
              }
            }
          }
        },
        "x-required-scope": "wallet.write"
      }
    },
    "/v1/wallet/top-ups": {
      "post": {
        "operationId": "wallet-topup",
        "summary": "Deposit funds",
        "description": "Starts a wallet deposit checkout ($10 minimum). Dashboard-session only — residents of a browser session, not API keys.",
        "tags": [
          "Wallet"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace to credit."
                  },
                  "amountUsd": {
                    "type": "number",
                    "description": "Deposit amount (min $10)."
                  },
                  "provider": {
                    "type": "string",
                    "description": "`creem`, `atlos`, `razorpay`, or `cashfree`."
                  },
                  "tosAccepted": {
                    "type": "boolean",
                    "description": "Must be literally `true`; passed to the gateway as terms acceptance."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Unique checkout key."
                  }
                },
                "required": [
                  "workspaceId",
                  "amountUsd",
                  "tosAccepted",
                  "idempotencyKey"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "amountUsd": 25,
                "provider": "creem",
                "tosAccepted": true,
                "idempotencyKey": "wallet-2026-10-24"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Checkout created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "checkoutUrl": "https://checkout.creem.io/ch/...",
                  "paymentId": "pay_01J9Z8K2"
                }
              }
            }
          }
        },
        "x-required-scope": "wallet.write"
      }
    },
    "/v1/wallet/transactions": {
      "get": {
        "operationId": "wallet-transactions",
        "summary": "Wallet transactions",
        "description": "Charges, refunds, and adjustments against the wallet balance.",
        "tags": [
          "Wallet"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum transactions to return (max 500).",
            "schema": {
              "type": "integer",
              "description": "Maximum transactions to return (max 500).",
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transactions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000d1",
                      "type": "charge",
                      "amountUsd": -0.42,
                      "description": "GPT Image 1 generation",
                      "createdAt": "2026-10-24T12:00:18.000Z"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "wallet.read"
      }
    },
    "/v1/wallet/deposits": {
      "get": {
        "operationId": "wallet-deposits",
        "summary": "Deposit history",
        "description": "Completed and pending wallet deposits with their provider references.",
        "tags": [
          "Wallet"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum deposits to return (max 500).",
            "schema": {
              "type": "integer",
              "description": "Maximum deposits to return (max 500).",
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deposits",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000d2",
                      "amountUsd": 25,
                      "status": "succeeded"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "wallet.read"
      }
    },
    "/v1/webhooks": {
      "get": {
        "operationId": "list-webhooks",
        "summary": "List webhook endpoints",
        "description": "Configured delivery endpoints for a workspace. Secrets are never returned after creation.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Endpoints",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000e1",
                      "name": "Production",
                      "url": "https://example.com/hooks/freeind",
                      "eventTypes": [
                        "generation.completed",
                        "generation.failed"
                      ],
                      "status": "active",
                      "createdAt": "2026-10-01T09:00:00.000Z"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "webhooks.manage"
      },
      "post": {
        "operationId": "create-webhook",
        "summary": "Create a webhook endpoint",
        "description": "Registers an HTTPS endpoint and returns the signing secret exactly once. Store it server-side; verify every delivery with HMAC-SHA256 over `<timestamp>.<raw body>`.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to register against.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to register against.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Human label (max 100)."
                  },
                  "url": {
                    "type": "string",
                    "description": "HTTPS endpoint that receives POSTs."
                  },
                  "eventTypes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "One or more of `generation.completed`, `generation.failed`, `generation.cancelled`, `generation.expired`, `workflow.completed`, `workflow.failed`, `workflow.cancelled`."
                  }
                },
                "required": [
                  "name",
                  "url",
                  "eventTypes"
                ]
              },
              "example": {
                "name": "Production",
                "url": "https://example.com/hooks/freeind",
                "eventTypes": [
                  "generation.completed",
                  "generation.failed"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Endpoint created — secret shown once",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000e1",
                  "name": "Production",
                  "url": "https://example.com/hooks/freeind",
                  "eventTypes": [
                    "generation.completed",
                    "generation.failed"
                  ],
                  "status": "active",
                  "secret": "whsec_9xJ2…"
                }
              }
            }
          }
        },
        "x-required-scope": "webhooks.manage",
        "x-notes": [
          "Signature header: `t=<unix>,v1=<hex>`. The signed payload is `t + \".\" + rawBody`. Reject deliveries older than 5 minutes."
        ]
      }
    },
    "/v1/webhooks/{webhookId}": {
      "patch": {
        "operationId": "update-webhook",
        "summary": "Update a webhook endpoint",
        "description": "Change the name, URL, event types, or enable/disable the endpoint.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "description": "Webhook id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Webhook id.",
              "example": "00000000-0000-4000-8000-0000000000e1"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "New label."
                  },
                  "url": {
                    "type": "string",
                    "description": "New HTTPS endpoint."
                  },
                  "eventTypes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Replacement event set."
                  },
                  "status": {
                    "type": "string",
                    "description": "`active` or `disabled`."
                  }
                },
                "required": []
              },
              "example": {
                "status": "disabled"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated endpoint",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "disabled"
                }
              }
            }
          }
        },
        "x-required-scope": "webhooks.manage"
      },
      "delete": {
        "operationId": "delete-webhook",
        "summary": "Delete a webhook endpoint",
        "description": "Removes the endpoint. Existing delivery history is retained.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "description": "Webhook id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Webhook id.",
              "example": "00000000-0000-4000-8000-0000000000e1"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "deleted"
                }
              }
            }
          }
        },
        "x-required-scope": "webhooks.manage"
      }
    },
    "/v1/webhooks/{webhookId}/deliveries": {
      "get": {
        "operationId": "webhook-deliveries",
        "summary": "Webhook delivery history",
        "description": "Delivery attempts with status codes, errors, and retry timing — the fastest way to debug a missed event.",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "webhookId",
            "in": "path",
            "required": true,
            "description": "Webhook id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Webhook id.",
              "example": "00000000-0000-4000-8000-0000000000e1"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deliveries (newest 100)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-0000000000e9",
                      "eventType": "generation.completed",
                      "status": "delivered",
                      "attempt": 1,
                      "maxAttempts": 6,
                      "responseStatus": 200,
                      "deliveredAt": "2026-10-24T12:00:20.000Z"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "webhooks.manage"
      }
    },
    "/v1/api-keys": {
      "get": {
        "operationId": "list-api-keys",
        "summary": "List API keys",
        "description": "Keys for the current workspace with prefix, scopes, last use, and expiry.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Keys",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": []
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "create-api-key",
        "summary": "Create an API key",
        "description": "Creates a scoped key. The plaintext key is returned exactly once — store it immediately.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace to scope the key to."
                  },
                  "name": {
                    "type": "string",
                    "description": "Label (max 100)."
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "One or more of `generations.write`, `generations.read`, `usage.read`, `files.write`, `assets.read`, `wallet.read`, `wallet.write`, `webhooks.manage`, `all`."
                  },
                  "expiresAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Optional expiry."
                  }
                },
                "required": [
                  "workspaceId",
                  "name",
                  "scopes"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "name": "Production",
                "scopes": [
                  "generations.write",
                  "generations.read"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Key created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000a1",
                  "keyPrefix": "fi_live_ab12…",
                  "key": "fi_live_ab12cd34…",
                  "scopes": [
                    "generations.write",
                    "generations.read"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/api-keys/{apiKeyId}": {
      "patch": {
        "operationId": "update-api-key",
        "summary": "Update or revoke a key",
        "description": "Rename, change scopes or expiry, or revoke a key.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "apiKeyId",
            "in": "path",
            "required": true,
            "description": "Key id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Key id.",
              "example": "00000000-0000-4000-8000-0000000000a1"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "New label."
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Replacement scopes."
                  },
                  "expiresAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "New expiry."
                  },
                  "revokedAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Set to revoke."
                  }
                },
                "required": []
              },
              "example": {
                "revokedAt": "2026-10-24T12:00:00.000Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-0000000000a1"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "delete-api-key",
        "summary": "Revoke a key",
        "description": "Immediately revokes the key. Requests already in flight may still complete.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "apiKeyId",
            "in": "path",
            "required": true,
            "description": "Key id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Key id.",
              "example": "00000000-0000-4000-8000-0000000000a1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "revoked"
                }
              }
            }
          }
        }
      }
    },
    "/v1/api-keys/{apiKeyId}/usage": {
      "get": {
        "operationId": "api-key-usage",
        "summary": "Per-key usage",
        "description": "Requests, errors, latency, and credits attributed to one key.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "apiKeyId",
            "in": "path",
            "required": true,
            "description": "Key id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Key id.",
              "example": "00000000-0000-4000-8000-0000000000a1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage report",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "requests": 0
                }
              }
            }
          }
        }
      }
    },
    "/v1/me": {
      "get": {
        "operationId": "get-me",
        "summary": "Current user",
        "description": "Profile of the signed-in user.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "…",
                  "email": "you@example.com"
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces": {
      "get": {
        "operationId": "list-workspaces",
        "summary": "List workspaces",
        "description": "Workspaces the signed-in user belongs to.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Workspaces",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": []
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/subscription": {
      "get": {
        "operationId": "billing-subscription",
        "summary": "Current subscription",
        "description": "Plan, status, renewal date, and entitlements for a workspace.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Subscription",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "planId": null,
                  "status": "none"
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/portal": {
      "post": {
        "operationId": "billing-portal",
        "summary": "Open the billing portal",
        "description": "Returns a hosted portal URL for payment methods, invoices, and cancellation.",
        "tags": [
          "Dashboard & account"
        ],
        "security": [
          {
            "cookieAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace to manage."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Portal URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "url": "https://billing.example.com/..."
                }
              }
            }
          }
        }
      }
    },
    "/v1/workflows": {
      "get": {
        "operationId": "list-workflows",
        "summary": "List workflows",
        "description": "Non-template workflows in a workspace, newest update first, with an estimated credit cost and step count per workflow.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "`draft`, `active`, or `archived`.",
            "schema": {
              "type": "string",
              "description": "`draft`, `active`, or `archived`."
            }
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Filter by a workflow tag.",
            "schema": {
              "type": "string",
              "description": "Filter by a workflow tag."
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Match name or description.",
            "schema": {
              "type": "string",
              "description": "Match name or description."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          },
          {
            "name": "perPage",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "description": "Page size.",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000101",
                      "name": "Product hero",
                      "status": "active",
                      "stepCount": 2,
                      "estimatedCredits": 120,
                      "updatedAt": "2026-10-24T12:00:00.000Z"
                    }
                  ],
                  "meta": {
                    "hasNextPage": false,
                    "nextCursor": null,
                    "total": null
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.read",
        "x-notes": [
          "free.flow must be enabled for the platform; otherwise the request fails with 403 forbidden."
        ]
      },
      "post": {
        "operationId": "create-workflow",
        "summary": "Create a workflow",
        "description": "Create from a `definition` (flow inputs + nodes) or adopt a `templateId`. Definitions are validated against the workspace plan, model modes, and token references before saving.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace that owns and pays for the workflow."
                  },
                  "name": {
                    "type": "string",
                    "description": "Required when creating from a definition."
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional description (max 500)."
                  },
                  "definition": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "`{ version: 1, flowInputs: [...], nodes: [...] }`. Each node has `id`, `modelId`, `mode`, `params`; optional `input`/`inputs` link a node to a flow input or a previous node."
                  },
                  "templateId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Adopt a template instead of supplying a definition (mutually exclusive)."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Up to 20 tags, 30 chars each."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "name": "Product hero",
                "definition": {
                  "version": 1,
                  "flowInputs": [
                    {
                      "id": "subject",
                      "name": "Subject",
                      "mediaType": "text",
                      "required": true,
                      "primary": true
                    }
                  ],
                  "nodes": [
                    {
                      "id": "hero",
                      "title": "Hero image",
                      "modelId": "00000000-0000-4000-8000-000000000001",
                      "mode": "text_to_image",
                      "params": {
                        "mode": "text_to_image",
                        "prompt": "{{subject}}, studio lighting, 85mm photograph"
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Workflow created as a draft",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000101",
                  "name": "Product hero",
                  "status": "draft",
                  "isTemplate": false,
                  "definition": {
                    "version": 1,
                    "flowInputs": [],
                    "nodes": []
                  },
                  "createdAt": "2026-10-24T12:00:00.000Z"
                }
              }
            }
          },
          "422": {
            "description": "Invalid definition, model, or token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "error": {
                    "code": "validation_error",
                    "message": "Unknown token {{subject}} in node hero",
                    "requestId": "req_01J9Z8K2"
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write",
        "x-notes": [
          "Node params may reference `{{flowInputId}}` and `{{nodeId}}` tokens. They are resolved in one pass at run time."
        ]
      }
    },
    "/v1/workflows/{workflowId}": {
      "get": {
        "operationId": "get-workflow",
        "summary": "Retrieve a workflow",
        "description": "Full definition, status, tags, and reference-template metadata when present.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Workflow id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workflow id.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Workflow",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000101",
                  "name": "Product hero",
                  "status": "active",
                  "definition": {
                    "version": 1,
                    "flowInputs": [],
                    "nodes": []
                  },
                  "createdAt": "2026-10-24T12:00:00.000Z",
                  "updatedAt": "2026-10-24T12:05:00.000Z"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.read"
      },
      "patch": {
        "operationId": "update-workflow",
        "summary": "Update a workflow",
        "description": "Rename, re-describe, retag, archive, or replace the definition. Updating a definition re-validates every node.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Workflow id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workflow id.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "New name."
                  },
                  "description": {
                    "type": "string",
                    "description": "New description."
                  },
                  "status": {
                    "type": "string",
                    "description": "`draft`, `active`, or `archived`."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Replacement tag list."
                  },
                  "definition": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Replacement graph (re-validated)."
                  }
                },
                "required": []
              },
              "example": {
                "status": "active",
                "tags": [
                  "product",
                  "hero"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated workflow",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000101"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      },
      "delete": {
        "operationId": "delete-workflow",
        "summary": "Delete a workflow",
        "description": "Deletes the workflow. Runs and their steps are retained for history.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Workflow id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workflow id.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "deleted": true
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/workflows/templates": {
      "get": {
        "operationId": "workflow-templates",
        "summary": "List workflow templates",
        "description": "Built-in templates, the workspace’s own templates, or both. Templates marked as reference analyses include their analysis status.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "scope",
            "in": "query",
            "required": false,
            "description": "`builtin` (default), `workspace`, or `all`.",
            "schema": {
              "type": "string",
              "description": "`builtin` (default), `workspace`, or `all`.",
              "default": "builtin"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "description": "Required for `workspace` and `all` scopes.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Required for `workspace` and `all` scopes."
            }
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Filter by tag.",
            "schema": {
              "type": "string",
              "description": "Filter by tag."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          },
          {
            "name": "perPage",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "description": "Page size.",
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Templates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000101",
                      "name": "Cinematic product reveal",
                      "isTemplate": true,
                      "tags": [
                        "product",
                        "video"
                      ],
                      "templateMeta": {
                        "kind": "reference",
                        "analysisStatus": "ready"
                      }
                    }
                  ],
                  "meta": {
                    "hasNextPage": false,
                    "nextCursor": null,
                    "total": null
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.read",
        "x-notes": [
          "Adopt a template with `POST /v1/workflows` and `{ \"templateId\": \"…\" }`."
        ]
      }
    },
    "/v1/workflows/{workflowId}/duplicate": {
      "post": {
        "operationId": "duplicate-workflow",
        "summary": "Duplicate a workflow",
        "description": "Creates a copy in the same or another workspace the caller can access.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Source workflow id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Source workflow id.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace that receives the copy."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Copied workflow",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000102"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/workflows/{workflowId}/activate": {
      "post": {
        "operationId": "activate-workflow",
        "summary": "Activate a reference template",
        "description": "Publishes a reference-analysis template once its analysis is ready and its `subject` flow input is valid. Generated workflows from `POST /v1/workflows` start as drafts; use `PATCH` for ordinary ones.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Template workflow id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Template workflow id.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Activated template",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000101",
                  "status": "active"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/workflows/{workflowId}/runs": {
      "post": {
        "operationId": "create-workflow-run",
        "summary": "Start a workflow run",
        "description": "Starts the pipeline with flow-input values. Each run reserves credits up front and advances step by step; poll `GET /v1/runs/{runId}` until it reaches a terminal status.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Workflow to run.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workflow to run.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "input": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Map of flow input id → `{ text }` or `{ assetIds }` / `{ urls }`. Media inputs accept up to 4 files."
                  },
                  "paymentMode": {
                    "type": "string",
                    "description": "`credits` (default), `wallet`, or `direct`."
                  },
                  "startStepIndex": {
                    "type": "integer",
                    "description": "Resume from a specific step index.",
                    "default": 0
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Safe-retry key."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "input": {
                  "subject": {
                    "text": "a red fox in fresh snow"
                  }
                },
                "paymentMode": "credits"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Run queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000102",
                  "workflowId": "00000000-0000-4000-8000-000000000101",
                  "status": "queued",
                  "stepIndex": 0,
                  "estimatedCredits": 40,
                  "steps": [],
                  "createdAt": "2026-10-24T12:00:00.000Z"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write",
        "x-notes": [
          "A workflow must not be archived. Run statuses: queued, running, succeeded, failed, cancelled, paused."
        ]
      },
      "get": {
        "operationId": "list-workflow-runs",
        "summary": "List runs for a workflow",
        "description": "Recent runs with per-run step progress.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Workflow id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workflow id.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by run status.",
            "schema": {
              "type": "string",
              "description": "Filter by run status."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Runs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000102",
                      "status": "succeeded",
                      "stepProgress": {
                        "total": 2,
                        "succeeded": 2
                      },
                      "estimatedCredits": 120,
                      "actualCredits": 120
                    }
                  ],
                  "meta": {
                    "hasNextPage": false,
                    "nextCursor": null,
                    "total": null
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.read"
      }
    },
    "/v1/runs": {
      "get": {
        "operationId": "list-runs",
        "summary": "List all workflow runs",
        "description": "Workspace-wide run history, optionally filtered by workflow or status.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "workflowId",
            "in": "query",
            "required": false,
            "description": "Filter by workflow.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Filter by workflow."
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by run status.",
            "schema": {
              "type": "string",
              "description": "Filter by run status."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Runs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [],
                  "meta": {
                    "hasNextPage": false,
                    "nextCursor": null,
                    "total": null
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.read"
      }
    },
    "/v1/runs/{runId}": {
      "get": {
        "operationId": "get-run",
        "summary": "Retrieve a run",
        "description": "Run state plus every step (node id, status, generation id, credits, timing). This is the polling endpoint for a workflow run.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run with steps",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000102",
                  "status": "succeeded",
                  "workflowName": "Product hero",
                  "stepIndex": 1,
                  "estimatedCredits": 40,
                  "actualCredits": 40,
                  "steps": [
                    {
                      "id": "00000000-0000-4000-8000-000000000111",
                      "nodeId": "hero",
                      "stepOrder": 0,
                      "status": "succeeded",
                      "generationId": "00000000-0000-4000-8000-0000000000aa",
                      "actualCredits": 40
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.read"
      }
    },
    "/v1/runs/{runId}/cancel": {
      "post": {
        "operationId": "cancel-run",
        "summary": "Cancel a run",
        "description": "Cancels the active step and stops the pipeline. Already-finished steps are kept.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": "string",
                    "description": "Optional audit reason."
                  }
                },
                "required": []
              },
              "example": {
                "reason": "Wrong input"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cancellation accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "cancel_requested"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/runs/{runId}/pause": {
      "post": {
        "operationId": "pause-run",
        "summary": "Pause a run",
        "description": "Lets the current step finish, then holds the run before the next step.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paused",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "paused"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/runs/{runId}/resume": {
      "post": {
        "operationId": "resume-run",
        "summary": "Resume a paused run",
        "description": "Continues a paused run from the next step.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Running",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "status": "running"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/runs/{runId}/retry": {
      "post": {
        "operationId": "retry-run",
        "summary": "Retry a finished run",
        "description": "Starts a new run from the failed step, reusing earlier successful steps. The new run carries `retryOfRunId`.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Parent run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Parent run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "paymentMode": {
                    "type": "string",
                    "description": "Override the payment mode."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Safe-retry key."
                  }
                },
                "required": []
              },
              "example": {
                "paymentMode": "credits"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "New run",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000112",
                  "retryOfRunId": "00000000-0000-4000-8000-000000000102"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/runs/{runId}/steps/{nodeId}/regenerate": {
      "post": {
        "operationId": "regenerate-step",
        "summary": "Regenerate one step",
        "description": "Forks the run at a node: that node and everything downstream re-run, earlier outputs are reused. Useful for iterating on one shot without paying for the whole pipeline.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Parent run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Parent run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          },
          {
            "name": "nodeId",
            "in": "path",
            "required": true,
            "description": "Node id from the run’s definition.",
            "schema": {
              "type": "string",
              "description": "Node id from the run’s definition.",
              "example": "hero"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "paymentMode": {
                    "type": "string",
                    "description": "Override the payment mode."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Safe-retry key."
                  }
                },
                "required": []
              },
              "example": {}
            }
          }
        },
        "responses": {
          "201": {
            "description": "Forked run",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000113",
                  "retryOfRunId": "00000000-0000-4000-8000-000000000102"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write",
        "x-notes": [
          "The parent run must be in a terminal state (succeeded, failed, or cancelled)."
        ]
      }
    },
    "/v1/runs/{runId}/payment": {
      "post": {
        "operationId": "run-payment",
        "summary": "Open a checkout for a direct-payment run",
        "description": "Creates or resumes the hosted checkout for a run created with `paymentMode: \"direct\"`.",
        "tags": [
          "free.flow · Workflows"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string",
                    "description": "`creem`, `atlos`, `razorpay`, or `cashfree`."
                  },
                  "tosAccepted": {
                    "type": "boolean",
                    "description": "Terms acceptance where required."
                  }
                },
                "required": []
              },
              "example": {
                "provider": "creem",
                "tosAccepted": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "payment": {
                    "checkoutUrl": "https://checkout.creem.io/ch/...",
                    "paymentSessionId": "ps_01J9Z8K2",
                    "amountUsd": 0.42,
                    "credits": 40
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/reference/quote": {
      "post": {
        "operationId": "reference-quote",
        "summary": "Quote a reference analysis",
        "description": "Estimated and maximum credits for analyzing an asset. Returns `cached: true` (and the existing template id) when that exact asset was analyzed before.",
        "tags": [
          "free.flow · Reference templates"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "assetId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Image or video asset to analyze."
                  },
                  "options": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "`keepLook`, `keepStructure`, `maxShots` (1–6), `includeMusic`, `subjectMode` (`text` | `own-photo`)."
                  }
                },
                "required": [
                  "workspaceId",
                  "assetId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "assetId": "00000000-0000-4000-8000-0000000000f1",
                "options": {
                  "keepLook": true,
                  "keepStructure": true,
                  "maxShots": 3
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Quote",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "assetId": "00000000-0000-4000-8000-0000000000f1",
                  "mediaType": "image",
                  "analyzerModel": "GPT-4.1 mini",
                  "estimatedCredits": 12,
                  "maximumCredits": 20,
                  "cached": false
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/reference/analyses": {
      "post": {
        "operationId": "reference-analyze",
        "summary": "Start a reference analysis",
        "description": "Queues the analysis and returns the workflow id it is building. Re-analyzing the same asset is free; an in-flight analysis returns 202 with the same id.",
        "tags": [
          "free.flow · Reference templates"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "assetId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Image or video asset."
                  },
                  "options": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Same options as the quote."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Safe-retry key."
                  }
                },
                "required": [
                  "workspaceId",
                  "assetId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "assetId": "00000000-0000-4000-8000-0000000000f1",
                "options": {
                  "keepLook": true,
                  "keepStructure": true,
                  "maxShots": 3
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Cached analysis reused",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "workflowId": "00000000-0000-4000-8000-000000000101",
                  "status": "ready",
                  "cached": true
                }
              }
            }
          },
          "202": {
            "description": "Analysis queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "workflowId": "00000000-0000-4000-8000-000000000101",
                  "status": "queued",
                  "estimatedCredits": 12,
                  "maximumCredits": 20
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/reference/analyses/{workflowId}": {
      "get": {
        "operationId": "get-reference-analysis",
        "summary": "Retrieve a reference analysis",
        "description": "Analysis status plus the derived template metadata (spec, slots, shots). Poll until `status` is `ready` before adopting the template.",
        "tags": [
          "free.flow · Reference templates"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Workflow id returned by the analysis.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workflow id returned by the analysis.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Analysis",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "workflowId": "00000000-0000-4000-8000-000000000101",
                  "name": "Cinematic product reveal",
                  "status": "ready",
                  "steps": 3,
                  "meta": {
                    "kind": "reference",
                    "analysisStatus": "ready",
                    "slots": []
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.read"
      }
    },
    "/v1/reference/analyses/{workflowId}/cancel": {
      "post": {
        "operationId": "cancel-reference-analysis",
        "summary": "Cancel an analysis",
        "description": "Cancels a queued or running analysis and releases its credit reservation.",
        "tags": [
          "free.flow · Reference templates"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Analysis workflow id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Analysis workflow id.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancelled",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "workflowId": "00000000-0000-4000-8000-000000000101",
                  "status": "cancelled"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/reference/analyses/{workflowId}/retry": {
      "post": {
        "operationId": "retry-reference-analysis",
        "summary": "Retry an analysis",
        "description": "Re-queues a failed analysis using the stored options.",
        "tags": [
          "free.flow · Reference templates"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workflowId",
            "in": "path",
            "required": true,
            "description": "Analysis workflow id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Analysis workflow id.",
              "example": "00000000-0000-4000-8000-000000000101"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Re-queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "workflowId": "00000000-0000-4000-8000-000000000101",
                  "status": "queued"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/slides/decks": {
      "post": {
        "operationId": "create-slide-deck",
        "summary": "Create a slide deck",
        "description": "Generates the outline from a brief, then queues one text-to-image generation per slide. Requires a paid plan and at least one image model available to the workspace.",
        "tags": [
          "free.slides · Presentations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "brief": {
                    "type": "string",
                    "description": "What the deck is about."
                  },
                  "slideCount": {
                    "type": "integer",
                    "description": "Number of slides.",
                    "default": 8
                  },
                  "style": {
                    "type": "string",
                    "description": "Visual/writing style hint."
                  },
                  "aspectRatio": {
                    "type": "string",
                    "description": "`16:9` or `4:3`.",
                    "default": "16:9"
                  },
                  "imageModelId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Text-to-image model for the visuals."
                  },
                  "paymentMode": {
                    "type": "string",
                    "description": "`credits`, `wallet`, or `direct`."
                  }
                },
                "required": [
                  "workspaceId",
                  "brief"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "brief": "Q4 product launch: what shipped, lessons learned, next bets",
                "slideCount": 8,
                "style": "Minimal, editorial, warm neutrals",
                "aspectRatio": "16:9"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Deck created and slides queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000103",
                  "title": "Q4 Product Launch",
                  "status": "generating",
                  "slideCount": 8,
                  "estimatedCredits": 360,
                  "slides": [
                    {
                      "index": 0,
                      "title": "What shipped",
                      "status": "queued",
                      "assetId": null
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      },
      "get": {
        "operationId": "list-slide-decks",
        "summary": "List slide decks",
        "description": "Decks for a workspace, newest first, each with per-slide generation state.",
        "tags": [
          "free.slides · Presentations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Decks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [],
                  "meta": {
                    "hasNextPage": false,
                    "nextCursor": null,
                    "total": null
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/slides/decks/{deckId}": {
      "get": {
        "operationId": "get-slide-deck",
        "summary": "Retrieve a slide deck",
        "description": "Deck outline, slide statuses, asset ids, and export availability. Poll until every slide finishes.",
        "tags": [
          "free.slides · Presentations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "deckId",
            "in": "path",
            "required": true,
            "description": "Deck id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Deck id.",
              "example": "00000000-0000-4000-8000-000000000103"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deck",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000103",
                  "title": "Q4 Product Launch",
                  "status": "ready",
                  "exported": {
                    "pptx": false,
                    "pdf": false
                  },
                  "slides": [
                    {
                      "index": 0,
                      "title": "What shipped",
                      "status": "succeeded",
                      "assetId": "00000000-0000-4000-8000-0000000000f1"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      },
      "patch": {
        "operationId": "update-slide-deck",
        "summary": "Edit deck text",
        "description": "Rename the deck or edit slide titles and bullets. Background visuals are unchanged.",
        "tags": [
          "free.slides · Presentations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "deckId",
            "in": "path",
            "required": true,
            "description": "Deck id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Deck id.",
              "example": "00000000-0000-4000-8000-000000000103"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "title": {
                    "type": "string",
                    "description": "New deck title."
                  },
                  "slides": {
                    "type": "array",
                    "items": {},
                    "description": "Partial slide edits: `{ index, title?, bullets? }`."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "slides": [
                  {
                    "index": 0,
                    "title": "What shipped in Q4",
                    "bullets": [
                      "Faster generation",
                      "New tools"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated deck",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000103",
                  "status": "ready"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/slides/decks/{deckId}/export": {
      "post": {
        "operationId": "export-slide-deck",
        "summary": "Export a deck",
        "description": "Renders every slide and writes both a raster PDF and an editable PPTX. Every slide must have succeeded.",
        "tags": [
          "free.slides · Presentations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "deckId",
            "in": "path",
            "required": true,
            "description": "Deck id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Deck id.",
              "example": "00000000-0000-4000-8000-000000000103"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deck exported",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000103",
                  "exported": {
                    "pptx": true,
                    "pdf": true
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/slides/decks/{deckId}/download/{format}": {
      "get": {
        "operationId": "download-slide-deck",
        "summary": "Download an exported deck",
        "description": "Short-lived URL for the PPTX or PDF. Export the deck first.",
        "tags": [
          "free.slides · Presentations"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "deckId",
            "in": "path",
            "required": true,
            "description": "Deck id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Deck id.",
              "example": "00000000-0000-4000-8000-000000000103"
            }
          },
          {
            "name": "format",
            "in": "path",
            "required": true,
            "description": "`pptx` or `pdf`.",
            "schema": {
              "type": "string",
              "description": "`pptx` or `pdf`.",
              "example": "pptx"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "url": "https://storage.example.com/.../deck.pptx?X-Amz-Signature=...",
                  "filename": "q4-product-launch.pptx",
                  "expiresInSeconds": 900
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/podcast/script": {
      "post": {
        "operationId": "write-podcast-script",
        "summary": "Write a podcast script",
        "description": "Turns a brief and a speaker roster into a timed dialogue script. Two to four speakers; each speaker can carry a persona to steer the writing.",
        "tags": [
          "free.podcast · Episodes"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "brief": {
                    "type": "string",
                    "description": "Episode topic and angle."
                  },
                  "speakers": {
                    "type": "array",
                    "items": {},
                    "description": "`{ id, name, persona? }` per speaker (2–4)."
                  },
                  "tone": {
                    "type": "string",
                    "description": "e.g. curious, contrarian, warm."
                  },
                  "audience": {
                    "type": "string",
                    "description": "Who the episode is for."
                  },
                  "language": {
                    "type": "string",
                    "description": "Spoken language."
                  },
                  "durationSeconds": {
                    "type": "integer",
                    "description": "Target length (30–3600)."
                  }
                },
                "required": [
                  "workspaceId",
                  "brief",
                  "speakers"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "brief": "Why small teams are shipping faster with AI tools",
                "speakers": [
                  {
                    "id": "host",
                    "name": "Maya",
                    "persona": "curious host"
                  },
                  {
                    "id": "guest",
                    "name": "Dev",
                    "persona": "pragmatic engineer"
                  }
                ],
                "tone": "curious",
                "durationSeconds": 600
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Script",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "title": "Small Teams, Big Ships",
                  "segments": [
                    {
                      "speakerId": "host",
                      "text": "Welcome back. Today we are asking…"
                    },
                    {
                      "speakerId": "guest",
                      "text": "The bottleneck was never the model…"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/podcast/episodes": {
      "post": {
        "operationId": "create-podcast-episode",
        "summary": "Render a podcast episode",
        "description": "Renders a (possibly edited) script: one TTS generation per turn plus an audio_concat mix. Optional music bed and outro, with ducking.",
        "tags": [
          "free.podcast · Episodes"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "title": {
                    "type": "string",
                    "description": "Episode title."
                  },
                  "speakers": {
                    "type": "array",
                    "items": {},
                    "description": "Full speaker roster including voice/model/speed for rendering."
                  },
                  "segments": {
                    "type": "array",
                    "items": {},
                    "description": "Ordered `{ speakerId, text }` turns (2+)."
                  },
                  "concat": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "`gapMs`, `crossfadeMs`, `outputFormat` (mp3/wav/ogg)."
                  },
                  "musicAssetId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Music bed asset."
                  },
                  "outroAssetId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Outro sting asset."
                  },
                  "musicVolume": {
                    "type": "number",
                    "description": "Music bed volume (default 0.25)."
                  },
                  "duckMusic": {
                    "type": "boolean",
                    "description": "Duck the bed under speech (default true)."
                  },
                  "paymentMode": {
                    "type": "string",
                    "description": "`credits`, `wallet`, or `direct`."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Safe-retry key."
                  }
                },
                "required": [
                  "workspaceId",
                  "title",
                  "speakers",
                  "segments"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "title": "Small Teams, Big Ships",
                "speakers": [
                  {
                    "id": "host",
                    "name": "Maya",
                    "voice": "alloy",
                    "speed": 1
                  },
                  {
                    "id": "guest",
                    "name": "Dev",
                    "voice": "ash",
                    "speed": 1
                  }
                ],
                "segments": [
                  {
                    "speakerId": "host",
                    "text": "Welcome back to the show."
                  },
                  {
                    "speakerId": "guest",
                    "text": "Thanks for having me."
                  }
                ],
                "concat": {
                  "gapMs": 300,
                  "outputFormat": "mp3"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Run queued",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000102",
                  "status": "queued",
                  "estimatedCredits": 240
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/podcast/runs/{runId}/transcript": {
      "get": {
        "operationId": "podcast-transcript",
        "summary": "Episode transcript (SRT)",
        "description": "SRT captions timed by each rendered turn’s real audio duration.",
        "tags": [
          "free.podcast · Episodes"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Podcast run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Podcast run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transcript",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "srt": "1\\n00:00:00,000 --> 00:00:03,200\\nWelcome back to the show.\\n",
                  "segments": [
                    {
                      "startSeconds": 0,
                      "endSeconds": 3.2,
                      "text": "Welcome back to the show."
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/podcast/runs/{runId}/retake": {
      "post": {
        "operationId": "podcast-retake",
        "summary": "Re-render one line",
        "description": "Regenerates a single `seg_<n>` turn and rebuilds the mix, without paying for the other lines.",
        "tags": [
          "free.podcast · Episodes"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "Podcast run id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Podcast run id.",
              "example": "00000000-0000-4000-8000-000000000102"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "nodeId": {
                    "type": "string",
                    "description": "Segment node id, e.g. `seg_2`."
                  },
                  "paymentMode": {
                    "type": "string",
                    "description": "Override the payment mode."
                  }
                },
                "required": [
                  "workspaceId",
                  "nodeId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "nodeId": "seg_2"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Retake run",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000114",
                  "retryOfRunId": "00000000-0000-4000-8000-000000000102"
                }
              }
            }
          }
        },
        "x-required-scope": "workflows.write"
      }
    },
    "/v1/audiobooks": {
      "post": {
        "operationId": "create-audiobook",
        "summary": "Create an audiobook",
        "description": "Chunks the text, queues one TTS generation per chunk, and returns the job with per-chunk progress.",
        "tags": [
          "free.audiobook · Narration"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "title": {
                    "type": "string",
                    "description": "Audiobook title."
                  },
                  "text": {
                    "type": "string",
                    "description": "Full narration text."
                  },
                  "voiceModelId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Text-to-speech model."
                  },
                  "voice": {
                    "type": "string",
                    "description": "Provider voice id/name."
                  },
                  "format": {
                    "type": "string",
                    "description": "`mp3`, `wav`, or `ogg`."
                  },
                  "gapMs": {
                    "type": "integer",
                    "description": "Silence between chunks (default 400)."
                  },
                  "speed": {
                    "type": "number",
                    "description": "Narration speed (0.5–2)."
                  },
                  "paymentMode": {
                    "type": "string",
                    "description": "`credits`, `wallet`, or `direct`."
                  }
                },
                "required": [
                  "workspaceId",
                  "title",
                  "text"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "title": "The Long Winter",
                "text": "Chapter one. The snow had not stopped for eleven days…",
                "format": "mp3",
                "gapMs": 400
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Job created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000104",
                  "title": "The Long Winter",
                  "status": "generating",
                  "chunkCount": 6,
                  "estimatedSeconds": 540,
                  "estimatedCredits": 180,
                  "chunks": [
                    {
                      "index": 0,
                      "characters": 1800,
                      "status": "queued"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      },
      "get": {
        "operationId": "list-audiobooks",
        "summary": "List audiobooks",
        "description": "Jobs for a workspace, newest first, with chunk progress.",
        "tags": [
          "free.audiobook · Narration"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Jobs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [],
                  "meta": {
                    "hasNextPage": false,
                    "nextCursor": null,
                    "total": null
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/audiobooks/{jobId}": {
      "get": {
        "operationId": "get-audiobook",
        "summary": "Retrieve an audiobook",
        "description": "Job state, per-chunk progress, and the final asset id once complete.",
        "tags": [
          "free.audiobook · Narration"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "Audiobook job id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Audiobook job id.",
              "example": "00000000-0000-4000-8000-000000000104"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000104",
                  "status": "complete",
                  "outputAssetId": "00000000-0000-4000-8000-0000000000f1",
                  "chunks": [
                    {
                      "index": 0,
                      "status": "succeeded"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/audiobooks/{jobId}/assemble": {
      "post": {
        "operationId": "assemble-audiobook",
        "summary": "Assemble the final mix",
        "description": "Concatenates every rendered chunk in order. Idempotent while a mix is running or complete; retry after a failed mix.",
        "tags": [
          "free.audiobook · Narration"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "Audiobook job id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Audiobook job id.",
              "example": "00000000-0000-4000-8000-000000000104"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Mixing",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000104",
                  "status": "assembling"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/audiobooks/{jobId}/download": {
      "get": {
        "operationId": "download-audiobook",
        "summary": "Download the audiobook",
        "description": "Short-lived URL for the finished audio file.",
        "tags": [
          "free.audiobook · Narration"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "Audiobook job id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Audiobook job id.",
              "example": "00000000-0000-4000-8000-000000000104"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "url": "https://storage.example.com/.../audiobook.mp3?X-Amz-Signature=...",
                  "filename": "the-long-winter.mp3"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/audiobooks/{jobId}/transcript": {
      "get": {
        "operationId": "audiobook-transcript",
        "summary": "Audiobook transcript (SRT)",
        "description": "SRT captions timed by each chunk’s real audio duration.",
        "tags": [
          "free.audiobook · Narration"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "Audiobook job id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Audiobook job id.",
              "example": "00000000-0000-4000-8000-000000000104"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Transcript",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "srt": "1\\n00:00:00,000 --> 00:00:08,400\\nChapter one…\\n",
                  "segments": []
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/voices": {
      "get": {
        "operationId": "list-voices",
        "summary": "List cloned voices",
        "description": "Voice profiles for a workspace with status, labels, and preview URL.",
        "tags": [
          "free.speech · Voices"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by profile status.",
            "schema": {
              "type": "string",
              "description": "Filter by profile status."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Voices",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000105",
                      "name": "Narrator — warm",
                      "providerVoiceId": "elv_abc123",
                      "status": "active",
                      "labels": {
                        "language": "en",
                        "gender": "female"
                      },
                      "previewUrl": "https://cdn.example.com/preview.mp3"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      },
      "post": {
        "operationId": "create-voice",
        "summary": "Clone a voice",
        "description": "Submits 1–5 sample assets to the cloning provider and stores the resulting profile. Requires `consent: true`.",
        "tags": [
          "free.speech · Voices"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "name": {
                    "type": "string",
                    "description": "Profile name (max 120)."
                  },
                  "description": {
                    "type": "string",
                    "description": "Internal description."
                  },
                  "sampleAssetIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "1–5 uploaded audio assets."
                  },
                  "labels": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Free-form labels (language, accent…)."
                  },
                  "consent": {
                    "type": "boolean",
                    "description": "Must be literally `true` — the operator confirms the right to clone."
                  }
                },
                "required": [
                  "workspaceId",
                  "name",
                  "sampleAssetIds",
                  "consent"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "name": "Narrator — warm",
                "sampleAssetIds": [
                  "00000000-0000-4000-8000-0000000000b1"
                ],
                "labels": {
                  "language": "en"
                },
                "consent": true
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Voice profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000105",
                  "name": "Narrator — warm",
                  "providerVoiceId": "elv_abc123",
                  "status": "active"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/voices/{voiceProfileId}/refresh": {
      "post": {
        "operationId": "refresh-voice",
        "summary": "Re-verify a voice",
        "description": "Re-checks the provider-side voice and updates the stored status/preview.",
        "tags": [
          "free.speech · Voices"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "voiceProfileId",
            "in": "path",
            "required": true,
            "description": "Voice profile id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Voice profile id.",
              "example": "00000000-0000-4000-8000-000000000105"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated profile",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000105",
                  "status": "active"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/voices/{voiceProfileId}": {
      "delete": {
        "operationId": "delete-voice",
        "summary": "Delete a voice",
        "description": "Removes the profile and the provider-side voice where supported.",
        "tags": [
          "free.speech · Voices"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "voiceProfileId",
            "in": "path",
            "required": true,
            "description": "Voice profile id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Voice profile id.",
              "example": "00000000-0000-4000-8000-000000000105"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "deleted": true
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/studio/effects": {
      "get": {
        "operationId": "studio-effects",
        "summary": "Effects and transitions catalog",
        "description": "Available video transitions, video effects, audio effects, and presets, with auto-generated controls. Public — no auth.",
        "tags": [
          "free.studio · Storyboard to video"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Catalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "transitions": [
                    {
                      "id": "crossfade",
                      "label": "Crossfade"
                    }
                  ],
                  "videoEffects": [
                    {
                      "id": "vignette",
                      "label": "Vignette"
                    }
                  ],
                  "audioEffects": [
                    {
                      "id": "duck",
                      "label": "Duck music"
                    }
                  ],
                  "presets": [
                    {
                      "id": "cinematic",
                      "label": "Cinematic"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/studio/plans": {
      "post": {
        "operationId": "create-studio-plan",
        "summary": "Create a studio plan",
        "description": "Turns a brief (prompt, optional media, duration, aspect ratio, quality) into a storyboard and a persisted workflow definition. Nothing renders until you run the plan.",
        "tags": [
          "free.studio · Storyboard to video"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "brief": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "`prompt`, `durationSeconds` (5–600), `aspectRatio`, `size`, `quality`, optional input assets/URLs, `voiceover`, `music`, `captions`, `budgetCredits`."
                  },
                  "tool": {
                    "type": "string",
                    "description": "`ad` to enforce the free.ad kill switch."
                  }
                },
                "required": [
                  "workspaceId",
                  "brief"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "brief": {
                  "prompt": "A 20-second launch ad for a matte black espresso machine",
                  "durationSeconds": 20,
                  "aspectRatio": "16:9",
                  "size": "wide",
                  "quality": "standard",
                  "captions": true
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Plan + storyboard",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000106",
                  "status": "draft",
                  "plan": {
                    "title": "Matte black launch",
                    "shots": [
                      {
                        "id": "shot_1",
                        "title": "Steam macro",
                        "mode": "text_to_video"
                      }
                    ],
                    "estimatedCredits": 480
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      },
      "get": {
        "operationId": "list-studio-plans",
        "summary": "List studio plans",
        "description": "Plans for a workspace with status and credit estimate.",
        "tags": [
          "free.studio · Storyboard to video"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filter by plan status.",
            "schema": {
              "type": "string",
              "description": "Filter by plan status."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plans",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": []
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/studio/plans/{planId}": {
      "get": {
        "operationId": "get-studio-plan",
        "summary": "Retrieve a studio plan",
        "description": "Storyboard, shots, audio, assembly settings, and estimated credits.",
        "tags": [
          "free.studio · Storyboard to video"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "planId",
            "in": "path",
            "required": true,
            "description": "Plan id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Plan id.",
              "example": "00000000-0000-4000-8000-000000000106"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Plan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000106",
                  "status": "draft"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      },
      "put": {
        "operationId": "update-studio-plan",
        "summary": "Update a studio plan",
        "description": "Saves an edited storyboard and rebuilds its workflow definition.",
        "tags": [
          "free.studio · Storyboard to video"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "planId",
            "in": "path",
            "required": true,
            "description": "Plan id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Plan id.",
              "example": "00000000-0000-4000-8000-000000000106"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "plan": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Full plan object (version 1)."
                  }
                },
                "required": [
                  "workspaceId",
                  "plan"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "plan": {
                  "version": 1
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated plan",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000106"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/studio/plans/{planId}/run": {
      "post": {
        "operationId": "run-studio-plan",
        "summary": "Render a studio plan",
        "description": "Starts the storyboard workflow and returns the run. Poll the run like any free.flow run.",
        "tags": [
          "free.studio · Storyboard to video"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "planId",
            "in": "path",
            "required": true,
            "description": "Plan id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Plan id.",
              "example": "00000000-0000-4000-8000-000000000106"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "paymentMode": {
                    "type": "string",
                    "description": "`credits`, `wallet`, or `direct`."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "description": "Safe-retry key."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "paymentMode": "credits"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Run started",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000102",
                  "status": "queued"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/studio/plans/{planId}/srt": {
      "get": {
        "operationId": "studio-srt",
        "summary": "Plan captions (SRT)",
        "description": "The same caption timeline the render burns in, exported as SRT.",
        "tags": [
          "free.studio · Storyboard to video"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "planId",
            "in": "path",
            "required": true,
            "description": "Plan id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Plan id.",
              "example": "00000000-0000-4000-8000-000000000106"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Captions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "srt": "1\\n00:00:00,000 --> 00:00:02,400\\nMatte black.\\n",
                  "filename": "plan.srt",
                  "segments": []
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      }
    },
    "/v1/boards": {
      "get": {
        "operationId": "list-boards",
        "summary": "List boards",
        "description": "Active or archived boards with item counts.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "`active` or `archived`.",
            "schema": {
              "type": "string",
              "description": "`active` or `archived`."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Boards",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000107",
                      "name": "Winter launch",
                      "status": "active",
                      "itemCount": 12
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      },
      "post": {
        "operationId": "create-board",
        "summary": "Create a board",
        "description": "Creates an empty board. Requires a paid plan.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "name": {
                    "type": "string",
                    "description": "Board name."
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional description."
                  }
                },
                "required": [
                  "workspaceId",
                  "name"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "name": "Winter launch",
                "description": "Direction options for the campaign"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Board",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000107",
                  "name": "Winter launch",
                  "itemCount": 0
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/boards/{boardId}": {
      "get": {
        "operationId": "get-board",
        "summary": "Retrieve a board",
        "description": "Board metadata plus its ordered items.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "boardId",
            "in": "path",
            "required": true,
            "description": "Board id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board id.",
              "example": "00000000-0000-4000-8000-000000000107"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Board detail",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "board": {
                    "id": "00000000-0000-4000-8000-000000000107",
                    "name": "Winter launch",
                    "itemCount": 1
                  },
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000108",
                      "assetId": "00000000-0000-4000-8000-0000000000f1",
                      "position": 0,
                      "note": null
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      },
      "patch": {
        "operationId": "update-board",
        "summary": "Rename or archive a board",
        "description": "Updates name, description, or status.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "boardId",
            "in": "path",
            "required": true,
            "description": "Board id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board id.",
              "example": "00000000-0000-4000-8000-000000000107"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "name": {
                    "type": "string",
                    "description": "New name."
                  },
                  "description": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "New description."
                  },
                  "status": {
                    "type": "string",
                    "description": "`active` or `archived`."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "status": "archived"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated board",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000107",
                  "status": "archived"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      },
      "delete": {
        "operationId": "delete-board",
        "summary": "Delete a board",
        "description": "Deletes the board and its items. Assets are untouched.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "boardId",
            "in": "path",
            "required": true,
            "description": "Board id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board id.",
              "example": "00000000-0000-4000-8000-000000000107"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "deleted": true
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/boards/{boardId}/items": {
      "post": {
        "operationId": "add-board-item",
        "summary": "Add an asset to a board",
        "description": "Appends an asset with an optional note. Boards hold up to 60 items.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "boardId",
            "in": "path",
            "required": true,
            "description": "Board id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board id.",
              "example": "00000000-0000-4000-8000-000000000107"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "assetId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Asset to add."
                  },
                  "note": {
                    "type": "string",
                    "description": "Optional note."
                  }
                },
                "required": [
                  "workspaceId",
                  "assetId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "assetId": "00000000-0000-4000-8000-0000000000f1",
                "note": "Hero direction"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Board item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000108",
                  "position": 0
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/boards/{boardId}/items/{itemId}": {
      "patch": {
        "operationId": "update-board-item",
        "summary": "Update an item note",
        "description": "Sets or clears the item note.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "boardId",
            "in": "path",
            "required": true,
            "description": "Board id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board id.",
              "example": "00000000-0000-4000-8000-000000000107"
            }
          },
          {
            "name": "itemId",
            "in": "path",
            "required": true,
            "description": "Board item id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board item id.",
              "example": "00000000-0000-4000-8000-000000000108"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "note": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "New note."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "note": "Approved"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000108",
                  "note": "Approved"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      },
      "delete": {
        "operationId": "delete-board-item",
        "summary": "Remove an item",
        "description": "Removes the item from the board. The asset is untouched.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "boardId",
            "in": "path",
            "required": true,
            "description": "Board id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board id.",
              "example": "00000000-0000-4000-8000-000000000107"
            }
          },
          {
            "name": "itemId",
            "in": "path",
            "required": true,
            "description": "Board item id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board item id.",
              "example": "00000000-0000-4000-8000-000000000108"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "deleted": true
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/boards/{boardId}/order": {
      "patch": {
        "operationId": "reorder-board-items",
        "summary": "Reorder board items",
        "description": "Full replacement order: every position is rewritten in one pass.",
        "tags": [
          "free.boards · Moodboards"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "boardId",
            "in": "path",
            "required": true,
            "description": "Board id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Board id.",
              "example": "00000000-0000-4000-8000-000000000107"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "itemIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "description": "Full ordered item id list."
                  }
                },
                "required": [
                  "workspaceId",
                  "itemIds"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "itemIds": [
                  "00000000-0000-4000-8000-000000000108"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Reordered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "ordered": 1
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/presets": {
      "get": {
        "operationId": "list-presets",
        "summary": "List presets",
        "description": "Presets for a workspace, optionally filtered by mode.",
        "tags": [
          "Presets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "description": "Filter by generation mode.",
            "schema": {
              "type": "string",
              "description": "Filter by generation mode."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Presets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000109",
                      "name": "Editorial portrait",
                      "mode": "text_to_image",
                      "params": {
                        "prompt": "editorial portrait, soft light",
                        "aspectRatio": "4:3"
                      }
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.read"
      },
      "post": {
        "operationId": "create-preset",
        "summary": "Save a preset",
        "description": "Stores a named setup. `params` is the generator form state (max 64 keys).",
        "tags": [
          "Presets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "name": {
                    "type": "string",
                    "description": "Preset name."
                  },
                  "mode": {
                    "type": "string",
                    "description": "Generation mode."
                  },
                  "modelId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Model to pin."
                  },
                  "modelSlug": {
                    "type": "string",
                    "description": "Model slug alternative to modelId."
                  },
                  "params": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "Form params to save."
                  }
                },
                "required": [
                  "workspaceId",
                  "name",
                  "mode",
                  "params"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "name": "Editorial portrait",
                "mode": "text_to_image",
                "params": {
                  "prompt": "editorial portrait, soft light",
                  "aspectRatio": "4:3"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Preset",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000109",
                  "name": "Editorial portrait"
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/presets/{presetId}": {
      "delete": {
        "operationId": "delete-preset",
        "summary": "Delete a preset",
        "description": "Deletes the saved setup.",
        "tags": [
          "Presets"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "presetId",
            "in": "path",
            "required": true,
            "description": "Preset id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Preset id.",
              "example": "00000000-0000-4000-8000-000000000109"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "deleted": true
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    },
    "/v1/projects": {
      "get": {
        "operationId": "list-projects",
        "summary": "List projects",
        "description": "Projects for a workspace, newest first.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Workspace to read.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace to read.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-indexed page.",
            "schema": {
              "type": "integer",
              "description": "1-indexed page.",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Projects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "items": [
                    {
                      "id": "00000000-0000-4000-8000-000000000110",
                      "name": "Winter campaign",
                      "archivedAt": null
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "assets.read"
      },
      "post": {
        "operationId": "create-project",
        "summary": "Create a project",
        "description": "Creates a project container.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "name": {
                    "type": "string",
                    "description": "Project name."
                  },
                  "description": {
                    "type": "string",
                    "description": "Optional description."
                  }
                },
                "required": [
                  "workspaceId",
                  "name"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "name": "Winter campaign"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Project",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000110",
                  "name": "Winter campaign"
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      }
    },
    "/v1/projects/{projectId}": {
      "get": {
        "operationId": "get-project",
        "summary": "Retrieve a project",
        "description": "Project metadata and cover asset.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "description": "Project id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Project id.",
              "example": "00000000-0000-4000-8000-000000000110"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Project",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000110",
                  "name": "Winter campaign"
                }
              }
            }
          }
        },
        "x-required-scope": "assets.read"
      },
      "patch": {
        "operationId": "update-project",
        "summary": "Update a project",
        "description": "Rename, re-describe, or archive a project.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "description": "Project id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Project id.",
              "example": "00000000-0000-4000-8000-000000000110"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Owning workspace."
                  },
                  "name": {
                    "type": "string",
                    "description": "New name."
                  },
                  "description": {
                    "type": "string",
                    "description": "New description."
                  },
                  "archivedAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "format": "date-time",
                    "description": "Archive timestamp."
                  }
                },
                "required": [
                  "workspaceId"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "name": "Winter campaign 2027"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated project",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "00000000-0000-4000-8000-000000000110"
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      },
      "delete": {
        "operationId": "delete-project",
        "summary": "Delete a project",
        "description": "Deletes the project container. Generations and assets are kept and unfiled.",
        "tags": [
          "Projects"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "projectId",
            "in": "path",
            "required": true,
            "description": "Project id.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Project id.",
              "example": "00000000-0000-4000-8000-000000000110"
            }
          },
          {
            "name": "workspaceId",
            "in": "query",
            "required": true,
            "description": "Owning workspace.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Owning workspace.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "deleted": true
                }
              }
            }
          }
        },
        "x-required-scope": "files.write"
      }
    },
    "/v1/chat/completions": {
      "post": {
        "operationId": "chat-completions",
        "summary": "Create a chat completion",
        "description": "OpenAI-compatible completions. Supports streaming (`stream: true`), tool calls, and attachments. `workspaceId` selects the paying workspace.",
        "tags": [
          "free.chat · OpenAI-compatible"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Workspace to bill."
                  },
                  "model": {
                    "type": "string",
                    "description": "Model id from `GET /v1/chat/models`."
                  },
                  "messages": {
                    "type": "array",
                    "items": {},
                    "description": "OpenAI message objects (`role`, `content`), with optional tool calls."
                  },
                  "stream": {
                    "type": "boolean",
                    "description": "Stream server-sent events."
                  },
                  "temperature": {
                    "type": "number",
                    "description": "Sampling temperature."
                  }
                },
                "required": [
                  "model",
                  "messages"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "model": "openai/gpt-4.1-mini",
                "messages": [
                  {
                    "role": "user",
                    "content": "Write a 2-line product tagline for a coffee brand."
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Completion (OpenAI shape)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "id": "chatcmpl_01J9Z8K2",
                  "object": "chat.completion",
                  "model": "openai/gpt-4.1-mini",
                  "choices": [
                    {
                      "index": 0,
                      "message": {
                        "role": "assistant",
                        "content": "Wake up. Drink better."
                      },
                      "finish_reason": "stop"
                    }
                  ],
                  "usage": {
                    "prompt_tokens": 18,
                    "completion_tokens": 9,
                    "total_tokens": 27
                  }
                }
              }
            }
          }
        },
        "x-required-scope": "all"
      }
    },
    "/v1/chat/models": {
      "get": {
        "operationId": "chat-models",
        "summary": "List chat models",
        "description": "OpenAI-style model list plus the current free chat model.",
        "tags": [
          "free.chat · OpenAI-compatible"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "description": "Workspace context for plan filtering.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace context for plan filtering.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Models",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "object": "list",
                  "data": [
                    {
                      "id": "openai/gpt-4.1-mini",
                      "object": "model",
                      "owned_by": "freeind"
                    }
                  ],
                  "free_model": "openai/gpt-4.1-mini"
                }
              }
            }
          }
        },
        "x-required-scope": "all"
      }
    },
    "/v1/chat/usage": {
      "get": {
        "operationId": "chat-usage",
        "summary": "Chat quota",
        "description": "Daily message quota for session users; API keys report unlimited.",
        "tags": [
          "free.chat · OpenAI-compatible"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspaceId",
            "in": "query",
            "required": false,
            "description": "Workspace context.",
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Workspace context.",
              "example": "00000000-0000-4000-8000-000000000000"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Quota",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "unlimited": true,
                  "limit": null,
                  "used": 0,
                  "remaining": null,
                  "resetsAt": "2026-10-25T00:00:00.000Z"
                }
              }
            }
          }
        },
        "x-required-scope": "all"
      }
    },
    "/v1/logo/brand-kit": {
      "post": {
        "operationId": "logo-brand-kit",
        "summary": "Generate a brand kit",
        "description": "Returns 3–5 name options, 3–5 taglines, and a 3–6 colour palette for a brand brief. Use the chosen name/palette as prompt context for logo image generations.",
        "tags": [
          "free.logo · Brand kit"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "workspaceId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Paying workspace."
                  },
                  "brandName": {
                    "type": "string",
                    "description": "Working brand name."
                  },
                  "description": {
                    "type": "string",
                    "description": "What the brand does."
                  },
                  "industry": {
                    "type": "string",
                    "description": "Industry or category."
                  },
                  "language": {
                    "type": "string",
                    "description": "Output language."
                  }
                },
                "required": [
                  "workspaceId",
                  "brandName"
                ]
              },
              "example": {
                "workspaceId": "00000000-0000-4000-8000-000000000000",
                "brandName": "Northwind",
                "description": "Specialty coffee roasted in small batches",
                "industry": "Food & beverage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Brand kit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": true
                },
                "example": {
                  "names": [
                    "Northwind",
                    "Northwind Roasters",
                    "Windward Coffee"
                  ],
                  "taglines": [
                    "Roasted by the wind.",
                    "Small batches, big mornings.",
                    "Find your north."
                  ],
                  "palette": [
                    {
                      "name": "Ink",
                      "hex": "#1b1b1b"
                    },
                    {
                      "name": "Cream",
                      "hex": "#f3ead8"
                    },
                    {
                      "name": "Ember",
                      "hex": "#c4552d"
                    }
                  ]
                }
              }
            }
          }
        },
        "x-required-scope": "generations.write"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "fi_live_...",
        "description": "Scoped API key created at https://free.ind.in/dashboard/api-keys"
      },
      "cookieAuth": {
        "type": "apiKey",
        "in": "cookie",
        "name": "better-auth.session_token",
        "description": "Dashboard session cookie. Used by account, billing, and workspace endpoints."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "type": "string"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "field": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "hasNextPage": {
            "type": "boolean"
          },
          "nextCursor": {
            "type": "string",
            "nullable": true
          },
          "total": {
            "type": "integer",
            "nullable": true
          }
        }
      }
    }
  },
  "x-error-codes": [
    {
      "code": "unauthenticated",
      "status": 401,
      "meaning": "Missing, invalid, expired, or revoked API key."
    },
    {
      "code": "forbidden",
      "status": 403,
      "meaning": "Key is missing the required scope or lacks workspace access."
    },
    {
      "code": "not_found",
      "status": 404,
      "meaning": "The resource does not exist in this workspace."
    },
    {
      "code": "validation_error",
      "status": 422,
      "meaning": "Body or query failed validation; `details[].field` points at the input."
    },
    {
      "code": "idempotency_conflict",
      "status": 409,
      "meaning": "The Idempotency-Key was already used in this workspace."
    },
    {
      "code": "conflict",
      "status": 409,
      "meaning": "The resource is not in a state that allows this action."
    },
    {
      "code": "insufficient_credits",
      "status": 402,
      "meaning": "Not enough plan credits or wallet balance for the job."
    },
    {
      "code": "rate_limited",
      "status": 429,
      "meaning": "Per-key request quota exhausted; retry after X-RateLimit-Reset."
    },
    {
      "code": "model_unavailable",
      "status": 422,
      "meaning": "Model is inactive or does not support the requested mode."
    },
    {
      "code": "upgrade_required",
      "status": 402,
      "meaning": "The feature needs a paid plan."
    },
    {
      "code": "service_unavailable",
      "status": 503,
      "meaning": "A dependency is down; retry with backoff."
    }
  ]
}