{
  "openapi": "3.1.0",
  "info": {
    "title": "Vydra AI API",
    "version": "1.0.0",
    "description": "One API for AI image generation, video generation, lip sync, motion transfer, and speech. Agents register with POST /api/v1/auth/bot-register, then generate through POST /api/v1/jobs and poll GET /api/v1/jobs/{id}. See /skill.md for the agent onboarding guide.\\nCredit pricing version 2026-09-06: /pricing.json and /docs/billing. Some unpriced legacy pipelines are temporarily unavailable.",
    "contact": {
      "name": "Shoaf Systems",
      "url": "https://vydra.ai"
    }
  },
  "servers": [
    {
      "url": "https://www.vydra.ai/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Discovery"
    },
    {
      "name": "Auth"
    },
    {
      "name": "Jobs"
    },
    {
      "name": "Models"
    },
    {
      "name": "Billing"
    },
    {
      "name": "Account"
    },
    {
      "name": "Assets"
    },
    {
      "name": "Studio"
    },
    {
      "name": "Library"
    },
    {
      "name": "Stories"
    },
    {
      "name": "Video restyle"
    },
    {
      "name": "Characters",
      "description": "Headless character creation, saved identities and finished videos"
    }
  ],
  "paths": {
    "/capabilities": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Discover workflows, models (with per-model guidance), endpoints, and auth methods",
        "security": [],
        "responses": {
          "200": {
            "description": "Capability document",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Capabilities"
                }
              }
            }
          }
        }
      }
    },
    "/openapi": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "This OpenAPI 3.1 document",
        "security": [],
        "responses": {
          "200": {
            "description": "OpenAPI JSON",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/auth/bot-register": {
      "post": {
        "tags": [
          "Auth"
        ],
        "summary": "Register an agent and mint an API key + dashboard token",
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "agent_name",
                  "billing_email"
                ],
                "properties": {
                  "agent_name": {
                    "type": "string",
                    "minLength": 2,
                    "description": "Name of your agent"
                  },
                  "billing_email": {
                    "type": "string",
                    "format": "email",
                    "description": "Your human's email for billing"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Account created (credentials shown once)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BotRegisterResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "409": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Get account plan, credit balance, and limits",
        "responses": {
          "200": {
            "description": "Account details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api-keys": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "List active API keys for the organization",
        "responses": {
          "200": {
            "description": "API keys",
            "content": {
              "application/json": {}
            }
          }
        }
      },
      "post": {
        "tags": [
          "Account"
        ],
        "summary": "Create a new API key",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "scopes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created key (shown once)",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/api-keys/{id}": {
      "delete": {
        "tags": [
          "Account"
        ],
        "summary": "Revoke an API key",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revoked"
          }
        }
      }
    },
    "/jobs": {
      "post": {
        "tags": [
          "Jobs"
        ],
        "summary": "Create a generation job (canonical entrypoint)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateJobRequest"
              },
              "examples": {
                "generate_video": {
                  "value": {
                    "workflow": "generate_video",
                    "input": {
                      "prompt": "A timelapse of a flower blooming",
                      "model": "seedance-2.5",
                      "duration": 8,
                      "resolution": "720p",
                      "aspect_ratio": "9:16"
                    }
                  }
                },
                "generate_image": {
                  "value": {
                    "workflow": "generate_image",
                    "input": {
                      "prompt": "A cyberpunk cityscape at golden hour",
                      "model": "gemini-image"
                    }
                  }
                },
                "nano_banana_pro": {
                  "value": {
                    "workflow": "generate_image",
                    "input": {
                      "model": "nano-banana-pro",
                      "prompt": "A photoreal dragon above an ancient sea temple",
                      "resolution": "4K",
                      "aspect_ratio": "16:9"
                    }
                  }
                },
                "gpt_image_2": {
                  "value": {
                    "workflow": "generate_image",
                    "input": {
                      "model": "gpt-image-2",
                      "prompt": "A cinematic futuristic city",
                      "aspect_ratio": "3:2"
                    }
                  }
                },
                "generate_speech": {
                  "value": {
                    "workflow": "generate_speech",
                    "input": {
                      "prompt": "Every great idea begins with curiosity.",
                      "voice_id": "21m00Tcm4TlvDq8ikWAM"
                    }
                  }
                },
                "improve_prompt": {
                  "value": {
                    "workflow": "improve_prompt",
                    "input": {
                      "prompt": "A white dragon over the ocean"
                    }
                  }
                },
                "gpt_image_25_sunburst": {
                  "value": {
                    "workflow": "generate_image",
                    "input": {
                      "model": "gpt-image-2.5-sunburst",
                      "prompt": "A cinematic futuristic city",
                      "aspect_ratio": "3:2",
                      "quality": "medium"
                    }
                  }
                },
                "gpt_image_25_flare": {
                  "value": {
                    "workflow": "generate_image",
                    "input": {
                      "model": "gpt-image-2.5-flare",
                      "prompt": "A cinematic futuristic city",
                      "aspect_ratio": "3:2",
                      "quality": "medium"
                    }
                  }
                },
                "gpt_image_25_edit": {
                  "value": {
                    "workflow": "edit_image",
                    "input": {
                      "model": "gpt-image-2.5-sunburst",
                      "prompt": "Use image 1 as the scene and image 2 as the subject. Preserve likeness.",
                      "image_urls": [
                        "https://your-vydra-media.example/template.png",
                        "https://your-vydra-media.example/portrait.png"
                      ],
                      "quality": "high",
                      "size": "1536x1024",
                      "input_fidelity": "high"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Job created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobCreated"
                }
              }
            }
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        },
        "description": " Each submission is a separate potentially billable job. This endpoint does not implement Studio Idempotency-Key semantics. Save the returned id and poll GET /jobs/{id}; retrieve the job even if creation reports completed to access result media or text. Gemini Omni: workflow generate_video, input.model gemini-omni-flash; optional Vydra-hosted imageUrl and videoUrl for prompted video edits. Flat 413 credits per clip up to 10s at 720p; duration omitted or 10. See /docs/workflows/gemini-omni."
      },
      "get": {
        "tags": [
          "Jobs"
        ],
        "summary": "List jobs",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "running",
                "completed",
                "failed"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Job"
                      }
                    },
                    "pagination": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{id}": {
      "get": {
        "tags": [
          "Jobs"
        ],
        "summary": "Poll a job's status and retrieve its output",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/models": {
      "get": {
        "tags": [
          "Models"
        ],
        "summary": "List available models with pricing",
        "responses": {
          "200": {
            "description": "Model list",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/models/recommend": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Recommend a model for a goal (static rules; no auth)",
        "security": [],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "goal": {
                    "type": "string",
                    "enum": [
                      "video",
                      "image",
                      "lipsync",
                      "motion",
                      "tts",
                      "transcribe"
                    ],
                    "default": "video"
                  },
                  "duration_seconds": {
                    "type": "number",
                    "minimum": 1,
                    "maximum": 60
                  },
                  "needs_audio": {
                    "type": "boolean"
                  },
                  "budget": {
                    "type": "string",
                    "enum": [
                      "economy",
                      "quality"
                    ],
                    "default": "quality"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recommendation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "recommendation": {
                      "type": "object",
                      "properties": {
                        "model": {
                          "type": "string"
                        },
                        "workflow": {
                          "type": "string"
                        },
                        "credits_estimate": {
                          "type": "integer"
                        },
                        "reason": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/models/veo3": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Generate video with Veo 3. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string"
                  },
                  "aspect_ratio": {
                    "type": "string",
                    "enum": [
                      "16:9",
                      "9:16",
                      "1:1"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "$ref": "#/components/responses/AsyncJobCreated"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          }
        }
      }
    },
    "/models/kling-3.1": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Generate video with Kling 3.1. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string"
                  },
                  "image_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "aspect_ratio": {
                    "type": "string",
                    "enum": [
                      "16:9",
                      "9:16",
                      "1:1"
                    ]
                  },
                  "duration": {
                    "type": "string",
                    "enum": [
                      "5",
                      "10"
                    ]
                  },
                  "negative_prompt": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "$ref": "#/components/responses/AsyncJobCreated"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          }
        }
      }
    },
    "/models/seedance": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Generate video with Seedance. version=2.0. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string"
                  },
                  "image_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "aspect_ratio": {
                    "type": "string",
                    "enum": [
                      "16:9",
                      "9:16",
                      "1:1"
                    ]
                  },
                  "duration": {
                    "type": "number",
                    "minimum": 4,
                    "maximum": 30,
                    "description": "Seconds. Seedance 2.0 accepts 4-15; Seedance 2.5 accepts 4-30 (default 5)."
                  },
                  "resolution": {
                    "type": "string",
                    "enum": [
                      "480p",
                      "720p",
                      "1080p"
                    ]
                  },
                  "fast": {
                    "type": "boolean",
                    "description": "Seedance 2.0 fast variant. Ignored on version 2.5, which has no fast tier."
                  },
                  "version": {
                    "type": "string",
                    "enum": [
                      "2.0",
                      "2.5"
                    ],
                    "default": "2.0",
                    "description": "Seedance model generation."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "$ref": "#/components/responses/AsyncJobCreated"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          }
        }
      }
    },
    "/models/kling": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Motion control — transfer motion onto a character image. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "image_url",
                  "video_url",
                  "prompt"
                ],
                "properties": {
                  "image_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "video_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "prompt": {
                    "type": "string"
                  },
                  "character_orientation": {
                    "type": "string",
                    "enum": [
                      "image",
                      "video"
                    ]
                  },
                  "keep_original_sound": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "$ref": "#/components/responses/AsyncJobCreated"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          }
        }
      }
    },
    "/models/grok-imagine": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Grok Imagine image (8) or video (150)",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string"
                  },
                  "model": {
                    "type": "string",
                    "enum": [
                      "text-to-image",
                      "text-to-video",
                      "image-to-video"
                    ]
                  },
                  "image_url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "aspect_ratio": {
                    "type": "string"
                  },
                  "duration": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Result or async job",
            "content": {
              "application/json": {}
            }
          },
          "402": {
            "$ref": "#/components/responses/InsufficientCredits"
          }
        }
      }
    },
    "/models/gemini/generate": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Generate image with Gemini. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string"
                  },
                  "aspectRatio": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Image",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/models/gemini/edit": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Edit image with Gemini. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "imageUrl",
                  "prompt"
                ],
                "properties": {
                  "imageUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "prompt": {
                    "type": "string"
                  },
                  "aspectRatio": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Image",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/models/nano-banana/generate": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Generate image with Nano Banana. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "prompt": {
                    "type": "string"
                  },
                  "aspect_ratio": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Image",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/models/flux-edit/edit": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Flux 2 multi-image edit. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "prompt"
                ],
                "properties": {
                  "imageUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "imageUrls": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "maxItems": 9
                  },
                  "prompt": {
                    "type": "string"
                  },
                  "numImages": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Images",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/models/elevenlabs/tts": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Text to speech. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "text"
                ],
                "properties": {
                  "text": {
                    "type": "string"
                  },
                  "voice_id": {
                    "type": "string"
                  },
                  "model_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audio",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/models/elevenlabs/sts": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Speech to speech / voice changer. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "audioUrl",
                  "voiceId"
                ],
                "properties": {
                  "audioUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "voiceId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audio",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/models/whisper": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Transcribe audio/video. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "language": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transcript",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/lipsync": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Create a lipsync job. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "imageUrl",
                  "audioUrl"
                ],
                "properties": {
                  "imageUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "audioUrl": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "$ref": "#/components/responses/AsyncJobCreated"
          }
        }
      }
    },
    "/lipsync/{jobId}": {
      "get": {
        "tags": [
          "Models"
        ],
        "summary": "Poll a lipsync job",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lipsync job status",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/billing/buy-credits": {
      "get": {
        "tags": [
          "Billing"
        ],
        "summary": "List credit packs and bot subscription options",
        "responses": {
          "200": {
            "description": "Packs",
            "content": {
              "application/json": {}
            }
          }
        }
      },
      "post": {
        "tags": [
          "Billing"
        ],
        "summary": "Get a Stripe billing_url for a credit pack",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "pack"
                ],
                "properties": {
                  "pack": {
                    "type": "string",
                    "enum": [
                      "small",
                      "medium",
                      "large",
                      "bot_default"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Checkout link",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "billing_url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "pack": {
                      "type": "string"
                    },
                    "credits": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/upload": {
      "post": {
        "tags": [
          "Assets"
        ],
        "summary": "Upload images or MP4 videos up to 20 MB",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "contentType",
                  "size"
                ],
                "properties": {
                  "filename": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "contentType": {
                    "type": "string",
                    "enum": [
                      "image/jpeg",
                      "image/jpg",
                      "image/png",
                      "image/webp",
                      "image/gif",
                      "video/mp4"
                    ]
                  },
                  "size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20971520
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "file"
                ],
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Uploaded URL",
            "content": {
              "application/json": {}
            }
          }
        },
        "description": "JSON requests return a 10-minute signed uploadUrl plus publicUrl/url and type. PUT the exact bytes with the returned Content-Type. Recommended for files over 4 MB to bypass serverless request limits. Multipart field file also accepts images and MP4 videos. Model input limits apply separately; Omni videos must be <=10s and <=20 MB."
      }
    },
    "/upload-audio": {
      "post": {
        "tags": [
          "Assets"
        ],
        "summary": "Upload an audio file (multipart/form-data)",
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Uploaded URL",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/assets": {
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "List completed output assets",
        "responses": {
          "200": {
            "description": "Assets",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/assets/{id}": {
      "get": {
        "tags": [
          "Assets"
        ],
        "summary": "Get a single asset",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asset",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/workflows": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "List DB-registered pipelines and their credit cost",
        "responses": {
          "200": {
            "description": "Pipelines",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/voice-changer/transform": {
      "post": {
        "tags": [
          "Models"
        ],
        "summary": "Voice changer / speech-to-speech. See current tariff at /pricing.json",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "audioUrl": {
                    "type": "string",
                    "format": "uri"
                  },
                  "voiceId": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transformed audio",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/voice-changer/voices": {
      "get": {
        "tags": [
          "Models"
        ],
        "summary": "List available voice-changer voices",
        "responses": {
          "200": {
            "description": "Voices",
            "content": {
              "application/json": {}
            }
          }
        }
      }
    },
    "/creator/models": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Model catalog shared by Create and Studio",
        "responses": {
          "200": {
            "description": "Shared creator catalog",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CreatorModel"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          }
        },
        "description": " Requires jobs:read (or a matching wildcard scope); resources are scoped to the authenticated organization."
      }
    },
    "/studio/workflows": {
      "get": {
        "tags": [
          "Studio"
        ],
        "summary": "List organization workflows",
        "responses": {
          "200": {
            "description": "Workflow list"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          }
        },
        "description": " Requires jobs:read (or a matching wildcard scope); resources are scoped to the authenticated organization."
      },
      "post": {
        "tags": [
          "Studio"
        ],
        "summary": "Save a workflow without running it",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "graph": {
                    "$ref": "#/components/schemas/StudioGraph"
                  }
                }
              },
              "example": {
                "name": "API image example",
                "description": "Text input to Nano Banana Pro to output",
                "graph": {
                  "nodes": [
                    {
                      "id": "prompt",
                      "type": "textInput",
                      "position": {
                        "x": 0,
                        "y": 0
                      },
                      "data": {
                        "text": "An ivory dragon above a stormy sea"
                      }
                    },
                    {
                      "id": "image",
                      "type": "generate",
                      "position": {
                        "x": 340,
                        "y": 0
                      },
                      "data": {
                        "model": "nano-banana-pro",
                        "resolution": "1K",
                        "aspectRatio": "16:9"
                      }
                    },
                    {
                      "id": "result",
                      "type": "output",
                      "position": {
                        "x": 680,
                        "y": 0
                      },
                      "data": {}
                    }
                  ],
                  "edges": [
                    {
                      "id": "prompt-image",
                      "source": "prompt",
                      "sourceHandle": "text",
                      "target": "image",
                      "targetHandle": "prompt"
                    },
                    {
                      "id": "image-result",
                      "source": "image",
                      "sourceHandle": "imageUrl",
                      "target": "result",
                      "targetHandle": "imageUrl"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Saved without execution or a generation charge",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "name": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "name"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid graph"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          }
        },
        "description": " Requires jobs:write (or a matching wildcard scope); resources are scoped to the authenticated organization."
      }
    },
    "/studio/workflows/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Studio"
        ],
        "summary": "Read a saved workflow",
        "responses": {
          "200": {
            "description": "Workflow including graph"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          },
          "404": {
            "description": "Not found"
          }
        },
        "description": " Requires jobs:read (or a matching wildcard scope); resources are scoped to the authenticated organization."
      },
      "put": {
        "tags": [
          "Studio"
        ],
        "summary": "Update a saved workflow",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 200
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "graph": {
                    "$ref": "#/components/schemas/StudioGraph"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated workflow"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          }
        },
        "description": " Requires jobs:write (or a matching wildcard scope); resources are scoped to the authenticated organization."
      },
      "delete": {
        "tags": [
          "Studio"
        ],
        "summary": "Delete a workflow without an active run",
        "responses": {
          "200": {
            "description": "Deleted"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          },
          "409": {
            "description": "Active run prevents deletion"
          }
        },
        "description": " Requires jobs:write (or a matching wildcard scope); resources are scoped to the authenticated organization."
      }
    },
    "/studio/workflows/{id}/run": {
      "post": {
        "tags": [
          "Studio"
        ],
        "summary": "Run an immutable snapshot of a saved workflow",
        "description": "Requires jobs:write. Each generation debits credits separately. Reuse the same key and inputs when retrying. New keys intentionally start new runs. Requires jobs:write (or a matching wildcard scope); resources are scoped to the authenticated organization. The key is organization-scoped. Its fingerprint includes workflow ID and input overrides, not subsequent saved-graph edits. Use a new key for a new run after editing the graph.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "inputs": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "maxLength": 20000
                    },
                    "description": "Input node IDs mapped to text or media URLs"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing run for the same key; poll its ID for current status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "runId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "creditsEstimated": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "runId",
                        "creditsEstimated"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "202": {
            "description": "New run snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "runId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "creditsEstimated": {
                          "type": "integer"
                        },
                        "status": {
                          "const": "running"
                        }
                      },
                      "required": [
                        "runId",
                        "creditsEstimated",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid graph or input"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          },
          "409": {
            "description": "Key reused with a different request"
          },
          "429": {
            "description": "Rate limit"
          }
        }
      }
    },
    "/studio/runs": {
      "get": {
        "tags": [
          "Studio"
        ],
        "summary": "Latest 30 organization workflow runs",
        "parameters": [
          {
            "name": "workflowId",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Run history"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          }
        },
        "description": " Requires jobs:read (or a matching wildcard scope); resources are scoped to the authenticated organization."
      }
    },
    "/studio/runs/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Studio"
        ],
        "summary": "Read run status, node outputs, and credits used. See current tariff at /pricing.json",
        "responses": {
          "200": {
            "description": "Run with per-node outputs and net credits; worker lease fields are omitted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/StudioRun"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          },
          "404": {
            "description": "Not found"
          }
        },
        "description": " Requires jobs:read (or a matching wildcard scope); resources are scoped to the authenticated organization."
      },
      "patch": {
        "tags": [
          "Studio"
        ],
        "summary": "Stop after current steps settle",
        "description": "Does not cancel provider jobs or refund completed generations. Stops unstarted steps; the worker sets final status to cancelled. Requires jobs:write (or a matching wildcard scope); resources are scoped to the authenticated organization.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "action"
                ],
                "additionalProperties": false,
                "properties": {
                  "action": {
                    "const": "cancel"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Request acknowledged; submitted jobs must still settle",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "cancelRequested": {
                          "const": true
                        }
                      },
                      "required": [
                        "id",
                        "cancelRequested"
                      ]
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          },
          "404": {
            "description": "No running workflow found"
          }
        }
      }
    },
    "/library": {
      "get": {
        "tags": [
          "Library"
        ],
        "summary": "List saved references, newest first (up to 200)",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "folder",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Saved entries only, not completed job assets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "maxItems": 200,
                      "items": {
                        "$ref": "#/components/schemas/MediaLibraryAsset"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          }
        },
        "description": " Requires jobs:read (or a matching wildcard scope); resources are scoped to the authenticated organization. No pagination. Omit folder for all folders; an empty folder selects root. Use /assets for completed job media."
      },
      "post": {
        "tags": [
          "Library"
        ],
        "summary": "Save an HTTPS reference or upload a file under 4 MB",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "maxLength": 200,
                    "minLength": 1
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "pattern": "^https://"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "image",
                      "video",
                      "audio"
                    ]
                  },
                  "folder": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "metadata": {
                    "type": "object",
                    "additionalProperties": true
                  }
                },
                "required": [
                  "name",
                  "url",
                  "kind"
                ]
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "folder": {
                    "type": "string"
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Saved media entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/MediaLibraryAsset"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid media"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          },
          "429": {
            "description": "Rate limit"
          }
        },
        "description": " Requires jobs:write (or a matching wildcard scope); resources are scoped to the authenticated organization. JSON saves a URL reference without copying remote bytes. Multipart files must be nonempty and at most 4194304 bytes; body limits also apply. Allowed MIME types: image/jpeg, image/png, image/webp, image/gif, video/mp4, video/webm, audio/mpeg, audio/wav."
      }
    },
    "/library/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "patch": {
        "tags": [
          "Library"
        ],
        "summary": "Rename, organize or favorite saved media",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "folder": {
                    "type": "string"
                  },
                  "favorite": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated entry",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/MediaLibraryAsset"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          },
          "404": {
            "description": "Not found"
          }
        },
        "description": " Requires jobs:write (or a matching wildcard scope); resources are scoped to the authenticated organization."
      },
      "delete": {
        "tags": [
          "Library"
        ],
        "summary": "Remove saved entry; completed job assets remain",
        "responses": {
          "200": {
            "description": "Entry removed; stored objects and completed jobs are not deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "const": true
                    }
                  },
                  "required": [
                    "success"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing required jobs scope"
          },
          "404": {
            "description": "Not found"
          }
        },
        "description": " Requires jobs:write (or a matching wildcard scope); resources are scoped to the authenticated organization."
      }
    },
    "/library/upload-url": {
      "post": {
        "summary": "Upload an image or video reference directly to Vydra storage",
        "description": "Requires jobs:write. PUT bytes to uploadUrl with the same Content-Type, then use publicUrl in an Omni generation. Actual media is validated before charging.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "contentType",
                  "size"
                ],
                "properties": {
                  "contentType": {
                    "type": "string",
                    "enum": [
                      "image/jpeg",
                      "image/png",
                      "image/webp",
                      "video/mp4"
                    ]
                  },
                  "size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 20971520,
                    "description": "Bytes. Images <=4 MB; MP4 <=20 MB."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signed uploadUrl (expires in 10 minutes) and publicUrl"
          },
          "400": {
            "description": "Invalid metadata"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing scope"
          },
          "429": {
            "description": "Rate limit"
          }
        }
      }
    },
    "/remix/story": {
      "post": {
        "operationId": "createStory",
        "tags": [
          "Stories"
        ],
        "summary": "Plan a narrated story (paid, asynchronous; no idempotency guarantee)",
        "description": "Requires jobs:write. Project IDs belong to /remix, not /jobs. See /docs/stories for lifecycle and retry rules.",
        "x-required-scopes": [
          "jobs:write"
        ],
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryProject"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "403": {
            "description": "Missing jobs scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "404": {
            "description": "Project not found in workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "409": {
            "description": "Invalid stage or incomplete assets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "500": {
            "description": "Service error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "503": {
            "description": "Provider not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StoryInput"
              }
            }
          }
        }
      }
    },
    "/remix": {
      "get": {
        "operationId": "listStories",
        "tags": [
          "Stories"
        ],
        "summary": "List story and remix projects in your workspace",
        "description": "Requires jobs:read. Project IDs belong to /remix, not /jobs. See /docs/stories for lifecycle and retry rules.",
        "x-required-scopes": [
          "jobs:read"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/StoryProject"
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "limit": {
                          "type": "number"
                        },
                        "offset": {
                          "type": "number"
                        },
                        "total": {
                          "type": "number"
                        },
                        "hasMore": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "limit",
                        "offset",
                        "total",
                        "hasMore"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "403": {
            "description": "Missing jobs scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "404": {
            "description": "Project not found in workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "409": {
            "description": "Invalid stage or incomplete assets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "500": {
            "description": "Service error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "503": {
            "description": "Provider not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ]
      }
    },
    "/remix/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "operationId": "getStory",
        "tags": [
          "Stories"
        ],
        "summary": "Poll project and asset status; inspect production flags",
        "description": "Requires jobs:read. Project IDs belong to /remix, not /jobs. See /docs/stories for lifecycle and retry rules.",
        "x-required-scopes": [
          "jobs:read"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryProject"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "403": {
            "description": "Missing jobs scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "404": {
            "description": "Project not found in workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "409": {
            "description": "Invalid stage or incomplete assets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "500": {
            "description": "Service error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "503": {
            "description": "Provider not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          }
        }
      }
    },
    "/remix/{id}/blueprint": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "patch": {
        "operationId": "updateStoryBlueprint",
        "tags": [
          "Stories"
        ],
        "summary": "Replace full blueprint while ready or done",
        "description": "Requires jobs:write. Project IDs belong to /remix, not /jobs. See /docs/stories for lifecycle and retry rules.",
        "x-required-scopes": [
          "jobs:write"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryProject"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "403": {
            "description": "Missing jobs scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "404": {
            "description": "Project not found in workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "409": {
            "description": "Invalid stage or incomplete assets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "500": {
            "description": "Service error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "503": {
            "description": "Provider not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "blueprint"
                ],
                "properties": {
                  "blueprint": {
                    "$ref": "#/components/schemas/StoryBlueprint"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/remix/{id}/estimate": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "operationId": "estimateStory",
        "tags": [
          "Stories"
        ],
        "summary": "Estimate remaining generation credits (free)",
        "description": "Requires jobs:read. Project IDs belong to /remix, not /jobs. See /docs/stories for lifecycle and retry rules.",
        "x-required-scopes": [
          "jobs:read"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryEstimate"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "403": {
            "description": "Missing jobs scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "404": {
            "description": "Project not found in workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "409": {
            "description": "Invalid stage or incomplete assets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "500": {
            "description": "Service error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "503": {
            "description": "Provider not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "stage": {
                    "type": "string",
                    "enum": [
                      "prepare",
                      "storyboard",
                      "build",
                      "review"
                    ]
                  },
                  "shotIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 12,
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/remix/{id}/build": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "operationId": "buildStory",
        "tags": [
          "Stories"
        ],
        "summary": "Prepare references/narration, then generate scenes (paid)",
        "description": "Requires jobs:write. Project IDs belong to /remix, not /jobs. See /docs/stories for lifecycle and retry rules.",
        "x-required-scopes": [
          "jobs:write"
        ],
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryProject"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "403": {
            "description": "Missing jobs scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "404": {
            "description": "Project not found in workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "409": {
            "description": "Invalid stage or incomplete assets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "500": {
            "description": "Service error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "503": {
            "description": "Provider not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "shotIds": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 12,
                    "items": {
                      "type": "string"
                    }
                  },
                  "stage": {
                    "type": "string",
                    "enum": [
                      "prepare",
                      "storyboard",
                      "build",
                      "review"
                    ],
                    "default": "build"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/remix/{id}/render": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "operationId": "renderStory",
        "tags": [
          "Stories"
        ],
        "summary": "Render when production.buildReady; poll until done for render.videoUrl",
        "description": "Requires jobs:write. Project IDs belong to /remix, not /jobs. See /docs/stories for lifecycle and retry rules.",
        "x-required-scopes": [
          "jobs:write"
        ],
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryProject"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "403": {
            "description": "Missing jobs scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "404": {
            "description": "Project not found in workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "409": {
            "description": "Invalid stage or incomplete assets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "500": {
            "description": "Service error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "503": {
            "description": "Provider not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          }
        }
      }
    },
    "/restyle/prepare": {
      "post": {
        "tags": [
          "Video restyle"
        ],
        "operationId": "prepareVideoRestyle",
        "summary": "Prepare a video restyle",
        "description": "Import public Instagram or direct HTTPS video. Exactly one source is required. For longer sources supply explicit segments totaling 4–15 seconds for direct Omni Pro generation; never silently splits. Returns a measured Omni Pro quote. Requires video:create. Receipts expire after seven days.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestylePrepareRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestylePrepareResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, receipt or approval"
          },
          "401": {
            "description": "Authentication required"
          },
          "402": {
            "description": "Insufficient generation credits"
          },
          "403": {
            "description": "Insufficient API scopes"
          },
          "409": {
            "description": "Generation not completed or idempotency conflict"
          },
          "422": {
            "description": "EDIT_REQUIRED, INSTAGRAM_UPLOAD_REQUIRED, or DURATION_MISMATCH"
          },
          "503": {
            "description": "Provider or signing configuration missing"
          }
        }
      }
    },
    "/restyle/preview": {
      "post": {
        "tags": [
          "Video restyle"
        ],
        "operationId": "previewVideoRestyle",
        "summary": "Preview a video restyle",
        "description": "Create a paid style preview. Reuse idempotencyKey for retries; different styles need new keys. Poll /jobs/{jobId}, show result.imageUrl and obtain user approval. Requires image:create. Receipts expire seven days after preparation. Requires the restyle app and media-worker rollout.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestylePreviewRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestylePreviewResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, receipt or approval"
          },
          "401": {
            "description": "Authentication required"
          },
          "402": {
            "description": "Insufficient generation credits"
          },
          "403": {
            "description": "Insufficient API scopes"
          },
          "409": {
            "description": "Generation not completed or idempotency conflict"
          },
          "422": {
            "description": "EDIT_REQUIRED, INSTAGRAM_UPLOAD_REQUIRED, or DURATION_MISMATCH"
          },
          "503": {
            "description": "Provider or signing configuration missing"
          }
        }
      }
    },
    "/restyle/render": {
      "post": {
        "tags": [
          "Video restyle"
        ],
        "operationId": "renderVideoRestyle",
        "summary": "Render a video restyle",
        "description": "Submit one whole-video Genjutsu 720p generation only after approval of the completed preview. Same previewToken returns the existing job without a second debit. Poll /jobs/{jobId}, then finalize. Requires video:create. Receipts expire seven days after preparation. Requires the restyle app and media-worker rollout.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestyleRenderRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestyleRenderResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, receipt or approval"
          },
          "401": {
            "description": "Authentication required"
          },
          "402": {
            "description": "Insufficient generation credits"
          },
          "403": {
            "description": "Insufficient API scopes"
          },
          "409": {
            "description": "Generation not completed or idempotency conflict"
          },
          "422": {
            "description": "EDIT_REQUIRED, INSTAGRAM_UPLOAD_REQUIRED, or DURATION_MISMATCH"
          },
          "503": {
            "description": "Provider or signing configuration missing"
          }
        }
      }
    },
    "/restyle/finalize": {
      "post": {
        "tags": [
          "Video restyle"
        ],
        "operationId": "finalizeVideoRestyle",
        "summary": "Finalize a video restyle",
        "description": "Restore edited source audio after generation completes and return a persistent MP4 URL. Safe to retry; no new generation charge. Requires video:create. Receipts expire seven days after preparation. Requires the restyle app and media-worker rollout.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestyleFinalizeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RestyleFinalizeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input, receipt or approval"
          },
          "401": {
            "description": "Authentication required"
          },
          "402": {
            "description": "Insufficient generation credits"
          },
          "403": {
            "description": "Insufficient API scopes"
          },
          "409": {
            "description": "Generation not completed or idempotency conflict"
          },
          "422": {
            "description": "EDIT_REQUIRED, INSTAGRAM_UPLOAD_REQUIRED, or DURATION_MISMATCH"
          },
          "503": {
            "description": "Provider or signing configuration missing"
          }
        }
      }
    },
    "/api/v1/restyle/styles": {
      "get": {
        "summary": "List reusable video styles",
        "description": "Returns versioned styles, preview model and current preview credit quote.",
        "security": [],
        "responses": {
          "200": {
            "description": "Style presets and preview pricing"
          }
        }
      }
    },
    "/api/v1/restyle/generate": {
      "post": {
        "summary": "Generate a restyled video directly",
        "description": "One paid Kling Omni Pro 1080p video job without an image preview or approval step. Requires video:create. The source must be 4–15 seconds. Reuse the idempotency key on retries.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "preparedToken",
                  "styleId",
                  "idempotencyKey"
                ],
                "properties": {
                  "preparedToken": {
                    "type": "string"
                  },
                  "styleId": {
                    "type": "string",
                    "description": "Style ID from GET /api/v1/restyle/styles"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 128
                  },
                  "style": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 1000,
                    "description": "Required only for styleId custom. Describe the requested visual style."
                  },
                  "styleReferenceUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Optional HTTPS art reference. Used for textures, rendering and lighting, not replacement subjects or setting. Changing it requires a new idempotency key."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Video job reserved; returns jobId, renderToken and creditsCharged"
          },
          "409": {
            "description": "Idempotency conflict"
          }
        }
      }
    },
    "/remix/{id}/repair": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "post": {
        "operationId": "repairStoryScene",
        "tags": [
          "Stories"
        ],
        "summary": "Retry an interrupted check or explicitly buy one replacement take",
        "description": "Requires jobs:write. Project IDs belong to /remix, not /jobs. See /docs/stories for lifecycle and retry rules.",
        "x-required-scopes": [
          "jobs:write"
        ],
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryProject"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "401": {
            "description": "Authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient credits",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "403": {
            "description": "Missing jobs scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "404": {
            "description": "Project not found in workspace",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "409": {
            "description": "Invalid stage or incomplete assets",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "500": {
            "description": "Service error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          },
          "503": {
            "description": "Provider not configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StoryError"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "shotId": {
                    "type": "string"
                  },
                  "mode": {
                    "type": "string",
                    "enum": [
                      "check",
                      "take"
                    ]
                  },
                  "expectedCredits": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "required": [
                  "shotId",
                  "mode",
                  "expectedCredits"
                ]
              }
            }
          }
        }
      }
    },
    "/characters": {
      "get": {
        "tags": [
          "Characters"
        ],
        "summary": "List saved characters in this workspace (jobs:read)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Character"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        }
      },
      "post": {
        "tags": [
          "Characters"
        ],
        "summary": "Save an owned image as a reusable character (jobs:write)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Character"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CharacterInput"
              }
            }
          }
        }
      }
    },
    "/characters/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Characters"
        ],
        "summary": "Read one saved character",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Character"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        }
      },
      "patch": {
        "tags": [
          "Characters"
        ],
        "summary": "Edit metadata, reference image or sheet; set default",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Character"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CharacterUpdate"
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Characters"
        ],
        "summary": "Delete a saved character",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        }
      }
    },
    "/character-templates": {
      "get": {
        "tags": [
          "Characters"
        ],
        "summary": "Discover character templates and ordered reference roles",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "references"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "kind": {
                            "enum": [
                              "image",
                              "video"
                            ]
                          },
                          "references": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "label": {
                                  "type": "string"
                                },
                                "type": {
                                  "type": "string"
                                }
                              }
                            }
                          },
                          "sourceVideoRequired": {
                            "type": "boolean"
                          },
                          "templateImageRequired": {
                            "type": "boolean"
                          },
                          "templateImagePath": {
                            "type": "string"
                          },
                          "acceptsBackground": {
                            "type": "boolean"
                          },
                          "acceptsCarDescription": {
                            "type": "boolean"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        },
        "description": "Only published imports are exposed. references are ordered; referenceIndex is zero-based. For templateImageRequired, upload the catalog templateImagePath through /upload and pass its owned URL."
      }
    },
    "/character-swap/prepare": {
      "post": {
        "tags": [
          "Characters"
        ],
        "summary": "Import an Instagram video or normalize an owned video upload (jobs:write)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "videoUrl": {
                          "type": "string",
                          "format": "uri"
                        },
                        "thumbnailUrl": {
                          "type": "string",
                          "format": "uri"
                        },
                        "durationSec": {
                          "type": "number",
                          "minimum": 4,
                          "maximum": 30
                        },
                        "width": {
                          "type": "integer"
                        },
                        "height": {
                          "type": "integer"
                        },
                        "hasAudio": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "422": {
            "description": "Instagram requires upload, or a video section is required"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CharacterSourceInput"
              }
            }
          }
        },
        "description": "Provide exactly one sourceUrl (public Instagram reel/video post) or videoUrl (workspace-owned upload). Optional segment: {start, end} selects 4–30 seconds. Does not generate or charge video credits. Sources over 30 seconds require an explicit section. Blocked Instagram imports return INSTAGRAM_UPLOAD_REQUIRED (422); upload the original instead. Use data.videoUrl as sourceVideoUrl for a recast run."
      }
    },
    "/characters/runs": {
      "post": {
        "tags": [
          "Characters"
        ],
        "summary": "Start an idempotent headless character operation (jobs:write)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "runId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "type": "string"
                        },
                        "creditsEstimated": {
                          "type": "integer"
                        },
                        "creditUnitsPerCredit": {
                          "const": 50
                        },
                        "_links": {
                          "type": "object"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "409": {
            "description": "Idempotency key reused for a different request"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CharacterRunInput"
              }
            }
          }
        },
        "description": "Requires jobs:write. Reuse the same key and request after transport failures; reuse with different input returns 409. Images must belong to the authenticated workspace. Generation does not save or overwrite a character. creditsEstimated uses ledger units (50 = one displayed credit)."
      }
    },
    "/characters/runs/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string",
            "format": "uuid"
          }
        }
      ],
      "get": {
        "tags": [
          "Characters"
        ],
        "summary": "Poll a character run and retrieve finished media (jobs:read)",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "status": {
                          "enum": [
                            "pending",
                            "running",
                            "completed",
                            "failed",
                            "cancelled"
                          ]
                        },
                        "outputs": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "nodeId": {
                                "type": "string"
                              },
                              "type": {
                                "enum": [
                                  "image",
                                  "video",
                                  "audio",
                                  "text"
                                ]
                              },
                              "url": {
                                "type": "string",
                                "format": "uri"
                              },
                              "text": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "design": {
                          "type": "object"
                        },
                        "creditsEstimated": {
                          "type": "integer"
                        },
                        "creditsUsed": {
                          "type": "integer"
                        },
                        "creditUnitsPerCredit": {
                          "const": 50
                        },
                        "error": {
                          "type": [
                            "object",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid input"
          },
          "401": {
            "description": "Invalid authentication"
          },
          "403": {
            "description": "Missing jobs:read or jobs:write scope"
          },
          "404": {
            "description": "Resource not found in this workspace"
          },
          "429": {
            "description": "Rate limited; retry later"
          }
        },
        "description": "outputs is empty until completed. Download the finished media URL for your own publishing tools. Design uses GPT to return JSON text with conversational ideas and structured concepts in design. Pass a chosen concept description to create for a GPT Image 2.5 image. Cancel using PATCH /api/v1/studio/runs/{id} with {action: cancel}. Submitted work settles normally."
      }
    },
    "/api/v1/restyle/history": {
      "get": {
        "tags": [
          "Video restyle"
        ],
        "summary": "List recent workspace restyles",
        "description": "Requires jobs:read. Returns up to 100 recent restyles, status, final delivery URL when available and whether the original source can be reopened.",
        "responses": {
          "200": {
            "description": "Workspace-owned saved restyles"
          },
          "401": {
            "description": "Authentication required"
          },
          "403": {
            "description": "Missing jobs:read scope"
          }
        }
      },
      "post": {
        "tags": [
          "Video restyle"
        ],
        "summary": "Reopen an earlier restyle",
        "description": "Requires jobs:read. Returns a renewed prepared source receipt, render receipt, style and cached result or delivery stage. Never creates a paid generation. Older sources may need media preparation. Use the renewed preparedToken with a new idempotency key to explicitly generate another look.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "jobId"
                ],
                "properties": {
                  "jobId": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recovered session and original source"
          },
          "404": {
            "description": "No matching restyle in this workspace"
          },
          "422": {
            "description": "Original source unavailable; upload again"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer YOUR_API_KEY"
      },
      "apiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key"
      }
    },
    "responses": {
      "Error": {
        "description": "Error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InsufficientCredits": {
        "description": "Not enough credits — fund via billing_url",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InsufficientCredits"
            }
          }
        }
      },
      "AsyncJobCreated": {
        "description": "Async job accepted — poll GET /jobs/{id} (or /lipsync/{jobId})",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/JobCreated"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "InsufficientCredits": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "example": "Insufficient credits"
          },
          "creditsRequired": {
            "type": "integer"
          },
          "creditsRemaining": {
            "type": "integer"
          },
          "billing_url": {
            "type": "string",
            "format": "uri"
          }
        }
      },
      "CreateJobRequest": {
        "type": "object",
        "required": [
          "workflow"
        ],
        "properties": {
          "workflow": {
            "type": "string",
            "description": "Canonical workflow or DB pipeline slug",
            "examples": [
              "generate_video",
              "generate_image",
              "edit_image",
              "lipsync_video",
              "transfer_motion",
              "generate_speech",
              "improve_prompt"
            ]
          },
          "input": {
            "type": "object",
            "description": "Workflow-specific input; see /capabilities for schemas"
          },
          "webhookUrl": {
            "type": "string",
            "format": "uri",
            "description": "Optional https callback on terminal state"
          }
        }
      },
      "JobCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed"
            ]
          },
          "workflow": {
            "type": "string"
          },
          "creditsCharged": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed",
              "failed"
            ]
          },
          "progress": {
            "type": "integer"
          },
          "workflowSlug": {
            "type": "string"
          },
          "creditsCharged": {
            "type": "integer"
          },
          "creditsRefunded": {
            "type": "integer"
          },
          "refundStatus": {
            "type": "string",
            "nullable": true
          },
          "output": {
            "type": "object",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "BotRegisterResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "agent": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "api_key": {
            "type": "string"
          },
          "dashboard_token": {
            "type": "string"
          },
          "dashboard_url": {
            "type": "string",
            "format": "uri"
          },
          "billing_url": {
            "type": "string",
            "format": "uri"
          },
          "billing_status": {
            "type": "string",
            "enum": [
              "plan_selection_ready",
              "checkout_ready",
              "billing_unconfigured"
            ]
          },
          "credits": {
            "type": "integer"
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Account": {
        "type": "object",
        "properties": {
          "plan": {
            "type": "string"
          },
          "creditsRemaining": {
            "type": "integer"
          },
          "limits": {
            "type": "object"
          }
        }
      },
      "Capabilities": {
        "type": "object",
        "properties": {
          "version": {
            "type": "string"
          },
          "workflows": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "models": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "endpoints": {
            "type": "object"
          },
          "auth": {
            "type": "object"
          }
        }
      },
      "StudioGraph": {
        "type": "object",
        "properties": {
          "nodes": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100,
                  "description": "Unique node ID; Object.prototype property names are reserved. Input overrides use this ID."
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "textInput",
                    "imageUpload",
                    "videoInput",
                    "audioInput",
                    "generate",
                    "grokImage",
                    "grokVideo",
                    "note",
                    "group",
                    "output"
                  ]
                },
                "position": {
                  "type": "object",
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "x",
                    "y"
                  ]
                },
                "data": {
                  "type": "object",
                  "additionalProperties": true
                },
                "parentId": {
                  "type": "string"
                },
                "style": {
                  "type": "object",
                  "properties": {
                    "width": {
                      "type": "number"
                    },
                    "height": {
                      "type": "number"
                    }
                  }
                }
              },
              "required": [
                "id",
                "type",
                "position"
              ]
            }
          },
          "edges": {
            "type": "array",
            "maxItems": 300,
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1
                },
                "source": {
                  "type": "string"
                },
                "target": {
                  "type": "string"
                },
                "sourceHandle": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "targetHandle": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "id",
                "source",
                "target"
              ]
            }
          }
        },
        "required": [
          "nodes",
          "edges"
        ]
      },
      "CreatorModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "audio",
              "text"
            ]
          },
          "workflow": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "ratios": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "durations": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "resolutions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "reference": {
            "type": "boolean"
          },
          "extraInputs": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "studioOnly": {
            "type": "boolean"
          },
          "defaults": {
            "type": "object",
            "additionalProperties": true
          },
          "estimatedCredits": {
            "type": "number",
            "description": "Estimate for default settings only. Actual duration, resolution, or text can change cost."
          }
        },
        "required": [
          "id",
          "name",
          "kind",
          "workflow",
          "ratios",
          "reference",
          "defaults",
          "estimatedCredits"
        ]
      },
      "StudioNodeResult": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed",
              "failed"
            ]
          },
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "output": {
            "type": "object",
            "additionalProperties": true
          },
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              }
            }
          },
          "startedAt": {
            "type": "string"
          },
          "completedAt": {
            "type": "string"
          }
        },
        "required": [
          "status"
        ]
      },
      "StudioRun": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "workflowId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed",
              "failed",
              "cancelled"
            ]
          },
          "nodeResults": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/StudioNodeResult"
            }
          },
          "graphSnapshot": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StudioGraph"
              },
              {
                "type": "null"
              }
            ]
          },
          "cancelRequested": {
            "type": "boolean"
          },
          "creditsEstimated": {
            "type": "integer"
          },
          "creditsUsed": {
            "type": "integer"
          },
          "error": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "startedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "completedAt": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "workflowId",
          "status",
          "nodeResults",
          "creditsEstimated",
          "creditsUsed",
          "cancelRequested"
        ]
      },
      "MediaLibraryAsset": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "kind": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "audio"
            ]
          },
          "folder": {
            "type": "string",
            "maxLength": 100
          },
          "favorite": {
            "type": "boolean"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "url",
          "kind",
          "folder",
          "favorite"
        ]
      },
      "StoryInput": {
        "type": "object",
        "properties": {
          "videoModel": {
            "type": "string",
            "enum": [
              "seedance-2",
              "seedance-2.5"
            ]
          },
          "referenceProjectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "productionMode": {
            "type": "string",
            "enum": [
              "direct",
              "reviewed",
              "automatic"
            ]
          },
          "audioMode": {
            "default": "native-dialogue",
            "type": "string",
            "enum": [
              "narration",
              "native-dialogue"
            ]
          },
          "idea": {
            "type": "string",
            "minLength": 10,
            "maxLength": 2000
          },
          "style": {
            "default": "Stylized 3D animation, expressive characters, cinematic lighting",
            "type": "string",
            "minLength": 3,
            "maxLength": 1000
          },
          "durationSec": {
            "default": 30,
            "anyOf": [
              {
                "type": "number",
                "const": 15
              },
              {
                "type": "number",
                "const": 30
              },
              {
                "type": "number",
                "const": 35
              },
              {
                "type": "number",
                "const": 45
              },
              {
                "type": "number",
                "const": 60
              },
              {
                "type": "number",
                "const": 120
              },
              {
                "type": "number",
                "const": 180
              }
            ]
          },
          "aspect": {
            "default": "9:16",
            "type": "string",
            "enum": [
              "9:16",
              "16:9",
              "1:1"
            ]
          }
        },
        "required": [
          "idea"
        ]
      },
      "StoryBlueprint": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300
          },
          "format": {
            "type": "string",
            "enum": [
              "ugc-talking",
              "ranking",
              "podcast",
              "interview",
              "montage",
              "other"
            ]
          },
          "durationSec": {
            "type": "number",
            "minimum": 1,
            "maximum": 600
          },
          "aspect": {
            "type": "string",
            "enum": [
              "9:16",
              "16:9",
              "1:1"
            ]
          },
          "language": {
            "type": "string",
            "minLength": 2,
            "maxLength": 40
          },
          "hook": {
            "type": "string",
            "minLength": 1,
            "maxLength": 600
          },
          "cast": {
            "minItems": 1,
            "maxItems": 8,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "presenter",
                    "guest",
                    "narrator"
                  ]
                },
                "description": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 2000
                },
                "voice": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 120
                },
                "voicePreset": {
                  "type": "string",
                  "enum": [
                    "adam",
                    "roger",
                    "liam",
                    "jessica",
                    "laura",
                    "sarah",
                    "callum",
                    "charlie"
                  ]
                },
                "voiceSample": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 300
                },
                "imageUrl": {
                  "type": "string",
                  "maxLength": 2000,
                  "format": "uri"
                }
              },
              "required": [
                "id",
                "role",
                "description",
                "voice"
              ]
            }
          },
          "product": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "description": {
                "type": "string",
                "minLength": 1,
                "maxLength": 2000
              },
              "imageUrl": {
                "type": "string",
                "maxLength": 2000,
                "format": "uri"
              }
            },
            "required": [
              "name",
              "description"
            ]
          },
          "script": {
            "minItems": 1,
            "maxItems": 80,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "castId": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "text": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 4000
                },
                "emphasis": {
                  "default": [],
                  "maxItems": 64,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "wordStart": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 4000
                      },
                      "wordEnd": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 4000
                      },
                      "tag": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 40
                      }
                    },
                    "required": [
                      "wordStart",
                      "wordEnd",
                      "tag"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "castId",
                "text"
              ]
            }
          },
          "shots": {
            "default": [],
            "maxItems": 160,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "continuesFrom": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "repairNotes": {
                  "type": "string",
                  "maxLength": 600
                },
                "frameRepairNotes": {
                  "type": "string",
                  "maxLength": 600
                },
                "staging": {
                  "type": "object",
                  "properties": {
                    "opening": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 350
                    },
                    "action": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 200
                    },
                    "closing": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 350
                    },
                    "camera": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 150
                    }
                  },
                  "required": [
                    "opening",
                    "action",
                    "closing",
                    "camera"
                  ]
                },
                "continuity": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 600
                },
                "overlayText": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 60
                },
                "locationId": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "take": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1000
                },
                "frameTake": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 1000
                },
                "approvedFrameUrl": {
                  "type": "string",
                  "maxLength": 2000,
                  "format": "uri"
                },
                "approvedVideoUrl": {
                  "type": "string",
                  "maxLength": 2000,
                  "format": "uri"
                },
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "a-roll",
                    "b-roll",
                    "scene",
                    "graphic"
                  ]
                },
                "scriptId": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "wordStart": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 4000
                },
                "wordEnd": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 4000
                },
                "description": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 2000
                },
                "prompt": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 4000
                },
                "model": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 80
                },
                "castId": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "castIds": {
                  "maxItems": 3,
                  "type": "array",
                  "items": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64,
                    "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                  }
                },
                "durationSec": {
                  "type": "integer",
                  "minimum": 4,
                  "maximum": 30
                },
                "dialogue": {
                  "minItems": 1,
                  "maxItems": 6,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "castId": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 64,
                        "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                      },
                      "text": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      }
                    },
                    "required": [
                      "castId",
                      "text"
                    ]
                  }
                }
              },
              "required": [
                "id",
                "kind",
                "scriptId",
                "wordStart",
                "wordEnd",
                "description",
                "prompt"
              ]
            }
          },
          "captions": {
            "type": "object",
            "properties": {
              "style": {
                "type": "string",
                "enum": [
                  "karaoke",
                  "boxed",
                  "minimal"
                ]
              },
              "position": {
                "type": "string",
                "enum": [
                  "bottom",
                  "center",
                  "top"
                ]
              },
              "accent": {
                "type": "string",
                "minLength": 1,
                "maxLength": 40
              }
            },
            "required": [
              "style",
              "position"
            ]
          },
          "graphics": {
            "default": [],
            "maxItems": 32,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 64,
                  "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "ranking-board",
                    "lower-third",
                    "title"
                  ]
                },
                "data": {
                  "type": "object",
                  "propertyNames": {
                    "type": "string"
                  },
                  "additionalProperties": {}
                }
              },
              "required": [
                "id",
                "kind",
                "data"
              ]
            }
          },
          "music": {
            "type": "object",
            "properties": {
              "mood": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              }
            },
            "required": [
              "mood"
            ]
          },
          "sourceNotes": {
            "default": "",
            "type": "string",
            "maxLength": 4000
          },
          "story": {
            "type": "object",
            "properties": {
              "pipelineVersion": {
                "type": "number",
                "const": 2
              },
              "videoModel": {
                "type": "string",
                "enum": [
                  "seedance-2",
                  "seedance-2.5"
                ]
              },
              "productionMode": {
                "type": "string",
                "enum": [
                  "direct",
                  "reviewed",
                  "automatic"
                ]
              },
              "locations": {
                "maxItems": 6,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 64,
                      "pattern": "^[a-zA-Z0-9][a-zA-Z0-9_-]*$"
                    },
                    "name": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "description": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 1000
                    },
                    "imageUrl": {
                      "type": "string",
                      "maxLength": 2000,
                      "format": "uri"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "description"
                  ]
                }
              },
              "audioMode": {
                "type": "string",
                "enum": [
                  "narration",
                  "native-dialogue"
                ]
              },
              "idea": {
                "type": "string",
                "minLength": 10,
                "maxLength": 2000
              },
              "style": {
                "type": "string",
                "minLength": 3,
                "maxLength": 1000
              }
            },
            "required": [
              "idea",
              "style"
            ]
          }
        },
        "required": [
          "title",
          "format",
          "durationSec",
          "aspect",
          "language",
          "hook",
          "cast",
          "script",
          "captions",
          "music"
        ],
        "description": "Full editable blueprint. Story rules: narration uses one narrator; native-dialogue has ordered speaking turns. Reviewed production requires shared locations, approved current frame URLs before video and approved current video URLs before rendering. <=12 lines, <=26 whitespace-separated words per line; each line has one scene covering [0,word count), and explicit castIds for visible cast (empty for scenery). IDs must be unique and references valid. Preserve story metadata."
      },
      "StoryAsset": {
        "type": "object",
        "properties": {
          "frameQuality": {
            "type": "object",
            "properties": {
              "identity": {
                "type": "string",
                "enum": [
                  "pass",
                  "fail",
                  "uncertain"
                ]
              },
              "staging": {
                "type": "string",
                "enum": [
                  "pass",
                  "fail",
                  "uncertain"
                ]
              },
              "findings": {
                "maxItems": 8,
                "type": "array",
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 600
                }
              },
              "contextHash": {
                "type": "string"
              },
              "checkedAt": {
                "type": "string"
              },
              "model": {
                "type": "string"
              }
            },
            "required": [
              "identity",
              "staging",
              "findings",
              "contextHash",
              "checkedAt",
              "model"
            ]
          },
          "quality": {
            "type": "object",
            "properties": {
              "identity": {
                "type": "string",
                "enum": [
                  "pass",
                  "fail",
                  "uncertain"
                ]
              },
              "voices": {
                "type": "string",
                "enum": [
                  "pass",
                  "fail",
                  "uncertain"
                ]
              },
              "dialogue": {
                "type": "string",
                "enum": [
                  "pass",
                  "fail",
                  "uncertain"
                ]
              },
              "physics": {
                "type": "string",
                "enum": [
                  "pass",
                  "fail",
                  "uncertain"
                ]
              },
              "continuity": {
                "type": "string",
                "enum": [
                  "pass",
                  "fail",
                  "uncertain"
                ]
              },
              "pacing": {
                "type": "string",
                "enum": [
                  "pass",
                  "fail",
                  "uncertain"
                ]
              },
              "findings": {
                "maxItems": 12,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "atSec": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 30
                    },
                    "detail": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 600
                    }
                  },
                  "required": [
                    "atSec",
                    "detail"
                  ]
                }
              },
              "contextHash": {
                "type": "string"
              },
              "checkedAt": {
                "type": "string"
              },
              "model": {
                "type": "string"
              }
            },
            "required": [
              "identity",
              "voices",
              "dialogue",
              "physics",
              "continuity",
              "pacing",
              "findings",
              "contextHash",
              "checkedAt",
              "model"
            ]
          },
          "id": {
            "type": "string",
            "minLength": 1
          },
          "shotId": {
            "type": "string"
          },
          "castId": {
            "type": "string"
          },
          "scriptId": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "video",
              "image",
              "audio",
              "alignment"
            ]
          },
          "jobId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed",
              "failed"
            ]
          },
          "url": {
            "type": "string"
          },
          "credits": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "error": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "kind",
          "status",
          "credits"
        ]
      },
      "StoryError": {
        "type": "object",
        "required": [
          "error",
          "code"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "details": {},
          "creditsRequired": {
            "type": "number"
          },
          "creditsRemaining": {
            "type": "number"
          }
        }
      },
      "StoryEstimate": {
        "type": "object",
        "properties": {
          "credits": {
            "type": "number"
          },
          "lines": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "label": {
                  "type": "string"
                },
                "model": {
                  "type": "string"
                },
                "credits": {
                  "type": "number"
                }
              },
              "required": [
                "label",
                "model",
                "credits"
              ]
            }
          }
        },
        "required": [
          "credits",
          "lines"
        ]
      },
      "StoryProject": {
        "type": "object",
        "required": [
          "id",
          "organizationId",
          "status",
          "blueprint",
          "assets",
          "credits",
          "render",
          "error",
          "createdAt",
          "updatedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "organizationId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "analyzing",
              "ready",
              "building",
              "rendering",
              "reviewing",
              "done",
              "failed"
            ]
          },
          "sourceUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "sourceVideoUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "thumbnailUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "parentId": {
            "type": [
              "string",
              "null"
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "blueprint": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/StoryBlueprint"
              },
              {
                "type": "null"
              }
            ]
          },
          "assets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StoryAsset"
            }
          },
          "credits": {
            "type": "object",
            "properties": {
              "analysis": {
                "type": "number"
              },
              "estimatedBuild": {
                "type": "number"
              },
              "spent": {
                "type": "number"
              }
            },
            "required": [
              "analysis",
              "estimatedBuild",
              "spent"
            ]
          },
          "production": {
            "type": "object",
            "properties": {
              "quality": {
                "type": "object",
                "properties": {
                  "passed": {
                    "type": "number"
                  },
                  "total": {
                    "type": "number"
                  },
                  "next": {
                    "type": "object",
                    "properties": {
                      "shotId": {
                        "type": "string"
                      },
                      "stage": {
                        "type": "string",
                        "enum": [
                          "review",
                          "storyboard",
                          "build"
                        ]
                      },
                      "credits": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "shotId",
                      "stage",
                      "credits"
                    ]
                  },
                  "repair": {
                    "type": "object",
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": [
                          "frame",
                          "video"
                        ]
                      },
                      "shotId": {
                        "type": "string"
                      },
                      "videoUrl": {
                        "type": "string"
                      },
                      "findings": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "atSec": {
                              "type": "number"
                            },
                            "detail": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "atSec",
                            "detail"
                          ]
                        }
                      },
                      "retryCredits": {
                        "type": "number"
                      },
                      "retryMode": {
                        "type": "string",
                        "enum": [
                          "take",
                          "check"
                        ]
                      }
                    },
                    "required": [
                      "kind",
                      "shotId",
                      "videoUrl",
                      "findings",
                      "retryCredits",
                      "retryMode"
                    ]
                  }
                },
                "required": [
                  "passed",
                  "total"
                ]
              },
              "preparationReady": {
                "type": "boolean"
              },
              "buildReady": {
                "type": "boolean"
              },
              "storyboardReady": {
                "type": "boolean"
              },
              "storyboardApproved": {
                "type": "boolean"
              },
              "videoApproved": {
                "type": "boolean"
              },
              "frames": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "shotId": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "approved": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "shotId",
                    "approved"
                  ]
                }
              },
              "scenes": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "shotId": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string"
                    },
                    "approved": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "shotId",
                    "approved"
                  ]
                }
              }
            },
            "required": [
              "preparationReady",
              "buildReady"
            ]
          },
          "render": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "videoUrl": {
                    "type": "string"
                  },
                  "credits": {
                    "type": "number"
                  },
                  "renderedAt": {
                    "type": "string"
                  }
                },
                "required": [
                  "videoUrl",
                  "credits",
                  "renderedAt"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "RestylePrepareRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "sourceUrl": {
            "type": "string",
            "format": "uri"
          },
          "videoUrl": {
            "type": "string",
            "format": "uri"
          },
          "segments": {
            "type": "array",
            "minItems": 1,
            "maxItems": 12,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "properties": {
                "start": {
                  "type": "number",
                  "minimum": 0
                },
                "end": {
                  "type": "number",
                  "exclusiveMinimum": 0
                }
              },
              "required": [
                "start",
                "end"
              ]
            }
          },
          "trim": {
            "type": "string",
            "enum": [
              "first-30",
              "last-30"
            ]
          },
          "frameAt": {
            "type": "number",
            "minimum": 0,
            "maximum": 30
          }
        },
        "required": [],
        "oneOf": [
          {
            "required": [
              "sourceUrl"
            ],
            "not": {
              "required": [
                "videoUrl"
              ]
            }
          },
          {
            "required": [
              "videoUrl"
            ],
            "not": {
              "required": [
                "sourceUrl"
              ]
            }
          }
        ]
      },
      "RestylePrepareResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "preparedToken": {
            "type": "string"
          },
          "videoUrl": {
            "type": "string",
            "format": "uri"
          },
          "thumbnailUrl": {
            "type": "string",
            "format": "uri"
          },
          "durationSec": {
            "type": "number"
          },
          "width": {
            "type": "integer"
          },
          "height": {
            "type": "integer"
          },
          "hasAudio": {
            "type": "boolean"
          },
          "renderCredits": {
            "type": "integer"
          },
          "next": {
            "type": "string"
          }
        },
        "required": [
          "preparedToken",
          "videoUrl",
          "thumbnailUrl",
          "durationSec",
          "renderCredits"
        ]
      },
      "RestylePreviewRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "preparedToken": {
            "type": "string"
          },
          "style": {
            "type": "string",
            "minLength": 3,
            "maxLength": 1800
          },
          "idempotencyKey": {
            "type": "string",
            "minLength": 8,
            "maxLength": 128
          },
          "styleId": {
            "type": "string",
            "enum": [
              "pixar",
              "cartoon",
              "hand-drawn",
              "anime",
              "clay",
              "comic"
            ]
          }
        },
        "required": [
          "preparedToken",
          "idempotencyKey"
        ],
        "oneOf": [
          {
            "required": [
              "style"
            ],
            "not": {
              "required": [
                "styleId"
              ]
            }
          },
          {
            "required": [
              "styleId"
            ],
            "not": {
              "required": [
                "style"
              ]
            }
          }
        ]
      },
      "RestylePreviewResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "statusUrl": {
            "type": "string"
          },
          "creditsCharged": {
            "type": "integer"
          },
          "next": {
            "type": "string"
          },
          "previewToken": {
            "type": "string"
          },
          "approvalRequired": {
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "jobId",
          "previewToken",
          "approvalRequired"
        ]
      },
      "RestyleRenderRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "previewToken": {
            "type": "string"
          },
          "approved": {
            "type": "boolean",
            "const": true
          }
        },
        "required": [
          "previewToken",
          "approved"
        ]
      },
      "RestyleRenderResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string"
          },
          "statusUrl": {
            "type": "string"
          },
          "creditsCharged": {
            "type": "integer"
          },
          "next": {
            "type": "string"
          },
          "renderToken": {
            "type": "string"
          }
        },
        "required": [
          "jobId",
          "renderToken"
        ]
      },
      "RestyleFinalizeRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "renderToken": {
            "type": "string"
          }
        },
        "required": [
          "renderToken"
        ]
      },
      "RestyleFinalizeResponse": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "videoUrl": {
            "type": "string",
            "format": "uri"
          },
          "durationSec": {
            "type": "number"
          }
        },
        "required": [
          "jobId",
          "videoUrl",
          "durationSec"
        ]
      },
      "CharacterSourceInput": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "sourceUrl": {
            "type": "string",
            "maxLength": 4096,
            "format": "uri"
          },
          "videoUrl": {
            "type": "string",
            "maxLength": 4096,
            "format": "uri"
          },
          "segment": {
            "type": "object",
            "properties": {
              "start": {
                "type": "number",
                "minimum": 0
              },
              "end": {
                "type": "number",
                "exclusiveMinimum": 0
              }
            },
            "required": [
              "start",
              "end"
            ],
            "additionalProperties": false
          }
        },
        "additionalProperties": false,
        "oneOf": [
          {
            "required": [
              "sourceUrl"
            ],
            "not": {
              "required": [
                "videoUrl"
              ]
            }
          },
          {
            "required": [
              "videoUrl"
            ],
            "not": {
              "required": [
                "sourceUrl"
              ]
            }
          }
        ]
      },
      "CharacterRunInput": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "design"
              },
              "messages": {
                "minItems": 1,
                "maxItems": 40,
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "role": {
                      "type": "string",
                      "enum": [
                        "user",
                        "assistant"
                      ]
                    },
                    "content": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 10000
                    }
                  },
                  "required": [
                    "role",
                    "content"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "action",
              "messages"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "create"
              },
              "description": {
                "type": "string",
                "minLength": 1,
                "maxLength": 2600
              }
            },
            "required": [
              "action",
              "description"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "edit"
              },
              "description": {
                "type": "string",
                "minLength": 1,
                "maxLength": 2600
              },
              "reference": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "characterId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "useReferenceSheet": {
                        "default": false,
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "characterId",
                      "useReferenceSheet"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "imageUrl": {
                        "type": "string",
                        "maxLength": 2000,
                        "format": "uri"
                      }
                    },
                    "required": [
                      "imageUrl"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            },
            "required": [
              "action",
              "description",
              "reference"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "sheet"
              },
              "description": {
                "default": "",
                "type": "string",
                "maxLength": 2600
              },
              "reference": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "characterId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "useReferenceSheet": {
                        "default": false,
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "characterId",
                      "useReferenceSheet"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "imageUrl": {
                        "type": "string",
                        "maxLength": 2000,
                        "format": "uri"
                      }
                    },
                    "required": [
                      "imageUrl"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            },
            "required": [
              "action",
              "description",
              "reference"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "video"
              },
              "prompt": {
                "type": "string",
                "minLength": 1,
                "maxLength": 4000
              },
              "reference": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "characterId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "useReferenceSheet": {
                        "default": false,
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "characterId",
                      "useReferenceSheet"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "imageUrl": {
                        "type": "string",
                        "maxLength": 2000,
                        "format": "uri"
                      }
                    },
                    "required": [
                      "imageUrl"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "duration": {
                "default": 5,
                "type": "integer",
                "minimum": 4,
                "maximum": 15
              },
              "aspectRatio": {
                "default": "9:16",
                "type": "string",
                "enum": [
                  "9:16",
                  "16:9",
                  "1:1"
                ]
              }
            },
            "required": [
              "action",
              "prompt",
              "reference",
              "duration",
              "aspectRatio"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "recast"
              },
              "reference": {
                "anyOf": [
                  {
                    "type": "object",
                    "properties": {
                      "characterId": {
                        "type": "string",
                        "format": "uuid",
                        "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                      },
                      "useReferenceSheet": {
                        "default": false,
                        "type": "boolean"
                      }
                    },
                    "required": [
                      "characterId",
                      "useReferenceSheet"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "imageUrl": {
                        "type": "string",
                        "maxLength": 2000,
                        "format": "uri"
                      }
                    },
                    "required": [
                      "imageUrl"
                    ],
                    "additionalProperties": false
                  }
                ]
              },
              "sourceVideoUrl": {
                "type": "string",
                "maxLength": 2000,
                "format": "uri"
              },
              "resolution": {
                "default": "720p",
                "type": "string",
                "enum": [
                  "480p",
                  "720p"
                ]
              }
            },
            "required": [
              "action",
              "reference",
              "sourceVideoUrl",
              "resolution"
            ],
            "additionalProperties": false
          },
          {
            "type": "object",
            "properties": {
              "action": {
                "type": "string",
                "const": "template"
              },
              "templateId": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "references": {
                "maxItems": 8,
                "type": "array",
                "items": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "characterId": {
                          "type": "string",
                          "format": "uuid",
                          "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                        },
                        "useReferenceSheet": {
                          "default": false,
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "characterId",
                        "useReferenceSheet"
                      ],
                      "additionalProperties": false
                    },
                    {
                      "type": "object",
                      "properties": {
                        "imageUrl": {
                          "type": "string",
                          "maxLength": 2000,
                          "format": "uri"
                        }
                      },
                      "required": [
                        "imageUrl"
                      ],
                      "additionalProperties": false
                    }
                  ]
                }
              },
              "carDescription": {
                "type": "string",
                "minLength": 1,
                "maxLength": 500
              },
              "templateImageUrl": {
                "type": "string",
                "maxLength": 2000,
                "format": "uri"
              },
              "sourceVideoUrl": {
                "type": "string",
                "maxLength": 2000,
                "format": "uri"
              },
              "background": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "mode": {
                        "type": "string",
                        "const": "original"
                      }
                    },
                    "required": [
                      "mode"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "mode": {
                        "type": "string",
                        "const": "reference"
                      },
                      "referenceIndex": {
                        "type": "integer",
                        "minimum": 0,
                        "maximum": 7
                      }
                    },
                    "required": [
                      "mode",
                      "referenceIndex"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "mode": {
                        "type": "string",
                        "const": "image"
                      },
                      "imageUrl": {
                        "type": "string",
                        "maxLength": 2000,
                        "format": "uri"
                      }
                    },
                    "required": [
                      "mode",
                      "imageUrl"
                    ],
                    "additionalProperties": false
                  },
                  {
                    "type": "object",
                    "properties": {
                      "mode": {
                        "type": "string",
                        "const": "description"
                      },
                      "description": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500
                      }
                    },
                    "required": [
                      "mode",
                      "description"
                    ],
                    "additionalProperties": false
                  }
                ]
              }
            },
            "required": [
              "action",
              "templateId",
              "references"
            ],
            "additionalProperties": false
          }
        ]
      },
      "CharacterInput": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "imageUrl": {
            "type": "string",
            "maxLength": 2000,
            "format": "uri"
          },
          "description": {
            "default": "",
            "type": "string",
            "maxLength": 2600
          },
          "referenceSheetUrl": {
            "default": null,
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000,
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "isDefault": {
            "default": false,
            "type": "boolean"
          }
        },
        "required": [
          "name",
          "imageUrl",
          "description",
          "referenceSheetUrl",
          "isDefault"
        ],
        "additionalProperties": false
      },
      "CharacterUpdate": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "imageUrl": {
            "type": "string",
            "maxLength": 2000,
            "format": "uri"
          },
          "description": {
            "type": "string",
            "maxLength": 2600
          },
          "referenceSheetUrl": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000,
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "isDefault": {
            "type": "boolean",
            "const": true
          }
        },
        "additionalProperties": false
      },
      "Character": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 80
          },
          "imageUrl": {
            "type": "string",
            "maxLength": 2000,
            "format": "uri"
          },
          "description": {
            "default": "",
            "type": "string",
            "maxLength": 2600
          },
          "referenceSheetUrl": {
            "default": null,
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2000,
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          },
          "isDefault": {
            "default": false,
            "type": "boolean"
          },
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "imageUrl"
        ],
        "additionalProperties": true
      }
    }
  }
}
