ffmpeg-micro-com Transcodes API

The Transcodes API from ffmpeg-micro-com — 4 operation(s) for transcodes.

Operations 5

POST /v1/transcodes Create a transcode or multi-video composition #
GET /v1/transcodes List transcodes (for the authenticated user) #
GET /v1/transcodes/{id} Get a transcode #
PATCH /v1/transcodes/{id}/cancel Cancel a transcode job #
GET /v1/transcodes/{id}/download Get a signed download URL for a completed transcode #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/ffmpeg-micro-com:ffmpeg-micro-com-transcodes-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

ffmpeg-micro-com-transcodes-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: FFmpeg Micro Transcodes API
  version: 1.0.0
  description: 'The FFmpeg Micro API runs FFmpeg for you. Upload a file or point at a URL,

    create a transcode or transcription job, poll it, and download the result

    from a signed URL.


    Getting started:


    1. Sign up at https://www.ffmpeg-micro.com and create an API key on the dashboard.

    2. Send the key on every request as `Authorization: Bearer `.

    3. Create a job with `POST /v1/transcodes` (or `POST /v1/transcribe`), poll

    `GET /v1/transcodes/{id}` until `status` is `completed`, then call

    `GET /v1/transcodes/{id}/download` for a signed download URL.


    Billing is metered per second of input duration. Free accounts start with a

    one-time token grant and no card.


    This file is the official contract. It is the same spec the API serves at

    https://api.ffmpeg-micro.com/openapi.yaml, and the public Postman

    workspace is generated from it.'
servers:
- url: https://api.ffmpeg-micro.com
  description: Production
tags:
- name: Transcodes
paths:
  /v1/transcodes:
    post:
      summary: Create a transcode or multi-video composition
      description: 'Queues a new transcode job with support for single or multiple inputs. Supports simple presets (quality/resolution) or advanced mode (raw FFmpeg options). Billing is based on total input duration (sum of all inputs). Returns a short acknowledgement with `status=pending`; poll `GET /v1/transcodes/{id}` for the full resource.

        Quota and plan limits (processing minutes, max input file size) are checked asynchronously after the 201: a job that exceeds them transitions to `failed` with an explanatory `error_message` and `error_category` (`quota` or `file_size`) instead of an HTTP error.'
      security:
      - bearerApiKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTranscodeRequest'
            examples:
              singleVideoPreset:
                summary: Single video with quality preset (simple mode)
                value:
                  inputs:
                  - url: https://cdn.pixabay.com/video/2021/05/22/74779-554220620_large.mp4
                  outputFormat: mp4
                  preset:
                    quality: high
                    resolution: 1080p
              multiVideoComposition:
                summary: Stitch multiple videos together
                value:
                  inputs:
                  - url: https://cdn.pixabay.com/video/2021/05/22/74779-554220620_large.mp4
                  - url: https://cdn.pixabay.com/video/2021/05/22/74779-554220620_large.mp4
                  - url: https://cdn.pixabay.com/video/2021/05/22/74779-554220620_large.mp4
                  outputFormat: mp4
                  preset:
                    quality: medium
              advancedOptions:
                summary: Advanced mode with raw FFmpeg options
                value:
                  inputs:
                  - url: https://cdn.pixabay.com/video/2021/05/22/74779-554220620_large.mp4
                  outputFormat: mp4
                  options:
                  - option: -c:v
                    argument: libx265
                  - option: -crf
                    argument: '28'
                  - option: -preset
                    argument: slow
              textOverlay:
                summary: Add text overlay with auto word-wrap
                value:
                  inputs:
                  - url: https://cdn.pixabay.com/video/2021/05/22/74779-554220620_large.mp4
                  outputFormat: mp4
                  options:
                  - option: '@text-overlay'
                    argument:
                      text: I dont know who needs to hear this but building features without talking to users is just guessing
                      style:
                        charsPerLine: 18
                        fontSize: 60
                        lineSpacing: 15
                        x: 0.15*w
                        y: (h-text_h)/2
                        boxBorderW: 12
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: object
                required:
                - id
                - status
                properties:
                  id:
                    type: string
                    format: uuid
                  status:
                    type: string
                    enum:
                    - pending
                    description: New jobs always start as `pending`
                  inputUrl:
                    type: string
                    description: First input URL (echo)
                  outputFormat:
                    type: string
                  downloadToken:
                    type: string
                    description: Token for anonymous "Try It" downloads
                  metadata:
                    type: object
                    description: Present only when the request carried `metadata`; echoed as `metadata.user`
                    properties:
                      user:
                        type: object
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/QuotaWall'
        '500':
          $ref: '#/components/responses/ServerError'
      tags:
      - Transcodes
      operationId: postV1Transcodes
      x-operation-id-source: derived
    get:
      summary: List transcodes (for the authenticated user)
      security:
      - bearerApiKey: []
      parameters:
      - in: query
        name: status
        schema:
          $ref: '#/components/schemas/TranscodeStatus'
        description: 'Filter by status. The value is not validated against the enum — an unknown value returns an empty result set, not an error.

          '
      - in: query
        name: page
        schema:
          type: integer
          minimum: 1
          default: 1
      - in: query
        name: limit
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 10
        description: Values outside 1-100 are clamped; non-numeric values return 400
      - in: query
        name: order
        schema:
          type: string
          enum:
          - created_at.desc
          - updated_at.asc
          - updated_at.desc
          default: created_at.desc
        description: 'Result ordering. Use `updated_at.asc` for cursor-based polling so the sort matches the `since` filter (both key on `updated_at`); paging forward with the default `created_at.desc` skips backlog items. Use `updated_at.desc` for a newest-first view on the same cursor column (for example, choosing where a poller starts). Unknown values return 400.

          '
      - in: query
        name: job_type
        schema:
          type: string
          enum:
          - transcode
          - transcribe
        description: 'Restrict to one job type. Without it this endpoint returns BOTH transcode and transcribe jobs (they share the resource shape).

          '
      - in: query
        name: since
        schema:
          type: string
          format: date-time
        description: 'Return transcodes last updated at/after this timestamp (filters on `updated_at`, not `created_at` — a job created earlier but completed inside the window is included). Invalid dates are rejected with 400.

          '
      - in: query
        name: until
        schema:
          type: string
          format: date-time
        description: Return transcodes last updated at/before this timestamp (filters on `updated_at`)
      responses:
        '200':
          description: OK (total count is in the body `total` field)
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/Transcode'
                  page:
                    type: integer
                  limit:
                    type: integer
                  total:
                    type: integer
        '400':
          description: Invalid page, limit, since, or until parameter
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
      tags:
      - Transcodes
      operationId: getV1Transcodes
      x-operation-id-source: derived
  /v1/transcodes/{id}:
    get:
      summary: Get a transcode
      security:
      - bearerApiKey: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transcode'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
      tags:
      - Transcodes
      operationId: getV1TranscodesById
      x-operation-id-source: derived
  /v1/transcodes/{id}/cancel:
    patch:
      summary: Cancel a transcode job
      description: Cancels a transcode job that is currently `pending` or `processing`. Completed, failed, or already-canceled jobs cannot be cancelled and return 400. If the job has been handed off to the toolkit service, a best-effort cancel is also sent to the toolkit — failures there are logged but do not fail this request.
      security:
      - bearerApiKey: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Job cancelled successfully
          content:
            application/json:
              schema:
                type: object
                required:
                - success
                - message
                - job
                properties:
                  success:
                    type: boolean
                    example: true
                  message:
                    type: string
                    example: Job cancelled successfully
                  job:
                    $ref: '#/components/schemas/Transcode'
        '400':
          description: Job is not in a cancellable state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: 'Cannot cancel job with status: completed'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'
      tags:
      - Transcodes
      operationId: patchV1TranscodesByIdCancel
      x-operation-id-source: derived
  /v1/transcodes/{id}/download:
    get:
      summary: Get a signed download URL for a completed transcode
      description: 'Returns a short-lived (10 minute) signed HTTPS URL for the completed output file.

        Because `output_url` on the transcode resource is a `gs://` URL that cannot be fetched directly by HTTP clients, use this endpoint to obtain a fetchable URL. The client is then responsible for downloading the file directly from the returned URL — the gateway does not proxy file bytes.

        The job must be in `completed` status and have a non-null `output_url`.'
      security:
      - bearerApiKey: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: Signed HTTPS URL valid for 10 minutes
          content:
            application/json:
              schema:
                type: object
                required:
                - url
                properties:
                  url:
                    type: string
                    format: uri
                    description: Signed HTTPS URL valid for 10 minutes
                    example: https://storage.googleapis.com/my-bucket/output.mp4?X-Goog-Algorithm=...
        '400':
          description: Transcode not completed or has no output
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                notCompleted:
                  value:
                    error: Transcode not completed
                noOutput:
                  value:
                    error: No output available for this transcode
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/ServerError'
      tags:
      - Transcodes
      operationId: getV1TranscodesByIdDownload
      x-operation-id-source: derived
components:
  responses:
    BadRequest:
      description: Invalid input
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    Unauthorized:
      description: Missing/invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              value:
                error: unauthorized
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ServerError:
      description: Unexpected error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    QuotaWall:
      description: 'The account is fully capped: zero plan minutes remaining AND a zero token balance, so no job of any size can run until the plan renews, the plan is upgraded, or tokens are topped up. Returned synchronously instead of a `201` — no processing is attempted. A job record IS still created (visible in job listings with `status: failed`), and its id is returned so the blocked attempt can be inspected. Automations should treat `402` as terminal for the billing period and STOP retrying: the same request will keep returning `402` until the account''s quota state changes. Partially-capped accounts (some minutes or tokens remaining) still return `201`, with any quota failure reported asynchronously on the job''s `status`/`error_message`.

        '
      content:
        application/json:
          schema:
            type: object
            required:
            - error
            - job_id
            - upgrade_url
            properties:
              error:
                type: string
                description: Human-readable refusal naming the remedy
              job_id:
                type: string
                format: uuid
                description: The failed job row recording this blocked attempt
              upgrade_url:
                type: string
                description: Deep link to billing, carrying `job=<job_id>`
          examples:
            example:
              value:
                error: 'Quota exceeded: Video Processing Minutes. Available: 0.00 minutes and your token balance is 0. Upgrade or top up tokens to continue: https://www.ffmpeg-micro.com/dashboard/billing?utm_source=usage-alert&utm_medium=api&utm_campaign=quota-api-block&utm_content=error-message&job=6a1f0c9e-6a56-4a1a-9d2f-0d5d0f7b1c2d'
                job_id: 6a1f0c9e-6a56-4a1a-9d2f-0d5d0f7b1c2d
                upgrade_url: https://www.ffmpeg-micro.com/dashboard/billing?utm_source=usage-alert&utm_medium=api&utm_campaign=quota-api-block&utm_content=error-message&job=6a1f0c9e-6a56-4a1a-9d2f-0d5d0f7b1c2d
  schemas:
    CreateTranscodeRequest:
      type: object
      required:
      - inputs
      - outputFormat
      properties:
        inputs:
          type: array
          description: Array of input videos (single for transcode, multiple for composition)
          minItems: 1
          maxItems: 10
          items:
            type: object
            required:
            - url
            properties:
              url:
                type: string
                description: 'GCS URL (gs://bucket/object) from presigned upload, or public HTTP(S) URL. Prefer gs:// to avoid egress charges.

                  '
                example: https://cdn.pixabay.com/video/2021/05/22/74779-554220620_large.mp4
        outputFormat:
          type: string
          enum:
          - mp4
          - webm
          - mov
          - avi
          - mp3
          - m4a
          - aac
          - wav
          - ogg
          - opus
          - flac
          - jpeg
          - jpg
          - png
          - gif
          - webp
          description: 'Output container format — video (mp4, webm, mov, avi), audio (mp3, m4a, aac, wav, ogg, opus, flac) or image (jpeg/jpg, png, gif, webp). Validation is case/alias-insensitive (`jpg` = `jpeg`), but the value is STORED VERBATIM and reads back exactly as submitted. webm output automatically uses VP9/Opus codecs in preset and default modes; you only need explicit `-c:v`/`-c:a` options when supplying raw options.

            '
        preset:
          type: object
          description: Simple mode - quality and resolution presets (ignored if options provided)
          properties:
            quality:
              type: string
              enum:
              - high
              - medium
              - low
              description: Maps to CRF values (high=18, medium=23, low=28)
            resolution:
              type: string
              enum:
              - 480p
              - 720p
              - 1080p
              - 4k
              description: Output resolution preset
        options:
          type: array
          description: 'Advanced mode - FFmpeg options or virtual options (overrides preset if both provided).

            **Virtual Options** (prefix with `@`): - `@text-overlay`: Add text overlay with auto word-wrap and styling

            **FFmpeg Options**: Only allowlisted flags accepted for security.

            '
          items:
            oneOf:
            - $ref: '#/components/schemas/VirtualOption'
            - $ref: '#/components/schemas/FFmpegOption'
        metadata:
          type: object
          additionalProperties: true
          description: 'Optional caller-supplied metadata for cross-referencing jobs with external systems (for example an original filename or a source record ID). Must be a JSON object; serialized size is capped at 8192 bytes. Stored under the `user` key of the job''s `metadata` field, so the submitted value is available at `metadata.user` when fetching or listing jobs, and is echoed as `metadata.user` in the create response.

            '
          example:
            original_filename: clip.mp4
            drive_file_id: 1a2b3c
    VirtualOption:
      type: object
      required:
      - option
      - argument
      properties:
        option:
          type: string
          enum:
          - '@text-overlay'
          description: Virtual option name (prefixed with @)
        argument:
          oneOf:
          - $ref: '#/components/schemas/TextOverlayConfig'
          description: Configuration object for the virtual option
    TranscodeStatus:
      type: string
      enum:
      - pending
      - processing
      - completed
      - failed
      - canceled
      description: 'Job lifecycle: `pending` (created, awaiting pickup) → `processing` → `completed` | `failed`; a user cancellation sets `canceled` (US spelling). Note there is no `queued` status — new jobs start as `pending`.

        '
    ErrorResponse:
      type: object
      required:
      - error
      properties:
        error:
          type: string
        details:
          type:
          - string
          - 'null'
    FFmpegOption:
      type: object
      required:
      - option
      - argument
      properties:
        option:
          type: string
          description: FFmpeg flag (e.g., -c:v, -crf, -preset)
          example: -c:v
        argument:
          type: string
          description: Flag value
          example: libx264
    TextOverlayConfig:
      type: object
      required:
      - text
      properties:
        text:
          type: string
          description: Text to display (use \n for manual line breaks, or use charsPerLine for auto word-wrap)
          example: 'Hello

            World'
          maxLength: 10000
        style:
          type: object
          properties:
            charsPerLine:
              type: integer
              description: 'Auto word-wrap at this character width (default: no wrap)'
              minimum: 5
              maximum: 100
              example: 18
            font:
              type: string
              description: 'Font name (default: Arial)'
              example: Arial
            fontSize:
              type: integer
              minimum: 12
              maximum: 200
              description: 'Font size in pixels (default: 48)'
              example: 60
            lineSpacing:
              type: integer
              description: 'Space between lines in pixels (default: 10)'
              minimum: 0
              maximum: 100
              example: 15
            fontColor:
              type: string
              description: 'Font color (default: white)'
              example: white
            x:
              type: string
              description: 'X position FFmpeg expression (default: (w-text_w)/2 for center)'
              example: 0.15*w
            y:
              type: string
              description: 'Y position FFmpeg expression (default: (h-text_h)/2 for center)'
              example: (h-text_h)/2
            boxBorderW:
              type: integer
              description: 'Box padding/border width in pixels (default: 20)'
              minimum: 0
              maximum: 100
              example: 12
    Transcode:
      type: object
      required:
      - id
      - status
      - output_format
      - created_at
      properties:
        id:
          type: string
          format: uuid
          example: b5f5a9c0-9e33-4e77-8a5b-6a0c2cd9c0b3
        status:
          $ref: '#/components/schemas/TranscodeStatus'
        inputs:
          type: array
          description: 'Array of processed input metadata, populated at enqueue from the media probe.

            '
          items:
            type: object
            properties:
              url:
                type: string
                description: GCS URL of the (possibly re-hosted) input
              filename:
                type: string
              duration:
                type: number
                description: Seconds; 0 for still images
              format:
                type: string
              size_bytes:
                description: 'File size in bytes, as a decimal string the way the media probe reports it (`"991017"`; `"0"` when the probe gave no size). Older jobs may carry an integer. Parse it as a number before doing arithmetic.

                  '
                oneOf:
                - type: integer
                - type: string
                  pattern: ^[0-9]+$
              downloadUrl:
                type: string
                description: Short-lived signed HTTPS URL for the input
              options:
                type: array
                items:
                  type: object
                description: Per-input FFmpeg options as submitted
        outputs:
          type: array
          description: Output file records, populated on completion
          items:
            type: object
            properties:
              url:
                type: string
                description: gs:// URL of the output file
              filename:
                type: string
              size_bytes:
                type: integer
              format:
                type: string
        output_format:
          type: string
          description: 'Output format as submitted — the value is stored verbatim, so a job created with `jpg` or `MP4` reads back exactly that way (validation is case/alias-insensitive; canonical values are mp4, webm, mov, avi, mp3, m4a, aac, wav, ogg, opus, flac, jpeg, png, gif, webp). Rows with `job_type: transcribe` carry `srt`.

            '
        job_type:
          type: string
          enum:
          - transcode
          - transcribe
          description: 'Discriminator — transcode and transcribe jobs share this resource shape and both appear in `GET /v1/transcodes` listings (there is no job_type filter). Transcribe rows additionally carry `media_url`.

            '
        billable_minutes:
          type: number
          description: 'Billable minutes, metered per second on input duration (a 19-second job bills 0.3167). Not an integer.

            '
          example: 2.25
        duration_seconds:
          type: number
          description: 'While the job is pending/processing: the billable input span (sum of input durations after trim options such as `-ss`/`-t`). Once completed: replaced by the measured duration of the OUTPUT file, which can differ from the input span (e.g. loops run longer). Billing always uses the input-side value.

            '
          example: 135.0
        processing_time_seconds:
          type:
          - number
          - 'null'
          description: Wall-clock processing time measured by the toolkit; null until completed
        queue_position:
          type:
          - integer
          - 'null'
          description: 'Jobs waiting in the job''s toolkit lane at acceptance, this one included: the accepting worker''s queue length right after this job was enqueued, so 1 means it was next in line. Set once at acceptance and never updated: a rough "how far back was I", not a live counter. Once `started_at` is set the job is no longer waiting, whatever this says. Null on jobs accepted before the field existed, or when the toolkit''s accept response carried no queue length.

            '
          example: 3
        lane:
          type:
          - string
          - 'null'
          enum:
          - short
          - long
          - heavy
          - null
          description: 'The processing lane the job runs in. Jobs with many large inputs (more than five 4K frames'' worth of pixels in total) go to `heavy`, a service with more memory. Otherwise, inputs longer than two minutes (by probed length or requested output span) go to `long`; everything else is `short`. Each lane is a separate service, so nothing in one can delay a job in another. Null on jobs accepted before lanes existed.

            '
        started_at:
          type:
          - string
          - 'null'
          format: date-time
          description: 'When the toolkit began executing the job. Set as soon as encoding starts, so null means the job is still waiting in its lane and non-null with status `processing` means it is encoding now. If that start signal was missed, it is filled from the completion or failure report. `started_at - created_at` is submission-to-start and includes the gateway''s own download and probe before dispatch, so it is an upper bound on queue wait, not the wait itself.

            '
        error_message:
          type:
          - string
          - 'null'
          description: 'Populated when status is `failed`, and also on user cancellation (`canceled` jobs carry "Job canceled by user") — do not treat non-null error_message alone as job failure.

            '
        error_category:
          type: string
          enum:
          - processing_limit
          - file_size
          - quota
          - upload
          - storage
          - validation
          - processing
          - transient
          - unknown
          description: 'Machine classification derived from error_message (generated column). Only meaningful when status is `failed`; jobs with no error carry `unknown`, never null. `processing_limit` is reserved for a job stopped at a per-job processing ceiling; no deployed release emits it yet (the ceiling ships separately).

            '
        completed_at:
          type:
          - string
          - 'null'
          format: date-time
          description: Set on successful completion only — failed jobs keep this null
        metadata:
          type: object
          description: 'Job metadata object. Caller-supplied metadata from the create request is echoed under `metadata.user` (JSON object, max 8 KB serialized). The object also carries internal keys written by the service (e.g. preset details, request origin, download token for the anonymous "Try It" flow) — treat keys other than `user` as opaque and unstable.

            '
          properties:
            user:
              type: object
        ffmpeg_options:
          type: object
          description: Final FFmpeg options used (audit trail)
          properties:
            source:
              type: string
              enum:
              - preset
              - raw_options
              - virtual_options
              - defaults
              description: 'How the options were derived. `raw_options`: the caller''s `options`, sanitized. `virtual_options`: the caller''s `options` included a virtual option (for example `@text-overlay`) that the gateway expanded. `preset`: a named preset. `defaults`: neither options nor a preset was given.

                '
            options:
              type: array
              description: The normalized option list handed to FFmpeg, in order.
              items:
                type: object
                required:
                - option
                properties:
                  option:
                    type: string
                    description: FFmpeg flag (e.g. `-c:v`, `-crf`, `-f`)
                    example: -c:v
                  argument:
                    oneOf:
                    - type: string
                    - type: number
                    description: 'Flag value. Omitted (never null) for flag-only options (`-an`, `-vn`, `-shortest`) and whenever the caller sent null, so a bare flag serializes without one.

                      '
                    example: libx264
            preset:
              type:
              - object
              - 'null'
        output_url:
          type:
          - string
          - 'null'
          description: Populated when status = completed
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        user_id:
          type: string
          description: Internal user identifier resolved from API key
        input_url:
          type: string
          deprecated: true
          description: '[DEPRECATED] Use inputs array instead'
  securitySchemes:
    bearerApiKey:
      type: http
      scheme: bearer
      bearerFormat: opaque-api-key
externalDocs:
  description: Guides and examples
  url: https://www.ffmpeg-micro.com/docs