> ## Documentation Index
> Fetch the complete documentation index at: https://docs.eachlabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Poll a prediction

> Returns the prediction's current state. Poll every 3-5 seconds until a terminal status (success, error, cancelled).



## OpenAPI

````yaml /openapi_specs/video_api.json get /v1/prediction/{id}
openapi: 3.1.0
info:
  title: eachlabs Video API (beta)
  version: v1-beta
  description: >-
    Machine-readable contract for the eachlabs Video API: 45 capability input
    schemas embedded token-for-token from the engine's capability registry (the
    canonical contract — content and key order preserved, whitespace re-flowed;
    keep_ranges and silence_remove are one capability under two accepted names),
    the prediction submit/poll/cancel envelopes, and the error taxonomy.
    GENERATED — do not edit by hand; regenerate with `make openapi` in
    be-monorepo/video-api. Human documentation:
    https://docs.eachlabs.ai/video/overview.
  contact:
    name: eachlabs
    url: https://docs.eachlabs.ai/video/overview
  x-generator: be-monorepo/video-api cmd/openapigen
servers:
  - url: https://api.eachlabs.ai
security:
  - BearerAuth: []
tags:
  - name: video
    description: eachlabs Video API prediction surface
externalDocs:
  description: Human documentation for the video surface
  url: https://docs.eachlabs.ai/video/overview
paths:
  /v1/prediction/{id}:
    get:
      tags:
        - video
      summary: Poll a prediction
      description: >-
        Returns the prediction's current state. Poll every 3-5 seconds until a
        terminal status (success, error, cancelled).
      operationId: getVideoPrediction
      parameters:
        - description: The prediction id returned by submit as predictionID.
          example: eb474c68-0fc6-40a3-8c4a-63f1b064b8b0
          in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      responses:
        '200':
          content:
            application/json:
              examples:
                analysis:
                  summary: 'Analysis capability: structured JSON in output, no artifact'
                  value:
                    id: 7c31ba02-9e4d-4f6a-b18c-52e7d04a86c9
                    input:
                      capability: probe
                      input_url: https://your-host.example/source.mp4
                      params: {}
                      tier: cpu
                    logs: null
                    metrics:
                      cost: 0.0075
                      predict_time: 4.12
                    output:
                      format:
                        duration: '12.032000'
                        format_name: mov,mp4,m4a,3gp,3g2,mj2
                      streams:
                        - codec_name: h264
                          codec_type: video
                          height: 720
                          width: 1280
                    status: success
                    urls:
                      cancel: >-
                        https://api.eachlabs.ai/v1/prediction/7c31ba02-9e4d-4f6a-b18c-52e7d04a86c9/cancel
                      get: >-
                        https://api.eachlabs.ai/v1/prediction/7c31ba02-9e4d-4f6a-b18c-52e7d04a86c9
                error:
                  summary: >-
                    Zero-billed input-validation reject (captured envelope
                    shape)
                  value:
                    id: eb474c68-0fc6-40a3-8c4a-63f1b064b8b0
                    input:
                      capability: silence_remove
                      input_url: https://your-host.example/long-source.mp4
                      params:
                        ranges:
                          - end: 210
                            start: 200
                      tier: cpu
                    logs: null
                    metrics:
                      cost: 0
                      predict_time: 3.493916429
                    output:
                      classification:
                        category: VALIDATION
                      error: Execution failed
                      error_code: INPUT_VALIDATION_ERROR
                      error_message: >-
                        ranges: range start 200s is at or beyond source duration
                        120s (empty output)
                      error_step: Surface Customer Reject.0
                      execution_id: eb474c68-0fc6-40a3-8c4a-63f1b064b8b0
                      model_id: e3b3d84f-a2dc-46a3-b6e7-e9d80face367
                      model_slug: eachlabs-video-api
                      provider: videoapi
                      retryable: false
                      status: ERROR
                      success: false
                    status: error
                    urls:
                      cancel: >-
                        https://api.eachlabs.ai/v1/prediction/eb474c68-0fc6-40a3-8c4a-63f1b064b8b0/cancel
                      get: >-
                        https://api.eachlabs.ai/v1/prediction/eb474c68-0fc6-40a3-8c4a-63f1b064b8b0
                processing:
                  summary: 'Non-terminal poll: output and metrics fields are null'
                  value:
                    id: 1f0fdf4d-7b3c-4e9a-8d25-c61f90ab4e73
                    input:
                      capability: transcode
                      input_url: https://your-host.example/source.mp4
                      params:
                        crf: 28
                        vcodec: h264
                      tier: cpu
                    logs: null
                    metrics:
                      cost: null
                      predict_time: null
                    output: null
                    status: processing
                    urls:
                      cancel: >-
                        https://api.eachlabs.ai/v1/prediction/1f0fdf4d-7b3c-4e9a-8d25-c61f90ab4e73/cancel
                      get: >-
                        https://api.eachlabs.ai/v1/prediction/1f0fdf4d-7b3c-4e9a-8d25-c61f90ab4e73
                success:
                  summary: Terminal success with one hosted artifact
                  value:
                    id: 1f0fdf4d-7b3c-4e9a-8d25-c61f90ab4e73
                    input:
                      capability: transcode
                      input_url: https://your-host.example/source.mp4
                      params:
                        crf: 28
                        vcodec: h264
                      tier: cpu
                    logs: null
                    metrics:
                      cost: 0.2865
                      predict_time: 194.86
                    output:
                      - >-
                        https://cdn-us.eachlabs.ai/uploads/9b967c93-6e1d-4a5f-b2c8-40d7e93a51f6.mp4
                    status: success
                    urls:
                      cancel: >-
                        https://api.eachlabs.ai/v1/prediction/1f0fdf4d-7b3c-4e9a-8d25-c61f90ab4e73/cancel
                      get: >-
                        https://api.eachlabs.ai/v1/prediction/1f0fdf4d-7b3c-4e9a-8d25-c61f90ab4e73
              schema:
                $ref: '#/components/schemas/GetPredictionResponse'
          description: Current prediction state.
        '401':
          content:
            application/json:
              schema:
                description: Empty object.
                type: object
          description: Missing or invalid API key. The body is an empty JSON object today.
        '404':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
          description: No prediction with that id.
        default:
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GatewayError'
          description: Any other gateway failure.
components:
  schemas:
    GetPredictionResponse:
      description: Body of GET /v1/prediction/{id} — the poll envelope.
      properties:
        id:
          type: string
        input:
          $ref: '#/components/schemas/VideoInput'
          description: >-
            Your submitted input, echoed back as sent — a tolerated legacy
            submission that omitted capability or params echoes without those
            fields.
        logs:
          description: Present on every poll; null today.
          type:
            - string
            - 'null'
        metrics:
          properties:
            cost:
              description: >-
                What the job actually billed, in USD. Rejected, failed, and
                cancelled predictions settle 0 in beta — the engine still meters
                customer-fault seconds, so do not design flows that rely on
                failed compute staying free.
              type:
                - number
                - 'null'
            predict_time:
              description: >-
                The prediction's full wall time in seconds, from processing
                start to completion detection, including internal queueing and
                ~5 s poll quantization. NOT the billed quantity — cost comes
                from engine-metered billed execution seconds × the tier rate.
              type:
                - number
                - 'null'
          type: object
        output:
          $ref: '#/components/schemas/PredictionOutput'
        status:
          description: >-
            Typical flow: starting → processing → success. Terminal states:
            success, error, cancelled. The video surface writes "starting" as
            the initial state; "created" appears only on legacy paths, so a poll
            loop may never observe it. A failed prediction reports "error",
            never "failed". Poll every 3-5 seconds — platform status checks are
            quantized to ~5 s, tighter loops buy nothing. No queue-time bound is
            enforced: a prediction can wait in "starting" behind the per-tier
            concurrency cap; keep polling.
          enum:
            - created
            - starting
            - processing
            - success
            - error
            - cancelled
          type: string
        urls:
          properties:
            cancel:
              description: >-
                POST here (same Authorization header) to cancel. Cancellation is
                record-only and a cancelled prediction never bills.
              format: uri
              type: string
            get:
              description: This prediction's poll URL.
              format: uri
              type: string
          type: object
      required:
        - id
        - input
        - logs
        - status
        - output
        - metrics
        - urls
      type: object
    GatewayError:
      description: >-
        Gateway-level error body for errors mapped by the gateway's error
        handler (unknown prediction, internal failures), e.g. {"status": 404,
        "error": "not found"}. Exceptions returning an empty JSON object body
        today: 401 (missing or invalid API key), 400 (request validation), and
        422 (malformed JSON).
      properties:
        details:
          description: Optional detail; shape varies by the failing layer.
        error:
          type: string
        status:
          description: HTTP status code echoed in the body.
          type: integer
      type: object
    VideoInput:
      description: >-
        The job to run: a capability input envelope (dispatch on the capability
        field) or raw run_ffmpeg mode (mode: "run_ffmpeg"). The gateway
        tolerates an omitted capability/tier by defaulting to transcode/cpu, but
        this contract requires capability explicitly — omission is not a
        supported integration path.
      oneOf:
        - $ref: '#/components/schemas/CapabilityInput'
        - $ref: '#/components/schemas/RunFFmpegInput'
    PredictionOutput:
      anyOf:
        - description: Hosted artifact URL(s), one element per delivered artifact.
          items:
            format: uri
            type: string
          type: array
        - description: >-
            A single artifact URL, or an analysis result serialized as a JSON
            string.
          type: string
        - description: Analysis JSON, a named-output map, or a bundle object.
          type: object
        - $ref: '#/components/schemas/ErrorOutput'
        - description: Not yet terminal, or cancelled.
          type: 'null'
      description: >-
        Value of the poll envelope's output field. Capability descriptions that
        mention an output_urls array refer to THIS field — through the gateway
        the artifact URL array IS the output value. The shape follows the
        capability's output class: media capabilities deliver hosted artifact
        URL(s) as an array (single-artifact capabilities deliver a one-element
        array); analysis capabilities (probe, scene_detect, silence_detect,
        audio_analysis) deliver structured JSON (an object, which may also
        arrive as a JSON string or as a URL to a JSON body); packaging
        capabilities (package_abr, package_abr_ladder, hls_ladder) deliver the
        manifest plus artifacts. On status "error" this is the ErrorOutput
        object. Download or persist artifact URLs promptly; treat them as valid
        for at least 24 hours.
    CapabilityInput:
      description: >-
        One of the 45 capability input envelopes, discriminated by the
        capability field.
      discriminator:
        mapping:
          audio_analysis:
            $ref: '#/components/schemas/CapabilityInput_audio_analysis'
          audio_duck:
            $ref: '#/components/schemas/CapabilityInput_audio_duck'
          audio_master:
            $ref: '#/components/schemas/CapabilityInput_audio_master'
          audio_replace:
            $ref: '#/components/schemas/CapabilityInput_audio_replace'
          captions:
            $ref: '#/components/schemas/CapabilityInput_captions'
          color:
            $ref: '#/components/schemas/CapabilityInput_color'
          concat:
            $ref: '#/components/schemas/CapabilityInput_concat'
          concat_copy:
            $ref: '#/components/schemas/CapabilityInput_concat_copy'
          crop:
            $ref: '#/components/schemas/CapabilityInput_crop'
          crossfade:
            $ref: '#/components/schemas/CapabilityInput_crossfade'
          extract_audio:
            $ref: '#/components/schemas/CapabilityInput_extract_audio'
          fade:
            $ref: '#/components/schemas/CapabilityInput_fade'
          gif:
            $ref: '#/components/schemas/CapabilityInput_gif'
          hls_ladder:
            $ref: '#/components/schemas/CapabilityInput_hls_ladder'
          keep_ranges:
            $ref: '#/components/schemas/CapabilityInput_keep_ranges'
          loudnorm:
            $ref: '#/components/schemas/CapabilityInput_loudnorm'
          lut3d:
            $ref: '#/components/schemas/CapabilityInput_lut3d'
          overlay:
            $ref: '#/components/schemas/CapabilityInput_overlay'
          package_abr:
            $ref: '#/components/schemas/CapabilityInput_package_abr'
          package_abr_ladder:
            $ref: '#/components/schemas/CapabilityInput_package_abr_ladder'
          pad:
            $ref: '#/components/schemas/CapabilityInput_pad'
          poster:
            $ref: '#/components/schemas/CapabilityInput_poster'
          probe:
            $ref: '#/components/schemas/CapabilityInput_probe'
          reframe:
            $ref: '#/components/schemas/CapabilityInput_reframe'
          reframe_track:
            $ref: '#/components/schemas/CapabilityInput_reframe_track'
          reverse:
            $ref: '#/components/schemas/CapabilityInput_reverse'
          rotate:
            $ref: '#/components/schemas/CapabilityInput_rotate'
          scale:
            $ref: '#/components/schemas/CapabilityInput_scale'
          scene_detect:
            $ref: '#/components/schemas/CapabilityInput_scene_detect'
          segment:
            $ref: '#/components/schemas/CapabilityInput_segment'
          silence_detect:
            $ref: '#/components/schemas/CapabilityInput_silence_detect'
          silence_remove:
            $ref: '#/components/schemas/CapabilityInput_silence_remove'
          silence_split:
            $ref: '#/components/schemas/CapabilityInput_silence_split'
          slideshow:
            $ref: '#/components/schemas/CapabilityInput_slideshow'
          speed:
            $ref: '#/components/schemas/CapabilityInput_speed'
          sticker_overlay:
            $ref: '#/components/schemas/CapabilityInput_sticker_overlay'
          stills:
            $ref: '#/components/schemas/CapabilityInput_stills'
          storyboard_sprites:
            $ref: '#/components/schemas/CapabilityInput_storyboard_sprites'
          subtitle_compose:
            $ref: '#/components/schemas/CapabilityInput_subtitle_compose'
          thumbnails:
            $ref: '#/components/schemas/CapabilityInput_thumbnails'
          title_card:
            $ref: '#/components/schemas/CapabilityInput_title_card'
          transcode:
            $ref: '#/components/schemas/CapabilityInput_transcode'
          trim:
            $ref: '#/components/schemas/CapabilityInput_trim'
          volume:
            $ref: '#/components/schemas/CapabilityInput_volume'
          watermark:
            $ref: '#/components/schemas/CapabilityInput_watermark'
        propertyName: capability
      oneOf:
        - $ref: '#/components/schemas/CapabilityInput_audio_analysis'
        - $ref: '#/components/schemas/CapabilityInput_audio_duck'
        - $ref: '#/components/schemas/CapabilityInput_audio_master'
        - $ref: '#/components/schemas/CapabilityInput_audio_replace'
        - $ref: '#/components/schemas/CapabilityInput_captions'
        - $ref: '#/components/schemas/CapabilityInput_color'
        - $ref: '#/components/schemas/CapabilityInput_concat'
        - $ref: '#/components/schemas/CapabilityInput_concat_copy'
        - $ref: '#/components/schemas/CapabilityInput_crop'
        - $ref: '#/components/schemas/CapabilityInput_crossfade'
        - $ref: '#/components/schemas/CapabilityInput_extract_audio'
        - $ref: '#/components/schemas/CapabilityInput_fade'
        - $ref: '#/components/schemas/CapabilityInput_gif'
        - $ref: '#/components/schemas/CapabilityInput_hls_ladder'
        - $ref: '#/components/schemas/CapabilityInput_keep_ranges'
        - $ref: '#/components/schemas/CapabilityInput_loudnorm'
        - $ref: '#/components/schemas/CapabilityInput_lut3d'
        - $ref: '#/components/schemas/CapabilityInput_overlay'
        - $ref: '#/components/schemas/CapabilityInput_package_abr'
        - $ref: '#/components/schemas/CapabilityInput_package_abr_ladder'
        - $ref: '#/components/schemas/CapabilityInput_pad'
        - $ref: '#/components/schemas/CapabilityInput_poster'
        - $ref: '#/components/schemas/CapabilityInput_probe'
        - $ref: '#/components/schemas/CapabilityInput_reframe'
        - $ref: '#/components/schemas/CapabilityInput_reframe_track'
        - $ref: '#/components/schemas/CapabilityInput_reverse'
        - $ref: '#/components/schemas/CapabilityInput_rotate'
        - $ref: '#/components/schemas/CapabilityInput_scale'
        - $ref: '#/components/schemas/CapabilityInput_scene_detect'
        - $ref: '#/components/schemas/CapabilityInput_segment'
        - $ref: '#/components/schemas/CapabilityInput_silence_detect'
        - $ref: '#/components/schemas/CapabilityInput_silence_remove'
        - $ref: '#/components/schemas/CapabilityInput_silence_split'
        - $ref: '#/components/schemas/CapabilityInput_slideshow'
        - $ref: '#/components/schemas/CapabilityInput_speed'
        - $ref: '#/components/schemas/CapabilityInput_sticker_overlay'
        - $ref: '#/components/schemas/CapabilityInput_stills'
        - $ref: '#/components/schemas/CapabilityInput_storyboard_sprites'
        - $ref: '#/components/schemas/CapabilityInput_subtitle_compose'
        - $ref: '#/components/schemas/CapabilityInput_thumbnails'
        - $ref: '#/components/schemas/CapabilityInput_title_card'
        - $ref: '#/components/schemas/CapabilityInput_transcode'
        - $ref: '#/components/schemas/CapabilityInput_trim'
        - $ref: '#/components/schemas/CapabilityInput_volume'
        - $ref: '#/components/schemas/CapabilityInput_watermark'
    RunFFmpegInput:
      description: >-
        Input envelope for raw run_ffmpeg mode — the escape hatch for long-tail
        cases no named capability covers. Access is a beta grant managed
        server-side (per organization during the beta); it cannot be
        self-granted via the API key, and a submit without the grant fails as
        the engine scope_denied reject (an engine 403 — surfaced with platform
        error_code PROVIDER_AUTH_ERROR). The same gates as capability jobs
        apply: a staged input longer than 3600 seconds is rejected before
        billing (duration_over_cap), and execution is killed at the
        3600-metered-seconds cap — a killed job wastes its wall clock and, like
        every non-success prediction, settles metrics.cost 0 in beta. Prefer a
        capability when one fits.
      properties:
        argv:
          description: >-
            Full argv whose first token must be exactly ffmpeg or ffprobe (an
            ffprobe argv returns its captured stdout as the job result instead
            of a file). Reference media only via {placeholders}: one input_url
            binds {input}, N input_urls bind {input0}, {input1}, … in array
            order, and the output path is {output} (extension set by
            output_format). Rejected at submit with the named code: any URL or
            protocol scheme in any token (http:, file:, concat:, and so on — the
            only allowed prefix is expr: for expression values; at runtime only
            the file protocol is available), the movie= and amovie= filters,
            -protocol_whitelist, -safe with any value other than 1, the bare
            token - (stdin/stdout — for a discard sink write -f null /dev/null
            instead of -f null -), a -var_stream_map value outside the strict
            v:<n>/a:<n> grammar (name:/agroup: options are rejected as
            invalid_command), placeholder-assembled paths containing /../ or
            starting with ../ (literal_path) or starting with - (flag_denied),
            and filtergraph metacharacters in spliced bound paths
            (invalid_command). Raw literal path tokens like /dev/null pass
            validation (run_ffmpeg compiles in escalated mode), though only
            placeholder paths resolve to your media; a command ffmpeg itself
            rejects fails at execution as exec_error.
          items:
            type: string
          type: array
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: run_ffmpeg
          type: string
        output_format:
          default: mp4
          description: >-
            Sets {output}'s extension; hls yields .m3u8, dash yields .mpd. An
            unknown or empty value falls back to mp4.
          enum:
            - mp4
            - webm
            - mkv
            - mov
            - gif
            - mp3
            - wav
            - m4a
            - jpg
            - png
            - vtt
            - hls
            - dash
          type: string
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - mode
        - argv
      type: object
    ErrorOutput:
      description: >-
        The output object when status is "error" (and for pre-billing rejects).
        Every non-success prediction settles metrics.cost 0 in beta. A dispatch
        failure at submit writes a minimal envelope carrying only the error
        field.
      properties:
        classification:
          properties:
            category:
              description: >-
                Known values: VALIDATION, PROVIDER, AUTH, RATE_LIMIT, NETWORK,
                TIMEOUT, INTERNAL.
              type: string
          type: object
        error:
          description: Human-readable summary, e.g. "Execution failed".
          type: string
        error_code:
          description: >-
            Common values on the video surface — INPUT_VALIDATION_ERROR: the
            engine rejected the input or command before billable compute
            (error_message carries the typed reason). PROVIDER_REJECTED: an
            input could not be staged for processing. PROVIDER_FAILED: the job
            was accepted and failed during execution (error_step "poll").
            PROVIDER_RATE_LIMIT: engine throttling (classification RATE_LIMIT,
            retryable true) — retry with backoff. Platform-level codes can also
            surface: PROVIDER_BAD_REQUEST (an engine 400/409 at submit, carrying
            the EngineRejectError body in error_message), PROVIDER_AUTH_ERROR
            (engine 401/403, e.g. a run_ffmpeg submit without the grant),
            NETWORK_ERROR, EXECUTION_TIMEOUT, INPUT_DOWNLOAD_ERROR. Treat an
            unknown code as terminal unless retryable is true.
          type: string
        error_message:
          description: >-
            Specific failure detail. Engine submit rejects carry the
            EngineRejectError fields; input-gate rejects carry the typed reject
            reason (e.g. duration_over_cap); execution failures carry the engine
            FailureClass.
          type: string
        error_step:
          description: >-
            Pipeline step that failed; "poll" marks a post-accept provider
            failure.
          type: string
        execution_id:
          type: string
        model_id:
          type: string
        model_slug:
          type: string
        provider:
          type: string
        provider_error_code:
          type: string
        retryable:
          description: >-
            Set by the platform's error classification: true for rate-limit,
            network, provider-5xx, and worker-lost classes (a max-duration
            EXECUTION_TIMEOUT reads false despite its timeout class — its
            producer overrides the classifier); false otherwise — including
            engine platform_fault, the one engine failure class that IS
            retryable. For engine-side failures use error_message and the
            failure class as the retry authority, not this field.
          type: boolean
        status:
          description: Uppercase execution-status mirror ("ERROR").
          type: string
        success:
          type: boolean
      required:
        - error
      type: object
    CapabilityInput_audio_analysis:
      description: >-
        Input envelope for the "audio_analysis" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly ({} accepts every default) — required fields inside it
        are enforced at submit as invalid_command.
      properties:
        capability:
          const: audio_analysis
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: audio_analysis
          description: >-
            Measure the audio track: integrated loudness (LUFS), loudness range
            (LU), true peak (dBTP), sample peak (dBFS), and the astats clipping
            indicators flat_factor (dB flatness of consecutive equal samples)
            and peak_count (occurrences of the max sample) via astats+ebur128.
            Returns structured JSON, no uploaded artifact (zero egress). The
            input MUST carry an audio stream: a video-only input is rejected
            before billing. Any field that cannot be measured is omitted from
            the result rather than reported as zero: a digitally silent input
            returns no true_peak_dbtp and no sample_peak_dbfs (silence has no
            finite dB peak), and any statistic ffmpeg reports as -inf/nan is
            likewise omitted. Treat a missing field as not-measurable, never as
            0. Runs on the cpu tier.
          type: object
          properties: {}
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_audio_duck:
      description: >-
        Input envelope for the "audio_duck" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: audio_duck
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: audio_duck
          description: >-
            Duck a music/program bed under a voice track using two inputs:
            input0 is the music, input1 is the voice. The voice drives a
            sidechain compressor that lowers the music while the voice is above
            threshold, and the SAME voice is then mixed on top, so the output
            carries the voice over the ducked bed. The output is always
            audio-only (mp3, wav, or m4a): a video input0 contributes only its
            audio track and its video stream is discarded. The output runs
            exactly as long as input0's audio: a voice longer than the music is
            truncated at the music's end, and a voice shorter than the music
            leaves the remaining music playing at full level. Inputs that differ
            in sample rate or channel layout are never rejected: the voice is
            silently resampled and up/down-mixed to the music's format, and the
            output inherits input0's sample rate and channel count. Levels are
            never auto-normalized: the voice and the ducked music keep their
            source loudness, which can clip if both are hot. Both inputs must
            carry an audio stream: an input without one is rejected before
            billing. Runs on the cpu tier.
          type: object
          properties:
            threshold:
              type: number
              minimum: 0.000976563
              maximum: 1
              default: 0.05
              description: >-
                Voice level that triggers the duck, as LINEAR amplitude where 1
                is full scale (0 dBFS); the default 0.05 is about -26 dBFS. The
                music is compressed while the voice is above this level; lower
                values duck on quieter voice.
            ratio:
              type: number
              minimum: 1
              maximum: 20
              default: 8
              description: >-
                How hard the music is reduced once the voice crosses threshold:
                1 leaves it untouched, 20 flattens it. The default 8 is a firm
                broadcast-style duck.
            attack_ms:
              type: number
              minimum: 0.01
              maximum: 2000
              default: 20
              description: >-
                Milliseconds for the duck to fully engage after the voice
                crosses threshold.
            release_ms:
              type: number
              minimum: 0.01
              maximum: 9000
              default: 250
              description: >-
                Milliseconds for the music to recover to full level after the
                voice falls below threshold.
            container:
              type: string
              enum:
                - mp3
                - wav
                - m4a
              default: mp3
              description: >-
                Output audio format and codec (default mp3): mp3 encodes with
                libmp3lame and m4a with AAC; wav writes lossless PCM.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_audio_master:
      description: >-
        Input envelope for the "audio_master" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly ({} accepts every default) — required fields inside it
        are enforced at submit as invalid_command.
      properties:
        capability:
          const: audio_master
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: audio_master
          description: >-
            Master the audio track to a distribution loudness target: compressor
            -> EBU R128 loudness normalization (single-pass) -> true-peak
            limiter, written audio-only. The input MUST carry an audio stream: a
            video-only input is rejected before billing. A fixed gentle
            compressor (2:1 ratio, -18 dB threshold, 30 ms attack) is always
            applied before normalization and cannot be disabled; for loudness
            normalization without compression use the loudnorm capability
            instead. Normalization runs in a single pass, so the output's
            measured integrated loudness can deviate from target_lufs,
            especially on short or highly dynamic inputs; ceiling_dbtp is still
            enforced by the final limiter. The output is always resampled to
            44100 Hz regardless of the source sample rate; there is no way to
            keep the source rate. Runs on the cpu tier.
          type: object
          properties:
            target_lufs:
              type: number
              minimum: -30
              maximum: -8
              default: -14
              description: >-
                Integrated loudness target in LUFS. -14 is the common streaming
                target, -16 podcast, -23 EBU R128 broadcast.
            ceiling_dbtp:
              type: number
              minimum: -9
              maximum: 0
              default: -1
              description: True-peak ceiling in dBTP; the final limiter enforces it.
            bitrate:
              type: string
              enum:
                - 128k
                - 192k
                - 256k
                - 320k
              default: 320k
              description: >-
                Audio bitrate for the lossy containers (mp3/m4a). Rejected for
                wav (lossless).
            preset:
              type: string
              enum:
                - broadcast
                - podcast
                - streaming
              description: >-
                Named target pair: streaming = -14 LUFS / -1 dBTP, podcast = -16
                / -1.5, broadcast = -23 / -2. Mutually exclusive with
                target_lufs/ceiling_dbtp.
            container:
              type: string
              enum:
                - mp3
                - wav
                - m4a
              default: mp3
              description: >-
                Output audio format and codec (default mp3): mp3 encodes with
                libmp3lame and m4a with AAC, both honoring the bitrate param;
                wav writes lossless PCM and rejects an explicit bitrate.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_audio_replace:
      description: >-
        Input envelope for the "audio_replace" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly ({} accepts every default) — required fields inside it
        are enforced at submit as invalid_command.
      properties:
        capability:
          const: audio_replace
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: audio_replace
          description: >-
            Swap or mix a video's audio using two inputs: input0 is the video,
            input1 is the audio source. The video stream is always copied
            without re-encoding; the output audio is always re-encoded to AAC
            regardless of the source codec. replace mode requires input0 to
            carry a video stream and input1 an audio stream; mix mode
            additionally requires input0 to carry its own audio stream. An input
            missing a required stream is rejected before billing.
          type: object
          properties:
            mode:
              type: string
              enum:
                - replace
                - mix
              default: replace
              description: >-
                replace: input1's audio replaces input0's; -shortest ends the
                output at the shorter of video and audio, so a video longer than
                the new audio is trimmed to the audio and audio longer than the
                video is trimmed to the video. mix: input1's audio is mixed into
                input0's over the full-length copied video; the mixed audio
                track ends when the SHORTER of the two audio streams ends, and
                the remainder of the video plays with no audio at all (the
                original audio does not continue past the mix end). Match
                input1's length to the video to avoid a silent tail.
            container:
              type: string
              enum:
                - mp4
                - mkv
              default: mp4
              description: >-
                Output container. Restricted to mp4/mkv because the video stream
                is copied (not re-encoded) and webm holds only VP8/VP9, not a
                copied H.264 stream.
            normalize:
              type: boolean
              default: true
              description: >-
                mix only: amix loudness normalization. true (default,
                no-clip-safe) scales each track by 1/n, so the original and
                added audio are each halved. false preserves source levels
                (louder, can clip if both inputs are hot). Ignored in replace
                mode.
            offset_ms:
              type: integer
              minimum: 0
              maximum: 3600000
              default: 0
              description: >-
                Milliseconds of silence prepended to input1's audio (adelay, all
                channels equally) before the replace/mix, so narration can start
                at t>0 without client-side pre-padding. In replace mode
                -shortest still ends the output at min(video, offset+audio): an
                offset pushing the narration past the video end truncates it,
                and an offset at/past the video duration yields a full-length
                video whose audio is entirely silent. In mix mode the delayed
                audio mixes over the full copied video.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_captions:
      description: >-
        Input envelope for the "captions" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: captions
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: captions
          description: >-
            Burn a subtitle file into the video as open captions. Supply exactly
            two inputs in order: the first is the video, the second is the
            subtitle file (SRT, VTT, or ASS). The whole video is re-encoded to
            apply the burn-in. Runs on the cpu tier.
          type: object
          properties:
            font_size:
              type: integer
              minimum: 8
              maximum: 200
              description: >-
                Subtitle font size in points; omit for the libass/source
                default.
            text_color:
              type: string
              description: >-
                Primary text color: a named color (white, black, gray/grey, red,
                green, blue, yellow) or #RRGGBB hex. Omit for the source
                default.
            position:
              type: string
              enum:
                - bottom
                - top
              description: >-
                Caption anchor; omit to keep the subtitle file's own alignment
                (libass defaults to bottom).
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container. Audio is always re-encoded to the container's
                native codec - AAC for mp4/mkv, Opus for webm - never copied
                from the source. mp4 output is written with faststart so
                playback can begin before the file fully downloads.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_color:
      description: >-
        Input envelope for the "color" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: color
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: color
          description: >-
            Color-grade the clip: brightness, contrast, saturation, and gamma.
            Video and audio are always re-encoded (audio becomes AAC for mp4/mkv
            or Opus for webm); nothing is stream-copied, and an all-default call
            is an identity grade that still re-encodes without visibly changing
            the picture. Runs on the cpu tier.
          type: object
          properties:
            brightness:
              type: number
              minimum: -1
              maximum: 1
              default: 0
              description: Additive luma offset; 0 = unchanged.
            contrast:
              type: number
              minimum: 0
              maximum: 2
              default: 1
              description: Contrast multiplier; 1 = unchanged, 0 = flat gray.
            saturation:
              type: number
              minimum: 0
              maximum: 3
              default: 1
              description: Chroma saturation; 1 = unchanged, 0 = grayscale.
            gamma:
              type: number
              minimum: 0.1
              maximum: 10
              default: 1
              description: Gamma curve; 1 = unchanged. Must be > 0 (schema min 0.1).
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container: mp4 (default), webm or mkv; video is
                re-encoded to the container's default codec (H.264 for mp4/mkv,
                VP9 for webm) and audio to AAC for mp4/mkv or Opus for webm.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_concat:
      description: >-
        Input envelope for the "concat" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: concat
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: concat
          description: >-
            Join the inputs end to end into one re-encoded file. Every input is
            first normalized to the width x height canvas: scaled to fit with
            aspect preserved, then padded with centered black bars to exactly
            width x height; audio is resampled to 44.1 kHz stereo. Inputs of
            different sizes and formats join cleanly, and none is cropped or
            stretched. Every input must contain both a video and an audio
            stream; a job where any input lacks either is rejected before
            billing.
          type: object
          properties:
            inputs:
              type: integer
              minimum: 2
              maximum: 10
              default: 2
              description: Number of inputs to join; supply exactly this many input_urls.
            width:
              type: integer
              minimum: 16
              default: 1280
              description: >-
                Output canvas width in pixels (default 1280). Every input is
                scaled to fit and padded with centered black bars to exactly
                width x height, so the output is always exactly this size
                regardless of input sizes.
            height:
              type: integer
              minimum: 16
              default: 720
              description: >-
                Output canvas height in pixels (default 720). Every input is
                scaled to fit and padded with centered black bars to exactly
                width x height, so the output is always exactly this size
                regardless of input sizes.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container (default mp4): no video or audio codec is
                pinned on the cpu tier, so ffmpeg's per-container default
                encoders apply (H.264 video for mp4/mkv, VP9 for webm, and the
                muxer's default audio encoder); mp4 output is written with the
                faststart flag so it progressive-plays.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_concat_copy:
      description: >-
        Input envelope for the "concat_copy" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: concat_copy
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: concat_copy
          description: >-
            Rejoin already-encoded chunks of one video into a single mp4
            (default), mkv or ts file via the concat demuxer with -c copy: video
            and audio are copied byte for byte, never re-encoded, so codecs,
            resolution and quality are preserved exactly, and since no encoder
            runs the capability is accepted on every tier. Supply the chunks in
            play order via input_urls (2-50, set by inputs); all chunks must
            match on video codec, width, height and pixel format and on audio
            codec, sample rate and channel count, and must agree on whether an
            audio stream is present - any mismatch is rejected before billing.
            An mp4 output additionally gets a faststart moov relocation so it
            can start playing before the file fully downloads; to join
            dissimilar inputs use concat instead, which normalizes and
            re-encodes.
          type: object
          properties:
            inputs:
              type: integer
              minimum: 2
              maximum: 50
              default: 2
              description: >-
                Number of chunks to rejoin (2-50); supply exactly this many
                input_urls in play order. All chunks must match exactly on video
                codec, width, height and pixel format, and on audio codec,
                sample rate and channel count, and must agree on whether an
                audio stream is present - any mismatch is rejected before
                billing, because a byte-copy join of divergent streams produces
                a corrupt file.
            container:
              type: string
              enum:
                - mp4
                - mkv
                - ts
              default: mp4
              description: >-
                Output container: mp4 (default), mkv or ts. Streams are copied
                byte-for-byte with no re-encode, so the chunks' codecs must be
                ones the chosen container can carry (for example mp4 carries
                H.264/H.265 with AAC but cannot carry VP8 from webm chunks) - an
                incompatible pairing fails at run time.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_crop:
      description: >-
        Input envelope for the "crop" capability. The params schema below is the
        complete, canonical contract for this capability; send params explicitly
        ({} accepts every default) — required fields inside it are enforced at
        submit as invalid_command.
      properties:
        capability:
          const: crop
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: crop
          description: >-
            Cut a width x height rectangle out of the frame; x/y position the
            rectangle and omitting them centers it. The rectangle is not checked
            against the source dimensions at submit, so a rectangle that does
            not fit inside the source fails at execution. Video and audio are
            always re-encoded (audio becomes AAC for mp4/mkv or Opus for webm);
            nothing is stream-copied.
          type: object
          properties:
            width:
              type: integer
              minimum: 1
              maximum: 8192
              default: 640
              description: Crop rectangle width in pixels (default 640).
            height:
              type: integer
              minimum: 1
              maximum: 8192
              default: 480
              description: Crop rectangle height in pixels (default 480).
            x:
              type: integer
              minimum: 0
              maximum: 8192
              description: Left offset; omit to center.
            'y':
              type: integer
              minimum: 0
              maximum: 8192
              description: Top offset; omit to center.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: Output container.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_crossfade:
      description: >-
        Input envelope for the "crossfade" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: crossfade
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: crossfade
          description: >-
            Crossfade two clips into one. Supply exactly two inputs in order:
            the video transition starts offset seconds into the first clip and
            blends into the second over duration seconds (xfade); the audio is
            always crossfaded at the junction of the two audio tracks over the
            same duration (acrossfade ignores offset). With offset omitted it is
            derived from the probed first input (first duration minus duration)
            so video and audio cross at the same junction and the output runs
            first plus second minus duration seconds; when the first input's
            duration cannot be probed (direct bindings), an omitted offset is
            rejected before billing - supply offset explicitly. A supplied
            offset earlier than the junction switches the video to the second
            clip early while the audio still crosses at the junction, so the
            audio track outlasts the video track. Both inputs must contain a
            video AND an audio stream - an input missing either is rejected
            before billing. The second input's video is scaled (stretched,
            square pixels) to the probed size of the first input; when that size
            is unknown the input sizes must already match or the run fails at
            execution. Both inputs must share a frame rate - mismatched rates
            fail at execution; container timebases are normalized in-graph, so
            inputs with identical frame rates but different encoder timescales
            are safe. A second input shorter than duration truncates the
            transition. Video and audio are always re-encoded (audio becomes AAC
            for mp4/mkv or Opus for webm); nothing is stream-copied. Runs on the
            cpu tier.
          type: object
          properties:
            transition:
              type: string
              enum:
                - circleclose
                - circleopen
                - dissolve
                - fade
                - fadeblack
                - fadewhite
                - pixelize
                - radial
                - slidedown
                - slideleft
                - slideright
                - slideup
                - wipedown
                - wipeleft
                - wiperight
                - wipeup
              default: fade
              description: >-
                Which xfade wipe/blend the video transition uses; the audio
                always uses a plain acrossfade regardless.
            duration:
              type: number
              minimum: 0.1
              maximum: 10
              default: 1
              description: >-
                Transition length in seconds, shared by the video xfade and the
                audio acrossfade. Must not exceed the first input's probed
                duration (rejected before billing; unchecked when the duration
                is unknown).
            offset:
              type: number
              minimum: 0
              maximum: 86400
              description: >-
                Seconds into the first input where the video transition starts.
                Omit for the junction (first input duration minus duration,
                derived from the probe). offset plus duration must not exceed
                the first input's probed duration (rejected before billing;
                unchecked when the duration is unknown). The audio crossfade
                ignores offset and always sits at the audio junction.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container (default mp4): it fixes the pinned audio codec
                (AAC for mp4/mkv, Opus for webm) while video uses the
                container's cpu default encoder (H.264 for mp4/mkv, VP9 for
                webm), and mp4 output is written with the faststart flag so it
                progressive-plays.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_extract_audio:
      description: >-
        Input envelope for the "extract_audio" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly ({} accepts every default) — required fields inside it
        are enforced at submit as invalid_command.
      properties:
        capability:
          const: extract_audio
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: extract_audio
          description: >-
            Extract the input's audio track to a standalone audio file, dropping
            the video. The input must contain an audio stream: a video-only
            input is not rejected up front and fails at execution.
          type: object
          properties:
            format:
              type: string
              enum:
                - mp3
                - wav
                - m4a
              default: mp3
              description: >-
                Output format: mp3 (libmp3lame at the encoder default bitrate;
                bitrate is not configurable here, use the audio_master
                capability to choose one), wav (lossless 16-bit PCM;
                higher-bit-depth or float sources are quantized to 16-bit), m4a
                (AAC at the encoder default bitrate). mp3 supports at most 48000
                Hz, so a higher-rate source is resampled down even when
                sample_rate is omitted.
            sample_rate:
              type: integer
              minimum: 8000
              maximum: 48000
              description: >-
                Resample the audio to this rate in Hz (STT models want a fixed
                rate, e.g. 16000). Omit to keep the source rate.
            mono:
              type: boolean
              default: false
              description: >-
                Downmix to a single channel (STT models expect mono). Omit/false
                keeps the source channel layout.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_fade:
      description: >-
        Input envelope for the "fade" capability. The params schema below is the
        complete, canonical contract for this capability; send params explicitly
        ({} accepts every default) — required fields inside it are enforced at
        submit as invalid_command.
      properties:
        capability:
          const: fade
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: fade
          description: >-
            Fade the clip in and/or out. The same fade is applied to the audio
            track with identical timings; a video-only input still succeeds (the
            audio fade is skipped). Video and audio are always re-encoded (audio
            becomes AAC for mp4/mkv or Opus for webm); nothing is stream-copied.
            Runs on the cpu tier.
          type: object
          properties:
            type:
              type: string
              enum:
                - in
                - out
                - both
              default: in
              description: >-
                Which fades to apply. Default in: a bare fade is a 1s fade-in
                (st=0). out and both REQUIRE fade_out_start (static argv cannot
                derive the clip duration).
            fade_in_duration:
              type: number
              exclusiveMinimum: 0
              maximum: 3600
              default: 1
              description: >-
                Fade-in length in seconds (from t=0); must be > 0 (ffmpeg treats
                0 as unset and substitutes ~1s). Validated whenever supplied;
                applied only when type is in or both.
            fade_out_duration:
              type: number
              exclusiveMinimum: 0
              maximum: 3600
              default: 1
              description: >-
                Fade-out length in seconds; must be > 0 (ffmpeg treats 0 as
                unset and substitutes ~1s). Validated whenever supplied; applied
                only when type is out or both.
            fade_out_start:
              type: number
              minimum: 0
              maximum: 86400
              description: >-
                Timestamp (seconds) the fade-out begins. REQUIRED when type is
                out or both; validated whenever supplied, applied only for those
                types. A value at or after the probed source duration is
                rejected before billing (the fade never fires); it fails open
                when the duration is unknown (direct-bindings / no probe).
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container (default mp4): it fixes the pinned audio codec
                (AAC for mp4/mkv, Opus for webm) while video uses the
                container's cpu default encoder (H.264 for mp4/mkv, VP9 for
                webm), and mp4 output is written with the faststart flag so it
                progressive-plays.
          if:
            required:
              - type
            properties:
              type:
                enum:
                  - out
                  - both
          then:
            required:
              - fade_out_start
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_gif:
      description: >-
        Input envelope for the "gif" capability. The params schema below is the
        complete, canonical contract for this capability; send params explicitly
        ({} accepts every default) — required fields inside it are enforced at
        submit as invalid_command.
      properties:
        capability:
          const: gif
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: gif
          description: >-
            Convert the ENTIRE input to an animated GIF: there is no start or
            duration control, so cut the clip first with trim if only a portion
            is wanted; the whole input is re-encoded and a long video produces a
            very large file. The output is silent and uses ffmpeg's standard
            256-color palette (single pass, not per-video optimized).
          type: object
          properties:
            fps:
              type: integer
              minimum: 1
              maximum: 50
              default: 10
              description: >-
                Output GIF frame rate in frames per second (default 10): the
                whole clip is resampled to exactly this constant rate regardless
                of the source frame rate, and a value outside 1-50 is rejected
                rather than clamped.
            width:
              type: integer
              minimum: 1
              default: 480
              description: >-
                Output width in pixels; the height is derived automatically to
                preserve the source aspect ratio and cannot be set.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_hls_ladder:
      description: >-
        Input envelope for the "hls_ladder" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: hls_ladder
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: hls_ladder
          description: >-
            Encode a multi-rendition adaptive-bitrate HLS ladder (master.m3u8 +
            N variant playlists/segments) in one ffmpeg pass. Re-encodes each
            rung, so any source codec is accepted; the input must carry both a
            video and an audio stream. Audio is always re-encoded to AAC (one
            audio track per variant) - the source audio codec is never
            preserved. The result is a bundle: master.m3u8 is the entrypoint,
            delivered alongside the per-variant playlists (stream_0.m3u8,
            stream_1.m3u8, and so on) and their MPEG-TS segments as separate
            artifact URLs, with a VOD playlist type. Give an explicit renditions
            list OR a ladder preset (not both); omit both for a default 3-rung
            720p ladder. Upscaling above the source is NOT rejected, so choose
            rungs at or below the source height.
          type: object
          properties:
            renditions:
              type: array
              minItems: 1
              maxItems: 6
              description: >-
                Explicit rungs. Width is derived from the source aspect,
                even-rounded. Reject duplicate heights. Mutually exclusive with
                ladder.
              items:
                type: object
                properties:
                  height:
                    type: integer
                    enum:
                      - 144
                      - 240
                      - 360
                      - 480
                      - 720
                      - 1080
                      - 1440
                      - 2160
                    description: >-
                      Rendition height in px. Width is derived from the source
                      aspect (even-rounded).
                  bitrate_kbps:
                    type: integer
                    minimum: 100
                    maximum: 50000
                    description: Target video bitrate in kbps.
                required:
                  - height
                  - bitrate_kbps
                additionalProperties: false
            ladder:
              type: string
              enum:
                - 240p
                - 360p
                - 480p
                - 720p
                - 1080p
              description: >-
                Preset rung set (height at kbps): 240p = 240@600; 360p =
                360@1000, 240@600; 480p = 480@1500, 360@1000, 240@600; 720p =
                720@3000, 480@1500, 360@1000; 1080p = 1080@5000, 720@3000,
                480@1500. Omitting both ladder and renditions uses the 720p set.
                Presets are NOT clipped to the source height - rungs above the
                source will upscale. Mutually exclusive with renditions.
            segment_duration:
              type: integer
              minimum: 1
              maximum: 30
              default: 4
              description: >-
                Target segment length in seconds. Segment boundaries fall on
                encoder keyframes and no fixed keyframe interval is forced, so
                actual segments may be longer than this target (up to the
                encoder default keyframe spacing).
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_keep_ranges:
      description: >-
        Input envelope for the "keep_ranges" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly (this capability has required params) — required fields
        inside it are enforced at submit as invalid_command. Also accepted as
        "silence_remove" — one capability, one billing bucket.
      properties:
        capability:
          const: keep_ranges
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: silence_remove
          description: >-
            Keep only the listed time ranges and join them into one continuous
            file in a single pass. Frame-accurate: the full source is re-encoded
            (video to the container's codec, audio to AAC for mp4/mkv or Opus
            for webm), so it is slower than a stream-copy trim but cuts exactly
            where asked. Also exposed under the name keep_ranges - identical
            behavior and billing.
          type: object
          properties:
            ranges:
              type: array
              minItems: 1
              maxItems: 100
              description: >-
                Time ranges to KEEP, in seconds, sorted ascending and
                non-overlapping. The kept ranges are concatenated into one
                continuous output; everything outside them is dropped. Chain
                silence_detect first and invert its silent spans to get these.
                An end past the source duration keeps to the end of the file.
                When the source can be probed, a first range starting at or
                after the source duration, or a total kept window shorter than
                one video frame, is rejected before billing; when it cannot be
                probed these checks are skipped and a near-empty output may be
                produced and billed.
              items:
                type: object
                properties:
                  start:
                    type: number
                    minimum: 0
                    description: Range start in seconds.
                  end:
                    type: number
                    minimum: 0
                    description: Range end in seconds (must be greater than start).
                required:
                  - start
                  - end
                additionalProperties: false
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container: mp4 (default), webm or mkv. Audio is
                re-encoded to the container's codec (AAC for mp4/mkv, Opus for
                webm).
          required:
            - ranges
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_loudnorm:
      description: >-
        Input envelope for the "loudnorm" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: loudnorm
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: loudnorm
          description: >-
            Normalize audio loudness to an EBU R128 target (single-pass). The
            input MUST carry an audio stream: a video-only input is rejected
            before billing, since loudnorm cannot normalize absent audio and
            would otherwise return a silently un-normalized file. Video is
            copied untouched, so the container is limited to mp4/mkv. The audio
            track is re-encoded to AAC regardless of its source codec, and the
            output sample rate is not preserved: the loudness filter internally
            resamples to 192 kHz and no sample-rate reset is applied, so the AAC
            output lands at 96 kHz (the highest rate AAC accepts), not the
            source rate; for a 44100 Hz audio-only master use the audio_master
            capability instead. Normalization runs in a single pass, so the
            output's measured integrated loudness can deviate from target_i,
            especially on short or highly dynamic inputs.
          type: object
          properties:
            target_i:
              type: number
              minimum: -70
              maximum: -5
              default: -14
              description: >-
                Integrated loudness target in LUFS. -14 is the common streaming
                target; -23 is EBU R128 broadcast.
            true_peak:
              type: number
              minimum: -9
              maximum: 0
              default: -1
              description: Maximum true peak in dBTP.
            lra:
              type: number
              minimum: 1
              maximum: 50
              default: 11
              description: Target loudness range in LU.
            container:
              type: string
              enum:
                - mp4
                - mkv
              default: mp4
              description: >-
                Output container (default mp4), limited to mp4 and mkv because
                the video stream is copied untouched and must land in a
                container that accepts it; the audio track is re-encoded to AAC
                in either container, and mp4 output is written with the
                faststart flag so it progressive-plays.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_lut3d:
      description: >-
        Input envelope for the "lut3d" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: lut3d
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: lut3d
          description: >-
            Color-grade the video with a 3D LUT. Supply exactly two inputs in
            order: the first is the video, the second is the LUT as a .cube
            file. The whole video is re-encoded to apply the grade. Runs on the
            cpu tier.
          type: object
          properties:
            interp:
              type: string
              enum:
                - nearest
                - trilinear
                - tetrahedral
              description: >-
                3D-LUT interpolation mode; omit for the ffmpeg default
                (tetrahedral).
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container. Audio is always re-encoded to the container's
                native codec - AAC for mp4/mkv, Opus for webm - never copied
                from the source. mp4 output is written with faststart so
                playback can begin before the file fully downloads.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_overlay:
      description: >-
        Input envelope for the "overlay" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: overlay
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: overlay
          description: >-
            Composite the second input (input1) over the base video (input0).
            The output keeps the base's resolution, and its video track runs for
            the base's length: an overlay that ends earlier stays frozen on its
            last frame for the remainder; one that runs longer has its extra
            tail dropped. Only the base's audio is kept (a silent base still
            succeeds); the overlay input's audio is always discarded. Both
            inputs must contain a video stream (a still image counts) - an input
            without one is rejected before billing. Video and audio are always
            re-encoded (audio becomes AAC for mp4/mkv or Opus for webm); nothing
            is stream-copied.
          type: object
          properties:
            position:
              type: string
              enum:
                - top_left
                - top_right
                - bottom_left
                - bottom_right
                - center
              default: bottom_right
              description: >-
                Anchor for the overlay. Corners offset by margin; center ignores
                margin.
            margin:
              type: number
              minimum: 0
              maximum: 1024
              default: 0
              description: Inset in pixels from the anchored edge(s). Ignored for center.
            scale:
              type: number
              minimum: 0.01
              maximum: 10
              description: >-
                Optional factor to resize the overlay before compositing (iw/ih
                * factor). Omit to keep the overlay's native size.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: Output container.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_package_abr:
      description: >-
        Input envelope for the "package_abr" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: package_abr
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: package_abr
          description: >-
            Package an input into a CMAF HLS + DASH bundle (clear, no DRM) with
            a SINGLE rendition at the source quality: all source streams are
            copied bit-exact, never re-encoded, so quality, codecs, and
            resolution stay exactly as the source. The result is a bundle whose
            entrypoint is master.m3u8, delivered alongside manifest.mpd and
            every fragmented-mp4 segment as separate artifact URLs. For a true
            multi-quality ladder use package_abr_ladder. Input should carry both
            a video and an audio stream.
          type: object
          properties:
            segment_duration:
              type: integer
              minimum: 1
              maximum: 30
              default: 4
              description: >-
                Target segment length in seconds. Because packaging
                stream-copies, segments can be cut only at existing source
                keyframes, so actual segment lengths follow the source keyframe
                spacing and may be much longer than this target. Use
                package_abr_ladder (which re-encodes) when segment lengths need
                to track the target.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_package_abr_ladder:
      description: >-
        Input envelope for the "package_abr_ladder" capability. The params
        schema below is the complete, canonical contract for this capability;
        send params explicitly ({} accepts every default) — required fields
        inside it are enforced at submit as invalid_command.
      properties:
        capability:
          const: package_abr_ladder
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: package_abr_ladder
          description: >-
            Package an input into a multi-rendition CMAF HLS + DASH
            adaptive-bitrate ladder (master.m3u8 + manifest.mpd over N
            renditions, clear, no DRM). Re-encodes each rung, so any source
            codec is accepted; the input must carry both a video and an audio
            stream. Audio is always re-encoded to a single shared AAC track used
            by every rendition - the source audio codec is never preserved. Give
            an explicit renditions list OR a ladder preset (not both); omit both
            for the default ladder of 1080 at 5000 kbps, 720 at 2800 kbps, and
            480 at 1200 kbps, clipped to the source height. Widths are derived
            from the source aspect (even-rounded), never supplied. A rung taller
            than the source is rejected (no upscaling). If the source is shorter
            than every default or preset rung, the ladder collapses to a single
            rung at the source height (rounded down to even) at 1200 kbps rather
            than failing. If the source height cannot be probed, the default or
            preset ladder is used unclipped and explicit rungs are not checked
            against the source, so upscaling can occur in that case.
          type: object
          properties:
            renditions:
              type: array
              minItems: 1
              maxItems: 6
              description: >-
                Explicit rungs. Width is derived from the source aspect
                (even-rounded). Reject duplicate heights and any height above
                the source. Mutually exclusive with ladder.
              items:
                type: object
                properties:
                  height:
                    type: integer
                    enum:
                      - 360
                      - 480
                      - 720
                      - 1080
                      - 1440
                      - 2160
                    description: >-
                      Rendition height in px. Width is derived from the source
                      aspect (even-rounded).
                  bitrate_kbps:
                    type: integer
                    minimum: 100
                    maximum: 50000
                    description: Target video bitrate in kbps.
                required:
                  - height
                  - bitrate_kbps
                additionalProperties: false
            ladder:
              type: string
              enum:
                - 360p
                - 480p
                - 720p
                - 1080p
                - 1440p
                - 2160p
              description: >-
                Preset rung set, clipped to the source height. Exact rungs
                (height at kbps): 360p = 360@1000; 480p = 480@1500, 360@1000;
                720p = 720@3000, 480@1500, 360@1000; 1080p = 1080@5000,
                720@3000, 480@1500; 1440p = 1440@8000, 1080@5000, 720@3000;
                2160p = 2160@16000, 1080@5000, 720@3000 (2160p does NOT include
                a 1440 rung). Mutually exclusive with renditions.
            segment_duration:
              type: integer
              minimum: 1
              maximum: 30
              default: 4
              description: >-
                Target segment length in seconds. Segment boundaries fall on
                encoder keyframes and no fixed keyframe interval is forced, so
                actual segments may be longer than this target (up to the
                encoder default keyframe spacing).
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_pad:
      description: >-
        Input envelope for the "pad" capability. The params schema below is the
        complete, canonical contract for this capability; send params explicitly
        ({} accepts every default) — required fields inside it are enforced at
        submit as invalid_command.
      properties:
        capability:
          const: pad
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: pad
          description: >-
            Frame the picture inside a width x height canvas filled with a
            background color, centered unless x/y are given. The canvas is not
            checked against the source dimensions at submit, so a canvas smaller
            than the picture fails at execution. Video and audio are always
            re-encoded (audio becomes AAC for mp4/mkv or Opus for webm); nothing
            is stream-copied.
          type: object
          properties:
            width:
              type: integer
              minimum: 1
              maximum: 8192
              default: 1280
              description: Output canvas width in pixels (default 1280).
            height:
              type: integer
              minimum: 1
              maximum: 8192
              default: 720
              description: Output canvas height in pixels (default 720).
            x:
              type: integer
              minimum: 0
              maximum: 8192
              description: Left offset; omit to center.
            'y':
              type: integer
              minimum: 0
              maximum: 8192
              description: Top offset; omit to center.
            color:
              type: string
              default: black
              description: 'Background: a named color or #RRGGBB hex.'
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: Output container.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_poster:
      description: >-
        Input envelope for the "poster" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: poster
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: poster
          description: >-
            Produce TWO named outputs in one job, returned in the outputs object
            keyed video and thumbnail: video is the ENTIRE source re-encoded to
            H.264/AAC MP4 in yuv420p with faststart (all source streams are kept
            and every audio track is re-encoded to AAC; the container is always
            mp4 - there is no container parameter), and thumbnail is a single
            JPEG frame taken at thumbnail_second. This re-encodes the full
            source, so it costs the same as a transcode, not a still extraction;
            for a still image alone use stills.
          type: object
          properties:
            crf:
              type: integer
              minimum: 0
              maximum: 51
              default: 23
              description: >-
                H.264 quality for the video output (lower = higher quality). On
                the cpu tier this is libx264 -crf.
            thumbnail_second:
              type: integer
              minimum: 0
              maximum: 36000
              default: 0
              description: >-
                Timestamp in seconds of the still frame; 0 = first frame. The
                seek is frame-accurate. Must be strictly inside the clip: a
                value at or after the source's probed duration is rejected
                before billing (it would yield no frame); when the duration
                could not be probed the request is accepted and the run may
                fail.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_probe:
      description: >-
        Input envelope for the "probe" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: probe
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: probe
          description: >-
            Inspect the input with ffprobe and return its container and
            per-stream metadata as a JSON document (fields 'format' and
            'streams') directly in the job result. No output file is produced or
            uploaded (zero egress); bind only {input}, never an output.
          type: object
          properties: {}
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_reframe:
      description: >-
        Input envelope for the "reframe" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: reframe
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: reframe
          description: >-
            Reframe the clip to a social aspect ratio. Runs on the cpu tier.
            Video and audio are always re-encoded (audio becomes AAC for mp4/mkv
            or Opus for webm); nothing is stream-copied.
          type: object
          properties:
            aspect:
              type: string
              enum:
                - '9:16'
                - '1:1'
                - '4:5'
                - '16:9'
              default: '9:16'
              description: >-
                Target social aspect ratio; maps to a fixed output resolution
                (9:16=1080x1920, 1:1=1080x1080, 4:5=1080x1350, 16:9=1920x1080).
                The output is always exactly that resolution: a smaller source
                is upscaled to it in both modes; the source resolution is never
                preserved.
            mode:
              type: string
              enum:
                - crop
                - pad
              default: crop
              description: >-
                crop = fill + center-crop the overflow (no bars); pad = fit
                inside + letterbox.
            pad_color:
              type: string
              enum:
                - black
                - white
              default: black
              description: Letterbox color (pad mode only).
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container: the video is re-encoded with the container's
                default encoder (H.264 for mp4/mkv, VP9 for webm - no explicit
                video codec is set), and mp4 output is written with faststart so
                playback can begin before the file fully downloads.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_reframe_track:
      description: >-
        Input envelope for the "reframe_track" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly ({} accepts every default) — required fields inside it
        are enforced at submit as invalid_command.
      properties:
        capability:
          const: reframe_track
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: reframe_track
          description: >-
            Pan a fixed-size crop window across the frame, driven by the
            crop-track sidecar (input1). The window starts centered and moves
            only when the track issues position commands. The output is a width
            x height video; video and audio are always re-encoded (audio becomes
            AAC for mp4/mkv or Opus for webm). Runs on the cpu tier.
          type: object
          properties:
            width:
              type: integer
              minimum: 1
              maximum: 8192
              default: 640
              description: >-
                Crop window width in pixels, fixed for the whole clip. It is NOT
                checked against the source before running: a window wider than
                the source fails at execution as a metered exec_error (settles
                $0 in beta) - probe the source dimensions first and keep the
                window inside them.
            height:
              type: integer
              minimum: 1
              maximum: 8192
              default: 360
              description: >-
                Crop window height in pixels, fixed for the whole clip. It is
                NOT checked against the source before running: a window taller
                than the source fails at execution as a metered exec_error
                (settles $0 in beta) - probe the source dimensions first and
                keep the window inside them.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container: the video is re-encoded with the container's
                default encoder (H.264 for mp4/mkv, VP9 for webm - no explicit
                video codec is set), and mp4 output is written with faststart so
                playback can begin before the file fully downloads.
          additionalProperties: false
          $comment: >-
            input1 is a crop-track sidecar: an ffmpeg sendcmd script of
            timestamped crop commands, e.g. '0.0 crop x 100, crop y 50;\n1.5
            crop x 240;'. It is emitted upstream by a saliency/face model not
            yet in the catalog, so this capability is inert until that model is
            onboarded.
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_reverse:
      description: >-
        Input envelope for the "reverse" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: reverse
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: reverse
          description: >-
            Play the clip backwards, reversing both video and audio. The whole
            clip is buffered in memory to reverse it, so long or high-resolution
            inputs can exhaust memory and fail mid-run as a metered exec_error
            (settles $0 in beta); intended for short clips. A video-only input
            still succeeds (the audio stage is skipped). Video and audio are
            always re-encoded (audio becomes AAC for mp4/mkv or Opus for webm);
            nothing is stream-copied.
          type: object
          properties:
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: Output container.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_rotate:
      description: >-
        Input envelope for the "rotate" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: rotate
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: rotate
          description: >-
            Rotate the picture clockwise in fixed 90-degree steps (90, 180, or
            270); 90 and 270 swap the output width and height, and arbitrary
            angles are not supported. Video and audio are always re-encoded
            (audio becomes AAC for mp4/mkv or Opus for webm); nothing is
            stream-copied.
          type: object
          properties:
            degrees:
              type: integer
              enum:
                - 90
                - 180
                - 270
              default: 90
              description: Clockwise rotation in fixed 90-degree steps.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: Output container.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_scale:
      description: >-
        Input envelope for the "scale" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: scale
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: scale
          description: >-
            Resize the video to a target width and height; the default height
            preserves the source aspect ratio rounded to an even dimension.
            Video and audio are always re-encoded (video to the container
            default H.264 for mp4/mkv or VP9 for webm; audio to AAC for mp4/mkv
            or Opus for webm); nothing is stream-copied.
          type: object
          properties:
            width:
              type: integer
              minimum: 1
              maximum: 8192
              default: 1280
              description: Output width in pixels.
            height:
              type: integer
              default: -2
              description: >-
                -2 keeps aspect rounded to an even dimension (h264-safe), -1
                keeps aspect, a positive value (1-8192) sets an explicit height.
                Other values are rejected.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container: mp4 (default), webm or mkv; it selects the
                re-encode codecs (audio becomes AAC for mp4/mkv or Opus for
                webm).
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_scene_detect:
      description: >-
        Input envelope for the "scene_detect" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly ({} accepts every default) — required fields inside it
        are enforced at submit as invalid_command.
      properties:
        capability:
          const: scene_detect
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: scene_detect
          description: >-
            Analyze the video for hard cuts and return them as a structured list
            in the job result: one entry per cut with time (seconds of the first
            frame past the threshold) and score (0..1). No media file is
            produced or uploaded (zero egress); a video with no cuts above the
            threshold returns an empty list, which is a success, not an error.
            The audio track is ignored. Runs on the cpu tier.
          type: object
          properties:
            threshold:
              type: number
              minimum: 0
              maximum: 1
              default: 0.3
              description: >-
                Scene-change sensitivity (0..1): a frame whose change score
                exceeds it is reported as a cut. Lower finds more cuts.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_segment:
      description: >-
        Input envelope for the "segment" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: segment
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: segment
          description: >-
            Split the input into consecutive chunks named seg_000, seg_001, and
            so on, delivered as output_urls in index order. The final chunk
            carries the remainder and is usually shorter than segment_seconds.
          type: object
          properties:
            segment_seconds:
              type: integer
              minimum: 1
              default: 10
              description: >-
                Target chunk length in seconds (default 10). With the default
                stream copy the actual cuts land on the input's existing
                keyframes, so chunks can be much longer than this; the final
                chunk carries the remainder and is usually shorter.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Container for every produced chunk: with the default
                reencode=false both source streams are copied unchanged, so the
                container must be able to hold the source codecs (webm holds
                only VP8/VP9/AV1 video and Opus/Vorbis audio, so a copied
                H.264/AAC source fails at execution), and with reencode=true
                video becomes H.264 - invalid in webm, rejected before billing -
                while audio is re-encoded to the container's default codec (no
                audio codec is pinned).
            reencode:
              type: boolean
              default: false
              description: >-
                false (default) stream-copies: near-instant and lossless, but
                the segment muxer cuts only on the input's existing keyframes,
                so a keyframe-sparse input yields fewer, longer segments than
                segment_seconds implies — down to a single file. true re-encodes
                to H.264 and forces a keyframe at each boundary, so every cut
                lands on the first frame at or after the boundary time (accurate
                to within one frame, not sample-exact). The webm container
                cannot hold H.264 (use mp4 or mkv, or keep copy for webm).
            crf:
              type: integer
              minimum: 0
              maximum: 51
              default: 23
              description: >-
                H.264 quality for reencode=true: 0 (best) to 51 (worst), default
                23. Ignored when reencode is false — stream copy does not
                re-encode.
            first_frame:
              type: boolean
              default: false
              description: >-
                true also delivers each clip's first frame as a companion still
                (seg_N_first.jpg|png), interleaved with the clips in output_urls
                (clip, still, clip, still, … in index order). A split that
                produces more than 999 clips fails the whole job after the split
                has run (the numbered names stop pairing with their stills);
                raise segment_seconds so the clip count stays at or under 999.
                With the default stream-copy the clip boundaries drift to the
                input's keyframes, so each first frame is boundary-accurate only
                with reencode=true.
            frame_format:
              type: string
              enum:
                - jpg
                - png
              default: jpg
              description: >-
                Companion-still image format. Validated whenever supplied;
                applied only when first_frame is true.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_silence_detect:
      description: >-
        Input envelope for the "silence_detect" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly ({} accepts every default) — required fields inside it
        are enforced at submit as invalid_command.
      properties:
        capability:
          const: silence_detect
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: silence_detect
          description: >-
            Analyze the audio track for silent spans and return them as a
            structured list in the job result: one entry per span with start,
            end, and duration in seconds. If the audio ends while still silent,
            the final entry carries start only and omits end and duration. No
            media file is produced or uploaded (zero egress); audio with no
            qualifying silence returns an empty list, which is a success, not an
            error. The video track is ignored, but the input must contain an
            audio stream - a video-only input is not rejected up front and fails
            at execution. Runs on the cpu tier.
          type: object
          properties:
            noise_db:
              type: integer
              minimum: -80
              maximum: 0
              default: -30
              description: >-
                Silence threshold in dBFS: samples quieter than this count as
                silence (e.g. -30, -50).
            min_silence_seconds:
              type: number
              exclusiveMinimum: 0
              maximum: 600
              default: 0.5
              description: Shortest span (seconds) reported as silence.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_silence_remove:
      description: >-
        Input envelope for the "silence_remove" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly (this capability has required params) — required
        fields inside it are enforced at submit as invalid_command. Also
        accepted as "keep_ranges" — one capability, one billing bucket.
      properties:
        capability:
          const: silence_remove
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: silence_remove
          description: >-
            Keep only the listed time ranges and join them into one continuous
            file in a single pass. Frame-accurate: the full source is re-encoded
            (video to the container's codec, audio to AAC for mp4/mkv or Opus
            for webm), so it is slower than a stream-copy trim but cuts exactly
            where asked. Also exposed under the name keep_ranges - identical
            behavior and billing.
          type: object
          properties:
            ranges:
              type: array
              minItems: 1
              maxItems: 100
              description: >-
                Time ranges to KEEP, in seconds, sorted ascending and
                non-overlapping. The kept ranges are concatenated into one
                continuous output; everything outside them is dropped. Chain
                silence_detect first and invert its silent spans to get these.
                An end past the source duration keeps to the end of the file.
                When the source can be probed, a first range starting at or
                after the source duration, or a total kept window shorter than
                one video frame, is rejected before billing; when it cannot be
                probed these checks are skipped and a near-empty output may be
                produced and billed.
              items:
                type: object
                properties:
                  start:
                    type: number
                    minimum: 0
                    description: Range start in seconds.
                  end:
                    type: number
                    minimum: 0
                    description: Range end in seconds (must be greater than start).
                required:
                  - start
                  - end
                additionalProperties: false
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container: mp4 (default), webm or mkv. Audio is
                re-encoded to the container's codec (AAC for mp4/mkv, Opus for
                webm).
          required:
            - ranges
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_silence_split:
      description: >-
        Input envelope for the "silence_split" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly (this capability has required params) — required
        fields inside it are enforced at submit as invalid_command.
      properties:
        capability:
          const: silence_split
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: silence_split
          description: >-
            Detect silences and split the file at them in one job: each cut
            lands at the END of a detected silence, so the silence stays
            attached to the end of the preceding segment and each new segment
            starts where sound resumes. Outputs are numbered seg_000, seg_001,
            and so on, delivered as output_urls in order; a source with no
            qualifying silence and no forced cap cut comes back as a single
            file. The input must contain an audio stream (rejected before
            billing otherwise). Runs on the cpu tier.
          type: object
          properties:
            noise_db:
              type: integer
              minimum: -80
              maximum: 0
              default: -30
              description: >-
                Silence threshold in dBFS: samples quieter than this count as
                silence (e.g. -30, -50).
            min_silence_seconds:
              type: number
              exclusiveMinimum: 0
              maximum: 600
              default: 0.5
              description: Shortest span (seconds) treated as a silence.
            max_segment_seconds:
              type: number
              minimum: 1
              maximum: 86400
              description: >-
                Hard cap on segment length in seconds: when the next usable
                silence is further away, cuts are forced at exactly this
                spacing. Required. Two cases can still exceed it: with the
                default reencode=false each cut snaps to the next keyframe, so a
                segment can run past the cap by up to one keyframe interval (use
                reencode=true for strict boundaries); and when the source
                duration cannot be probed the span after the last detected
                silence is never force-cut, so the final segment - or the whole
                file when no silence qualifies - can come back longer than the
                cap.
            min_segment_seconds:
              type: number
              minimum: 0
              default: 0
              description: >-
                A silence cut that would close a segment shorter than this many
                seconds is skipped, so the segment keeps growing until the next
                usable silence or the max_segment_seconds forced cut. Must not
                exceed max_segment_seconds. The default 0 allows arbitrarily
                short segments when silences cluster - set a positive value to
                avoid sliver clips. With the default reencode=false the actual
                cut snaps to the next keyframe, so delivered segment lengths can
                still deviate from this minimum.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Container for every produced segment: with the default
                reencode=false both source streams are copied unchanged, so the
                container must be able to hold the source codecs (webm holds
                only VP8/VP9/AV1 video and Opus/Vorbis audio, so a copied
                H.264/AAC source fails at execution), and with reencode=true
                video becomes H.264 - invalid in webm, rejected before billing -
                while audio is re-encoded to the container's default codec (no
                audio codec is pinned).
            reencode:
              type: boolean
              default: false
              description: >-
                false (default) stream-copies the split pass: near-instant and
                lossless, but the segment muxer cuts only on the input's
                existing keyframes, so cuts land on the keyframe at or after
                each computed time. true forces a keyframe at every computed cut
                for exact boundaries but re-encodes to H.264, which the webm
                container cannot hold (use mp4 or mkv, or keep copy for webm).
            crf:
              type: integer
              minimum: 0
              maximum: 51
              default: 23
              description: >-
                H.264 quality for reencode=true: 0 (best) to 51 (worst), default
                23. Ignored when reencode is false - stream copy does not
                re-encode.
          required:
            - max_segment_seconds
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_slideshow:
      description: >-
        Input envelope for the "slideshow" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: slideshow
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: slideshow
          description: >-
            Turn N still images into one SILENT video - no audio track is
            produced. With effect none each image is fitted onto the width x
            height canvas preserving its aspect ratio (letterboxed or
            pillarboxed with black); with effect kenburns each image is
            center-cropped to fill the canvas and slowly zoomed from 1.0x to
            1.5x. Encode quality is fixed (CRF 23) and cannot be tuned. An image
            that cannot be decoded is rejected before billing.
          type: object
          properties:
            images:
              type: integer
              minimum: 2
              maximum: 50
              default: 3
              description: Number of images; supply exactly this many input_urls.
            image_duration:
              type: number
              minimum: 0.5
              maximum: 30
              default: 3
              description: Seconds each image is shown.
            fps:
              type: integer
              minimum: 1
              maximum: 60
              default: 30
              description: >-
                Output frame rate: each image contributes about
                image_duration*fps frames, and with effect kenburns the zoom
                advances a fixed step per output frame, so a higher fps (or a
                longer image_duration) carries the zoom further toward its 1.5x
                cap.
            effect:
              type: string
              enum:
                - none
                - kenburns
              default: none
              description: >-
                Per-image treatment: none fits the image onto the canvas
                preserving its aspect ratio (black letterbox or pillarbox bars),
                kenburns center-crops it to fill the canvas and slowly zooms in
                on its center, so an aspect-mismatched image loses its edges.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container with a pinned video codec: mp4 (default) and
                mkv encode h264, webm encodes vp9; mp4 is written with
                +faststart so it progressive-plays.
            width:
              type: integer
              minimum: 16
              maximum: 8192
              default: 1280
              description: >-
                Canvas width in pixels - together with height it is the output
                resolution every image is normalized to.
            height:
              type: integer
              minimum: 16
              maximum: 8192
              default: 720
              description: >-
                Canvas height in pixels - together with width it is the output
                resolution every image is normalized to.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_speed:
      description: >-
        Input envelope for the "speed" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: speed
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: speed
          description: >-
            Change playback speed by retiming existing frames; no frame
            interpolation is performed. Slowing down keeps every source frame on
            screen longer (lower effective frame rate, which can look less
            smooth); speeding up plays every frame at a higher rate. Video and
            audio are always re-encoded (audio becomes AAC for mp4/mkv or Opus
            for webm); nothing is stream-copied.
          type: object
          properties:
            factor:
              type: number
              minimum: 0.25
              maximum: 4
              default: 2
              description: >-
                Playback speed multiplier; >1 faster, <1 slower. Audio is
                retimed with pitch preserved, and the output duration is the
                source duration divided by this factor. A video-only input still
                succeeds (the audio stage is skipped).
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: Output container.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_sticker_overlay:
      description: >-
        Input envelope for the "sticker_overlay" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly (this capability has required params) — required
        fields inside it are enforced at submit as invalid_command.
      properties:
        capability:
          const: sticker_overlay
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: sticker_overlay
          description: >-
            Composite the second input (input1, typically a still image: a
            sticker, logo, or watermark) over the base video (input0), visible
            only inside a timed window: from start until end, or until the end
            of the source when end is omitted. Placement uses the same anchors
            as overlay: a named corner/center position inset by margin. The
            sticker is composited at native size unless scale resizes it
            (bicubic, aspect preserved); there is no opacity control - the
            sticker's own alpha channel (e.g. a transparent PNG) is honored, and
            fully opaque pixels stay fully opaque. A sticker larger than the
            frame (natively or after scaling) is composited with the
            out-of-frame overflow cropped; the output always keeps the base's
            resolution and duration. An animated sticker plays on the base's
            timeline from t=0, not from start - the window only shows or hides
            it, so an animation shorter than start shows only its frozen last
            frame inside the window; one that ends earlier stays frozen on its
            last frame for the remainder, and one that runs longer has its extra
            tail dropped. A still image is unaffected. Only the base's audio is
            kept (a silent base still succeeds); the sticker input's audio is
            discarded. Both inputs must contain a video stream (a still image
            counts) - an input without one is rejected before billing. When the
            source can be probed, a start at or after the source duration and a
            supplied end past it are rejected before billing (never silently
            clamped - omit end to run to the source end); the checks compare
            against the source's video stream duration when it disagrees with
            the container duration; when it cannot be probed the window is
            range-checked only. Video and audio are always re-encoded (audio
            becomes AAC for mp4/mkv or Opus for webm); nothing is stream-copied.
            Runs on the cpu tier.
          type: object
          properties:
            start:
              type: number
              minimum: 0
              maximum: 3600
              description: >-
                Second of the base video the sticker appears (inclusive).
                REQUIRED. Must be less than end when end is supplied; when the
                source can be probed a start at or after the source duration is
                rejected before billing (the sticker would never appear).
            end:
              type: number
              minimum: 0
              maximum: 3600
              description: >-
                Second of the base video the sticker disappears. Omit to keep
                the sticker visible until the end of the source. Must be greater
                than start; when the source can be probed a value past the
                source duration is rejected before billing (never clamped).
            position:
              type: string
              enum:
                - top_left
                - top_right
                - bottom_left
                - bottom_right
                - center
              default: bottom_right
              description: >-
                Anchor for the sticker. Corners offset by margin; center ignores
                margin.
            margin:
              type: number
              minimum: 0
              maximum: 1024
              default: 0
              description: Inset in pixels from the anchored edge(s). Ignored for center.
            scale:
              type: number
              minimum: 0.05
              maximum: 4
              default: 1
              description: >-
                Factor to resize the sticker before compositing (bicubic, aspect
                preserved). The default 1 composites at native size with no
                resample pass.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container (default mp4): it fixes the pinned audio codec
                (AAC for mp4/mkv, Opus for webm) while video uses the
                container's cpu default encoder (H.264 for mp4/mkv, VP9 for
                webm), and mp4 output is written with the faststart flag so it
                progressive-plays.
          required:
            - start
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_stills:
      description: >-
        Input envelope for the "stills" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: stills
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: stills
          description: >-
            Extract exactly one frame from the clip as a jpg (default) or png
            image: position selects the first frame, the last frame, or the
            frame at an exact timestamp. The frame is always decoded and encoded
            to the chosen image format - nothing is stream-copied - and audio is
            discarded, since the output is a single image file. The only encode
            is the software mjpeg/png image encoder - no video-stream encoder is
            needed - so the capability runs on the cpu tier.
          type: object
          properties:
            position:
              type: string
              enum:
                - first
                - last
                - at
              default: first
              description: >-
                Which frame to extract. first = frame at t=0; last = the final
                frame; at REQUIRES timestamp and is frame-accurate - it decodes
                to the exact time (no keyframe snapping) and returns the first
                frame at or after the requested timestamp.
            timestamp:
              type: number
              minimum: 0
              maximum: 86400
              description: >-
                Seconds from start of the frame to extract. REQUIRED when
                position is at; validated whenever supplied, used only for at.
                Must be strictly inside the clip: a timestamp at or after the
                source's probed duration is rejected before billing (it would
                yield no frame); when the duration could not be probed the
                request is accepted and the run may fail.
            format:
              type: string
              enum:
                - jpg
                - png
              default: jpg
              description: >-
                Output image format: jpg (default) or png; the command pins no
                image encoder, so the file extension selects the codec, and the
                quality parameter applies only to jpg (png is lossless).
            quality:
              type: integer
              minimum: 2
              maximum: 31
              description: >-
                JPEG quality (2 = best, 31 = worst). Validated whenever
                supplied; applied only to jpg (png is lossless).
          if:
            required:
              - position
            properties:
              position:
                enum:
                  - at
          then:
            required:
              - timestamp
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_storyboard_sprites:
      description: >-
        Input envelope for the "storyboard_sprites" capability. The params
        schema below is the complete, canonical contract for this capability;
        send params explicitly ({} accepts every default) — required fields
        inside it are enforced at submit as invalid_command.
      properties:
        capability:
          const: storyboard_sprites
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: storyboard_sprites
          description: >-
            Sample one frame every interval_seconds and pack the frames into ONE
            tiled sheet image, delivered as two named outputs: sheet (the tiled
            jpg or png) and vtt (a WebVTT thumbnail index mapping each time
            window to its tile region of the sheet). When the source duration
            can be probed, the index covers only the sampled frames and its
            final cue ends exactly at the clip end; when it cannot be probed,
            the index covers the full columns x rows grid. Grid cells beyond the
            sampled frames are left blank in the sheet.
          type: object
          properties:
            interval_seconds:
              type: number
              minimum: 0.1
              default: 2
              description: >-
                Seconds between sampled thumbnails. Only one sheet is produced,
                so at most columns*rows thumbnails are kept: any part of the
                video past columns*rows*interval_seconds is silently omitted
                from both the sheet and the index. Choose interval_seconds so
                that duration/interval_seconds fits within columns*rows.
            tile_width:
              type: integer
              minimum: 16
              maximum: 8192
              default: 160
              description: >-
                Tile width in pixels. Each sampled frame is stretched to exactly
                tile_width x tile_height WITHOUT preserving its aspect ratio -
                pick a tile with the same aspect ratio as the source to avoid
                distortion.
            tile_height:
              type: integer
              minimum: 16
              maximum: 8192
              default: 90
              description: >-
                Tile height in pixels: each sampled frame is stretched to
                exactly tile_width x tile_height without preserving its aspect
                ratio (see tile_width), making the sheet rows*tile_height pixels
                tall.
            columns:
              type: integer
              minimum: 1
              maximum: 20
              default: 5
              description: >-
                Tile columns in the sheet, filled left to right before wrapping
                to the next row: the sheet is columns*tile_width pixels wide,
                and columns*rows caps how many thumbnails are kept (see
                interval_seconds).
            rows:
              type: integer
              minimum: 1
              maximum: 20
              default: 5
              description: >-
                Tile rows in the sheet: the sheet is rows*tile_height pixels
                tall, and columns*rows caps how many thumbnails are kept (see
                interval_seconds).
            format:
              type: string
              enum:
                - jpg
                - png
              default: jpg
              description: >-
                Image format of the sheet: jpg (default) or png; it names the
                sheet output sprites.jpg or sprites.png, and the vtt index cues
                reference the sheet by that filename.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_subtitle_compose:
      description: >-
        Input envelope for the "subtitle_compose" capability. The params schema
        below is the complete, canonical contract for this capability; send
        params explicitly (this capability has required params) — required
        fields inside it are enforced at submit as invalid_command.
      properties:
        capability:
          const: subtitle_compose
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: subtitle_compose
          description: >-
            Author animated word-timed captions from the transcript and burn
            them into the single input video (the whole video is re-encoded; the
            subtitle document is generated server-side, no subtitle file is
            supplied). Words must be listed in non-decreasing start_ms order
            with 0 <= start_ms <= end_ms for each - out-of-order or inverted
            spans are rejected before billing. Backslashes and curly braces are
            stripped from word and hook text; newlines and tabs become spaces.
            Runs on the cpu tier.
          type: object
          properties:
            words:
              type: array
              minItems: 1
              description: >-
                Normalized transcript tokens, in order; each is one word with an
                absolute ms span.
              items:
                type: object
                properties:
                  text:
                    type: string
                    description: Word text (whitespace-stripped).
                  start_ms:
                    type: integer
                    minimum: 0
                    maximum: 86400000
                    description: Absolute word start, milliseconds (24h cap).
                  end_ms:
                    type: integer
                    minimum: 0
                    maximum: 86400000
                    description: Absolute word end, milliseconds (>= start_ms, 24h cap).
                required:
                  - text
                  - start_ms
                  - end_ms
                additionalProperties: false
            hook:
              type: object
              description: Optional timed top-overlay line shown above the transcript.
              properties:
                text:
                  type: string
                start_ms:
                  type: integer
                  minimum: 0
                  maximum: 86400000
                end_ms:
                  type: integer
                  minimum: 0
                  maximum: 86400000
              required:
                - text
                - start_ms
                - end_ms
              additionalProperties: false
            style:
              type: object
              description: Concrete caption style (Ring resolves a named preset to this).
              properties:
                font:
                  type: string
                  enum:
                    - Liberation Sans
                    - Liberation Serif
                    - Liberation Mono
                    - DejaVu Sans
                    - DejaVu Serif
                    - DejaVu Sans Mono
                    - Anton
                    - Archivo Black
                    - Bangers
                    - Inter
                    - Montserrat
                    - Montserrat Black
                    - Poppins
                    - TikTok Sans
                    - TikTok Sans Medium
                    - TikTok Display
                    - TikTok Display Medium
                    - TikTok Text
                    - TikTok Text Medium
                    - Public Sans
                    - Public Sans Medium
                  default: Liberation Sans
                  description: >-
                    Caption font family; rendered from fonts bundled in the
                    runtime image.
                font_size_pct:
                  type: integer
                  minimum: 3
                  maximum: 15
                  default: 5
                  description: Caption font size as % of frame height.
                hook_font:
                  type: string
                  enum:
                    - Liberation Sans
                    - Liberation Serif
                    - Liberation Mono
                    - DejaVu Sans
                    - DejaVu Serif
                    - DejaVu Sans Mono
                    - Anton
                    - Archivo Black
                    - Bangers
                    - Inter
                    - Montserrat
                    - Montserrat Black
                    - Poppins
                    - TikTok Sans
                    - TikTok Sans Medium
                    - TikTok Display
                    - TikTok Display Medium
                    - TikTok Text
                    - TikTok Text Medium
                    - Public Sans
                    - Public Sans Medium
                  default: Liberation Sans
                hook_size_pct:
                  type: integer
                  minimum: 4
                  maximum: 16
                  default: 6
                text_color:
                  type: string
                  default: white
                  description: >-
                    Base word colour: a named palette colour (white, black,
                    yellow, gold, lime, green, cyan, blue, magenta, pink, red,
                    orange, purple) or #RRGGBB.
                active_color:
                  type: string
                  default: gold
                  description: 'Active/highlighted word colour (named or #RRGGBB).'
                hook_color:
                  type: string
                  default: yellow
                outline_color:
                  type: string
                  default: black
                outline_width:
                  type: integer
                  minimum: 0
                  maximum: 20
                  default: 7
                shadow_depth:
                  type: integer
                  minimum: 0
                  maximum: 10
                  default: 3
                margin_v_pct:
                  type: integer
                  minimum: 5
                  maximum: 40
                  default: 20
                  description: Caption distance from the frame bottom, % of height.
                animation:
                  type: string
                  enum:
                    - highlight
                    - fill
                  default: highlight
                  description: >-
                    highlight = active-word recolour in place; fill = native
                    karaoke colour sweep.
                hook_animation:
                  type: string
                  enum:
                    - pop
                    - fade
                    - none
                  default: pop
                  description: >-
                    Hook entrance: pop = fade + scale pop (a hook long enough to
                    wrap can re-wrap mid-animation); fade = fade-in only (never
                    re-wraps); none = the hook appears directly with no
                    animation.
                max_words:
                  type: integer
                  minimum: 1
                  maximum: 6
                  default: 4
                  description: Max words per caption page.
                combine_ms:
                  type: integer
                  minimum: 0
                  maximum: 2000
                  default: 450
                  description: >-
                    Break a page when the gap to the next word exceeds this many
                    ms.
                uppercase:
                  type: boolean
                  default: true
                  description: >-
                    Render all caption words AND the hook text in uppercase.
                    Defaults to true - set false to keep the original casing of
                    the supplied text.
              additionalProperties: false
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container: audio is always re-encoded to the container's
                native codec (AAC for mp4/mkv, Opus for webm - never copied),
                the burned video is re-encoded with the container's default
                encoder (H.264 for mp4/mkv, VP9 for webm - no explicit video
                codec is set), and mp4 output is written with faststart so
                playback can begin before the file fully downloads.
          required:
            - words
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_thumbnails:
      description: >-
        Input envelope for the "thumbnails" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: thumbnails
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: thumbnails
          description: >-
            Extract one frame every interval_seconds across the whole clip
            (first frame at t=0), producing about ceil(duration /
            interval_seconds) images named thumb_001, thumb_002, and so on,
            returned in time order as the output_urls array - every frame is
            uploaded (artifact upload is not billed in beta). Frames keep the
            full source resolution; there is no resize parameter. For small
            tiled previews use storyboard_sprites instead.
          type: object
          properties:
            interval_seconds:
              type: number
              minimum: 0.1
              default: 2
              description: >-
                Seconds between extracted frames; the output count scales as
                ceil(duration / interval_seconds), so a small interval on a long
                clip yields proportionally many uploaded images, and a value
                below the 0.1 minimum is rejected rather than clamped (there is
                no upper bound).
            format:
              type: string
              enum:
                - jpg
                - png
              default: jpg
              description: >-
                Image format of every extracted frame: jpg (default) or png,
                setting the extension the frames are encoded with and named by
                (thumb_001.jpg, thumb_002.jpg, and so on).
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_title_card:
      description: >-
        Input envelope for the "title_card" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly (this capability has required params) — required fields
        inside it are enforced at submit as invalid_command.
      properties:
        capability:
          const: title_card
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: title_card
          description: >-
            Draw a text title over the single input video with the drawtext
            filter. The text is staged as a server-generated text file and
            rendered with expansion disabled, so it is drawn verbatim: quotes,
            colons, backslashes, and ffmpeg %{...} expansion sequences have no
            effect on the command. Normalization before rendering: CRLF and CR
            become LF and newlines render as line breaks (multi-line titles are
            supported); tabs become single spaces; other control characters are
            removed; leading and trailing whitespace is trimmed. After
            normalization the text must be non-empty and at most 200 characters
            or the request is rejected before billing. Show window: omit start
            and end to show the title for the whole video; start alone shows it
            from start to the end of the video; end alone shows it from the
            beginning until end; when both are given, start must be less than
            end. When the source duration is probed, a start at or after it, or
            an end past it, is rejected before billing; when the duration is
            unknown the window is range-checked only. The input must contain a
            video stream or it is rejected before billing. Video and audio are
            always re-encoded (audio becomes AAC for mp4/mkv or Opus for webm);
            nothing is stream-copied. Runs on the cpu tier.
          type: object
          properties:
            text:
              type: string
              minLength: 1
              description: >-
                Title text; at most 200 characters after normalization. Newlines
                render as line breaks.
            font:
              type: string
              enum:
                - Liberation Sans
                - Liberation Serif
                - Liberation Mono
                - DejaVu Sans
                - DejaVu Serif
                - DejaVu Sans Mono
                - Anton
                - Archivo Black
                - Bangers
                - Inter
                - Montserrat
                - Montserrat Black
                - Poppins
                - TikTok Sans
                - TikTok Sans Medium
                - TikTok Display
                - TikTok Display Medium
                - TikTok Text
                - TikTok Text Medium
                - Public Sans
                - Public Sans Medium
              default: Liberation Sans
              description: >-
                Font family; rendered from the value's baked font file bundled
                in the runtime image, never a fontconfig fallback.
            font_size:
              type: integer
              minimum: 12
              maximum: 288
              default: 64
              description: Text size in pixels.
            font_color:
              type: string
              default: white
              description: >-
                Text color: a named color (black, white, gray, grey, red, green,
                blue, yellow) or #RRGGBB hex.
            position:
              type: string
              enum:
                - center
                - top
                - bottom
                - top_left
                - top_right
                - bottom_left
                - bottom_right
              default: center
              description: >-
                Anchor for the text block. Non-center anchors are inset from the
                frame edge by 5% of the frame dimension.
            start:
              type: number
              minimum: 0
              maximum: 86400
              description: >-
                Seconds when the title becomes visible. Omit (with end also
                omitted) to show the title for the whole video; supplied alone
                it shows the title from start to the end of the video. Must be
                less than end when both are given; a start at or after the
                probed source duration is rejected before billing (the title
                would never show).
            end:
              type: number
              exclusiveMinimum: 0
              maximum: 86400
              description: >-
                Seconds when the title stops being visible. Supplied alone it
                shows the title from the beginning until end. Must be greater
                than start when both are given; an end past the probed source
                duration is rejected before billing.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container (default mp4): audio is re-encoded to the
                container's native codec (AAC for mp4/mkv, Opus for webm), video
                uses the container's cpu default encoder (H.264 for mp4/mkv, VP9
                for webm), and mp4 output is written with faststart so it
                progressive-plays.
          required:
            - text
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_transcode:
      description: >-
        Input envelope for the "transcode" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: transcode
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: transcode
          description: >-
            Re-encode the source into the chosen container and codecs. Video and
            audio are ALWAYS re-encoded, never stream-copied - even when the
            source already matches the target codec.
          type: object
          properties:
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: >-
                Output container: mp4 and mkv accept every vcodec/acodec in the
                enums (vp9-in-mp4 included), webm pairs only with vcodec vp9 or
                av1 and acodec opus (any other pairing is rejected before
                billing), and mp4 output is written with faststart so playback
                can begin before the file fully downloads.
            vcodec:
              type: string
              enum:
                - h264
                - vp9
                - hevc
                - av1
              default: h264
              description: >-
                Video codec to re-encode to. h264 and hevc are invalid in webm
                (which carries only vp8/vp9/av1) — pair webm with vp9 or av1.
            acodec:
              type: string
              enum:
                - aac
                - opus
              description: >-
                Audio codec to re-encode to. Omitting it still RE-ENCODES audio
                - to the container's default codec - and never stream-copies the
                source audio. aac is invalid in webm (use opus).
            crf:
              type: integer
              minimum: 0
              maximum: 51
              default: 23
              description: >-
                Quality: 0 (best) to 51 (worst), default 23. Applied as -crf to
                the software encoders. With vcodec vp9 the value acts only as a
                quality cap constrained by the encoder's default bitrate, so vp9
                output is markedly lower quality than the same value in h264,
                hevc, or av1.
            pix_fmt:
              type: string
              enum:
                - yuv420p
                - yuv444p
              default: yuv420p
              description: Output pixel format.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_trim:
      description: >-
        Input envelope for the "trim" capability. The params schema below is the
        complete, canonical contract for this capability; send params explicitly
        ({} accepts every default) — required fields inside it are enforced at
        submit as invalid_command.
      properties:
        capability:
          const: trim
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: trim
          description: >-
            Cut a clip starting at start, keeping duration seconds, WITHOUT
            re-encoding (stream copy). Cut points snap to the input's existing
            keyframes: the output can begin up to one keyframe interval before
            the requested start and boundaries are not frame-exact; for
            frame-accurate cutting use silence_remove with a single keep range.
            Codecs are copied unchanged, so the job-level output_format (default
            mp4) must be a container that can hold the source codecs.
          type: object
          properties:
            start:
              type: number
              minimum: 0
              default: 0
              description: >-
                Seek position in seconds. When the source can be probed, a start
                at or after the source duration is rejected before billing
                (empty output); when it cannot be probed the job runs and may
                produce and bill a near-empty file.
            duration:
              type: number
              minimum: 0
              default: 5
              description: >-
                Length to keep in seconds, measured from start (not an end
                timestamp); default 5. A duration running past the end of the
                source keeps everything to the end without error. When the
                source can be probed, a kept window shorter than one video frame
                at the source frame rate is rejected before billing.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_volume:
      description: >-
        Input envelope for the "volume" capability. The params schema below is
        the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: volume
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: volume
          description: >-
            Scale audio loudness by a linear gain factor. The video stream is
            copied without re-encoding; the audio is re-encoded to AAC
            regardless of its source codec. The container is limited to mp4/mkv
            because a copied H.264 video stream cannot live in a webm container.
            An input with no audio stream is NOT rejected: the job succeeds,
            returns the video unchanged, and is billed as a normal job; verify
            the input carries audio before submitting.
          type: object
          properties:
            factor:
              type: number
              minimum: 0
              maximum: 10
              default: 2
              description: >-
                Linear gain: 0 mutes, 1 unchanged, 2 doubles. A factor above 1
                can clip audio that is already near full scale: samples are
                hard-limited at full scale with audible distortion and no
                automatic protection. For level-safe loudness changes use the
                loudnorm or audio_master capability.
            container:
              type: string
              enum:
                - mp4
                - mkv
              default: mp4
              description: >-
                Output container: mp4 output is written with faststart so
                playback can begin before the file fully downloads, mkv output
                is not; both carry the copied video stream with the audio
                re-encoded to AAC.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
    CapabilityInput_watermark:
      description: >-
        Input envelope for the "watermark" capability. The params schema below
        is the complete, canonical contract for this capability; send params
        explicitly ({} accepts every default) — required fields inside it are
        enforced at submit as invalid_command.
      properties:
        capability:
          const: watermark
          type: string
        input_url:
          description: >-
            One input media URL: a publicly downloadable https URL pointing
            directly at a media file identified by its path extension (video
            .mp4 .webm .mov .avi .mkv .flv; audio .mp3 .wav .ogg .flac .m4a .aac
            .opus .wma; image .png .jpg .jpeg .gif .webp .bmp .tiff; subtitle
            .vtt .srt .ass; color LUT .cube), an eachlabs CDN/storage URL
            (staged directly), or a raw s3:// URI the engine can read. A URL
            with no path extension may declare its type with a mime_type= query
            parameter, underscore-encoded — first '_' becomes '/', later '_'
            becomes '-' (mime_type=video_mp4 is video/mp4; any video/*, audio/*,
            or image/* type is accepted); the parameter cannot override an
            unrecognized extension. A URL that cannot be staged is rejected
            before billing at $0 with error_code PROVIDER_REJECTED. A capability
            that requires media submitted with no input_url/input_urls at all is
            rejected at submit (placeholder_unbound, $0).
          format: uri
          type: string
        input_urls:
          description: >-
            Ordered list of input media URLs for multi-input jobs; same staging
            rules as input_url. Capabilities consume them in order; run_ffmpeg
            binds one URL as {input} and N URLs as {input0}, {input1}, … in
            array order.
          items:
            format: uri
            type: string
          type: array
        mode:
          const: capability
          default: capability
          description: Optional for capability jobs; "capability" is the default mode.
          type: string
        params:
          $schema: https://json-schema.org/draft/2020-12/schema
          title: watermark
          description: >-
            Composite the second input (input1: an image or video) onto the base
            video (input0) at a fixed pixel offset from the base's top-left
            corner. The output keeps the base's resolution and duration: a
            still-image watermark persists for the whole clip, a video watermark
            that ends early freezes on its last frame, and one longer than the
            base is cut at the base's end. Both inputs must contain a video
            stream (a still image counts) - an audio-only input is rejected
            before billing. The output audio is chosen by ffmpeg's default
            selection across BOTH inputs: the audio stream with the most
            channels wins (ties go to the base), so a video watermark carrying
            more audio channels than the base replaces the base's audio - use a
            still image or a silent watermark to guarantee the base audio is
            kept. Video and audio are always re-encoded (audio becomes AAC for
            mp4/mkv or Opus for webm); nothing is stream-copied. To place a
            watermark by named corner instead of pixel offset, use overlay.
          type: object
          properties:
            x:
              type: integer
              minimum: 0
              default: 10
              description: >-
                Horizontal offset in pixels of the watermark's top-left corner
                from the base's left edge. There is no upper bound: an offset
                past the base frame pushes the watermark off-screen, and the run
                still succeeds and is billed with no visible watermark - keep
                offsets inside the base's dimensions.
            'y':
              type: integer
              minimum: 0
              default: 10
              description: >-
                Vertical offset in pixels of the watermark's top-left corner
                from the base's top edge. There is no upper bound: an offset
                past the base frame pushes the watermark off-screen, and the run
                still succeeds and is billed with no visible watermark - keep
                offsets inside the base's dimensions.
            container:
              type: string
              enum:
                - mp4
                - webm
                - mkv
              default: mp4
              description: Output container.
          additionalProperties: false
        tier:
          default: cpu
          description: >-
            Compute tier (pricing/hardware class). A tier outside this enum is
            rejected at submit before billing at $0.
          enum:
            - cpu
          type: string
      required:
        - capability
        - params
      type: object
  securitySchemes:
    BearerAuth:
      description: >-
        Your eachlabs API key (dashboard → API keys), sent as Authorization:
        Bearer <api_key> on every request. One key authenticates and bills every
        video operation.
      scheme: bearer
      type: http

````