{"slug": "make-a-runway-clone-in-one-shot-or-something-else", "title": "Make a Runway Clone in one shot, or something else!", "summary": "Backboard.io co-founder Jon announced that video generation models are now live on the Backboard platform, including ByteDance's Seedance family served through OpenRouter alongside models like Veo 3.1, Wan 3.0, Kling 3.0, Hailuo 3 and Grok Imagine. The integration handles provider job APIs, polling and storage server-side so developers can generate video through the same add_message call used for text, with clips returned in generated_media and persisted in the conversation thread.", "body_md": "*i'm jon, i co-founded [backboard.io](https://backboard.io). this is a launch post. it's short and there's code.*\n\nvideo models are live on backboard.\n\nHere is a video of me and my dog rapping if you don't believe me.\n\nByteDance's Seedance family is in, served through OpenRouter, along with the rest of the OpenRouter video catalog.\n\nthat's the news. here's why you should care.\n\ntext you've figured out. images, mostly. video is where it gets ugly.\n\nevery provider has its own job api. submit. get an id. poll. poll again. time out. retry. download the file. store it somewhere. pass a url back to your agent. hope the agent remembers what it made two turns ago.\n\nthat's a whole service. for one feature. and it's different for every model.\n\nso we built it once. same way we did memory, rag, routing, voice and image.\n\n**ByteDance Seedance**\n\n`bytedance/seedance-2.5` (up to 30s, with audio)`bytedance/seedance-2.0`` bytedance/seedance-2.0-fast`\n`bytedance/seedance-2.0-mini`\n\n**the rest of the OpenRouter video catalog**\n\nVeo 3.1, Wan 3.0, Kling 3.0, Hailuo 3, Grok Imagine and more\n\n`client.list_video_models()` shows exactly what's live and what each model supports. `client.get_video_model(model_id)` gives you one model's limits.\n\nsix ways in:\n\ntext to video\n\nfirst frame to video (animate an image)\n\nfirst and last frame\n\nvideo to video (edit, extend, upscale)\n\nreferences (images, audio or video as a guide)\n\nmixed references\n\nit's the `add_message` call you already make. four extra keys.\n\n``` python\nimport asyncio\nimport os\nfrom backboard import BackboardClient\n\nsettings = {\n    \"llm_provider\": \"openai\",\n    \"model_name\": \"gpt-4.1\",\n    \"video_generation\": \"auto\",\n    \"video_model_provider\": \"openrouter\",\n    \"video_model_name\": \"bytedance/seedance-2.0-fast\",\n    \"video_config\": {\"duration\": 5, \"aspect_ratio\": \"16:9\", \"resolution\": \"720p\"},\n}\n\nasync def main():\n    client = BackboardClient(api_key=os.environ[\"BACKBOARD_API_KEY\"], timeout=1900)\n    assistant = await client.create_assistant(name=\"video assistant\")\n    thread = await client.create_thread(assistant.assistant_id)\n    thread_id = str(thread.thread_id)\n\n    result = await client.add_message(\n        thread_id,\n        content=\"a paper boat drifting down a rainy city gutter, golden hour\",\n        stream=False,\n        **settings,\n    )\n\n    for message in result.messages:\n        for media in message.get(\"generated_media\") or []:\n            print(media[\"document_id\"], media[\"url\"])\n\nasyncio.run(main())\n```\n\nno job queue. no polling loop. we poll for you, for up to 30 minutes, and hand back the clip.\n\nevery clip comes back in `generated_media` with a `document_id` and a url. it lives in the thread. next to the memory. next to everything else your agent already knows.\n\nwant to animate an image instead? add a file.\n\n```\nresult = await client.add_message(\n    thread_id,\n    content=\"slow push in, steam rising off the coffee\",\n    files=[\"start.png\"],\n    stream=False,\n    **settings,\n)\n```\n\ntwo files is first frame plus last frame. an `.mp4` is video to video.\n\nthe clip isn't a loose file. it's in the conversation. so the next turn can just be:\n\n```\nawait client.add_message(\n    thread_id,\n    content=\"same shot, but at night. neon reflections in the water.\",\n    stream=False,\n    **settings,\n)\n```\n\nno re-uploading. no passing urls around. the agent knows what it made, because it made it in the same thread.\n\n`video_generation=\"auto\"` hands your assistant a `generate_video` tool. it calls it when the ask needs a video. it won't render one because you said hi.`stream=True` and a long client timeout. we use 1900 seconds.`video_config` covers duration, resolution, aspect ratio, size, audio, seed, upscale and provider routing. only where the model supports it. check `get_video_model()` first.`operation=\"generate_video\"`. swap `bytedance/seedance-2.0-fast` for `google/veo-3.1-fast`. one string. nothing else moves.\n\nthat's the whole backboard thing. the model is a parameter. text, voice, image and now video, behind one key, with memory under all of it. so your agent doesn't forget what it just made.\n\nyou were going to write that polling loop this weekend. don't.\n\nget a key: [app.backboard.io](https://app.backboard.io)\n\nvideo docs: [docs.backboard.io/sdk/video-tool](https://docs.backboard.io/sdk/video-tool)", "url": "https://wpnews.pro/news/make-a-runway-clone-in-one-shot-or-something-else", "canonical_source": "https://dev.to/jon_at_backboardio/make-a-runway-clone-in-one-shot-or-something-else-5hdg", "published_at": "2026-09-17 17:20:20+00:00", "updated_at": "2026-09-17 17:23:04.783735+00:00", "lang": "en", "topics": ["ai-products", "generative-ai", "ai-tools", "developer-tools", "ai-agents"], "entities": ["Backboard.io", "Jon", "ByteDance", "Seedance", "OpenRouter", "Veo 3.1", "Kling 3.0", "Grok Imagine"], "alternates": {"html": "https://wpnews.pro/news/make-a-runway-clone-in-one-shot-or-something-else", "markdown": "https://wpnews.pro/news/make-a-runway-clone-in-one-shot-or-something-else.md", "text": "https://wpnews.pro/news/make-a-runway-clone-in-one-shot-or-something-else.txt", "jsonld": "https://wpnews.pro/news/make-a-runway-clone-in-one-shot-or-something-else.jsonld"}}