Skip to content

Support OpenRouter's async video generation endpoints (/api/v1/videos job lifecycle) #261

Description

@tombeckenham

Context

TanStack AI just added an openRouterVideo adapter targeting OpenRouter's dedicated async video API (TanStack/ai#740, docs). aimock 1.29's video handler mocks the OpenAI-shaped /v1/videos resource (status/progress/url on the video object), but OpenRouter uses a different path prefix and a different job-lifecycle wire shape, so the adapter's E2E coverage currently has to stay unit-test-only (feature-support.ts exclusion).

What OpenRouter's API looks like (live-verified)

SubmitPOST /api/v1/videos (JSON):

{
  "model": "bytedance/seedance-2.0",
  "prompt": "",
  // optional:
  "duration": 8, "resolution": "720p", "aspect_ratio": "16:9", "size": "1280x720",
  "seed": 42, "generate_audio": true, "callback_url": "https://…",
  "frame_images": [{ "type": "image_url", "image_url": { "url": "" }, "frame_type": "first_frame" }],
  "input_references": [{ "type": "image_url", "image_url": { "url": "" } }],
  "provider": { "options": { "<slug>": { /* passthrough */ } } }
}

Response: { "id": "<jobId>", "polling_url": "…/api/v1/videos/<jobId>", "status": "pending" }

PollGET /api/v1/videos/{jobId}:

  • status: pending → in_progress → completed | failed (also cancelled, expired)
  • on completion adds "unsigned_urls": ["…/api/v1/videos/<jobId>/content?index=0"] and "usage": { "cost": 0.05 }
  • on failure adds "error": "<message>"

DownloadGET /api/v1/videos/{jobId}/content?index=0:

  • requires the Authorization: Bearer <key> header (401 without it)
  • serves the bytes with Content-Type: video/mp4

Model listGET /api/v1/videos/models (nice-to-have): { "data": [{ "id", "name", "supported_durations", "supported_resolutions", "supported_aspect_ratios", "supported_frame_images", "supported_sizes", "generate_audio", "seed", "pricing_skus" }] } — video models do not appear in the plain /api/v1/models listing.

Ask

Route POST /api/v1/videos + GET /api/v1/videos/{jobId} (+ /content) on the OpenRouter mock surface with the shape above — fixture matching on prompt/model like the existing OpenAI video handler, with the same staged status progression. That would let TanStack AI's video-gen / image-to-video matrix rows add openrouter and run the submit→poll→download lifecycle end-to-end against fixtures.

One client-behavior note: the @openrouter/sdk (Speakeasy-generated) sends Accept: application/octet-stream for the content download but the real endpoint replies video/mp4 — TanStack AI's adapter fetches the unsigned URL directly, so the mock should serve video/mp4 to match production.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions