{
  "openapi": "3.1.0",
  "info": {
    "title": "Soup.video API",
    "version": "1.1.0",
    "summary": "AI Director generate, poll, and authored-workflow API",
    "description": "Soup is an AI Director for filmmakers. You bring the idea; Soup directs the shots and generates the film on listed image and video models. Generation is billed to the API key owner.\n\nMachine-readable spec: https://soup.video/openapi.json\nRemote MCP: https://soup.video/mcp\nHuman docs: https://soup.video/docs",
    "contact": {
      "email": "hello@soup.video",
      "url": "https://soup.video"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://soup.video/terms"
    }
  },
  "servers": [
    {
      "url": "https://soup.video",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Models",
      "description": "Listed image and video models"
    },
    {
      "name": "Generations",
      "description": "Create and poll jobs"
    },
    {
      "name": "Workflows",
      "description": "Run published workflows you authored"
    }
  ],
  "paths": {
    "/api/models": {
      "get": {
        "operationId": "listModels",
        "tags": [
          "Models"
        ],
        "summary": "List listed models and their input schemas",
        "security": [],
        "responses": {
          "200": {
            "description": "Models the generate endpoint accepts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "models": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Model"
                      }
                    }
                  },
                  "required": [
                    "models"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/generations": {
      "post": {
        "operationId": "createGeneration",
        "tags": [
          "Generations"
        ],
        "summary": "Start an image or video generation",
        "description": "Asynchronous. Charges the API key owner, then returns a job_id to poll. Failed model steps refund; see /docs/billing.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateGenerationRequest"
              },
              "examples": {
                "landscape": {
                  "value": {
                    "model": "veo-3-1",
                    "inputs": {
                      "prompt": "A cinematic tracking shot of a sports car through a neon city at night.",
                      "resolution": "720p",
                      "quality": "lite",
                      "aspect_ratio": "16:9"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAccepted"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error"
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "402": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/generations/{job_id}": {
      "get": {
        "operationId": "getGeneration",
        "tags": [
          "Generations"
        ],
        "summary": "Poll generation or workflow job status",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "processing, completed, or failed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobStatus"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    },
    "/api/v1/workflows/{slug}/runs": {
      "post": {
        "operationId": "runWorkflow",
        "tags": [
          "Workflows"
        ],
        "summary": "Run a published workflow you authored",
        "description": "Author-only. Listing a graph on soup.video does not open it to other API keys. Poll GET /api/v1/generations/{job_id}.",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunWorkflowRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Run accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobAccepted"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error"
          },
          "403": {
            "$ref": "#/components/responses/Error"
          },
          "404": {
            "$ref": "#/components/responses/Error"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk_soup_",
        "description": "Soup API key from https://soup.video/settings. Header: Authorization: Bearer sk_soup_…"
      }
    },
    "responses": {
      "Error": {
        "description": "Error",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "string"
                }
              },
              "required": [
                "error"
              ]
            }
          }
        }
      }
    },
    "schemas": {
      "JobAccepted": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string",
            "format": "uuid"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing"
            ]
          },
          "check_url": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "job_id",
          "status",
          "check_url"
        ]
      },
      "CreateGenerationRequest": {
        "type": "object",
        "required": [
          "model",
          "inputs"
        ],
        "properties": {
          "model": {
            "type": "string",
            "description": "Model id from GET /api/models (slug or id).",
            "examples": [
              "veo-3-1",
              "kling-3-0"
            ]
          },
          "inputs": {
            "type": "object",
            "additionalProperties": true,
            "description": "Model-specific fields. Must include prompt or multi_prompt.",
            "properties": {
              "prompt": {
                "type": "string"
              },
              "aspect_ratio": {
                "type": "string",
                "examples": [
                  "16:9",
                  "9:16"
                ]
              },
              "duration": {
                "type": "number"
              }
            }
          }
        }
      },
      "RunWorkflowRequest": {
        "type": "object",
        "properties": {
          "inputs": {
            "type": "object",
            "additionalProperties": true,
            "description": "Same payload the workflow form would submit."
          }
        }
      },
      "JobStatus": {
        "type": "object",
        "properties": {
          "job_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "completed",
              "failed"
            ]
          },
          "error": {
            "type": "string"
          },
          "asset": {
            "$ref": "#/components/schemas/CompletedAsset"
          }
        },
        "required": [
          "job_id",
          "status"
        ]
      },
      "CompletedAsset": {
        "type": "object",
        "properties": {
          "page_url": {
            "type": "string",
            "format": "uri"
          },
          "media_url": {
            "type": "string",
            "format": "uri"
          },
          "thumbnail_url": {
            "type": "string",
            "format": "uri"
          },
          "cost": {
            "type": "number",
            "description": "Credits charged (1 credit = $0.01)."
          },
          "cost_usd": {
            "type": "string"
          }
        }
      },
      "Model": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "image",
              "video"
            ]
          },
          "description": {
            "type": "string"
          },
          "pricing": {
            "type": "object",
            "additionalProperties": true
          },
          "params": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "required": {
                  "type": "boolean"
                },
                "expected_values": {
                  "type": "array",
                  "items": {}
                },
                "default_value": {}
              }
            }
          }
        }
      }
    }
  }
}