App-only tools

episode_render

Render an episode to a downloadable file

Renders a persisted episode (composition) into a downloadable MP4 — the materialize step after episode_create / episode_edit. Music authored by the development preview is refused before queueing or charging until music export ships. Otherwise this charges one export credit, queues the render asynchronously, and returns the render status. IDEMPOTENT: re-rendering an episode that is already rendered for its current revision (or already queued/rendering) is a NO-OP — it does NOT charge a second credit or re-queue (so a retry is safe). An episode that was edited since its last render (stale_media) renders again. After a "queued" status, episode_status with the same episode_id reports progress until "ready" and then returns separate playback and download capabilities. Optional title / aspect_ratio set them on this render. An Episode that uses an effect or look the released renderer can't draw yet, such as placed photos, is refused with effect_unavailable before anything is charged or queued; details.effects names each, and next_action either changes a look back to the plain fade or is retry_after_renderer_update.

Surface: App-only

Product release 185ad8f4adfa21ae055b5bd6f97968d9044480d1
Public contract commit d2ab41fab4088c07c0f6b924fa4f3c63481b936a
Public contract SHA-256 2365c73c2aef7b9f85e8434d8e29ea29f40824bc3a46a72a356155ea328757fc
Captured 2026-10-29T03:35:56.855Z. Review or improve this contract on GitHub.

These blocks show the complete MCP descriptors captured from serving Rails. Security schemes and resource URIs can differ by connected host.

App descriptor

{
  "name": "episode_render",
  "title": "Render an episode to a downloadable file",
  "description": "Renders a persisted episode (composition) into a downloadable MP4 — the materialize step after episode_create / episode_edit. Music authored by the development preview is refused before queueing or charging until music export ships. Otherwise this charges one export credit, queues the render asynchronously, and returns the render status. IDEMPOTENT: re-rendering an episode that is already rendered for its current revision (or already queued/rendering) is a NO-OP — it does NOT charge a second credit or re-queue (so a retry is safe). An episode that was edited since its last render (stale_media) renders again. After a \"queued\" status, episode_status with the same episode_id reports progress until \"ready\" and then returns separate playback and download capabilities. Optional title / aspect_ratio set them on this render. An Episode that uses an effect or look the released renderer can't draw yet, such as placed photos, is refused with effect_unavailable before anything is charged or queued; details.effects names each, and next_action either changes a look back to the plain fade or is retry_after_renderer_update.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "episode_id": {
        "type": "string",
        "description": "The episode (composition) public ID, such as comp_..., to render."
      },
      "title": {
        "type": "string",
        "description": "Optional title to set on this render."
      },
      "aspect_ratio": {
        "type": "string",
        "enum": [
          "9:16",
          "16:9",
          "1:1"
        ],
        "description": "Optional aspect ratio for this render."
      }
    },
    "required": [
      "episode_id"
    ],
    "additionalProperties": false
  },
  "annotations": {
    "title": "Render an episode to a downloadable file",
    "readOnlyHint": false,
    "destructiveHint": false,
    "idempotentHint": true,
    "openWorldHint": false
  },
  "securitySchemes": [
    {
      "type": "noauth"
    }
  ],
  "_meta": {
    "securitySchemes": [
      {
        "type": "noauth"
      }
    ],
    "ui": {
      "visibility": [
        "app"
      ]
    },
    "openai/widgetAccessible": true,
    "openai/visibility": "private"
  },
  "outputSchema": {
    "type": "object",
    "properties": {
      "episode_id": {
        "type": "string"
      },
      "composition_id": {
        "type": "string"
      },
      "title": {
        "type": "string"
      },
      "revision": {
        "type": "integer"
      },
      "render_plan_hash": {
        "type": "string",
        "pattern": "^[0-9a-f]{64}$"
      },
      "status": {
        "type": "string",
        "description": "Render lifecycle state: draft | queued | rendering | ready | failed."
      },
      "progress": {
        "type": "number",
        "description": "0.0–1.0 render progress."
      },
      "media": {
        "type": "object",
        "description": "The §7 media sub-status.",
        "properties": {
          "state": {
            "type": "string",
            "description": "ready (current playable media, including imported playback) | stale (the Composition changed) | missing (no settled playback)."
          },
          "rendered_revision": {
            "type": "string",
            "description": "Compatibility revision token for the current media."
          },
          "rendered_structural_revision": {
            "type": "integer",
            "description": "Exact Episode structural revision encoded into the current media."
          }
        }
      },
      "skipped": {
        "type": "boolean",
        "description": "true when the render was an idempotent no-op (already current or in flight) — no credit charged."
      },
      "render_id": {
        "type": [
          "string",
          "null"
        ]
      },
      "render_generation": {
        "type": [
          "string",
          "null"
        ]
      },
      "export_id": {
        "type": [
          "string",
          "null"
        ]
      },
      "download_available": {
        "type": "boolean"
      },
      "playback_url": {
        "type": [
          "string",
          "null"
        ]
      },
      "poster_url": {
        "type": [
          "string",
          "null"
        ]
      },
      "download_url": {
        "type": [
          "string",
          "null"
        ]
      },
      "expires_at": {
        "type": [
          "string",
          "null"
        ]
      },
      "poll": {
        "type": "object"
      },
      "blockers": {
        "type": "array",
        "items": {
          "type": "object"
        }
      },
      "dialogue_seam_review": {
        "type": "object",
        "description": "Exact-render, measurement-only evidence when this idempotent call reuses an already-current MP4."
      },
      "picture_program_render_receipt": {
        "type": "object",
        "description": "Bounded authoritative receipt when this idempotent call reuses an exact current MP4 with a simultaneous Picture Program."
      },
      "error": {
        "type": [
          "object",
          "null"
        ]
      },
      "render_error": {
        "type": [
          "object",
          "null"
        ],
        "description": "Last public render failure, retained while a retry is in flight."
      },
      "last_error": {
        "type": [
          "object",
          "null"
        ],
        "description": "Compatibility-explicit alias of render_error."
      },
      "render_error_history": {
        "type": "array",
        "items": {
          "type": "object"
        },
        "description": "At most the three most recent public render failures."
      },
      "render_request_id": {
        "type": [
          "string",
          "null"
        ],
        "pattern": "^rrq_[a-z0-9]+$",
        "description": "Exact admitted customer render request when known; it identifies this result for recovery after navigation or a newer revision."
      },
      "render_attempt": {
        "type": [
          "integer",
          "null"
        ]
      },
      "render_attempt_started_at": {
        "type": [
          "string",
          "null"
        ]
      },
      "next_action": {
        "type": "object",
        "description": "Next step kind (poll_until_ready / download / failed)."
      }
    },
    "required": [],
    "additionalProperties": false
  }
}

Errors

[
  "composition_not_found",
  "music_asset_missing",
  "music_asset_mismatch",
  "music_anchor_unavailable",
  "music_range_inverted",
  "music_ranges_overlap",
  "music_asset_too_short",
  "music_trim_out_of_range",
  "music_fades_too_long",
  "music_presentation_map_unsupported",
  "angle_interval_exceeds_recording",
  "effect_unavailable",
  "invalid_input",
  "billing_required"
]

Examples

[
  {
    "label": "Render an episode after editing it",
    "input": {
      "episode_id": "comp_..."
    }
  }
]