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

# Reframe Video

> Change a video's aspect ratio without re-generating it (metered; long-running).

One video in, the same shot at a new framing out — the newly exposed edges
are painted in rather than cropped to. The input is never modified and the
result records it as its lineage parent. No prompt and no model choice: the
serving engine is a Moda-side table entry.

Like ``generate-video``, the provider render runs within this call (can take
minutes). The response's ``applied`` block reports the framing and
resolution actually rendered; ``adjustments`` lists any snap away from the
exact ask. Inputs whose estimate exceeds the per-reframe cost ceiling are
rejected before anything is paid for.



## OpenAPI

````yaml /openapi/moda-public-api.yaml post /media/reframe-video
openapi: 3.1.0
info:
  title: Moda Public API
  description: >
    Programmatic access to Moda's canvas design platform. Create designs, export
    assets, manage brand kits, and run AI design tasks.


    ## Versioning


    Pin response shapes with a calendar-dated `Moda-Version` header (e.g.
    `2026-05-01`). **The pin is global** — it applies to every endpoint in the
    request, not just the one you adopted it for, so raising it to use a new
    endpoint also moves your other responses to that version's shapes.


    ### Migrating `2026-04-12` → `2026-05-01`


    - **Tasks** move from the flat `JobResponse` (`job_id`, `canvas_url`,
    `can_export`) to the canonical `Task` envelope. The export artifact is now
    under `result.export` as `{url, format, page_count}`; update any code that
    read the export URL from the old top-level fields.

    - **Multi-page PNG/JPEG exports are delivered as a single `.zip`** of
    per-page files (`page-1.png`, …), so `result.export.format` is `zip`. For
    one bundled document instead, request `format=pdf` or `pptx`; for a single
    image, pass `page_number`.
  version: 1.0.0
  x-moda-api-version: '2026-05-01'
servers:
  - url: https://api.moda.app/v1
    description: Production
security: []
tags:
  - name: canvases
    description: List, search, read, export, and share canvases
  - name: tasks
    description: Start and monitor AI design tasks
  - name: organizations
    description: List organizations and teams
  - name: credits
    description: Check credit balance and usage
  - name: brand-kits
    description: Manage brand kits
  - name: remix
    description: Duplicate and edit canvases
  - name: share-links
    description: Resolve share URLs to canvas identifiers
  - name: uploads
    description: Upload files for use as attachments
  - name: usage
    description: Aggregate API usage stats for the caller's team
  - name: embed
    description: Signed iframe embed sessions
  - name: web
    description: 'Metered web research: search and page reading'
  - name: websites
    description: >-
      Create, update, publish, screenshot, and manage hosted multi-page static
      sites
  - name: drive
    description: >-
      Organize the workspace: folders, the folder tree, and item
      move/rename/visibility/delete for folders, canvases, and files
paths:
  /media/reframe-video:
    post:
      tags:
        - media
      summary: Reframe Video
      description: >-
        Change a video's aspect ratio without re-generating it (metered;
        long-running).


        One video in, the same shot at a new framing out — the newly exposed
        edges

        are painted in rather than cropped to. The input is never modified and
        the

        result records it as its lineage parent. No prompt and no model choice:
        the

        serving engine is a Moda-side table entry.


        Like ``generate-video``, the provider render runs within this call (can
        take

        minutes). The response's ``applied`` block reports the framing and

        resolution actually rendered; ``adjustments`` lists any snap away from
        the

        exact ask. Inputs whose estimate exceeds the per-reframe cost ceiling
        are

        rejected before anything is paid for.
      operationId: mediaReframeVideo
      parameters:
        - $ref: '#/components/parameters/ModaVersion'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReframeVideoRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                additionalProperties: true
                type: object
                title: Response Mediareframevideo
        '401':
          description: Authentication required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '402':
          description: Insufficient credits for a metered operation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '403':
          description: Permission denied for this scope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: Resource not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: Conflict (idempotency / resource state).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '422':
          description: Request validation failed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: Internal error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - API Key: []
components:
  parameters:
    ModaVersion:
      name: Moda-Version
      in: header
      required: false
      description: >-
        Calendar-dated API version pin. New integrations should pin `2026-05-01`
        to opt into the newest response shapes. For back-compat the server also
        accepts requests with no header and resolves them to the current default
        (today: `2026-04-12`); that default advances on each [sunset
        date](/api-reference/versioning). Any unsupported value returns 400
        `unsupported_version`.
      example: '2026-05-01'
      schema:
        type: string
        enum:
          - '2026-04-12'
          - '2026-05-01'
        default: '2026-05-01'
        example: '2026-05-01'
  schemas:
    ReframeVideoRequest:
      properties:
        video:
          type: string
          title: Video
          description: >-
            The video to reframe: a file_ id from an upload or an http(s) video
            URL.
        aspect_ratio:
          type: string
          title: Aspect Ratio
          description: >-
            The framing to deliver: one of 16:9, 5:4, 1:1, 4:5, 9:16. Required —
            it is the request.
        resolution:
          type: string
          title: Resolution
          description: One of 720p, 1080p. 720p costs half as much as 1080p.
          default: 1080p
        idempotency_key:
          anyOf:
            - type: string
              maxLength: 200
            - type: 'null'
          title: Idempotency Key
          description: >-
            Keys the provider-job checkpoint: a retried call with the same key
            resumes the existing reframe instead of paying for a duplicate.
      additionalProperties: false
      type: object
      required:
        - video
        - aspect_ratio
      title: ReframeVideoRequest
    ErrorEnvelope:
      properties:
        type:
          $ref: '#/components/schemas/ErrorType'
        code:
          type: string
          title: Code
          description: >-
            Stable machine string keyed to doc_url. Never changes once
            published.
        message:
          type: string
          title: Message
          description: >-
            Human-readable message, for developers. Not localized, not
            user-facing.
        doc_url:
          type: string
          title: Doc Url
          description: Permalink to the docs page for this code.
        request_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Request Id
          description: Correlator for logs/Sentry/audit.
        causes:
          anyOf:
            - items:
                $ref: '#/components/schemas/ErrorEnvelope'
              type: array
            - type: 'null'
          title: Causes
          description: Aggregated upstream failures (e.g. per-page export errors).
        details:
          anyOf:
            - additionalProperties: true
              type: object
            - type: 'null'
          title: Details
          description: >-
            Code-specific detail payload (e.g. validation field list). Callers
            should pass ``None`` rather than ``{}`` to omit the key from the
            response.
        retry_after_ms:
          anyOf:
            - type: integer
            - type: 'null'
          title: Retry After Ms
          description: Hint for rate-limited or transient errors.
        retryable:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Retryable
          description: >-
            Explicit retryability for this code, from the error-code registry:
            ``false`` means retrying the same request cannot succeed (fix the
            input / resource first); ``true`` means the condition is transient
            and a retry (with backoff / after the blocker clears) can succeed.
            Omitted for codes whose retryability is context-dependent — do not
            derive it from ``type`` or the HTTP status when this field is
            present.
      type: object
      required:
        - type
        - code
        - message
        - doc_url
      title: ErrorEnvelope
      description: >-
        Canonical error payload, nested under the top-level ``{"error": ...}``
        key.
    ErrorType:
      type: string
      enum:
        - invalid_request
        - authentication
        - permission
        - not_found
        - conflict
        - rate_limited
        - idempotency_conflict
        - unprocessable
        - upstream_error
        - internal_error
      title: ErrorType
      description: Closed set of high-level categories SDKs branch on.
  securitySchemes:
    API Key:
      type: http
      description: API key from Settings > Developer > REST API
      scheme: bearer

````