{
  "openapi": "3.1.0",
  "info": {
    "title": "One More Shot Public API",
    "version": "1.0.0",
    "description": "Pre-release contract. Create keys in Settings \u2192 API after a purchase. Keep keys server-side. Limits and pricing can be configured; default request limit is 60/minute per key. Media downloads are limited to 100 MB. Webhooks are best-effort; poll for authoritative status."
  },
  "servers": [
    {
      "url": "https://api.onemoreshot.ai/v1",
      "description": "Production (access requires rollout enablement)"
    },
    {
      "url": "https://onemoreshot-public-api-dev.web.app/v1",
      "description": "Development"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/account": {
      "get": {
        "operationId": "getAccount",
        "summary": "Read balance and webhook signing secret",
        "responses": {
          "200": {
            "description": "Account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient tokens",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/lyric-videos": {
      "post": {
        "operationId": "createVideo",
        "summary": "Create a video from 10\u2013420 seconds of audio. Default prices: basic 33 tokens/second, pro 40; charge is ceil(duration \u00d7 rate). Failed and confirmed canceled jobs refund the full charge.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "description": "Printable ASCII. Identical requests replay for 24 hours per account and endpoint; a changed payload returns 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateVideo"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Job queued before media validation or charging; poll or await the signed webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            },
            "headers": {
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                "description": "Present on a replay."
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/lyric-videos/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "getVideo",
        "summary": "Poll until completed, failed or canceled",
        "responses": {
          "200": {
            "description": "Current job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient tokens",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "cancelVideo",
        "summary": "Queue cancellation immediately before the first media-preparation worker claim, with no charge. Once preparation has started, the configured waiting period from job creation applies (60-minute fallback); earlier requests return 409 with Retry-After. Confirm terminal status and refund via GET or signed webhook; repeated confirmed cancellation returns 204.",
        "responses": {
          "204": {
            "description": "Cancellation confirmed"
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient tokens",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until the configured cancellation delay elapses; present for not_cancellable_yet."
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "202": {
            "description": "Cancellation queued; completion is asynchronous.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "cancellation_requested": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "id",
                    "status",
                    "cancellation_requested"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/lyric-videos/transcriptions": {
      "post": {
        "operationId": "createTranscription",
        "summary": "Transcribe audio of at most 420 seconds for 5 tokens by default. If trimming, supply both bounds within the source audio.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "description": "Printable ASCII. Identical requests replay for 24 hours per account and endpoint; a changed payload returns 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTranscription"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Job queued before media validation or charging; poll or await the signed webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            },
            "headers": {
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                "description": "Present on a replay."
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/lyric-videos/transcriptions/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "getTranscription",
        "summary": "Poll until completed, failed or canceled",
        "responses": {
          "200": {
            "description": "Current job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient tokens",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/music-videos": {
      "post": {
        "operationId": "createNarrativeVideo",
        "summary": "Queue a narrative music video with one singer and up to three additional characters.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "description": "Printable ASCII. Identical requests replay for 24 hours per account and endpoint; a changed payload returns 409."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateNarrativeVideo"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Job queued before media validation or charging; poll or await the signed webhook.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Accepted"
                }
              }
            },
            "headers": {
              "Idempotency-Replayed": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true"
                  ]
                },
                "description": "Present on a replay."
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Audio: 10\u2013420 seconds, up to 100 MB. Initially uncharged; the worker snapshots media, then charges ceil(duration \u00d7 rate). Defaults: basic 50 tokens/second, pro 80. Creative assets are generated internally; callers cannot supply creative_seed, preview assets or provider settings."
      }
    },
    "/music-videos/{id}": {
      "parameters": [
        {
          "name": "id",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "get": {
        "operationId": "getNarrativeVideo",
        "summary": "Get a narrative video job.",
        "responses": {
          "200": {
            "description": "Current job",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient tokens",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "cancelNarrativeVideo",
        "summary": "Queue cancellation immediately before the first media-preparation worker claim, with no charge. Once preparation has started, the configured waiting period from job creation applies (60-minute fallback); earlier requests return 409 with Retry-After. Confirm terminal status and refund via GET or signed webhook; repeated confirmed cancellation returns 204.",
        "responses": {
          "204": {
            "description": "Cancellation confirmed"
          },
          "400": {
            "description": "Invalid request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Invalid, revoked or wrong-environment key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Insufficient tokens",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Missing scope",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found or belongs to another account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Idempotency conflict or job already terminal",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until the configured cancellation delay elapses; present for not_cancellable_yet."
              }
            }
          },
          "413": {
            "description": "JSON body exceeds 1 MB",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited; honor Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "string"
                },
                "description": "Seconds until retry."
              }
            }
          },
          "500": {
            "description": "Internal error; retry POST with the same idempotency key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "New jobs disabled, pricing unavailable or cancellation unconfirmed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "202": {
            "description": "Cancellation queued; completion is asynchronous.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "cancellation_requested": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "id",
                    "status",
                    "cancellation_requested"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "oms_<env>_<id>_<secret>"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Segment": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "start": {
            "type": "number",
            "minimum": 0
          },
          "end": {
            "type": "number",
            "minimum": 0
          },
          "duration": {
            "type": "number",
            "minimum": 0
          },
          "wordCount": {
            "type": "integer",
            "minimum": 0
          },
          "timedWords": {
            "type": "array",
            "maxItems": 1000,
            "items": {
              "type": "object",
              "properties": {
                "text": {
                  "type": "string"
                },
                "start": {
                  "type": "number",
                  "minimum": 0
                },
                "end": {
                  "type": "number",
                  "minimum": 0
                }
              },
              "required": [
                "text",
                "start",
                "end"
              ]
            }
          }
        },
        "required": [
          "text",
          "start",
          "end",
          "duration",
          "wordCount",
          "timedWords"
        ],
        "description": "Ordered, non-overlapping segments within the audio. end > start; duration equals end-start within 0.05 seconds. Timed words must remain within their segment."
      },
      "CreateVideo": {
        "type": "object",
        "properties": {
          "song_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTP(S) URL, port 80 or 443; credentials, private/reserved addresses and local hostnames are rejected."
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTPS callback URL. Redirects are not followed. See webhook verification in the API guide."
          },
          "idempotency_key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "Optional alternative to Idempotency-Key header; both must match if provided."
          },
          "quality": {
            "type": "string",
            "enum": [
              "basic",
              "pro"
            ],
            "default": "basic"
          },
          "aspect_ratio": {
            "type": "string",
            "enum": [
              "9:16",
              "16:9",
              "1:1"
            ],
            "default": "9:16"
          },
          "style_preset": {
            "type": "string",
            "enum": [
              "80S_ILLUSTRATION",
              "ART_BRUT",
              "ART_POSTER",
              "BAUHAUS",
              "BLUEPRINT",
              "C4D_CARTOON",
              "CHILDRENS_BOOK",
              "COLLAGE",
              "DOODLE",
              "EMOTIONAL_MINIMAL",
              "FLAT_ART",
              "FLAT_VECTOR",
              "GRAFFITI_I",
              "GRAFFITI_II",
              "MINIMAL_ILLUSTRATION",
              "MIXED_MEDIA",
              "PAINT_GESTURE",
              "POP_ART",
              "RETRO_ETCHING",
              "WATERCOLOR",
              "WEIRD",
              "WOODBLOCK_PRINT"
            ]
          },
          "song_genre": {
            "type": "string",
            "maxLength": 500
          },
          "singer_image_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTP(S) URL, port 80 or 443; credentials, private/reserved addresses and local hostnames are rejected."
          },
          "segments": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1000,
            "items": {
              "$ref": "#/components/schemas/Segment"
            }
          }
        },
        "required": [
          "song_url"
        ]
      },
      "CreateTranscription": {
        "type": "object",
        "properties": {
          "song_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTP(S) URL, port 80 or 443; credentials, private/reserved addresses and local hostnames are rejected."
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTPS callback URL. Redirects are not followed. See webhook verification in the API guide."
          },
          "idempotency_key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "Optional alternative to Idempotency-Key header; both must match if provided."
          },
          "trim_start": {
            "type": "number",
            "minimum": 0
          },
          "trim_end": {
            "type": "number",
            "minimum": 0
          }
        },
        "required": [
          "song_url"
        ]
      },
      "Accepted": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "completed",
              "failed",
              "canceled"
            ]
          },
          "credits_charged": {
            "type": "number",
            "minimum": 0
          },
          "duration_seconds": {
            "type": "number",
            "minimum": 0
          }
        },
        "required": [
          "id",
          "status",
          "credits_charged"
        ],
        "description": "Queued admission. credits_charged is initially zero; measured duration and actual charge become available after preparation. Media or balance failures are reported on the job and its webhook."
      },
      "Job": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "processing",
              "completed",
              "failed",
              "canceled"
            ]
          },
          "credits_charged": {
            "type": "number",
            "minimum": 0
          },
          "credits_refunded": {
            "type": "number",
            "minimum": 0
          },
          "duration_seconds": {
            "type": "number",
            "minimum": 0
          },
          "video_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "segments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Segment"
            }
          },
          "language": {
            "type": [
              "string",
              "null"
            ]
          },
          "error": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "code": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  }
                }
              },
              {
                "type": "null"
              }
            ]
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "cancellation_requested": {
            "type": "boolean",
            "description": "Cancellation is queued; terminal status and refund confirm its outcome."
          }
        },
        "required": [
          "id",
          "status",
          "credits_charged",
          "credits_refunded",
          "error",
          "created_at",
          "completed_at"
        ]
      },
      "Account": {
        "type": "object",
        "properties": {
          "credits": {
            "type": "number",
            "minimum": 0
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "rate_limit_rpm": {
            "type": "integer"
          },
          "webhook_secret": {
            "type": [
              "string",
              "null"
            ],
            "description": "HMAC-SHA256 signing secret. Null until the first webhook-enabled job."
          }
        },
        "required": [
          "credits",
          "scopes",
          "rate_limit_rpm",
          "webhook_secret"
        ]
      },
      "CreateNarrativeVideo": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "song_url",
          "prompt",
          "characters"
        ],
        "properties": {
          "song_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTP(S) URL, port 80 or 443; credentials, private/reserved addresses and local hostnames are rejected."
          },
          "quality": {
            "type": "string",
            "enum": [
              "basic",
              "pro"
            ],
            "default": "basic"
          },
          "aspect_ratio": {
            "type": "string",
            "enum": [
              "9:16",
              "16:9",
              "1:1"
            ],
            "default": "9:16"
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "description": "Public HTTPS callback URL. Redirects are not followed. See webhook verification in the API guide."
          },
          "idempotency_key": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "Optional alternative to Idempotency-Key header; both must match if provided."
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "maxLength": 10000,
            "description": "Nonempty creative direction or storyline."
          },
          "style_preset": {
            "type": "string",
            "enum": [
              "90s-anime",
              "ghibli",
              "yellow-family",
              "pixar-3d",
              "ps2-low-poly",
              "disney-90s",
              "lego",
              "cartoon-network",
              "pixel-art"
            ],
            "description": "Narrative visual style. Omit for realistic styling."
          },
          "characters": {
            "type": "array",
            "minItems": 1,
            "maxItems": 4,
            "description": "Exactly one singer; up to three other characters. No duet support. Each image is limited to 10 MB and 25 megapixels.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "name",
                "role",
                "image_url"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "singer",
                    "character"
                  ]
                },
                "image_url": {
                  "type": "string",
                  "format": "uri",
                  "description": "Public HTTP(S) URL, port 80 or 443; credentials, private/reserved addresses and local hostnames are rejected."
                },
                "description": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 2000
                }
              }
            }
          }
        }
      }
    }
  }
}
