openapi: 3.0.3
info:
  title: Mirelo AI API
  version: 2.0.0
  description: |-
    The Mirelo API lets you add AI-generated audio to video. You can generate sound effects from a text prompt or directly from a video, using the audio-visual context of the footage to create matching sounds. Results are returned as audio URLs ready to mix or play back.

    ## Authentication

    All requests require an API key passed as a Bearer token:

    ```
    Authorization: Bearer sk-your-key-here
    ```

    Keys begin with `sk-`. You can generate keys in the [Mirelo dashboard](https://mirelo.ai/studio/api-keys).

    ## Credits

    Generation costs credits. The number of credits consumed depends on the generation type, the duration requested, and the number of samples. Credits are deducted only on success — failed or errored generations are not charged. Use the `/preflight` endpoint on any generation route to see the exact cost before committing.

    `GET /v2/me` exposes the account credit contract:

    - `credits_remaining` — spendable ledger balance (included + top-up). `credits_available` is a backward-compatible alias for the same value.
    - `credits_used_this_period` — credits consumed in the active billing period (included + top-up). Can exceed `plan_allocation`; it is not `plan_allocation - credits_remaining`.
    - `plan_allocation` — monthly included credits on the active plan (0 when there is no plan).
    - `provisioning_state` — `ready` | `pending` | `stalled` for the current-period included grant. `is_provisioning` is true only while the state is `pending`.
    - `provisioning_deadline` — ms epoch when a cached `pending` response should become `stalled` without re-fetching (null when provisioning does not apply).

    ## Pricing

    Credit costs vary by model. For full model pricing details — including credits per second for each model — see the [Mirelo pricing page](https://mirelo.ai/pricing).

    ## Sync vs Async

    Every generation endpoint has two modes: **sync** and **async**.

    - **`/sync`** blocks until generation completes and returns audio URLs directly. Simple — one request, one response. Suitable for short durations (≤ 10 seconds) and server-side scripts. Note: HTTP connections time out after ~30 seconds in most environments, so sync is unreliable for longer generations.
    - **`/jobs`** returns immediately with a `job_id` and an estimated completion time. Poll `GET .../jobs/{job_id}` until `status` is `"succeeded"` or `"errored"`. Recommended for browser environments, longer durations, and production integrations where you need a responsive UI.

    **Rule of thumb:** use `/sync` for `duration_ms` ≤ 10000 and `/jobs` for anything longer.

    ## Preflight

    Before triggering generation, call `GET .../preflight` on any generation endpoint to get the exact credit cost and estimated duration. Use it to confirm costs in your UI or build a progress bar.

    `credits` is exact and will match what gets deducted if you proceed. `estimated_ms` is a statistical estimate calibrated to cover ~90% of real jobs at that duration. Jobs that exceed it are expected — poll until `status` is terminal rather than treating the estimate as a deadline.

    ## Model Versions

    The model version is part of the URL path (e.g., `/v2/text-to-sfx/{version}/sync`). Each model version has its own parameter contract. Pin the version you want — requesting an unsupported version returns `404`. **v1.6 is the latest version and is recommended for all integrations.** Earlier versions are marked deprecated — they remain functional for now but may be retired in the future, so migrate to the latest version when you can.

    ## Errors

    All errors follow a consistent shape:

    ```json
    { "error": { "code": "insufficient_credits", "message": "...", "http_status": 402 } }
    ```

    `code` is always one of a defined set of values (listed below), so you can branch on it reliably. Internal error details are never leaked.

    Standard HTTP status codes apply: `400` for bad input, `401` for missing or invalid key, `402` for insufficient credits, `404` for unknown resource or job, `422` for generation failures, `500` for unexpected server errors.

    **Error codes:**

    | Code | HTTP | Description |
    |------|------|-------------|
    | `invalid_request` | 400 | Bad input — check your parameters |
    | `video_url_unreachable` | 400 | Video URL returned a non-2xx response during the video URL check — check the URL is public and has not expired |
    | `video_format_unsupported` | 400 | Video container not recognized — supported containers are MP4, MOV, WebM, and MKV |
    | `video_too_short` | 400 | Video is shorter than `start_offset_ms` + `duration_ms` — the error message includes the exact lengths |
    | `invalid_video` | 422 | Video could not be decoded by the generation service — use H.264, VP8, or VP9 and ensure the file is not corrupted |
    | `invalid_asset` | 422 | Asset not found or inaccessible |
    | `insufficient_credits` | 402 | Not enough credits — top up your balance |
    | `rate_limited` | 429 | Throttled — wait and retry; the request and any URLs in it are still valid |
    | `generation_failed` | 502 | Upstream generation error — retry or contact support |
    | `generation_timeout` | 504 | Job took too long — retry or contact support |
    | `job_not_found` | 404 | Job doesn't exist, has expired (24h TTL), or belongs to another key |
    | `server_error` | 500 | Unexpected server error — retry or contact support |

    ## Video Input

    All video endpoints accept two ways to provide a video. **Prefer the URL form for anything above a few KB** — the API fetches the media server-side, so you skip the upload round-trip entirely.

    - **URL (preferred)** — pass `{type: "url", video_url: "https://..."}`. The URL must be publicly accessible (no auth required). See the Video URL Check section for supported formats and hosting recommendations.
    - **Asset** — pre-upload your video in three steps:
      1. Call `POST /v2/assets` to create an asset. The response contains an `asset_id` and a pre-signed `upload_url`.
      2. Upload your video file directly to the `upload_url` via an HTTP `PUT` request (no API key needed — the URL is pre-signed).
      3. Use the `asset_id` from step 1 in your generation request: `{type: "asset", asset_id: "..."}`.

      Asset IDs stay valid for **24 hours** after upload.

    Use assets when your video is not publicly accessible, when you want to avoid re-uploading the same file for multiple generation calls, or when your URL is a short-lived signed token that may expire before the generation runs.

    **Reusing a job result as video input:** a `result_urls` entry from an earlier job is a valid `video_url` **only when that result is itself a muxed video file** — audio results are rejected by the video URL check. Requesting `output: "video"` is not sufficient to know: past the video chunk limit the long-clip path returns audio regardless of the flag. Pass such a URL directly while it is still valid; do not download and re-upload it. If it stops resolving, re-run the job that produced it — polling an existing job returns the same stored URLs, never a fresh one.

    ## Audio Input

    Extend and inpaint endpoints take audio the same two ways: `{type: "url", audio_url: "https://..."}` or `{type: "asset", asset_id: "..."}`, and the same recommendation applies — **prefer the URL form for anything above a few KB**, since the API fetches it server-side.

    A `result_urls` entry from an earlier job is a valid `audio_url`, so generate → extend → inpaint chains need no uploads at all: pass the URL straight through while it is still valid instead of downloading and re-uploading the audio. **Prefer the matching `download_urls` entry when the earlier response carried one** — it is signed when it is followed, so a long chain does not have to outrun the raw URL's clock. If a raw `result_urls` entry stops resolving, re-run the job that produced it — polling an existing job returns the same stored URLs, never a fresh one.

    ## Video URL Check

    All video endpoints (`video-to-sfx`) perform a lightweight video URL check before dispatching to any generation service. This catches common problems early and returns a clear error before any credits are at risk.

    **What the check does:**

    The API fetches the first 128 KB of your video via an HTTP Range request. From those bytes it:

    1. Verifies the URL returns a 2xx response (`video_url_unreachable` if not)
    2. Identifies the container format from the file header (`video_format_unsupported` if unrecognized)
    3. Parses the container's duration header and validates it covers `start_offset_ms` + `duration_ms` (`video_too_short` if not — the error message includes the exact values)

    **Supported containers:** MP4, MOV, M4V, WebM, MKV. These cover the vast majority of real-world video files.

    **Hosting recommendations:**

    - Use S3, Google Cloud Storage, Cloudflare R2, or any major CDN — all support HTTP Range requests and respond quickly
    - Avoid URLs that require cookies, auth headers, or short-lived signed tokens that may expire between the video URL check and the generation call
    - If your MP4 was encoded without web-optimisation (`moov` atom at end of file), the check may fall back to a second range fetch; this still resolves well within the timeout on any CDN
    - If you see `video_format_unsupported` for a valid MP4, re-encode with: `ffmpeg -i input.mp4 -c copy -movflags faststart output.mp4`

    ## SDKs

    Official SDKs are available for Node.js/TypeScript and Python:

    - **Node.js / TypeScript** — [`@mirelo/sdk`](https://www.npmjs.com/package/@mirelo/sdk): `npm install @mirelo/sdk`
    - **Python** — [`mirelo-sdk`](https://pypi.org/project/mirelo-sdk/): `pip install mirelo-sdk`

    Source and full documentation: [github.com/mirelo-ai/sdk](https://github.com/mirelo-ai/sdk)
  contact:
    name: Mirelo Support
    url: https://mirelo.ai
    email: info@mirelo.ai
servers:
  - url: https://api.mirelo.ai
    description: Production API
security:
  - BearerAuth: []
components:
  schemas:
    TextToSfxRequest:
      type: object
      properties:
        prompt:
          type: string
          minLength: 1
          maxLength: 5000
          description: Text description of the sound to generate
          example: rain falling on leaves
        duration_ms:
          type: number
          minimum: 1000
          maximum: 10000
          default: 10000
          description: Duration in milliseconds (max 10000ms). Defaults to 10000.
        num_samples:
          type: integer
          minimum: 1
          maximum: 4
          default: 1
          description: Number of audio variants to generate
      required:
        - prompt
      example:
        prompt: thunder rumbling in the distance
    VideoToSfxRequest:
      type: object
      properties:
        video:
          $ref: '#/components/schemas/VideoSource'
        duration_ms:
          type: number
          minimum: 1000
          maximum: 600000
          description: Duration in milliseconds
        start_offset_ms:
          type: number
          minimum: 0
          description: Start offset into the video in milliseconds. Defaults to 0 (beginning of video).
        num_samples:
          type: integer
          minimum: 1
          maximum: 4
          default: 1
          description: Number of audio variants to generate
        output:
          type: string
          enum:
            - audio
            - video
          default: audio
          description: Output format. "audio" (default) returns SFX audio files only. "video" returns the original video with the generated SFX mixed in.
      required:
        - video
        - duration_ms
      example:
        video:
          type: url
          video_url: https://example.com/clip.mp4
        duration_ms: 10000
        num_samples: 1
        output: audio
    VideoSource:
      oneOf:
        - type: object
          properties:
            type:
              type: string
              enum:
                - url
            video_url:
              type: string
              format: uri
              description: 'Publicly accessible video URL (no auth required). Supported containers: MP4, MOV, WebM, MKV. A video URL check is performed before generation — see the Video URL Check section.'
          required:
            - type
            - video_url
          title: URL
        - type: object
          properties:
            type:
              type: string
              enum:
                - asset
            asset_id:
              type: string
              format: uuid
              description: Customer asset ID obtained from POST /v2/assets
          required:
            - type
            - asset_id
          title: Asset
    TextToSfxV16Request:
      type: object
      properties:
        prompt:
          type: string
          minLength: 1
          maxLength: 5000
          description: Text description of the sound to generate
          example: rain falling on leaves
        duration_ms:
          type: number
          minimum: 1000
          maximum: 600000
          default: 60000
          description: 'Duration in milliseconds. Without `loop`: 1,000–60,000 ms. With `loop: true`: 3,000–600,000 ms (up to 10 minutes). Requests longer than 60,000 ms are automatically handled server-side by generating a loopable chunk and tiling it — callers don''t need to do anything special.'
        num_samples:
          type: integer
          minimum: 1
          maximum: 4
          default: 1
          description: Number of audio variants to generate
        loop:
          type: boolean
          default: false
          description: When `true`, the output is optimized for seamless looping — ideal for background ambience, UI sounds, and game audio. Enables extended durations up to 600,000 ms (10 minutes). Minimum `duration_ms` is 3,000 when looping.
        seed:
          type: integer
          nullable: true
          minimum: -1
          description: 'Seed for reproducible generation. Integer, minimum -1. Omit, or send -1 or null, for a randomly chosen seed. The seed pins both generation and the server-side prompt rewrite. It does not guarantee identical audio: repeated identical requests still vary, because generation is not bit-deterministic across inference workers.'
          example: 42
        output_format:
          type: string
          enum:
            - wav
            - mp3
            - aac
            - flac
          description: Container for the generated audio. One of "wav" (default), "mp3", "aac", "flac". Omit for WAV, which is what every request returned before this parameter existed. Requests that need server-side post-processing — a tiled loop, a windowed extend or inpaint, a long video clip — are generated losslessly and encoded into this container once, at the end.
          example: mp3
      required:
        - prompt
      example:
        prompt: thunder rumbling in the distance
        duration_ms: 15000
        loop: false
    VideoToSfxV16Request:
      type: object
      properties:
        video:
          $ref: '#/components/schemas/VideoSource'
        duration_ms:
          type: number
          minimum: 1000
          maximum: 600000
          description: Duration in milliseconds
        start_offset_ms:
          type: number
          minimum: 0
          description: Start offset into the video in milliseconds. Defaults to 0 (beginning of video).
        prompt:
          type: string
          minLength: 1
          maxLength: 5000
          description: Optional text prompt. When provided, the video drives the timing while the prompt guides which sound to generate (video-synced style transfer). Omit for pure video-driven generation.
        num_samples:
          type: integer
          minimum: 1
          maximum: 4
          default: 1
          description: Number of audio variants to generate
        output:
          type: string
          enum:
            - audio
            - video
          default: audio
          description: Output format. "audio" (default) returns SFX audio files only. "video" returns the original video with the generated SFX mixed in.
        seed:
          type: integer
          nullable: true
          minimum: -1
          description: 'Seed for reproducible generation. Integer, minimum -1. Omit, or send -1 or null, for a randomly chosen seed. The seed pins both generation and the server-side prompt rewrite. It does not guarantee identical audio: repeated identical requests still vary, because generation is not bit-deterministic across inference workers.'
          example: 42
        output_format:
          type: string
          enum:
            - wav
            - mp3
            - aac
            - flac
          description: Container for the generated audio. One of "wav" (default), "mp3", "aac", "flac". Omit for WAV, which is what every request returned before this parameter existed. Requests that need server-side post-processing — a tiled loop, a windowed extend or inpaint, a long video clip — are generated losslessly and encoded into this container once, at the end.
          example: mp3
      required:
        - video
        - duration_ms
      example:
        video:
          type: url
          video_url: https://example.com/clip.mp4
        duration_ms: 10000
        num_samples: 1
        output: audio
    ExtendAudioRequest:
      type: object
      oneOf:
        - required:
            - audio
            - append_duration_ms
          properties:
            audio:
              $ref: '#/components/schemas/AudioSource'
            prompt:
              type: string
              minLength: 1
              maxLength: 5000
              description: Text description to guide the extension style.
              example: heavy rain continues to intensify
            num_samples:
              type: integer
              minimum: 1
              maximum: 4
              default: 1
              description: Number of audio variants to generate
            loop:
              type: boolean
              default: false
              description: 'When `true`, produces output that loops seamlessly — the end joins cleanly back to the beginning. Loop mode imposes stricter limits: the prefix is never shortened, so `prefix + appended audio` must stay within 60000 ms — appending the maximum therefore requires a prefix at the 3 s minimum. The model also modifies approximately the first 0.3 s of the original audio.'
            seed:
              type: integer
              nullable: true
              minimum: -1
              description: 'Seed for reproducible generation. Integer, minimum -1. Omit, or send -1 or null, for a randomly chosen seed. The seed pins both generation and the server-side prompt rewrite. It does not guarantee identical audio: repeated identical requests still vary, because generation is not bit-deterministic across inference workers.'
              example: 42
            output_format:
              type: string
              enum:
                - wav
                - mp3
                - aac
                - flac
              description: Container for the generated audio. One of "wav" (default), "mp3", "aac", "flac". Omit for WAV, which is what every request returned before this parameter existed. Requests that need server-side post-processing — a tiled loop, a windowed extend or inpaint, a long video clip — are generated losslessly and encoded into this container once, at the end.
              example: mp3
            append_duration_ms:
              type: integer
              minimum: 1000
              maximum: 57000
              description: 'Preferred: milliseconds of new audio to append after the prefix. Maximum 57000 ms — see `loop` for the extra bound that applies when looping. Provide exactly one of `append_duration_ms` or `duration_ms`.'
        - required:
            - audio
            - duration_ms
          properties:
            audio:
              $ref: '#/components/schemas/AudioSource'
            prompt:
              type: string
              minLength: 1
              maxLength: 5000
              description: Text description to guide the extension style.
              example: heavy rain continues to intensify
            num_samples:
              type: integer
              minimum: 1
              maximum: 4
              default: 1
              description: Number of audio variants to generate
            loop:
              type: boolean
              default: false
              description: 'When `true`, produces output that loops seamlessly — the end joins cleanly back to the beginning. Loop mode imposes stricter limits: the prefix is never shortened, so `prefix + appended audio` must stay within 60000 ms — appending the maximum therefore requires a prefix at the 3 s minimum. The model also modifies approximately the first 0.3 s of the original audio.'
            seed:
              type: integer
              nullable: true
              minimum: -1
              description: 'Seed for reproducible generation. Integer, minimum -1. Omit, or send -1 or null, for a randomly chosen seed. The seed pins both generation and the server-side prompt rewrite. It does not guarantee identical audio: repeated identical requests still vary, because generation is not bit-deterministic across inference workers.'
              example: 42
            output_format:
              type: string
              enum:
                - wav
                - mp3
                - aac
                - flac
              description: Container for the generated audio. One of "wav" (default), "mp3", "aac", "flac". Omit for WAV, which is what every request returned before this parameter existed. Requests that need server-side post-processing — a tiled loop, a windowed extend or inpaint, a long video clip — are generated losslessly and encoded into this container once, at the end.
              example: mp3
            duration_ms:
              type: number
              minimum: 100
              description: 'Legacy — prefer `append_duration_ms`. Total output duration in milliseconds (prefix + extension). Must exceed the input audio length. Credits are charged only for the generated extension (total − input). No hard upper bound: the extension is computed as (duration_ms − probed prefix) and capped separately.'
      example:
        audio:
          type: url
          audio_url: https://example.com/my-sfx.wav
        prompt: heavy rain continues to intensify
        append_duration_ms: 5000
        num_samples: 1
    AudioSource:
      oneOf:
        - type: object
          properties:
            type:
              type: string
              enum:
                - url
            audio_url:
              type: string
              format: uri
              description: 'Publicly accessible audio URL (no auth required). Supported formats: WAV, FLAC, MP3, OGG, AAC. An audio URL check is performed before generation.'
          required:
            - type
            - audio_url
          title: URL
        - type: object
          properties:
            type:
              type: string
              enum:
                - asset
            asset_id:
              type: string
              format: uuid
              description: Customer asset ID obtained from POST /v2/assets
          required:
            - type
            - asset_id
          title: Asset
    InpaintAudioRequest:
      type: object
      properties:
        audio:
          $ref: '#/components/schemas/AudioSource'
        segment:
          type: object
          properties:
            start_ms:
              type: integer
              minimum: 1000
              description: Start of the replacement region in milliseconds (≥ 1000 — region must not begin in the first second of the file).
            end_ms:
              type: integer
              minimum: 0
              description: End of the replacement region in milliseconds. Must exceed `start_ms` by at least 1000ms; `(end_ms - start_ms)` must be at most 8000ms. May equal the total audio duration (gap can extend to the end of the file).
          required:
            - start_ms
            - end_ms
          description: The region to replace. `start_ms` must be at least 1000 (first second is not replaceable). Gap width (`end_ms` minus `start_ms`) must be at least 1000ms and at most 8000ms. The gap may extend to the end of the file — there is no tail restriction on `end_ms`.
        prompt:
          type: string
          minLength: 1
          maxLength: 5000
          description: Optional text prompt to guide the replacement. If omitted, the model infers appropriate content from surrounding audio context.
          example: gentle wind instead of traffic noise
        num_samples:
          type: integer
          minimum: 1
          maximum: 4
          default: 1
          description: Number of audio variants to generate
        seed:
          type: integer
          nullable: true
          minimum: -1
          description: 'Seed for reproducible generation. Integer, minimum -1. Omit, or send -1 or null, for a randomly chosen seed. The seed pins both generation and the server-side prompt rewrite. It does not guarantee identical audio: repeated identical requests still vary, because generation is not bit-deterministic across inference workers.'
          example: 42
        output_format:
          type: string
          enum:
            - wav
            - mp3
            - aac
            - flac
          description: Container for the generated audio. One of "wav" (default), "mp3", "aac", "flac". Omit for WAV, which is what every request returned before this parameter existed. Requests that need server-side post-processing — a tiled loop, a windowed extend or inpaint, a long video clip — are generated losslessly and encoded into this container once, at the end.
          example: mp3
      required:
        - audio
        - segment
      example:
        audio:
          type: url
          audio_url: https://example.com/my-sfx.wav
        segment:
          start_ms: 2000
          end_ms: 4000
        num_samples: 1
    InpaintAudioWithVideoRequest:
      type: object
      properties:
        audio:
          $ref: '#/components/schemas/AudioSource'
        segment:
          type: object
          properties:
            start_ms:
              type: integer
              minimum: 1000
              description: Start of the replacement region in milliseconds (≥ 1000 — region must not begin in the first second of the file).
            end_ms:
              type: integer
              minimum: 0
              description: End of the replacement region in milliseconds. Must exceed `start_ms` by at least 1000ms; `(end_ms - start_ms)` must be at most 8000ms. May equal the total audio duration (gap can extend to the end of the file).
          required:
            - start_ms
            - end_ms
          description: The region to replace. `start_ms` must be at least 1000 (first second is not replaceable). Gap width (`end_ms` minus `start_ms`) must be at least 1000ms and at most 8000ms. The gap may extend to the end of the file — there is no tail restriction on `end_ms`.
        video:
          $ref: '#/components/schemas/VideoSource'
        prompt:
          type: string
          minLength: 1
          maxLength: 5000
          description: Optional text prompt to guide the replacement. If omitted, the model infers content from surrounding audio context and the video.
          example: gentle wind matching the outdoor scene
        num_samples:
          type: integer
          minimum: 1
          maximum: 4
          default: 1
          description: Number of audio variants to generate
        seed:
          type: integer
          nullable: true
          minimum: -1
          description: 'Seed for reproducible generation. Integer, minimum -1. Omit, or send -1 or null, for a randomly chosen seed. The seed pins both generation and the server-side prompt rewrite. It does not guarantee identical audio: repeated identical requests still vary, because generation is not bit-deterministic across inference workers.'
          example: 42
        output_format:
          type: string
          enum:
            - wav
            - mp3
            - aac
            - flac
          description: Container for the generated audio. One of "wav" (default), "mp3", "aac", "flac". Omit for WAV, which is what every request returned before this parameter existed. Requests that need server-side post-processing — a tiled loop, a windowed extend or inpaint, a long video clip — are generated losslessly and encoded into this container once, at the end.
          example: mp3
      required:
        - audio
        - segment
        - video
      example:
        audio:
          type: url
          audio_url: https://example.com/my-sfx.wav
        segment:
          start_ms: 2000
          end_ms: 4000
        video:
          type: url
          video_url: https://example.com/clip.mp4
        num_samples: 1
    VideoToSfxStemsAnalyzeRequest:
      type: object
      properties:
        video:
          $ref: '#/components/schemas/VideoSource'
        duration_ms:
          type: number
          minimum: 1000
          maximum: 600000
          description: Length of the supplied video in milliseconds. The analysis covers the whole video.
      required:
        - video
        - duration_ms
      example:
        video:
          type: url
          video_url: https://example.com/clip.mp4
        duration_ms: 12000
    VideoToSfxStemsGenerateRequest:
      type: object
      properties:
        plan_id:
          type: string
          minLength: 1
          description: Plan id returned by POST /v2/video-to-sfx-stems/v1.6/analyze
        num_samples:
          type: integer
          minimum: 1
          maximum: 4
          default: 1
          description: Number of audio variants to generate
      required:
        - plan_id
      example:
        plan_id: b3f1c2a4-...
        num_samples: 1
    AudioToMidiRequest:
      type: object
      properties:
        audio:
          $ref: '#/components/schemas/AudioSource'
        timing:
          type: string
          enum:
            - performance
            - quantized
          default: performance
          description: How note times are written. `performance` (default) keeps the take as played and describes it with a tempo map. `quantized` snaps notes onto the detected beats, and is honoured only when the beat grid is reliable enough to move notes onto — otherwise the response reports `performance` with a `fallback_reason`.
        instruments:
          type: array
          items:
            type: string
            enum:
              - acoustic_piano
              - electric_piano
              - chromatic_percussion
              - organ
              - acoustic_guitar
              - clean_electric_guitar
              - distorted_electric_guitar
              - acoustic_bass
              - electric_bass
              - violin
              - viola
              - cello
              - contrabass
              - orchestral_harp
              - timpani
              - string_ensemble
              - synth_strings
              - voice
              - orchestra_hit
              - trumpet
              - trombone
              - tuba
              - french_horn
              - brass_section
              - soprano_and_alto_sax
              - tenor_sax
              - baritone_sax
              - oboe
              - english_horn
              - bassoon
              - clarinet
              - flutes
              - synth_lead
              - synth_pad
              - drums
            example: acoustic_guitar
          maxItems: 35
          description: 'Every instrument the recording contains. Optional: omit it — the default — and the model transcribes unconditioned, which is what this endpoint has always done. The list is exhaustive, not a selection. The model masks every instrument outside it out of its vocabulary, so an instrument you do not list cannot appear in the output at all. Both ways of getting it wrong cost, on different axes: a name you leave out takes its part with it, and a name that is not in the audio makes the model split a real part across two. So list every instrument the recording contains, do not list anything you are not sure is there, and if you cannot do both, send no list at all — omitting the field is unconditioned and safe, which a short list is not. Order is irrelevant; the server sorts the list into the model''s vocabulary order before conditioning on it. Unknown names are rejected with a 400 rather than dropped. Accepted names: acoustic_piano, electric_piano, chromatic_percussion, organ, acoustic_guitar, clean_electric_guitar, distorted_electric_guitar, acoustic_bass, electric_bass, violin, viola, cello, contrabass, orchestral_harp, timpani, string_ensemble, synth_strings, voice, orchestra_hit, trumpet, trombone, tuba, french_horn, brass_section, soprano_and_alto_sax, tenor_sax, baritone_sax, oboe, english_horn, bassoon, clarinet, flutes, synth_lead, synth_pad, drums.'
          example:
            - acoustic_guitar
            - voice
      required:
        - audio
      additionalProperties: false
      example:
        audio:
          type: url
          audio_url: https://example.com/song.mp3
        timing: performance
        instruments:
          - acoustic_guitar
          - voice
    MeResponse:
      type: object
      properties:
        id:
          type: string
          description: User document ID
        email:
          type: string
          description: Account email
        credits_remaining:
          type: integer
          description: Spendable ledger balance (included + top-up). Prefer this over credits_available.
        credits_used_this_period:
          type: integer
          description: Credits consumed in the active billing period, counting top-up spend as well as included spend. 0 without an active plan, so this can exceed plan_allocation and does not subtract from it to give credits_remaining.
        plan_allocation:
          type: integer
          description: Monthly included credits on the active plan (0 when none)
        provisioning_state:
          type: string
          enum:
            - ready
            - pending
            - stalled
          description: Whether the current-period included grant has landed. Use provisioning_deadline to transition pending→stalled client-side.
        provisioning_deadline:
          type: integer
          nullable: true
          description: ms epoch when pending becomes stalled, or null when provisioning does not apply
        credits_available:
          type: integer
          description: Backward-compatible alias for credits_remaining
        is_provisioning:
          type: boolean
          description: Backward-compatible alias for provisioning_state === pending
        overage_enabled:
          type: boolean
          description: Whether the account can exceed its included credit limit
        created_at:
          type: number
          description: Account creation time (ms epoch)
        telemetry:
          $ref: '#/components/schemas/PluginTelemetryIdentity'
      required:
        - id
        - email
        - credits_remaining
        - credits_used_this_period
        - plan_allocation
        - provisioning_state
        - provisioning_deadline
        - credits_available
        - is_provisioning
        - overage_enabled
        - created_at
    PluginTelemetryIdentity:
      type: object
      properties:
        studio_user_doc_id:
          type: string
        api_key_id:
          type: string
        api_key_display_name:
          type: string
          description: API key display name. Distinct from analytics api_key_label (user:<email>).
        client_source:
          type: string
        is_test_account:
          type: boolean
      required:
        - studio_user_doc_id
        - client_source
        - is_test_account
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: API key prefixed with sk-. Obtain from the Mirelo dashboard.
tags:
  - name: Text to SFX
    description: Generate sound effects from a text prompt
  - name: Video to SFX
    description: Generate sound effects from a video clip
  - name: Video to SFX (multi-stem)
    description: Detect distinct sound sources in a video and generate a separate SFX stem for each
  - name: Extend Audio
    description: Extend an existing audio clip at the end
  - name: Inpaint Audio
    description: Replace a specific segment of an existing audio clip (text-conditioned)
  - name: Inpaint Audio with Video
    description: Replace a specific segment of an existing audio clip using a matching video
  - name: Audio to MIDI
    description: Transcribe audio into MIDI, structured notes, and MusicXML
  - name: Assets
    description: Upload and manage audio or video assets
  - name: Account
    description: Account and credit information
paths:
  /v2/text-to-sfx/v1.6/preflight:
    get:
      operationId: textToSfxV16Preflight
      summary: Preflight
      description: Returns the exact credit cost and estimated duration for a text-to-sfx v1.6 generation. No generation occurs, no credits are deducted.
      tags:
        - Text to SFX
      security:
        - BearerAuth: []
      parameters:
        - name: duration_ms
          in: query
          schema:
            type: integer
            default: 10000
          description: Duration in milliseconds
        - name: num_samples
          in: query
          schema:
            type: integer
            default: 1
          description: Number of samples
      responses:
        '200':
          description: Credit cost and ETA
          content:
            application/json:
              schema:
                type: object
                required:
                  - credits
                  - estimated_ms
                properties:
                  credits:
                    type: integer
                    description: Exact credit cost — matches what will be deducted on success
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds (p90 calibrated)
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/text-to-sfx/v1.6/sync:
    post:
      operationId: textToSfxV16Sync
      summary: Generate SFX from text (sync)
      description: 'Generate sound effects from a text prompt using the v1.6 model. Without `loop`: 1–60 s. With `loop: true`: 3 s – 10 min (600,000 ms) — long requests are automatically tiled server-side from a single seamless chunk. Blocks until complete.'
      tags:
        - Text to SFX
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TextToSfxV16Request'
      responses:
        '200':
          description: Generated audio URLs
          content:
            application/json:
              schema:
                type: object
                required:
                  - result_urls
                properties:
                  result_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                  download_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                  generation_id:
                    type: string
                    description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/text-to-sfx/v1.6/jobs:
    post:
      operationId: textToSfxV16JobCreate
      summary: Create async job
      description: 'Start an async text-to-sfx v1.6 generation job. Returns immediately with a `job_id`. Poll the job status endpoint until `status` is `succeeded` or `errored`. Supports up to 10 minutes (600,000 ms) with `loop: true`.'
      tags:
        - Text to SFX
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TextToSfxV16Request'
      responses:
        '202':
          description: Job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/text-to-sfx/v1.6/jobs/{job_id}:
    get:
      operationId: textToSfxV16JobPoll
      summary: Poll job
      description: 'Poll the status of an async text-to-sfx v1.6 job. Returns a discriminated union on `status`: `processing`, `succeeded`, or `errored`.'
      tags:
        - Text to SFX
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
          description: Job ID returned from the job creation endpoint
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Processing
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - estimated_completion_at
                      - estimated_ms
                      - progress_percent
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                        description: ETA in milliseconds
                      progress_percent:
                        type: integer
                        minimum: 0
                        maximum: 96
                        description: Estimated progress. Climbs linearly over the ETA, then asymptotically approaches the cap until completion.
                      request:
                        type: object
                        description: Original request parameters echoed back
                  - title: Succeeded
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - completed_at
                      - result
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - result_urls
                        properties:
                          result_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                          download_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                          generation_id:
                            type: string
                            description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
                        description: The generation result — identical in shape to the response from the sync endpoint. Audio URLs for all endpoints except video-to-sfx with output="video", which returns the original video with SFX mixed in.
                      request:
                        type: object
                  - title: Errored
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - error
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
                      request:
                        type: object
                discriminator:
                  propertyName: status
              examples:
                processing:
                  summary: Job is still processing
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: processing
                    created_at: '2024-01-15T10:30:00.000Z'
                    estimated_completion_at: '2024-01-15T10:30:08.000Z'
                    estimated_ms: 8000
                    progress_percent: 45
                    request:
                      prompt: rain falling on leaves
                      duration_ms: 15000
                      loop: false
                      num_samples: 1
                succeeded:
                  summary: Job completed successfully
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: succeeded
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:07.312Z'
                    result:
                      result_urls:
                        - https://cdn.mirelo.ai/sfx/abc123_0.wav
                        - https://cdn.mirelo.ai/sfx/abc123_1.wav
                      download_urls:
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/0?k=Ab3dEfGhIjKlMnOp
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/1?k=QrStUvWxYz012345
                      generation_id: k17d8x2p9q4m3n6r5t7v0w1y
                    request:
                      prompt: rain falling on leaves
                      duration_ms: 15000
                      loop: false
                      num_samples: 1
                errored:
                  summary: Job failed — upstream generation error
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:05.201Z'
                    error:
                      code: generation_failed
                      message: Generation failed due to an upstream error. Retry or contact support if this persists.
                      http_status: 502
                    request:
                      prompt: rain falling on leaves
                      duration_ms: 15000
                      loop: false
                      num_samples: 1
                errored_precheck:
                  summary: Job failed — video too short (precheck)
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:01.543Z'
                    error:
                      code: video_too_short
                      message: 'Video is too short: start_offset_ms (0ms) + duration_ms (15000ms) = 15000ms, but the video is only 8200ms long.'
                      http_status: 400
                    request:
                      prompt: rain falling on leaves
                      duration_ms: 15000
                      loop: false
                      num_samples: 1
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found, expired, or belongs to a different API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx/v1.6/preflight:
    get:
      operationId: videoToSfxV16Preflight
      summary: Preflight
      description: Returns the exact credit cost and estimated duration for a video-to-sfx generation. No generation occurs, no credits are deducted.
      tags:
        - Video to SFX
      security:
        - BearerAuth: []
      parameters:
        - name: duration_ms
          in: query
          schema:
            type: integer
            default: 10000
          description: Duration in milliseconds
        - name: num_samples
          in: query
          schema:
            type: integer
            default: 1
          description: Number of samples
      responses:
        '200':
          description: Credit cost and ETA
          content:
            application/json:
              schema:
                type: object
                required:
                  - credits
                  - estimated_ms
                properties:
                  credits:
                    type: integer
                    description: Exact credit cost — matches what will be deducted on success
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds (p90 calibrated)
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx/v1.6/sync:
    post:
      operationId: videoToSfxV16Sync
      summary: Generate SFX from video (sync)
      description: 'Generate sound effects from a video clip. Provide a `video` object with either `{type: "url", video_url}` or `{type: "asset", asset_id}`. Blocks until complete. Use `output` to control whether the response contains audio-only files or the original video with SFX mixed in.'
      tags:
        - Video to SFX
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoToSfxV16Request'
      responses:
        '200':
          description: Generated output URLs. Audio files when output is "audio" (default); original video with SFX mixed in when output is "video".
          content:
            application/json:
              schema:
                type: object
                required:
                  - result_urls
                properties:
                  result_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                  download_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                  generation_id:
                    type: string
                    description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
        '400':
          description: 'Bad request or video URL check failure — error.code will be one of: invalid_request, video_url_unreachable, video_format_unsupported, video_too_short'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '422':
          description: Video could not be decoded — error.code will be invalid_video. Ensure the video uses a supported codec (H.264, VP8, or VP9) and is not corrupted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx/v1.6/jobs:
    post:
      operationId: videoToSfxV16JobCreate
      summary: Create async job
      description: Start an async video-to-sfx generation job. Returns immediately with a `job_id`. Recommended for videos longer than 10 seconds.
      tags:
        - Video to SFX
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoToSfxV16Request'
      responses:
        '202':
          description: Job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: 'Bad request or video URL check failure — error.code will be one of: invalid_request, video_url_unreachable, video_format_unsupported, video_too_short'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '422':
          description: Video could not be decoded — error.code will be invalid_video. Ensure the video uses a supported codec (H.264, VP8, or VP9) and is not corrupted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx/v1.6/jobs/{job_id}:
    get:
      operationId: videoToSfxV16JobPoll
      summary: Poll job
      description: 'Poll the status of an async video-to-sfx job. Returns a discriminated union on `status`: `processing`, `succeeded`, or `errored`.'
      tags:
        - Video to SFX
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Processing
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - estimated_completion_at
                      - estimated_ms
                      - progress_percent
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                        description: ETA in milliseconds
                      progress_percent:
                        type: integer
                        minimum: 0
                        maximum: 96
                        description: Estimated progress. Climbs linearly over the ETA, then asymptotically approaches the cap until completion.
                      request:
                        type: object
                        description: Original request parameters echoed back
                  - title: Succeeded
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - completed_at
                      - result
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - result_urls
                        properties:
                          result_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                          download_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                          generation_id:
                            type: string
                            description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
                        description: The generation result — identical in shape to the response from the sync endpoint. Audio URLs for all endpoints except video-to-sfx with output="video", which returns the original video with SFX mixed in.
                      request:
                        type: object
                  - title: Errored
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - error
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
                      request:
                        type: object
                discriminator:
                  propertyName: status
              examples:
                processing:
                  summary: Job is still processing
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: processing
                    created_at: '2024-01-15T10:30:00.000Z'
                    estimated_completion_at: '2024-01-15T10:30:08.000Z'
                    estimated_ms: 8000
                    progress_percent: 45
                    request:
                      video:
                        type: url
                        video_url: https://example.com/clip.mp4
                      duration_ms: 10000
                      num_samples: 1
                      output: audio
                succeeded:
                  summary: Job completed successfully
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: succeeded
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:07.312Z'
                    result:
                      result_urls:
                        - https://cdn.mirelo.ai/sfx/abc123_0.wav
                        - https://cdn.mirelo.ai/sfx/abc123_1.wav
                      download_urls:
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/0?k=Ab3dEfGhIjKlMnOp
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/1?k=QrStUvWxYz012345
                      generation_id: k17d8x2p9q4m3n6r5t7v0w1y
                    request:
                      video:
                        type: url
                        video_url: https://example.com/clip.mp4
                      duration_ms: 10000
                      num_samples: 1
                      output: audio
                errored:
                  summary: Job failed — upstream generation error
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:05.201Z'
                    error:
                      code: generation_failed
                      message: Generation failed due to an upstream error. Retry or contact support if this persists.
                      http_status: 502
                    request:
                      video:
                        type: url
                        video_url: https://example.com/clip.mp4
                      duration_ms: 10000
                      num_samples: 1
                      output: audio
                errored_precheck:
                  summary: Job failed — video too short (precheck)
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:01.543Z'
                    error:
                      code: video_too_short
                      message: 'Video is too short: start_offset_ms (0ms) + duration_ms (15000ms) = 15000ms, but the video is only 8200ms long.'
                      http_status: 400
                    request:
                      video:
                        type: url
                        video_url: https://example.com/clip.mp4
                      duration_ms: 10000
                      num_samples: 1
                      output: audio
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found or expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx-stems/v1.6/analyze:
    post:
      operationId: videoToSfxStemsAnalyze
      summary: Analyze a video into separate sound-source stems
      description: Runs sound-source detection (one Gemini pass) and returns a plan with the per-stem breakdown and exact total credit cost. No audio is generated and no credits are charged here. Pass the returned `plan_id` to POST /jobs to generate the stems.
      tags:
        - Video to SFX (multi-stem)
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoToSfxStemsAnalyzeRequest'
      responses:
        '200':
          description: Detected stems, total cost, and a plan id
          content:
            application/json:
              schema:
                type: object
                required:
                  - plan_id
                  - stems
                  - total_credits
                  - estimated_ms
                properties:
                  plan_id:
                    type: string
                    description: Pass to POST /jobs to generate the stems. Expires after 24h.
                  stems:
                    type: array
                    description: One entry per detected sound source.
                    items:
                      type: object
                      required:
                        - label
                        - start_ms
                        - end_ms
                        - generation_duration_ms
                      properties:
                        label:
                          type: string
                          description: Short description of the sound source
                        start_ms:
                          type: integer
                          description: Timeline placement offset for the generated clip (ms from video start)
                        end_ms:
                          type: integer
                          description: End of the placed clip (ms from video start)
                        generation_duration_ms:
                          type: integer
                          description: Generated clip length (ms) — recompute cost for any sample count from this
                  total_credits:
                    type: integer
                    description: Total credits the generate step will consume
                  estimated_ms:
                    type: integer
                    description: Estimated generation time in milliseconds
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx-stems/v1.6/jobs:
    post:
      operationId: videoToSfxStemsJobCreate
      summary: Generate every stem from a plan
      description: Generates one SFX clip (one sample) per detected stem from a plan produced by /analyze, and bills the plan's total credits on success. Returns a job to poll.
      tags:
        - Video to SFX (multi-stem)
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoToSfxStemsGenerateRequest'
      responses:
        '202':
          description: Async job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx-stems/v1.6/jobs/{job_id}:
    get:
      operationId: videoToSfxStemsJobPoll
      summary: Poll a multi-stem job
      description: Returns job status. On success, `result.stems` lists every generated stem with its placement and gain.
      tags:
        - Video to SFX (multi-stem)
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
          description: Job ID returned from the job creation endpoint
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    required:
                      - job_id
                      - status
                      - result
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - stems
                        properties:
                          stems:
                            type: array
                            items:
                              type: object
                              required:
                                - label
                                - result_urls
                                - start_ms
                                - end_ms
                                - volume
                              properties:
                                label:
                                  type: string
                                result_urls:
                                  type: array
                                  items:
                                    type: string
                                  description: Presigned URLs to the generated stem audio (WAV) — one per requested sample
                                start_ms:
                                  type: integer
                                  description: Timeline placement offset (ms from video start)
                                end_ms:
                                  type: integer
                                volume:
                                  type: number
                                  description: Suggested linear gain 0..1 for the placed clip
                  - type: object
                    required:
                      - job_id
                      - status
                      - progress_percent
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                      progress_percent:
                        type: number
                  - type: object
                    required:
                      - job_id
                      - status
                      - error
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found or not owned by this API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/extend-audio/v1.6/preflight:
    get:
      operationId: extendAudioV16Preflight
      summary: Preflight
      description: Returns the estimated credit cost for an extension job. The exact cost depends on the input audio duration, which is parsed at generation time.
      tags:
        - Extend Audio
      security:
        - BearerAuth: []
      parameters:
        - name: duration_ms
          in: query
          schema:
            type: integer
            default: 10000
          description: Duration in milliseconds
        - name: num_samples
          in: query
          schema:
            type: integer
            default: 1
          description: Number of samples
      responses:
        '200':
          description: Credit cost and ETA
          content:
            application/json:
              schema:
                type: object
                required:
                  - credits
                  - estimated_ms
                properties:
                  credits:
                    type: integer
                    description: Exact credit cost — matches what will be deducted on success
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds (p90 calibrated)
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/extend-audio/v1.6/sync:
    post:
      operationId: extendAudioV16Sync
      summary: Extend audio (sync)
      description: 'Extend an existing audio clip at the end. Pass the audio prefix and the desired total output duration. Credits are charged only for the generated extension portion (total_duration − input_duration). The prefix must be at least **3 seconds** long; `duration_ms` must exceed the prefix by at least **1s**. Maximum new audio is **57 seconds**. With `loop: true` the prefix is never shortened, so prefix + new audio must stay within **60 seconds** — appending the maximum then requires a prefix at the 3s minimum.'
      tags:
        - Extend Audio
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExtendAudioRequest'
      responses:
        '200':
          description: Extended audio URLs
          content:
            application/json:
              schema:
                type: object
                required:
                  - result_urls
                properties:
                  result_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                  download_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                  generation_id:
                    type: string
                    description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
        '400':
          description: 'Bad request or audio URL check failure — error.code will be one of: invalid_request, audio_url_unreachable, audio_format_unsupported, audio_too_short, audio_too_long'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/extend-audio/v1.6/jobs:
    post:
      operationId: extendAudioV16JobCreate
      summary: Create async job
      description: Start an async audio extension job. Returns immediately with a `job_id`. Poll until `status` is `succeeded` or `errored`.
      tags:
        - Extend Audio
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExtendAudioRequest'
      responses:
        '202':
          description: Job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: 'Bad request or audio URL check failure — error.code will be one of: invalid_request, audio_url_unreachable, audio_format_unsupported, audio_too_short, audio_too_long'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/extend-audio/v1.6/jobs/{job_id}:
    get:
      operationId: extendAudioV16JobPoll
      summary: Poll job
      description: Poll the status of an async audio extension job.
      tags:
        - Extend Audio
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
          description: Job ID returned from the job creation endpoint
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Processing
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - estimated_completion_at
                      - estimated_ms
                      - progress_percent
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                        description: ETA in milliseconds
                      progress_percent:
                        type: integer
                        minimum: 0
                        maximum: 96
                        description: Estimated progress. Climbs linearly over the ETA, then asymptotically approaches the cap until completion.
                      request:
                        type: object
                        description: Original request parameters echoed back
                  - title: Succeeded
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - completed_at
                      - result
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - result_urls
                        properties:
                          result_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                          download_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                          generation_id:
                            type: string
                            description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
                        description: The generation result — identical in shape to the response from the sync endpoint. Audio URLs for all endpoints except video-to-sfx with output="video", which returns the original video with SFX mixed in.
                      request:
                        type: object
                  - title: Errored
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - error
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
                      request:
                        type: object
                discriminator:
                  propertyName: status
              examples:
                processing:
                  summary: Job is still processing
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: processing
                    created_at: '2024-01-15T10:30:00.000Z'
                    estimated_completion_at: '2024-01-15T10:30:08.000Z'
                    estimated_ms: 8000
                    progress_percent: 45
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/my-sfx.wav
                      prompt: heavy rain continues to intensify
                      duration_ms: 20000
                      num_samples: 1
                succeeded:
                  summary: Job completed successfully
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: succeeded
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:07.312Z'
                    result:
                      result_urls:
                        - https://cdn.mirelo.ai/sfx/abc123_0.wav
                        - https://cdn.mirelo.ai/sfx/abc123_1.wav
                      download_urls:
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/0?k=Ab3dEfGhIjKlMnOp
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/1?k=QrStUvWxYz012345
                      generation_id: k17d8x2p9q4m3n6r5t7v0w1y
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/my-sfx.wav
                      prompt: heavy rain continues to intensify
                      duration_ms: 20000
                      num_samples: 1
                errored:
                  summary: Job failed — upstream generation error
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:05.201Z'
                    error:
                      code: generation_failed
                      message: Generation failed due to an upstream error. Retry or contact support if this persists.
                      http_status: 502
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/my-sfx.wav
                      prompt: heavy rain continues to intensify
                      duration_ms: 20000
                      num_samples: 1
                errored_precheck:
                  summary: Job failed — video too short (precheck)
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:01.543Z'
                    error:
                      code: video_too_short
                      message: 'Video is too short: start_offset_ms (0ms) + duration_ms (15000ms) = 15000ms, but the video is only 8200ms long.'
                      http_status: 400
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/my-sfx.wav
                      prompt: heavy rain continues to intensify
                      duration_ms: 20000
                      num_samples: 1
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found, expired, or belongs to a different API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/inpaint-audio/v1.6/preflight:
    get:
      operationId: inpaintAudioV16Preflight
      summary: Preflight
      description: Returns the estimated credit cost for an inpaint job. Credits are charged for the replaced segment duration (end_ms − start_ms).
      tags:
        - Inpaint Audio
      security:
        - BearerAuth: []
      parameters:
        - name: duration_ms
          in: query
          schema:
            type: integer
            default: 10000
          description: Duration in milliseconds
        - name: num_samples
          in: query
          schema:
            type: integer
            default: 1
          description: Number of samples
      responses:
        '200':
          description: Credit cost and ETA
          content:
            application/json:
              schema:
                type: object
                required:
                  - credits
                  - estimated_ms
                properties:
                  credits:
                    type: integer
                    description: Exact credit cost — matches what will be deducted on success
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds (p90 calibrated)
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/inpaint-audio/v1.6/sync:
    post:
      operationId: inpaintAudioV16Sync
      summary: Inpaint audio segment (sync)
      description: Replace a specific segment of an audio clip with AI-generated content using text conditioning only. The surrounding audio is preserved. The replaceable region must start at least 1s after the file start and be 1–8s wide; it may extend to the end of the file (no tail restriction). Long inputs are windowed (≤10s to the model) and reassembled to full length via FFmpeg. Credits are charged only for the replaced segment duration. For video-guided inpainting, use `/v2/inpaint-audio/with_video/v1.6`.
      tags:
        - Inpaint Audio
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InpaintAudioRequest'
      responses:
        '200':
          description: Inpainted audio URLs
          content:
            application/json:
              schema:
                type: object
                required:
                  - result_urls
                properties:
                  result_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                  download_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                  generation_id:
                    type: string
                    description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
        '400':
          description: 'Bad request or audio URL check failure — error.code will be one of: invalid_request, audio_url_unreachable, audio_format_unsupported, audio_too_short, audio_too_long'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/inpaint-audio/v1.6/jobs:
    post:
      operationId: inpaintAudioV16JobCreate
      summary: Create async job
      description: Start an async audio inpainting job (text-conditioned, no video). Returns immediately with a `job_id`. Poll until `status` is `succeeded` or `errored`.
      tags:
        - Inpaint Audio
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InpaintAudioRequest'
      responses:
        '202':
          description: Job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: 'Bad request or audio URL check failure — error.code will be one of: invalid_request, audio_url_unreachable, audio_format_unsupported, audio_too_short, audio_too_long'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/inpaint-audio/v1.6/jobs/{job_id}:
    get:
      operationId: inpaintAudioV16JobPoll
      summary: Poll job
      description: Poll the status of an async audio inpainting job.
      tags:
        - Inpaint Audio
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
          description: Job ID returned from the job creation endpoint
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Processing
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - estimated_completion_at
                      - estimated_ms
                      - progress_percent
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                        description: ETA in milliseconds
                      progress_percent:
                        type: integer
                        minimum: 0
                        maximum: 96
                        description: Estimated progress. Climbs linearly over the ETA, then asymptotically approaches the cap until completion.
                      request:
                        type: object
                        description: Original request parameters echoed back
                  - title: Succeeded
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - completed_at
                      - result
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - result_urls
                        properties:
                          result_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                          download_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                          generation_id:
                            type: string
                            description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
                        description: The generation result — identical in shape to the response from the sync endpoint. Audio URLs for all endpoints except video-to-sfx with output="video", which returns the original video with SFX mixed in.
                      request:
                        type: object
                  - title: Errored
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - error
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
                      request:
                        type: object
                discriminator:
                  propertyName: status
              examples:
                processing:
                  summary: Job is still processing
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: processing
                    created_at: '2024-01-15T10:30:00.000Z'
                    estimated_completion_at: '2024-01-15T10:30:08.000Z'
                    estimated_ms: 8000
                    progress_percent: 45
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/my-sfx.wav
                      segment:
                        start_ms: 2000
                        end_ms: 4000
                      num_samples: 1
                succeeded:
                  summary: Job completed successfully
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: succeeded
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:07.312Z'
                    result:
                      result_urls:
                        - https://cdn.mirelo.ai/sfx/abc123_0.wav
                        - https://cdn.mirelo.ai/sfx/abc123_1.wav
                      download_urls:
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/0?k=Ab3dEfGhIjKlMnOp
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/1?k=QrStUvWxYz012345
                      generation_id: k17d8x2p9q4m3n6r5t7v0w1y
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/my-sfx.wav
                      segment:
                        start_ms: 2000
                        end_ms: 4000
                      num_samples: 1
                errored:
                  summary: Job failed — upstream generation error
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:05.201Z'
                    error:
                      code: generation_failed
                      message: Generation failed due to an upstream error. Retry or contact support if this persists.
                      http_status: 502
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/my-sfx.wav
                      segment:
                        start_ms: 2000
                        end_ms: 4000
                      num_samples: 1
                errored_precheck:
                  summary: Job failed — video too short (precheck)
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:01.543Z'
                    error:
                      code: video_too_short
                      message: 'Video is too short: start_offset_ms (0ms) + duration_ms (15000ms) = 15000ms, but the video is only 8200ms long.'
                      http_status: 400
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/my-sfx.wav
                      segment:
                        start_ms: 2000
                        end_ms: 4000
                      num_samples: 1
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found, expired, or belongs to a different API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/inpaint-audio/with_video/v1.6/preflight:
    get:
      operationId: inpaintAudioWithVideoV16Preflight
      summary: Preflight
      description: Returns the estimated credit cost for a video-guided inpainting job. Credits are charged for the replaced segment duration (end_ms − start_ms).
      tags:
        - Inpaint Audio with Video
      security:
        - BearerAuth: []
      parameters:
        - name: duration_ms
          in: query
          schema:
            type: integer
            default: 10000
          description: Duration in milliseconds
        - name: num_samples
          in: query
          schema:
            type: integer
            default: 1
          description: Number of samples
      responses:
        '200':
          description: Credit cost and ETA
          content:
            application/json:
              schema:
                type: object
                required:
                  - credits
                  - estimated_ms
                properties:
                  credits:
                    type: integer
                    description: Exact credit cost — matches what will be deducted on success
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds (p90 calibrated)
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/inpaint-audio/with_video/v1.6/sync:
    post:
      operationId: inpaintAudioWithVideoV16Sync
      summary: Inpaint audio segment with video (sync)
      description: Replace a specific segment of an audio clip using a matching video clip to visually guide the generated replacement. Video is **required** — use `/v2/inpaint-audio/v1.6` for text-only conditioning. Both audio and video must be provided as assets or publicly accessible URLs.
      tags:
        - Inpaint Audio with Video
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InpaintAudioWithVideoRequest'
      responses:
        '200':
          description: Inpainted audio URLs
          content:
            application/json:
              schema:
                type: object
                required:
                  - result_urls
                properties:
                  result_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                  download_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                  generation_id:
                    type: string
                    description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
        '400':
          description: 'Bad request or audio URL check failure — error.code will be one of: invalid_request, audio_url_unreachable, audio_format_unsupported, audio_too_short, audio_too_long'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/inpaint-audio/with_video/v1.6/jobs:
    post:
      operationId: inpaintAudioWithVideoV16JobCreate
      summary: Create async job
      description: Start an async video-guided audio inpainting job. Returns immediately with a `job_id`. Poll until `status` is `succeeded` or `errored`.
      tags:
        - Inpaint Audio with Video
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InpaintAudioWithVideoRequest'
      responses:
        '202':
          description: Job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: 'Bad request or audio URL check failure — error.code will be one of: invalid_request, audio_url_unreachable, audio_format_unsupported, audio_too_short, audio_too_long'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/inpaint-audio/with_video/v1.6/jobs/{job_id}:
    get:
      operationId: inpaintAudioWithVideoV16JobPoll
      summary: Poll job
      description: Poll the status of an async video-guided audio inpainting job.
      tags:
        - Inpaint Audio with Video
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
          description: Job ID returned from the job creation endpoint
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Processing
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - estimated_completion_at
                      - estimated_ms
                      - progress_percent
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                        description: ETA in milliseconds
                      progress_percent:
                        type: integer
                        minimum: 0
                        maximum: 96
                        description: Estimated progress. Climbs linearly over the ETA, then asymptotically approaches the cap until completion.
                      request:
                        type: object
                        description: Original request parameters echoed back
                  - title: Succeeded
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - completed_at
                      - result
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - result_urls
                        properties:
                          result_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                          download_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                          generation_id:
                            type: string
                            description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
                        description: The generation result — identical in shape to the response from the sync endpoint. Audio URLs for all endpoints except video-to-sfx with output="video", which returns the original video with SFX mixed in.
                      request:
                        type: object
                  - title: Errored
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - error
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
                      request:
                        type: object
                discriminator:
                  propertyName: status
              examples:
                processing:
                  summary: Job is still processing
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: processing
                    created_at: '2024-01-15T10:30:00.000Z'
                    estimated_completion_at: '2024-01-15T10:30:08.000Z'
                    estimated_ms: 8000
                    progress_percent: 45
                    request:
                      audio:
                        type: asset
                        asset_id: 550e8400-e29b-41d4-a716-446655440002
                      video:
                        type: asset
                        asset_id: 550e8400-e29b-41d4-a716-446655440003
                      segment:
                        start_ms: 2000
                        end_ms: 4000
                      num_samples: 1
                succeeded:
                  summary: Job completed successfully
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: succeeded
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:07.312Z'
                    result:
                      result_urls:
                        - https://cdn.mirelo.ai/sfx/abc123_0.wav
                        - https://cdn.mirelo.ai/sfx/abc123_1.wav
                      download_urls:
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/0?k=Ab3dEfGhIjKlMnOp
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/1?k=QrStUvWxYz012345
                      generation_id: k17d8x2p9q4m3n6r5t7v0w1y
                    request:
                      audio:
                        type: asset
                        asset_id: 550e8400-e29b-41d4-a716-446655440002
                      video:
                        type: asset
                        asset_id: 550e8400-e29b-41d4-a716-446655440003
                      segment:
                        start_ms: 2000
                        end_ms: 4000
                      num_samples: 1
                errored:
                  summary: Job failed — upstream generation error
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:05.201Z'
                    error:
                      code: generation_failed
                      message: Generation failed due to an upstream error. Retry or contact support if this persists.
                      http_status: 502
                    request:
                      audio:
                        type: asset
                        asset_id: 550e8400-e29b-41d4-a716-446655440002
                      video:
                        type: asset
                        asset_id: 550e8400-e29b-41d4-a716-446655440003
                      segment:
                        start_ms: 2000
                        end_ms: 4000
                      num_samples: 1
                errored_precheck:
                  summary: Job failed — video too short (precheck)
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:01.543Z'
                    error:
                      code: video_too_short
                      message: 'Video is too short: start_offset_ms (0ms) + duration_ms (15000ms) = 15000ms, but the video is only 8200ms long.'
                      http_status: 400
                    request:
                      audio:
                        type: asset
                        asset_id: 550e8400-e29b-41d4-a716-446655440002
                      video:
                        type: asset
                        asset_id: 550e8400-e29b-41d4-a716-446655440003
                      segment:
                        start_ms: 2000
                        end_ms: 4000
                      num_samples: 1
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found, expired, or belongs to a different API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/audio-to-midi/v1.0/preflight:
    get:
      operationId: audioToMidiV10Preflight
      summary: Preflight
      description: Returns the exact credit cost and estimated duration for an audio-to-MIDI transcription. No transcription occurs, no credits are deducted. Only duration_ms is required.
      tags:
        - Audio to MIDI
      security:
        - BearerAuth: []
      parameters:
        - name: duration_ms
          in: query
          required: true
          schema:
            type: integer
            maximum: 600000
          description: Input audio duration in milliseconds (max 600,000)
      responses:
        '200':
          description: Credit cost and ETA
          content:
            application/json:
              schema:
                type: object
                required:
                  - credits
                  - estimated_ms
                properties:
                  credits:
                    type: integer
                    description: Exact credit cost — matches what will be deducted on success
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds (p90 calibrated)
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/audio-to-midi/v1.0/sync:
    post:
      operationId: audioToMidiV10Sync
      summary: Transcribe audio to MIDI (sync)
      description: Transcribe a monophonic or polyphonic audio clip into MIDI, structured notes, and MusicXML. Blocks until complete. Recommended for clips up to ~30 seconds; use async for longer files.
      tags:
        - Audio to MIDI
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AudioToMidiRequest'
      responses:
        '200':
          description: Transcription artifacts and metadata
          content:
            application/json:
              schema:
                type: object
                required:
                  - midi_url
                  - notes
                  - duration_seconds
                  - note_count
                  - timing
                properties:
                  midi_url:
                    type: string
                    format: uri
                    description: Presigned URL to the generated MIDI file
                  musicxml_url:
                    type: string
                    format: uri
                    description: Presigned URL to the generated MusicXML file. Omitted when transcription produced no notes.
                  notes:
                    type: array
                    items:
                      type: object
                      required:
                        - pitch
                        - start
                        - end
                        - instrument
                        - velocity
                      properties:
                        pitch:
                          type: number
                          description: MIDI note number
                        start:
                          type: number
                          description: Start time in seconds
                        end:
                          type: number
                          description: End time in seconds
                        instrument:
                          type: string
                          description: Detected or assigned instrument label
                        velocity:
                          type: number
                          description: Note velocity (0–127)
                    description: Structured note list
                  duration_seconds:
                    type: number
                    description: Duration of the input audio in seconds
                  note_count:
                    type: integer
                    description: Number of transcribed notes
                  tempo_bpm:
                    type: number
                    description: Estimated tempo in BPM when beat-grid detection succeeds
                  timing:
                    type: object
                    description: What the export did about time. `applied` is what the files carry; it differs from `requested` only when a `quantized` request met a beat grid too unreliable to move notes onto.
                    required:
                      - requested
                      - applied
                    properties:
                      requested:
                        type: string
                        enum:
                          - performance
                          - quantized
                      applied:
                        type: string
                        enum:
                          - performance
                          - quantized
                      fallback_reason:
                        type: string
                        enum:
                          - grid_unavailable
                          - too_few_beats
                          - low_coverage
                          - unstable_pacing
                          - unstable_intervals
                          - degenerate_downbeats
                          - implausible_tempo
                        description: 'Why the request was not honoured. Present only when `applied` differs from `requested`. `grid_unavailable`: Beat detection produced no grid for this audio. `too_few_beats`: Too few beats were detected to define a grid. `low_coverage`: The detected beats cover too little of the audio. `unstable_pacing`: The detected beats are spaced too unevenly to describe the performance. `unstable_intervals`: The detected beats are steady enough to describe the performance, but not steady enough to move notes onto. `degenerate_downbeats`: Nearly every beat was marked as a downbeat, so no metre was found. `implausible_tempo`: The detected beats imply a tempo outside the range a reader accepts.'
                  time_grid:
                    type: object
                    description: The bar grid the exported files state. Reported so a consumer can reconstruct bar lines instead of inferring them from `tempo_bpm`.
                    required:
                      - beats_per_bar
                      - meter_source
                      - pickup_beats
                      - tempo_bpm
                      - tempo_source
                      - tempo_curve
                    properties:
                      beats_per_bar:
                        type: number
                        description: Beats in a bar — the metre's numerator
                      meter_source:
                        type: string
                        enum:
                          - detected
                          - detected_weak
                          - default
                        description: '`detected` when the downbeats agreed on the metre, `detected_weak` when they landed on it without agreeing — still measured from this take, and written in preference to the fallback — and `default` when the downbeats implied no bar length at all and the 4/4 fallback was written.'
                      pickup_beats:
                        type: number
                        description: Beats before the first bar line (anacrusis). 0 when bar one starts at the beginning of the audio. A non-zero pickup shifts every bar line after it.
                      tempo_bpm:
                        type: number
                        description: The tempo the files state. Always present — unlike the top-level `tempo_bpm`, which is omitted when no tempo was detected.
                      tempo_source:
                        type: string
                        enum:
                          - detected
                          - default
                        description: Whether `tempo_bpm` came from the detected beats or is the export default.
                      tempo_curve:
                        type: boolean
                        description: True when the files carry a tempo map following the performance; false when they state one constant tempo.
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/audio-to-midi/v1.0/jobs:
    post:
      operationId: audioToMidiV10JobCreate
      summary: Create async job
      description: Start an async audio-to-MIDI job. Returns immediately with a job_id. Poll the job status endpoint until status is succeeded or errored.
      tags:
        - Audio to MIDI
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AudioToMidiRequest'
      responses:
        '202':
          description: Async job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/audio-to-midi/v1.0/jobs/{job_id}:
    get:
      operationId: audioToMidiV10JobPoll
      summary: Poll job status
      description: 'Poll the status of an async audio-to-MIDI job. Returns a discriminated union on status: processing, succeeded, or errored. While processing, `notes` / `note_count` grow with closed notes transcribed so far (onset+offset resolved). Sync stays all-or-nothing.'
      tags:
        - Audio to MIDI
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
          description: Job ID returned from the job creation endpoint
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Processing
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - estimated_completion_at
                      - estimated_ms
                      - progress_percent
                      - notes
                      - note_count
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                      progress_percent:
                        type: integer
                        minimum: 0
                        maximum: 96
                      notes:
                        type: array
                        description: 'Closed notes transcribed so far. Grows across polls until the job succeeds. Open onsets without an offset are not included. These are always performance times, even under a `quantized` request: snapping happens once, against the finished beat grid, so note times can move when the job succeeds. The applied timing is only reported on the succeeded response.'
                        items:
                          type: object
                          required:
                            - pitch
                            - start
                            - end
                            - instrument
                            - velocity
                          properties:
                            pitch:
                              type: number
                              description: MIDI note number
                            start:
                              type: number
                              description: Start time in seconds
                            end:
                              type: number
                              description: End time in seconds
                            instrument:
                              type: string
                              description: Detected or assigned instrument label
                            velocity:
                              type: number
                              description: Note velocity (0–127)
                      note_count:
                        type: integer
                        description: Number of closed notes in `notes` so far
                      request:
                        type: object
                  - title: Succeeded
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - completed_at
                      - result
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - midi_url
                          - notes
                          - duration_seconds
                          - note_count
                          - timing
                        properties:
                          midi_url:
                            type: string
                            format: uri
                            description: Presigned URL to the generated MIDI file
                          musicxml_url:
                            type: string
                            format: uri
                            description: Presigned URL to the generated MusicXML file. Omitted when transcription produced no notes.
                          notes:
                            type: array
                            items:
                              type: object
                              required:
                                - pitch
                                - start
                                - end
                                - instrument
                                - velocity
                              properties:
                                pitch:
                                  type: number
                                  description: MIDI note number
                                start:
                                  type: number
                                  description: Start time in seconds
                                end:
                                  type: number
                                  description: End time in seconds
                                instrument:
                                  type: string
                                  description: Detected or assigned instrument label
                                velocity:
                                  type: number
                                  description: Note velocity (0–127)
                            description: Structured note list
                          duration_seconds:
                            type: number
                            description: Duration of the input audio in seconds
                          note_count:
                            type: integer
                            description: Number of transcribed notes
                          tempo_bpm:
                            type: number
                            description: Estimated tempo in BPM when beat-grid detection succeeds
                          timing:
                            type: object
                            description: What the export did about time. `applied` is what the files carry; it differs from `requested` only when a `quantized` request met a beat grid too unreliable to move notes onto.
                            required:
                              - requested
                              - applied
                            properties:
                              requested:
                                type: string
                                enum:
                                  - performance
                                  - quantized
                              applied:
                                type: string
                                enum:
                                  - performance
                                  - quantized
                              fallback_reason:
                                type: string
                                enum:
                                  - grid_unavailable
                                  - too_few_beats
                                  - low_coverage
                                  - unstable_pacing
                                  - unstable_intervals
                                  - degenerate_downbeats
                                  - implausible_tempo
                                description: 'Why the request was not honoured. Present only when `applied` differs from `requested`. `grid_unavailable`: Beat detection produced no grid for this audio. `too_few_beats`: Too few beats were detected to define a grid. `low_coverage`: The detected beats cover too little of the audio. `unstable_pacing`: The detected beats are spaced too unevenly to describe the performance. `unstable_intervals`: The detected beats are steady enough to describe the performance, but not steady enough to move notes onto. `degenerate_downbeats`: Nearly every beat was marked as a downbeat, so no metre was found. `implausible_tempo`: The detected beats imply a tempo outside the range a reader accepts.'
                          time_grid:
                            type: object
                            description: The bar grid the exported files state. Reported so a consumer can reconstruct bar lines instead of inferring them from `tempo_bpm`.
                            required:
                              - beats_per_bar
                              - meter_source
                              - pickup_beats
                              - tempo_bpm
                              - tempo_source
                              - tempo_curve
                            properties:
                              beats_per_bar:
                                type: number
                                description: Beats in a bar — the metre's numerator
                              meter_source:
                                type: string
                                enum:
                                  - detected
                                  - detected_weak
                                  - default
                                description: '`detected` when the downbeats agreed on the metre, `detected_weak` when they landed on it without agreeing — still measured from this take, and written in preference to the fallback — and `default` when the downbeats implied no bar length at all and the 4/4 fallback was written.'
                              pickup_beats:
                                type: number
                                description: Beats before the first bar line (anacrusis). 0 when bar one starts at the beginning of the audio. A non-zero pickup shifts every bar line after it.
                              tempo_bpm:
                                type: number
                                description: The tempo the files state. Always present — unlike the top-level `tempo_bpm`, which is omitted when no tempo was detected.
                              tempo_source:
                                type: string
                                enum:
                                  - detected
                                  - default
                                description: Whether `tempo_bpm` came from the detected beats or is the export default.
                              tempo_curve:
                                type: boolean
                                description: True when the files carry a tempo map following the performance; false when they state one constant tempo.
                      request:
                        type: object
                  - title: Errored
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - error
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
                      request:
                        type: object
                discriminator:
                  propertyName: status
              examples:
                processing:
                  summary: Job is still processing
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440002
                    status: processing
                    created_at: '2024-01-15T10:30:00.000Z'
                    estimated_completion_at: '2024-01-15T10:30:45.000Z'
                    estimated_ms: 45000
                    progress_percent: 32
                    notes:
                      - pitch: 60
                        start: 0
                        end: 0.5
                        instrument: piano
                        velocity: 80
                    note_count: 1
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/song.mp3
                      timing: performance
                succeeded:
                  summary: Job completed successfully
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440002
                    status: succeeded
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:42.120Z'
                    result:
                      midi_url: https://cdn.mirelo.ai/api/audio-to-midi/abc/transcription.mid
                      musicxml_url: https://cdn.mirelo.ai/api/audio-to-midi/abc/transcription.musicxml
                      notes:
                        - pitch: 60
                          start: 0
                          end: 0.5
                          instrument: piano
                          velocity: 80
                      duration_seconds: 30.5
                      note_count: 128
                      tempo_bpm: 120
                      timing:
                        requested: performance
                        applied: performance
                      time_grid:
                        beats_per_bar: 4
                        meter_source: detected
                        pickup_beats: 0
                        tempo_bpm: 120
                        tempo_source: detected
                        tempo_curve: true
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/song.mp3
                      timing: performance
                errored:
                  summary: Job failed — upstream transcription error
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440002
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:12.000Z'
                    error:
                      code: generation_failed
                      message: Generation failed due to an upstream error. Retry or contact support if this persists.
                      http_status: 502
                    request:
                      audio:
                        type: url
                        audio_url: https://example.com/song.mp3
                      timing: performance
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found or not owned by this API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/text-to-sfx/v1.5/preflight:
    get:
      operationId: textToSfxPreflight
      deprecated: true
      summary: Preflight
      description: Returns the exact credit cost and estimated duration for a text-to-sfx generation. No generation occurs, no credits are deducted.
      tags:
        - Text to SFX
      security:
        - BearerAuth: []
      parameters:
        - name: duration_ms
          in: query
          schema:
            type: integer
            default: 10000
          description: Duration in milliseconds
        - name: num_samples
          in: query
          schema:
            type: integer
            default: 1
          description: Number of samples
      responses:
        '200':
          description: Credit cost and ETA
          content:
            application/json:
              schema:
                type: object
                required:
                  - credits
                  - estimated_ms
                properties:
                  credits:
                    type: integer
                    description: Exact credit cost — matches what will be deducted on success
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds (p90 calibrated)
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/text-to-sfx/v1.5/sync:
    post:
      operationId: textToSfxSync
      deprecated: true
      summary: Generate SFX from text (sync)
      description: Generate sound effects from a text prompt. Blocks until complete. Recommended for `duration_ms` ≤ 10000.
      tags:
        - Text to SFX
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TextToSfxRequest'
      responses:
        '200':
          description: Generated audio URLs
          content:
            application/json:
              schema:
                type: object
                required:
                  - result_urls
                properties:
                  result_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                  download_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                  generation_id:
                    type: string
                    description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/text-to-sfx/v1.5/jobs:
    post:
      operationId: textToSfxJobCreate
      deprecated: true
      summary: Create async job
      description: Start an async text-to-sfx generation job. Returns immediately with a `job_id`. Poll the job status endpoint until `status` is `succeeded` or `errored`.
      tags:
        - Text to SFX
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TextToSfxRequest'
      responses:
        '202':
          description: Job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/text-to-sfx/v1.5/jobs/{job_id}:
    get:
      operationId: textToSfxJobPoll
      deprecated: true
      summary: Poll job
      description: 'Poll the status of an async text-to-sfx job. Returns a discriminated union on `status`: `processing`, `succeeded`, or `errored`.'
      tags:
        - Text to SFX
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
          description: Job ID returned from the job creation endpoint
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Processing
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - estimated_completion_at
                      - estimated_ms
                      - progress_percent
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                        description: ETA in milliseconds
                      progress_percent:
                        type: integer
                        minimum: 0
                        maximum: 96
                        description: Estimated progress. Climbs linearly over the ETA, then asymptotically approaches the cap until completion.
                      request:
                        type: object
                        description: Original request parameters echoed back
                  - title: Succeeded
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - completed_at
                      - result
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - result_urls
                        properties:
                          result_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                          download_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                          generation_id:
                            type: string
                            description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
                        description: The generation result — identical in shape to the response from the sync endpoint. Audio URLs for all endpoints except video-to-sfx with output="video", which returns the original video with SFX mixed in.
                      request:
                        type: object
                  - title: Errored
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - error
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
                      request:
                        type: object
                discriminator:
                  propertyName: status
              examples:
                processing:
                  summary: Job is still processing
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: processing
                    created_at: '2024-01-15T10:30:00.000Z'
                    estimated_completion_at: '2024-01-15T10:30:08.000Z'
                    estimated_ms: 8000
                    progress_percent: 45
                    request:
                      prompt: rain falling on leaves
                      duration_ms: 10000
                      num_samples: 2
                succeeded:
                  summary: Job completed successfully
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: succeeded
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:07.312Z'
                    result:
                      result_urls:
                        - https://cdn.mirelo.ai/sfx/abc123_0.wav
                        - https://cdn.mirelo.ai/sfx/abc123_1.wav
                      download_urls:
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/0?k=Ab3dEfGhIjKlMnOp
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/1?k=QrStUvWxYz012345
                      generation_id: k17d8x2p9q4m3n6r5t7v0w1y
                    request:
                      prompt: rain falling on leaves
                      duration_ms: 10000
                      num_samples: 2
                errored:
                  summary: Job failed — upstream generation error
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:05.201Z'
                    error:
                      code: generation_failed
                      message: Generation failed due to an upstream error. Retry or contact support if this persists.
                      http_status: 502
                    request:
                      prompt: rain falling on leaves
                      duration_ms: 10000
                      num_samples: 2
                errored_precheck:
                  summary: Job failed — video too short (precheck)
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:01.543Z'
                    error:
                      code: video_too_short
                      message: 'Video is too short: start_offset_ms (0ms) + duration_ms (15000ms) = 15000ms, but the video is only 8200ms long.'
                      http_status: 400
                    request:
                      prompt: rain falling on leaves
                      duration_ms: 10000
                      num_samples: 2
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found, expired, or belongs to a different API key
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx/v1.5/preflight:
    get:
      operationId: videoToSfxPreflight
      deprecated: true
      summary: Preflight
      description: Returns the exact credit cost and estimated duration for a video-to-sfx generation. No generation occurs, no credits are deducted.
      tags:
        - Video to SFX
      security:
        - BearerAuth: []
      parameters:
        - name: duration_ms
          in: query
          schema:
            type: integer
            default: 10000
          description: Duration in milliseconds
        - name: num_samples
          in: query
          schema:
            type: integer
            default: 1
          description: Number of samples
      responses:
        '200':
          description: Credit cost and ETA
          content:
            application/json:
              schema:
                type: object
                required:
                  - credits
                  - estimated_ms
                properties:
                  credits:
                    type: integer
                    description: Exact credit cost — matches what will be deducted on success
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds (p90 calibrated)
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx/v1.5/sync:
    post:
      operationId: videoToSfxSync
      deprecated: true
      summary: Generate SFX from video (sync)
      description: 'Generate sound effects from a video clip. Provide a `video` object with either `{type: "url", video_url}` or `{type: "asset", asset_id}`. Blocks until complete. Use `output` to control whether the response contains audio-only files or the original video with SFX mixed in.'
      tags:
        - Video to SFX
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoToSfxRequest'
      responses:
        '200':
          description: Generated output URLs. Audio files when output is "audio" (default); original video with SFX mixed in when output is "video".
          content:
            application/json:
              schema:
                type: object
                required:
                  - result_urls
                properties:
                  result_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                  download_urls:
                    type: array
                    items:
                      type: string
                      format: uri
                    description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                  generation_id:
                    type: string
                    description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
        '400':
          description: 'Bad request or video URL check failure — error.code will be one of: invalid_request, video_url_unreachable, video_format_unsupported, video_too_short'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '422':
          description: Video could not be decoded — error.code will be invalid_video. Ensure the video uses a supported codec (H.264, VP8, or VP9) and is not corrupted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx/v1.5/jobs:
    post:
      operationId: videoToSfxJobCreate
      deprecated: true
      summary: Create async job
      description: Start an async video-to-sfx generation job. Returns immediately with a `job_id`. Recommended for videos longer than 10 seconds.
      tags:
        - Video to SFX
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VideoToSfxRequest'
      responses:
        '202':
          description: Job accepted
          content:
            application/json:
              schema:
                type: object
                required:
                  - job_id
                  - job_url
                  - estimated_ms
                  - estimated_completion_at
                properties:
                  job_id:
                    type: string
                    format: uuid
                    description: Unique identifier for the async job
                  job_url:
                    type: string
                    description: Relative URL to poll for job status, e.g. `/v2/text-to-sfx/{version}/jobs/{job_id}`. Append to your API base URL to form the full polling URL.
                  estimated_ms:
                    type: integer
                    description: Estimated completion time in milliseconds
                  estimated_completion_at:
                    type: string
                    format: date-time
                    description: ISO 8601 estimated completion timestamp
        '400':
          description: 'Bad request or video URL check failure — error.code will be one of: invalid_request, video_url_unreachable, video_format_unsupported, video_too_short'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '422':
          description: Video could not be decoded — error.code will be invalid_video. Ensure the video uses a supported codec (H.264, VP8, or VP9) and is not corrupted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/video-to-sfx/v1.5/jobs/{job_id}:
    get:
      operationId: videoToSfxJobPoll
      deprecated: true
      summary: Poll job
      description: 'Poll the status of an async video-to-sfx job. Returns a discriminated union on `status`: `processing`, `succeeded`, or `errored`.'
      tags:
        - Video to SFX
      security:
        - BearerAuth: []
      parameters:
        - name: job_id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Job status (discriminated union on status field)
          content:
            application/json:
              schema:
                oneOf:
                  - title: Processing
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - estimated_completion_at
                      - estimated_ms
                      - progress_percent
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - processing
                      created_at:
                        type: string
                        format: date-time
                      estimated_completion_at:
                        type: string
                        format: date-time
                      estimated_ms:
                        type: integer
                        description: ETA in milliseconds
                      progress_percent:
                        type: integer
                        minimum: 0
                        maximum: 96
                        description: Estimated progress. Climbs linearly over the ETA, then asymptotically approaches the cap until completion.
                      request:
                        type: object
                        description: Original request parameters echoed back
                  - title: Succeeded
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - completed_at
                      - result
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - succeeded
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                      result:
                        type: object
                        required:
                          - result_urls
                        properties:
                          result_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Array of URLs to the generated output files (audio, or video with SFX mixed in when output is "video"). Signed by the inference service at upload time and valid for one hour from then — not from when you read them. Prefer `download_urls`.
                          download_urls:
                            type: array
                            items:
                              type: string
                              format: uri
                            description: Short download links on `mirelo.ai`, index-aligned with `result_urls` when present. Each is a `302` to a URL signed at the moment you follow it, so the link stays valid for as long as the generation is retained instead of expiring on the job's clock. Short enough for clients that reject long URLs, and accepted anywhere this API takes an input URL. Repeated follows are expected and supported; a link followed hard enough to be throttled answers `429` with `Retry-After` rather than looking like a dead file. **Optional — always fall back to `result_urls`.** Every SFX endpoint emits it, extend and inpaint included; the music endpoints record no generation and so never carry one. Minting is best-effort on top of that, so even a response carrying `generation_id` may omit it.
                          generation_id:
                            type: string
                            description: Server-side generation record id, present when the generation was persisted. Retain it to later reference the generation (e.g. attach feedback). Absent when persistence was skipped or failed — never blocks the result.
                        description: The generation result — identical in shape to the response from the sync endpoint. Audio URLs for all endpoints except video-to-sfx with output="video", which returns the original video with SFX mixed in.
                      request:
                        type: object
                  - title: Errored
                    type: object
                    required:
                      - job_id
                      - status
                      - created_at
                      - error
                      - request
                    properties:
                      job_id:
                        type: string
                      status:
                        type: string
                        enum:
                          - errored
                      created_at:
                        type: string
                        format: date-time
                      completed_at:
                        type: string
                        format: date-time
                        nullable: true
                      error:
                        type: object
                        required:
                          - code
                          - message
                          - http_status
                        properties:
                          code:
                            type: string
                          message:
                            type: string
                          http_status:
                            type: integer
                      request:
                        type: object
                discriminator:
                  propertyName: status
              examples:
                processing:
                  summary: Job is still processing
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: processing
                    created_at: '2024-01-15T10:30:00.000Z'
                    estimated_completion_at: '2024-01-15T10:30:08.000Z'
                    estimated_ms: 8000
                    progress_percent: 45
                    request:
                      video:
                        type: url
                        video_url: https://example.com/clip.mp4
                      duration_ms: 10000
                      num_samples: 1
                      output: audio
                succeeded:
                  summary: Job completed successfully
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: succeeded
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:07.312Z'
                    result:
                      result_urls:
                        - https://cdn.mirelo.ai/sfx/abc123_0.wav
                        - https://cdn.mirelo.ai/sfx/abc123_1.wav
                      download_urls:
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/0?k=Ab3dEfGhIjKlMnOp
                        - https://mirelo.ai/dl/k17d8x2p9q4m3n6r5t7v0w1y/1?k=QrStUvWxYz012345
                      generation_id: k17d8x2p9q4m3n6r5t7v0w1y
                    request:
                      video:
                        type: url
                        video_url: https://example.com/clip.mp4
                      duration_ms: 10000
                      num_samples: 1
                      output: audio
                errored:
                  summary: Job failed — upstream generation error
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:05.201Z'
                    error:
                      code: generation_failed
                      message: Generation failed due to an upstream error. Retry or contact support if this persists.
                      http_status: 502
                    request:
                      video:
                        type: url
                        video_url: https://example.com/clip.mp4
                      duration_ms: 10000
                      num_samples: 1
                      output: audio
                errored_precheck:
                  summary: Job failed — video too short (precheck)
                  value:
                    job_id: 550e8400-e29b-41d4-a716-446655440001
                    status: errored
                    created_at: '2024-01-15T10:30:00.000Z'
                    completed_at: '2024-01-15T10:30:01.543Z'
                    error:
                      code: video_too_short
                      message: 'Video is too short: start_offset_ms (0ms) + duration_ms (15000ms) = 15000ms, but the video is only 8200ms long.'
                      http_status: 400
                    request:
                      video:
                        type: url
                        video_url: https://example.com/clip.mp4
                      duration_ms: 10000
                      num_samples: 1
                      output: audio
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '404':
          description: Job not found or expired
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/me:
    get:
      operationId: getMe
      summary: Get current user
      description: Returns the authenticated user's identity plus the canonical credit-account snapshot (remaining balance, period usage, plan allocation, and provisioning state).
      tags:
        - Account
      security:
        - BearerAuth: []
      responses:
        '200':
          description: Current user information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MeResponse'
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
  /v2/assets:
    post:
      operationId: createAsset
      summary: Create upload asset
      description: |-
        Creates a pre-signed upload URL. Upload your file directly to the returned `upload_url` via PUT, then use `asset_id` in generation requests.

        Send a `Content-Type` header on the PUT that matches the media you are uploading. Storage keeps whatever the PUT declares and nothing converts an upload afterwards, so a default `application/octet-stream` uploads successfully and is then rejected when you try to generate from it.

        ```bash
        curl -X PUT -T ad.mp4 -H 'Content-Type: video/mp4' "$UPLOAD_URL"
        ```
      tags:
        - Assets
      security:
        - BearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                content_type:
                  type: string
                  description: MIME type of the file (e.g. video/mp4). Send the same value as the `Content-Type` header on your PUT.
                  example: video/mp4
      responses:
        '201':
          description: Asset created
          content:
            application/json:
              schema:
                type: object
                required:
                  - asset_id
                  - upload_url
                properties:
                  asset_id:
                    type: string
                    description: 'Use as asset_id in the video object: {type: "asset", asset_id: "..."}'
                  upload_url:
                    type: string
                    format: uri
                    description: PUT your file to this URL. Short-lived — upload promptly after creating the asset, and create a new asset if it expires.
        '400':
          description: Invalid request — missing or malformed parameters
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '401':
          description: Unauthorized — missing or invalid Bearer token
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '402':
          description: Insufficient credits
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '429':
          description: 'Rate limited — `error.code` is `rate_limited`. Either this API key exceeded its own request ceiling, an input URL''s origin is throttling us (a short download link followed hard enough to be throttled does this), or an upstream model provider is throttling us. All three mean retry: the request and any URLs in it are still valid. `Retry-After` is present whenever the wait is known. Async jobs report the same code on the poll response.'
          headers:
            Retry-After:
              description: Seconds to wait before retrying. Omitted when the wait is unknown.
              schema:
                type: integer
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
        '500':
          description: Unexpected server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    required:
                      - code
                      - message
                      - http_status
                    properties:
                      code:
                        type: string
                        description: Machine-readable error code from the closed taxonomy
                      message:
                        type: string
                        description: Human-readable description of the error
                      http_status:
                        type: integer
                        description: HTTP status code mirroring the response status
