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

# Read a render

> Read a render by id.



## OpenAPI

````yaml https://roughy-api-staging.fly.dev/v1/openapi.json get /v1/renders/{render_id}
openapi: 3.1.0
info:
  title: Roughy Public API
  version: 0.0.0
servers:
  - url: https://roughy-api-staging.fly.dev
    description: Staging
security: []
tags:
  - name: Projects
    description: >-
      Workflow containers. Every asset lives inside a project; a project groups
      everything for one piece of work (an episode, an interview, a talk).
  - name: Assets
    description: >-
      The unit of media. `POST /assets` creates one and opens its upload in a
      single call: the response body is the asset (its `upload_url` carries the
      transfer URL while `pending_upload`), and the TUS transfer URL also comes
      back in the `Location` header. List, detail (with signed download URL),
      and delete round it out. Each asset belongs to exactly one project;
      `language` is set at create and immutable.
  - name: Uploads
    description: >-
      Drive the TUS-resumable transfer that streams an asset's bytes. `POST
      /assets` opens the upload; `PATCH`/`HEAD` move and resume the bytes,
      `DELETE` cancels (removing the asset). Lost the transfer URL? Re-`GET` the
      asset — while it's `pending_upload`, `upload_url` carries it.
  - name: Cuts
    description: >-
      A kept-segment plan for an asset, computed automatically by Roughy. Create
      one with `POST /cuts {asset_id, script?}`, list with `GET /cuts`, read a
      cut, export it to NLE formats, and export its generated subtitle (SRT /
      VTT).
  - name: Renders
    description: >-
      Renders an asset to a video (`mp4`/`mov`) or audio (`m4a`/`mp3`) output,
      optionally applying a `cut_id`. `POST /renders {asset_id, cut_id?,
      output}` creates one; list, read (with a signed download URL), and cancel
      as a top-level `/renders` resource.
  - name: Webhooks
    description: >-
      Register endpoints to receive signed terminal-state events (cut / render /
      asset) instead of polling.
  - name: Credits
    description: Credit balance and usage history.
  - name: Users
    description: Your account and profile.
  - name: OAuth
    description: >-
      Device authorization grant (RFC 8628), served at app.roughy.ai/oauth/* for
      the editor plugin. Internal surface — not part of the public /v1 SDK.
  - name: billing
    description: Stripe customer portal, invoices, subscriptions.
  - name: api-keys
    description: Mint and revoke API keys.
  - name: auth
    description: Sign up, log in, log out, and OAuth flows for the dashboard.
  - name: webhooks
    description: Inbound provider webhooks (Stripe, Resend, ElevenLabs).
  - name: email-preferences
    description: Per-category transactional-email opt-out preferences.
  - name: sse
    description: Server-sent live updates per asset.
  - name: health
    description: Liveness and readiness probes.
paths:
  /v1/renders/{render_id}:
    get:
      tags:
        - Renders
      summary: Read a render
      description: Read a render by id.
      operationId: get_render_v1_renders__render_id__get
      parameters:
        - name: render_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
            description: Identifier of the render.
            title: Render Id
          description: Identifier of the render.
      responses:
        '200':
          description: The render plus a short-lived signed `download_url`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RenderDetailResponse'
        '404':
          description: Not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: not_found
                  message: Not found.
      security:
        - HTTPBearer: []
components:
  schemas:
    RenderDetailResponse:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: Render id.
        asset_id:
          type: string
          format: uuid
          title: Asset Id
          description: The source asset this render was produced from.
        cut_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Cut Id
          description: The cut applied to this render, or null for a full-source render.
        state:
          $ref: '#/components/schemas/RenderState'
          description: >-
            Render lifecycle state: `pending` / `processing` while the render
            encodes, `completed` when ready, `failed` on error. `completed` and
            `failed` are terminal.
        output:
          $ref: '#/components/schemas/RenderOutput'
          description: The output spec this render was produced with.
        size_bytes:
          anyOf:
            - type: integer
            - type: 'null'
          title: Size Bytes
          description: Output size in bytes.
        error_code:
          anyOf:
            - type: string
            - type: 'null'
          title: Error Code
          description: Machine-readable failure code when `state=failed`.
        error_message:
          anyOf:
            - type: string
            - type: 'null'
          title: Error Message
          description: Human-readable failure detail when `state=failed`.
        created_at:
          type: string
          format: date-time
          title: Created At
          description: When the render was created.
        started_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Started At
          description: When encoding started.
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Completed At
          description: When the render reached a terminal state.
        download_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Download Url
          description: >-
            Short-lived signed URL for the rendered bytes; `null` until the
            render is `completed`. Re-fetch the render rather than caching the
            URL.
      type: object
      required:
        - id
        - asset_id
        - cut_id
        - state
        - output
        - size_bytes
        - error_code
        - error_message
        - created_at
        - started_at
        - completed_at
      title: RenderDetailResponse
      description: A render with a short-lived signed download URL.
    ErrorResponse:
      properties:
        error:
          $ref: '#/components/schemas/ErrorBody'
      type: object
      required:
        - error
      title: ErrorResponse
      description: |-
        The shape every error response returns.

        Request-correlation lives in the `X-Request-Id` response
        header — include that header value in a support ticket to
        correlate with server-side logs.
      example:
        error:
          code: validation_error
          fields:
            - field: body.name
              message: Field required
          message: Upload-Length must be at least 64 bytes.
    RenderState:
      type: string
      enum:
        - pending
        - processing
        - completed
        - failed
      title: RenderState
    RenderOutput:
      properties:
        format:
          $ref: '#/components/schemas/RenderFormat'
          description: 'Output format: video `mp4`/`mov` or audio `m4a`/`mp3`.'
        resolution:
          anyOf:
            - $ref: '#/components/schemas/RenderResolution'
            - type: 'null'
          description: >-
            Video resolution tier, aspect-preserving on the shorter edge and
            capped to the source: `720p`, `1080p`, or `4k`. Omit for the source
            resolution. Video formats only — rejected with `validation_error` on
            an audio format.
        video_bitrate:
          anyOf:
            - type: integer
              enum:
                - 5
                - 10
                - 20
                - 50
            - type: 'null'
          title: Video Bitrate
          description: >-
            Video bitrate in Mbps: `5`, `10`, `20`, or `50`. Omit for Auto (the
            tier default). Capped to the source bitrate. Video formats only.
        frame_rate:
          anyOf:
            - type: number
              maximum: 240
              exclusiveMinimum: 0
            - type: 'null'
          title: Frame Rate
          description: >-
            Output frame rate in fps, e.g. `25`, `29.97`, `23.976`. Omit to
            inherit the source frame rate. A rate above the source duplicates
            frames (constant-frame-rate up-conversion — a valid file, no
            smoother motion); below it drops frames. Video formats only —
            rejected with `validation_error` on an audio format.
        audio_bitrate:
          anyOf:
            - type: integer
              enum:
                - 128
                - 192
                - 256
                - 320
            - type: 'null'
          title: Audio Bitrate
          description: 'Audio bitrate in kbps: `128`, `192`, `256`, or `320`. Omit for Auto.'
      additionalProperties: false
      type: object
      required:
        - format
      title: RenderOutput
      description: >-
        The desired output spec.


        `format` picks the container + stack: `mp4`/`mov` are video, `m4a`/`mp3`

        are audio-only. The video-only knobs (`resolution`, `video_bitrate`,

        `frame_rate`) are rejected on an audio format. Every field is part of
        the

        dedup key — an identical `output` for the same `(asset, cut)` returns
        the

        existing render.
    ErrorBody:
      properties:
        code:
          $ref: '#/components/schemas/ErrorCode'
          description: >-
            Stable enum classifier. Clients should switch on this to drive retry
            / display logic; `message` is for humans.
        message:
          type: string
          title: Message
          description: >-
            One-line human-readable description of the failure. Safe to show end
            users; never carries backend internals.
        fields:
          anyOf:
            - items:
                $ref: '#/components/schemas/ErrorFieldDetail'
              type: array
            - type: 'null'
          title: Fields
          description: >-
            Per-field validation errors, set only for `code: validation_error`
            responses. Omitted in every other case.
      type: object
      required:
        - code
        - message
      title: ErrorBody
      description: Inner `error` object — the body of `ErrorResponse.error`.
    RenderFormat:
      type: string
      enum:
        - mp4
        - mov
        - m4a
        - mp3
      title: RenderFormat
      description: |-
        Render output format/container. `mp4`/`mov` are video (h264+aac, same
        stack, different container); `m4a`/`mp3` are audio-only outputs.
    RenderResolution:
      type: string
      enum:
        - 720p
        - 1080p
        - 4k
      title: RenderResolution
      description: |-
        Aspect-preserving resolution tier — targets the shorter edge and scales
        the source to it without padding, capped to the source. `hd` = 720,
        `fhd` = 1080, `uhd` = 2160 (4K) on the shorter edge.
    ErrorCode:
      type: string
      enum:
        - bad_request
        - unauthenticated
        - forbidden
        - not_found
        - conflict
        - gone
        - precondition_failed
        - payload_too_large
        - unsupported_media_type
        - validation_error
        - account_locked
        - rate_limited
        - insufficient_credits
        - internal_error
        - upstream_error
        - upstream_unavailable
        - asset_processing
        - asset_payment_required
        - asset_failed
        - asset_not_ready
        - modifier_not_ready
        - unsupported_format
        - frame_rate_required
        - cut_not_proposed
      title: ErrorCode
      description: |-
        Stable, client-facing error-classifier enum.

        New entries require an ADR amendment so SDK consumers can rely
        on the list being closed. Numeric HTTP status code stays in the
        response status line — `code` is the orthogonal *category*
        clients switch on without parsing the message.
    ErrorFieldDetail:
      properties:
        field:
          type: string
          title: Field
          description: >-
            Dotted path to the offending field, rooted at the request location
            (e.g. `body.name`, `query.limit`, `path.project_id`).
        message:
          type: string
          title: Message
          description: Human-readable explanation for this field.
      type: object
      required:
        - field
        - message
      title: ErrorFieldDetail
      description: Per-field validation failure on a single request field.
  securitySchemes:
    HTTPBearer:
      type: http
      description: >-
        Pass your API key as `Authorization: Bearer sk_…`. Mint a key from your
        dashboard's API-keys page.
      scheme: bearer
      bearerFormat: sk_…

````