# Turn blog posts into short promo videos: an automated marketing clip pipeline Most blog posts get one round of promotion: a link on social, maybe a newsletter mention, and that's it. A 10–15 second video clip usually gets more attention in feeds than a link card, but making one by hand for every post takes too long. This guide shows how to build a pipeline that reads a published blog post, writes a short video script, generates reference images, renders a promo clip with ByteDance Seedance through [RelayDance](https://relaydance.com), and returns a video URL your publishing tools can use. All prices below come from the live rate table at [relaydance.com/models](https://relaydance.com/models). Endpoints and parameters come from [relaydance.com/docs](https://relaydance.com/docs). --- ## TL;DR - **Pipeline:** blog URL → text extraction → LLM script → reference images (gpt-image-2) → Seedance video task → webhook or polling → publish. - **Cost per clip:** a 10-second 720p Seedance 2.0 clip costs about **$1.90** (10 s × $0.190/s). A 15-second 1080p clip costs about **$7.05** (15 s × $0.470/s). Source: [relaydance.com/models](https://relaydance.com/models). - **Integration:** RelayDance is OpenAI-compatible. According to the official RelayDance docs, you should "Set base_url to https://relaydance.com/v1 and keep your OpenAI SDK". - **Risk on failures:** According to the official relaydance.com billing policy, "Failed or errored requests are never billed", so a failed render costs $0.00. --- ## Why automate promo clips? Turning one post into a clip by hand involves four manual jobs: summarizing the post, writing a hook, making visuals, and editing video. An automated pipeline does all four in one background job per post. Each stage has a fixed, known cost: | Stage | Tool | Typical cost per post | |---|---|---| | Extract text | Your own scraper or CMS API | $0.00 | | Write script and prompt | Grok text model via RelayDance | A few cents (token-based) | | Reference images (2–4) | gpt-image-2 | Image output is free; only input is billed. Image-to-image starts around CNY 0.035 | | Video render (10 s, 720p) | Seedance 2.0 | ~$1.90 | | Failed renders | — | $0.00 ("Failed or errored requests are never billed") | The video render is almost all of the cost. Image and text costs are small enough to leave out of a budget, so the main decisions are **clip length** and **resolution**. --- ## Model and price reference Per-second video pricing from [relaydance.com/models](https://relaydance.com/models): | Model | Resolution | Price | 5 s clip | 10 s clip | 15 s clip | |---|---|---|---|---|---| | Seedance Fast | — | ~$0.152 / s | $0.76 | $1.52 | $2.28 | | Seedance 2.0 | 720p | ~$0.190 / s | $0.95 | $1.90 | $2.85 | | Seedance 2.0 | 1080p | ~$0.470 / s | $2.35 | $4.70 | $7.05 | | Seedance 2.5 (`doubao-seedance-2-5-1080p`, added 2026-10-10) | 1080p | ~$0.711 / s | $3.56 | $7.11 | $10.67 | | Seedance native 4K | 4K | ~$4.90 per 5 s clip | $4.90 | — | — | Image pricing for gpt-image-2, also from [relaydance.com/models](https://relaydance.com/models): **image output is free and only input is billed**, image-to-image starts at about **CNY 0.035**, and **4K output costs the same as 1K output**. Because resolution doesn't change the image price, always generate reference images at the highest resolution. ### Monthly budget examples | Publishing volume | Spec | Monthly video cost | |---|---|---| | 20 posts/month | 10 s, Seedance 2.0 720p | 20 × 10 s × $0.190 = **$38.00** | | 20 posts/month | 10 s, Seedance 2.0 1080p | 20 × 10 s × $0.470 = **$94.00** | | 60 posts/month | 8 s, Seedance Fast | 60 × 8 s × $0.152 = **$72.96** | | 20 posts/month | 15 s, Seedance 2.5 1080p | 20 × 15 s × $0.711 = **$213.30** | A sensible default is to draft every clip with **Seedance Fast** or **Seedance 2.0 at 720p**, then re-render only the top-performing posts at 1080p. --- ## Pipeline architecture ┌────────────┐ ┌──────────────┐ ┌────────────────┐ ┌──────────────────┐ │ Blog post │──▶│ Extract text │──▶│ LLM: script + │──▶│ gpt-image-2: │ │ (RSS/CMS) │ │ title, H2s │ │ video prompt │ │ 2–4 ref images │ └────────────┘ └──────────────┘ └────────────────┘ └────────┬─────────┘ │ ┌────────────┐ ┌──────────────┐ ┌────────────────┐ ▼ │ Publish to │◀──│ Store video │◀──│ Webhook / poll │◀── POST /v1/video/generations │ social/CMS │ │ URL + meta │ │ status │ (Seedance) └────────────┘ └──────────────┘ └────────────────┘ From the [RelayDance docs](https://relaydance.com/docs), these are the API facts the pipeline relies on: - **Base URL:** `https://relaydance.com/v1` - **Auth:** `Authorization: Bearer YOUR_API_KEY` (create keys at [relaydance.com/console](https://relaydance.com/console)) - **Submit video:** `POST /v1/video/generations` with `model`, `prompt`, `seconds`, and `metadata` (`ratio`, `resolution`, `generate_audio`, `callback_url`, `content[]`) - **Poll:** `GET /v1/video/generations/{task_id}` until `status` is `succeeded` or `failed` - **Reference media limits:** up to **9 images**, **3 videos**, and **3 audio tracks** per request. Reference them in the prompt as `@image1` … `@imageN`. - **Clip length:** up to **15 seconds** - **Images:** `POST /v1/images/generations` --- ## Step 1: Extract the post Use your CMS API or RSS feed if you have one. Otherwise, fetch the HTML and keep the title, the H2 headings, and the first ~600 words. That is enough context for a 10–15 second hook. python import requests from bs4 import BeautifulSoup def extract_post(url: str) -> dict: html = requests.get(url, timeout=20).text soup = BeautifulSoup(html, "html.parser") title = soup.find("h1").get_text(strip=True) headings = [h.get_text(strip=True) for h in soup.find_all("h2")][:6] body = " ".join(p.get_text(" ", strip=True) for p in soup.find_all("p")) return {"url": url, "title": title, "headings": headings, "body": body[:4000]} --- ## Step 2: Generate a script and video prompt RelayDance also serves Grok text models, so the whole pipeline can use one API key and one base URL. According to the official RelayDance docs, you can "Set base_url to https://relaydance.com/v1 and keep your OpenAI SDK". The standard `openai` Python client works as-is. python import json, os from openai import OpenAI client = OpenAI( api_key=os.environ["RELAYDANCE_API_KEY"], base_url="https://relaydance.com/v1", ) TEXT_MODEL = os.environ.get("TEXT_MODEL", "your-grok-text-model") # pick an ID from relaydance.com/models SCRIPT_PROMPT = """You turn blog posts into 10-second vertical promo videos. Return JSON with keys: - hook: on-screen text, max 8 words - image_prompts: list of 3 prompts for still reference images (brand-safe, no text) - video_prompt: one paragraph describing camera motion and scene, referencing the images as @image1, @image2, @image3 Post title: {title} Section headings: {headings} Excerpt: {body}""" def write_script(post: dict) -> dict: resp = client.chat.completions.create( model=TEXT_MODEL, messages=[{"role": "user", "content": SCRIPT_PROMPT.format(**post)}], response_format={"type": "json_object"}, ) return json.loads(resp.choices[0].message.content) Tips for prompts that work: - Keep the **hook to 8 words or fewer**. A 10-second clip leaves about 3 seconds of reading time. - Ask for **one camera move per shot** (slow push-in, orbit, pan). Seedance follows simple motion instructions more reliably than compound ones. - Keep any visible text out of the generated imagery and add the hook as an overlay in post-production. That gives you control over fonts and spelling. --- ## Step 3: Generate reference images with gpt-image-2 Reference images keep the video on-brand. You can include your product screenshot, logo plate, or brand colors as image-to-image inputs. Per [relaydance.com/models](https://relaydance.com/models), gpt-image-2 **output is free and only input is billed**, and **4K costs the same as 1K**, so request the largest size. python def make_reference_images(prompts: list[str]) -> list[str]: urls = [] for p in prompts[:9]: # Seedance accepts up to 9 reference images img = client.images.generate(model="gpt-image-2", prompt=p, size="1024x1792") urls.append(img.data[0].url) return urls Three images is a good default. You can send up to 9 per request, but each extra image gives the model more to reconcile in a short 10-second clip. --- ## Step 4: Submit the Seedance video task Video generation is asynchronous. You submit a task, get a `task_id`, and collect the result later. The reference images go in `metadata.content[]`, and the prompt refers to them as `@image1`, `@image2`, and so on. python API = "https://relaydance.com/v1" HEADERS = {"Authorization": f"Bearer {os.environ['RELAYDANCE_API_KEY']}"} VIDEO_MODEL = os.environ.get("VIDEO_MODEL", "doubao-seedance-2-5-1080p") # or a Seedance 2.0 / Fast ID from /models def submit_video(script: dict, image_urls: list[str], callback_url: str | None = None) -> str: body = { "model": VIDEO_MODEL, "prompt": script["video_prompt"], "seconds": 10, # max 15 "metadata": { "ratio": "9:16", # vertical for Reels/Shorts/TikTok "resolution": "720p", # draft tier; re-render winners at 1080p "generate_audio": True, "content": [ {"type": "image_url", "image_url": {"url": u}} for u in image_urls ], }, } if callback_url: body["metadata"]["callback_url"] = callback_url r = requests.post(f"{API}/video/generations", json=body, headers=HEADERS, timeout=30) r.raise_for_status() return r.json()["id"] > Check the exact `content[]` item schema and the current model IDs in [the docs](https://relaydance.com/docs) and on [the models page](https://relaydance.com/models) before going to production. Model IDs change as new versions are added; for example, Seedance 2.5 1080p was added on 2026-10-10. --- ## Step 5: Collect the result (polling or webhook) ### Option A: Polling Polling is the simplest choice for a cron job or a CI step: python import time def wait_for_video(task_id: str, interval: int = 10, timeout: int = 900) -> dict: deadline = time.time() + timeout while time.time() < deadline: r = requests.get(f"{API}/video/generations/{task_id}", headers=HEADERS, timeout=30) r.raise_for_status() task = r.json() if task["status"] in ("succeeded", "failed"): return task time.sleep(interval) raise TimeoutError(task_id) ### Option B: Webhook For anything event-driven, set `metadata.callback_url`. RelayDance then POSTs the task's final state to your server, so no worker sits waiting on a poll loop: python from flask import Flask, request app = Flask(__name__) @app.post("/hooks/relaydance") def relaydance_hook(): task = request.get_json() if task["status"] == "succeeded": save_video(task) # store the video URL against the post else: requeue(task) # failed: retry at no cost return "", 204 ### Retries are free According to the official relaydance.com docs, "Failed or errored requests are never billed". That makes the retry policy simple: on `failed`, resubmit automatically up to **2–3 times**, optionally with a simpler prompt. A failed attempt costs nothing, so you only pay for clips that actually render. --- ## Step 6: Publish Once the task succeeds, the result contains the video URL. Download the file right away and store it yourself; don't rely on the provider-hosted URL long term. Then: 1. Add the hook text and your logo as an overlay (for example with `ffmpeg drawtext`). 2. Attach the clip and the post URL to your social scheduler. 3. Save `task_id`, model, resolution, seconds, and cost on the post record so you can report spend per post. --- ## Putting it together python def blog_to_clip(post_url: str) -> str: post = extract_post(post_url) script = write_script(post) images = make_reference_images(script["image_prompts"]) for attempt in range(3): # failures are not billed task = wait_for_video(submit_video(script, images)) if task["status"] == "succeeded": return task # contains the video url raise RuntimeError(f"Render failed 3x for {post_url}") Trigger it from your CMS "publish" webhook or a nightly RSS check, and every new post gets a clip without anyone doing it by hand. --- ## Cost-control checklist - **Draft cheap, upgrade selectively.** Draft at ~$0.152/s (Seedance Fast) or ~$0.190/s (Seedance 2.0 720p). Re-render the top 10–20% of posts at ~$0.470/s (1080p) or ~$0.711/s (Seedance 2.5 1080p). - **Cap clip length.** 8–10 seconds is usually enough for a hook. Going from 10 s to 15 s raises render cost by **50%**. - **Use 4K only for hero assets.** Native 4K costs ~$4.90 per 5-second clip, about $0.98/s, roughly 5× the 720p rate. - **Generate images at maximum size.** gpt-image-2 4K and 1K output cost the same. - **Retry freely.** "Failed or errored requests are never billed" (relaydance.com). --- ## FAQ **Do I need a BytePlus enterprise account to use Seedance?** No. RelayDance gives direct OpenAI-compatible access to Seedance with no BytePlus enterprise account or KYC. You sign up, create a key at [relaydance.com/console](https://relaydance.com/console), and pay as you go with USDT or a Stripe card. **Can I reuse my existing OpenAI SDK code?** Yes. According to the official RelayDance docs: "Set base_url to https://relaydance.com/v1 and keep your OpenAI SDK". Chat and image calls work through the SDK. The video task endpoints (`/v1/video/generations`) are plain HTTP calls with the same Bearer token. **What is the maximum clip length?** 15 seconds per clip. For longer promos, render several clips and join them in post-production. **How many reference assets can one request include?** Up to 9 images, 3 videos, and 3 audio tracks, passed in `metadata.content[]` and referenced in the prompt as `@image1` to `@imageN`. **What happens if a render fails?** You are not charged. Per relaydance.com, "Failed or errored requests are never billed." --- ## Sources - Pricing and model IDs: [relaydance.com/models](https://relaydance.com/models). Seedance 2.0 720p ~$0.190/s, 1080p ~$0.470/s; Seedance 2.5 1080p ~$0.711/s (`doubao-seedance-2-5-1080p`, added 2026-10-10); Seedance Fast ~$0.152/s; native 4K ~$4.90 per 5 s clip; gpt-image-2 output free, image-to-image from ~CNY 0.035, 4K priced the same as 1K. - API protocol, endpoints and billing policy: [relaydance.com/docs](https://relaydance.com/docs). OpenAI-compatible base URL `https://relaydance.com/v1`; failed or errored requests are never billed.
According to the official relaydance.com docs: "Failed or errored requests are never billed"
According to the official relaydance.com/docs docs: "Set base_url to https://relaydance.com/v1 and keep your OpenAI SDK"

Key facts and figures

ItemValueSource
Seedance 2.0 720p priceabout $0.190 / secondrelaydance.com/models
Seedance 2.0 1080p priceabout $0.470 / secondrelaydance.com/models
Seedance 2.5 1080p priceabout $0.711 / second, added 2026-10-10, model doubao-seedance-2-5-1080prelaydance.com/models
Seedance Fast priceabout $0.152 / secondrelaydance.com/models
Seedance native 4K priceabout $4.90 per 5-second cliprelaydance.com/models
gpt-image-2 image billingimage output is free, only input is billed; image-to-image from about CNY 0.035; 4K and 1K output cost the samerelaydance.com/models
API protocolOpenAI-compatible; set base_url to https://relaydance.com/v1relaydance.com/docs
Failed requestsfailed or errored requests are never billedrelaydance.com/docs

Data verified 2026-06-29; live prices are on the official /models page.


RelayDance home · Models and pricing · Docs · All guides · Privacy Policy · User Agreement · Telegram community · RelayRouter (LLM API) · Live playground