{
  "openapi": "3.1.0",
  "info": {
    "title": "Video Background Remover API",
    "version": "1.0.0",
    "description": "The public video background removal API for videobackgroundremover.ai. Authenticate with a Bearer API key issued on the developer page: https://videobackgroundremover.ai/video-background-remover-api. There is no free API tier."
  },
  "servers": [
    {
      "url": "https://videobackgroundremover.ai"
    }
  ],
  "security": [
    {
      "ApiKey": []
    }
  ],
  "paths": {
    "/api/jobs/estimate": {
      "post": {
        "summary": "Estimate credits without charging",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Estimate"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or unrecognized Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "unauthorized"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": "unauthorized"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key minute rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "rate"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "rate": {
                    "value": {
                      "error": "rate"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid duration, frames or keep.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "too_short"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "bad_format"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "too_short",
                      "message": "Choose at least one second."
                    }
                  },
                  "1": {
                    "value": {
                      "code": "bad_format",
                      "message": "Choose a supported format or background."
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Billable duration exceeds the limit.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "const": "too_long"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "too_long",
                      "message": "This clip is too long."
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Unhandled infrastructure or application failure: 503 upstream or 500 internal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "internal"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ]
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateRequest"
              }
            }
          }
        },
        "description": "Anonymous estimates return null balance/enough and needed = credits. With Bearer, needed = max(0, credits - balance).",
        "security": [
          {
            "ApiKey": []
          },
          {}
        ]
      }
    },
    "/api/jobs": {
      "post": {
        "summary": "Create a paid job from URL or reserve a single upload",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ImportedJob"
                    },
                    {
                      "$ref": "#/components/schemas/SingleUpload"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Invalid Bearer: {error: unauthorized}. Missing identity where required: {error: signin}.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "unauthorized"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "signin"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "unauthorized"
                    }
                  },
                  "1": {
                    "value": {
                      "error": "signin"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key minute limit returns error: rate; job burst/concurrency/quota returns code: busy with message.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "rate"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "busy"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "rate"
                    }
                  },
                  "1": {
                    "value": {
                      "code": "busy",
                      "message": "Processing is busy. Please try again later."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation/import failure or max_credits below estimate.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "too_short"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "bad_format"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "video_import"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ]
                    },
                    {
                      "$ref": "#/components/schemas/TooExpensiveError"
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "too_short",
                      "message": "Choose at least one second."
                    }
                  },
                  "1": {
                    "value": {
                      "code": "bad_format",
                      "message": "Choose a supported format or background."
                    }
                  },
                  "2": {
                    "value": {
                      "error": "video_import",
                      "message": "Use a public HTTPS video with Content-Length, at most 500 MB."
                    }
                  },
                  "3": {
                    "value": {
                      "error": "too_expensive",
                      "credits": 600,
                      "message": "Supply seconds to reduce the reservation."
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Not enough paid credits. needed is the full reservation, not the shortfall.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/InsufficientError"
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "insufficient",
                      "code": "insufficient",
                      "needed": 600,
                      "balance": 0,
                      "pricing": "https://videobackgroundremover.ai/pricing"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Agent requests cannot use free, trim or split.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "paid_only"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "paid_only"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Invalid bytes or excessive billable duration.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "too_large"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "too_long"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "too_large",
                      "message": "This file is too large."
                    }
                  },
                  "1": {
                    "value": {
                      "code": "too_long",
                      "message": "This clip is too long."
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Creation failed. May also return an unhandled internal failure with error and message.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "processing_failed"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "internal"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "processing_failed",
                      "message": "Processing failed. Your time has been returned."
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "URL imported but job already failed; inspect job.error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImportedJob"
                }
              }
            }
          },
          "503": {
            "description": "Processing is unavailable. May also return an unhandled upstream failure with error and message.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "unavailable"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "upstream"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "unavailable"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Unhandled infrastructure or application failure: 503 upstream or 500 internal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "internal"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ]
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRequest"
              }
            }
          }
        }
      },
      "get": {
        "summary": "List the most recent 20 owned jobs",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jobs": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/JobView"
                      }
                    }
                  },
                  "required": [
                    "jobs"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Invalid Bearer: {error: unauthorized}. Missing identity where required: {error: signin}.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "unauthorized"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "signin"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "unauthorized"
                    }
                  },
                  "1": {
                    "value": {
                      "error": "signin"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key minute rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "rate"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "rate": {
                    "value": {
                      "error": "rate"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Unhandled infrastructure or application failure: 503 upstream or 500 internal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "internal"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/jobs/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Read a job and fresh signed download URLs",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobView"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or unrecognized Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "unauthorized"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": "unauthorized"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key minute rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "rate"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "rate": {
                    "value": {
                      "error": "rate"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Missing job/file or not owned by caller.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "not_found"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "not_found"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Unhandled infrastructure or application failure: 503 upstream or 500 internal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "internal"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ]
                }
              }
            }
          }
        },
        "description": "Poll every 10\u201320 seconds. Ready files receive absolute signed links valid for 24 hours; results are retained for 7 days. Other job responses may contain relative file URLs."
      },
      "delete": {
        "summary": "Cancel an active job and refund unused credits",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobView"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or unrecognized Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "unauthorized"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": "unauthorized"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key minute rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "rate"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "rate": {
                    "value": {
                      "error": "rate"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Missing job/file or not owned by caller.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "not_found"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Job state does not allow this action.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "state"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "state"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Unhandled infrastructure or application failure: 503 upstream or 500 internal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "internal"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/jobs/{id}/start": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Verify the single PUT upload and enqueue",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobView"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or unrecognized Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "unauthorized"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": "unauthorized"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key minute rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "rate"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "rate": {
                    "value": {
                      "error": "rate"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Uploaded size differs from the reserved size.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "const": "upload_mismatch"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "upload_mismatch",
                      "message": "The uploaded file size does not match. Your time has been returned."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Missing job/file or not owned by caller.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "not_found"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Wrong state, concurrent start, or uploaded object changed during verification.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "state"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "upload_changed"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "state"
                    }
                  },
                  "upload_changed": {
                    "value": {
                      "error": "upload_changed"
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Job failed after enqueue; inspect error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobView"
                }
              }
            }
          },
          "503": {
            "description": "Upload could not be read. May also return an unhandled upstream failure with error and message.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "upload_unavailable"
                        }
                      },
                      "required": [
                        "error"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "upstream"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "upload_unavailable"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Unhandled infrastructure or application failure: 503 upstream or 500 internal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "internal"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ]
                }
              }
            }
          }
        },
        "description": "Only single-upload jobs in uploading state can start. No request body."
      }
    },
    "/api/jobs/{id}/exports": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "summary": "Export a completed job in another format",
        "responses": {
          "200": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/JobFile"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or unrecognized Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "unauthorized"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": "unauthorized"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key minute rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "rate"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "rate": {
                    "value": {
                      "error": "rate"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid format, part or background.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "const": "bad_format"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "bad_format",
                      "message": "Choose a supported format or background."
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Agent cannot export a free preview.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "paid_only"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "paid_only"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Missing job/file or not owned by caller.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "not_found"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "not_found"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Job state does not allow this action.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "state"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "state"
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "Result expired.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "const": "expired"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "expired",
                      "message": "This result has expired."
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Paid processing daily spend limit reached. May also return an unhandled upstream failure with error and message.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "code": {
                          "const": "busy"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "const": "upstream"
                        },
                        "message": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "error",
                        "message"
                      ]
                    }
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "busy",
                      "message": "Processing is busy. Please try again later."
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Unhandled infrastructure or application failure: 503 upstream or 500 internal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "internal"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ]
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExportRequest"
              }
            }
          }
        },
        "description": "Returns one JobFile, possibly pending or failed, not a JobView. No extra credits charged; daily encoding spend limits still apply."
      }
    },
    "/api/jobs/{id}/files/{fileId}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "fileId",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "summary": "Download a ready result (supports Range)",
        "responses": {
          "200": {
            "description": "File stream",
            "headers": {
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Length": {
                "schema": {
                  "type": "string"
                }
              },
              "Accept-Ranges": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "video/webm": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "video/quicktime": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "video/mp4": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or unrecognized Bearer token.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "unauthorized"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "unauthorized": {
                    "value": {
                      "error": "unauthorized"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "API key minute rate limit exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "rate"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "rate": {
                    "value": {
                      "error": "rate"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Missing job/file or not owned by caller.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "const": "not_found"
                    }
                  },
                  "required": [
                    "error"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "error": "not_found"
                    }
                  }
                }
              }
            }
          },
          "410": {
            "description": "Result expired.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "const": "expired"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "code",
                    "message"
                  ]
                },
                "examples": {
                  "0": {
                    "value": {
                      "code": "expired",
                      "message": "This result has expired."
                    }
                  }
                }
              }
            }
          },
          "416": {
            "description": "Invalid or unsatisfiable byte range. Empty body.",
            "headers": {
              "Content-Range": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "206": {
            "description": "Partial file stream",
            "headers": {
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Length": {
                "schema": {
                  "type": "string"
                }
              },
              "Accept-Ranges": {
                "schema": {
                  "type": "string"
                }
              },
              "Content-Range": {
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "video/webm": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "video/quicktime": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "video/mp4": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "default": {
            "description": "Unhandled infrastructure or application failure: 503 upstream or 500 internal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "upstream",
                        "internal"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error",
                    "message"
                  ]
                }
              }
            }
          }
        },
        "description": "Use Bearer, or the exp + sig query pair from GET /api/jobs/{id}; signed URLs need no Authorization header.",
        "security": [
          {
            "ApiKey": []
          },
          {
            "DownloadExpiry": [],
            "DownloadSignature": []
          }
        ],
        "parameters": [
          {
            "name": "Range",
            "in": "header",
            "schema": {
              "type": "string"
            },
            "description": "Single bytes range, e.g. bytes=0-1023."
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key issued on /video-background-remover-api, prefix vbr (Authorization: Bearer vbr_sk_...). Keep keys in backend scripts."
      },
      "DownloadExpiry": {
        "type": "apiKey",
        "in": "query",
        "name": "exp"
      },
      "DownloadSignature": {
        "type": "apiKey",
        "in": "query",
        "name": "sig"
      }
    },
    "schemas": {
      "Format": {
        "type": "string",
        "enum": [
          "hevc_mov",
          "prores",
          "webm",
          "green_mp4",
          "bg_mp4",
          "zip"
        ]
      },
      "Keep": {
        "type": "string",
        "enum": [
          "person",
          "objects"
        ],
        "default": "objects"
      },
      "Frames": {
        "type": "integer",
        "minimum": 1,
        "maximum": 10000000
      },
      "JobError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "too_long",
              "too_large",
              "too_short",
              "bad_format",
              "unreadable",
              "duration_mismatch",
              "no_subject",
              "insufficient",
              "free_used",
              "free_cap",
              "busy",
              "processing_failed",
              "expired",
              "upload_mismatch"
            ]
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "code",
          "message"
        ]
      },
      "JobFile": {
        "type": "object",
        "properties": {
          "fileId": {
            "type": "string"
          },
          "format": {
            "$ref": "#/components/schemas/Format"
          },
          "part": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "ready",
              "failed"
            ]
          },
          "bytes": {
            "type": "integer"
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "description": "Relative download path, or an absolute signed URL from GET /api/jobs/{id}. Null until ready or after expiry."
          }
        },
        "required": [
          "fileId",
          "format",
          "part",
          "status",
          "bytes",
          "url"
        ]
      },
      "JobView": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "uploading",
              "waiting",
              "queued",
              "running",
              "done",
              "no_subject",
              "failed",
              "canceled"
            ]
          },
          "stage": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "analyzing",
              "removing",
              "encoding",
              null
            ]
          },
          "progress": {
            "type": "number",
            "minimum": 0,
            "maximum": 1
          },
          "queueAhead": {
            "type": [
              "integer",
              "null"
            ]
          },
          "seconds": {
            "type": "number"
          },
          "free": {
            "type": "boolean"
          },
          "keep": {
            "$ref": "#/components/schemas/Keep"
          },
          "format": {
            "$ref": "#/components/schemas/Format"
          },
          "parts": {
            "anyOf": [
              {
                "type": "array",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  },
                  "minItems": 2,
                  "maxItems": 2
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "uploadedParts": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "result": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "greenScreen": {
                    "type": "boolean"
                  },
                  "width": {
                    "type": "integer"
                  },
                  "height": {
                    "type": "integer"
                  },
                  "fps": {
                    "type": "number"
                  },
                  "downscaled": {
                    "type": "boolean"
                  },
                  "hdrConverted": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "greenScreen",
                  "width",
                  "height",
                  "fps",
                  "downscaled",
                  "hdrConverted"
                ]
              },
              {
                "type": "null"
              }
            ]
          },
          "files": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JobFile"
            }
          },
          "error": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/JobError"
              },
              {
                "type": "null"
              }
            ]
          },
          "charged": {
            "type": "boolean"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "credits": {
            "type": "number"
          }
        },
        "required": [
          "id",
          "status",
          "stage",
          "progress",
          "queueAhead",
          "seconds",
          "free",
          "keep",
          "format",
          "parts",
          "uploadedParts",
          "result",
          "files",
          "error",
          "charged",
          "expiresAt",
          "credits"
        ]
      },
      "Background": {
        "description": "Color or gradient replacement. bg_mp4 requires a valid background. Photo backgrounds require a separate browser upload and are outside this script API.",
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "color"
              },
              "color": {
                "type": "string",
                "pattern": "^#[0-9a-fA-F]{6}$"
              },
              "x": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "default": 0.5
              },
              "y": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "default": 0.5
              },
              "scale": {
                "type": "number",
                "minimum": 0.3,
                "maximum": 2,
                "default": 1
              }
            },
            "required": [
              "type",
              "color"
            ]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "gradient"
              },
              "from": {
                "type": "string",
                "pattern": "^#[0-9a-fA-F]{6}$"
              },
              "to": {
                "type": "string",
                "pattern": "^#[0-9a-fA-F]{6}$"
              },
              "angle": {
                "type": "number"
              },
              "x": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "default": 0.5
              },
              "y": {
                "type": "number",
                "minimum": 0,
                "maximum": 1,
                "default": 0.5
              },
              "scale": {
                "type": "number",
                "minimum": 0.3,
                "maximum": 2,
                "default": 1
              }
            },
            "required": [
              "type",
              "from",
              "to",
              "angle"
            ]
          }
        ]
      },
      "EstimateRequest": {
        "type": "object",
        "properties": {
          "seconds": {
            "type": "number",
            "minimum": 1
          },
          "frames": {
            "$ref": "#/components/schemas/Frames"
          },
          "keep": {
            "$ref": "#/components/schemas/Keep"
          },
          "split": {
            "type": "boolean",
            "default": false,
            "description": "Estimate only: maximum billable seconds 300, or 600 when true. Agent creation rejects split."
          }
        },
        "required": [
          "seconds"
        ]
      },
      "Estimate": {
        "type": "object",
        "properties": {
          "seconds": {
            "type": "number"
          },
          "frames": {
            "type": "number"
          },
          "fps": {
            "type": "number"
          },
          "multiplier": {
            "type": "number"
          },
          "billableSeconds": {
            "type": "number"
          },
          "creditsPerSecond": {
            "type": "number"
          },
          "credits": {
            "type": "number"
          },
          "keep": {
            "$ref": "#/components/schemas/Keep"
          },
          "balance": {
            "type": [
              "number",
              "null"
            ]
          },
          "enough": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "needed": {
            "type": "number"
          }
        },
        "required": [
          "seconds",
          "frames",
          "fps",
          "multiplier",
          "billableSeconds",
          "creditsPerSecond",
          "credits",
          "keep",
          "balance",
          "enough",
          "needed"
        ]
      },
      "CreateRequest": {
        "type": "object",
        "properties": {
          "video_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTPS URL with Content-Length, at most 524288000 bytes. No credentials, private networks or nonstandard ports. Takes precedence over single."
          },
          "single": {
            "const": true,
            "description": "Reserve a one-time PUT upload; bytes is required. Call start after PUT."
          },
          "bytes": {
            "type": "integer",
            "minimum": 1,
            "maximum": 524288000
          },
          "fileName": {
            "type": "string"
          },
          "seconds": {
            "type": "number",
            "minimum": 1,
            "maximum": 300,
            "default": 300,
            "description": "Omitting reserves 600 credits at the default frame count."
          },
          "frames": {
            "$ref": "#/components/schemas/Frames"
          },
          "keep": {
            "$ref": "#/components/schemas/Keep"
          },
          "format": {
            "$ref": "#/components/schemas/Format",
            "default": "webm"
          },
          "max_credits": {
            "type": "number",
            "description": "Reject with too_expensive if below the estimated reservation."
          },
          "background": {
            "$ref": "#/components/schemas/Background"
          },
          "spill": {
            "type": "number",
            "minimum": 0,
            "maximum": 100,
            "default": 60
          },
          "screen": {
            "type": "string",
            "enum": [
              "green",
              "blue"
            ]
          }
        },
        "required": [],
        "anyOf": [
          {
            "required": [
              "video_url"
            ]
          },
          {
            "required": [
              "single",
              "bytes"
            ]
          }
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "format": {
                  "const": "bg_mp4"
                }
              },
              "required": [
                "format"
              ]
            },
            "then": {
              "required": [
                "background"
              ]
            }
          }
        ],
        "description": "Paid API only. free, trim and split are rejected with paid_only. Billing is ceil(max(5, seconds, frames/30) * 2); actual probe settles the reservation. At most two active paid jobs per account."
      },
      "ImportedJob": {
        "type": "object",
        "properties": {
          "job": {
            "$ref": "#/components/schemas/JobView"
          }
        },
        "required": [
          "job"
        ],
        "additionalProperties": false
      },
      "SingleUpload": {
        "type": "object",
        "properties": {
          "upload_id": {
            "type": "string"
          },
          "job": {
            "$ref": "#/components/schemas/JobView"
          },
          "upload": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "format": "uri"
              },
              "bytes": {
                "type": "integer"
              },
              "expiresAt": {
                "type": "integer",
                "description": "Unix seconds; upload expires after 15 minutes."
              },
              "headers": {
                "type": "object",
                "properties": {
                  "Content-Length": {
                    "type": "string"
                  },
                  "If-None-Match": {
                    "const": "*"
                  }
                },
                "required": [
                  "Content-Length",
                  "If-None-Match"
                ]
              },
              "command": {
                "type": "string"
              }
            },
            "required": [
              "url",
              "bytes",
              "expiresAt",
              "headers",
              "command"
            ]
          }
        },
        "required": [
          "upload_id",
          "job",
          "upload"
        ]
      },
      "Error": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/JobError"
          },
          {
            "$ref": "#/components/schemas/ApiError"
          }
        ]
      },
      "ExportRequest": {
        "type": "object",
        "properties": {
          "format": {
            "$ref": "#/components/schemas/Format"
          },
          "part": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Cannot exceed the job part count."
          },
          "background": {
            "$ref": "#/components/schemas/Background"
          }
        },
        "required": [
          "format"
        ],
        "allOf": [
          {
            "if": {
              "properties": {
                "format": {
                  "const": "bg_mp4"
                }
              },
              "required": [
                "format"
              ]
            },
            "then": {
              "required": [
                "background"
              ]
            }
          }
        ]
      },
      "ApiError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "error"
        ]
      },
      "InsufficientError": {
        "type": "object",
        "properties": {
          "error": {
            "const": "insufficient"
          },
          "code": {
            "const": "insufficient"
          },
          "needed": {
            "type": "number"
          },
          "balance": {
            "type": "number"
          },
          "pricing": {
            "type": "string",
            "format": "uri"
          }
        },
        "required": [
          "error",
          "code",
          "needed",
          "balance",
          "pricing"
        ]
      },
      "TooExpensiveError": {
        "type": "object",
        "properties": {
          "error": {
            "const": "too_expensive"
          },
          "credits": {
            "type": "number"
          },
          "message": {
            "type": "string"
          }
        },
        "required": [
          "error",
          "credits",
          "message"
        ]
      }
    }
  }
}
