DEV Community

Cover image for Raindance AI: Clip-Length Pickers, Head-Swap vs Whole-Person, and Seedance via TryAllAPI
Raindance Lab
Raindance Lab

Posted on Originally published at raindanceai.app

Raindance AI: Clip-Length Pickers, Head-Swap vs Whole-Person, and Seedance via TryAllAPI

How I shipped a timeline-aware Raindance remake product on Cloudflare Workers — where duration knobs drive Seedance costs through TryAllAPI.

raindanceai.app is not “upload and hope.” Users pick solo (1 photo) or duet (2 photos), choose Head swap or Whole person, then select a 3–10s moment from the trend clip (including quick Part 1 / 2 / 3 for a full ~30s stitch later in CapCut). Output is an MP4 ready for Shorts/Reels.

This post focuses on the API + duration economics side: why an aggregator, which Seedance knobs matter, and how pricing from $5.99 maps to credits. Prices and model ids change; treat live site / console as source of truth.

Raindance AI hero — solo/duet and clip picker

Product shape that drives the API design

Unlike one-shot 15s party templates, Raindance exposes length:

  • Clip length controls: 3s through 10s.
  • Quick parts: 0:00–0:10, 0:10–0:20, 0:20–0:30.
  • Mode: head swap vs whole person (different reference usage).
  • Solo vs duet changes photo count and composition.

That means the Worker must pass explicit duration every time. Omitting duration and letting the model “pick a smart length” is how bills drift — and how a $5.99 entry pack silently loses money.

Desktop screenshot of the Raindance create / timeline UI

Live pricing seen on the homepage while writing: packs from $5.99, with other tiers such as $9.99 one-video credit messaging and multi-packs ($23.99 / $14.99 / $36.99 variants appear in copy). No subscription required for the core path. Re-check the create CTA before you quote a friend.

Stack overview

Layer Choice Role
Front / SSR TanStack Start (Vite) Landing, upload panel, generation status
Runtime Cloudflare Workers Edge deploy, secrets, API routes
DB Cloudflare D1 Credits, orders, task rows (table prefixes if DBs are shared)
Payments Stripe Checkout One-time packs + optional larger packs; guest checkout
Video upstream TryAllAPI → Seedance Async create + poll
Analytics GA Funnel sanity check
solo/duet photos + length + mode
→ locked Raindance template prompt
→ check credits (else Stripe)
→ Worker creates Seedance task via TryAllAPI
→ poll until MP4 URL → store / show
→ on failure: refund credits
Enter fullscreen mode Exit fullscreen mode

Raindance scene / sample still used in marketing

Demo clips / scene stills are self-hosted with the product. Do not scrape other CDNs for marketing.

Why TryAllAPI instead of five vendor SDKs

Direct vendor onboarding for every video model means accounts, KYC, docs drift, and different async status machines. For a small indie product I wanted one API key in Workers Secrets, USD balance billed by usage, and a path to Seedance without rewriting the client each time the console UI changes.

That is what TryAllAPI is for on this project.

Operational checklist after register / top-up:

  1. Confirm available USD balance in the console (not only the checkout success page).
  2. Create a token in pay-as-you-go style billing.
  3. Enable the video / Seedance-related channel group on that token. Wrong group → “no available channel” even when the model id looks right.
  4. Prefer separate keys per product (raindance-prod vs sandbox).
  5. Put the key only in Workers Secrets (for example TRYALLAPI_API_KEY). Never in the frontend bundle or a blog post.

Conceptually the call shape looks like this (field names follow the aggregator’s v3 contents API; always re-check current docs):

POST /api/v3/contents/generations/tasks
Authorization: Bearer <TRYALLAPI_API_KEY>
Content-Type: application/json
Accept-Encoding: identity

GET /api/v3/contents/generations/tasks/{id}
Enter fullscreen mode Exit fullscreen mode

I send Accept-Encoding: identity from the Worker because some gateways behave badly with transparent decompression. Model ids used in production look like Seedance 2.x family strings — treat console ids as source of truth, not this paragraph.

Seedance parameters this product forces you to get right

A few details that bit me across this family of sites:

  • Pass duration as an explicit integer. Some models default to “smart length.” Omitting duration can silently lengthen the clip and the bill.
  • resolution and ratio. Cost tracks resolution tier and duration more than portrait vs landscape. Match whatever the create UI offers (often 480p/720p and 9:16 for Shorts).
  • generate_audio. When the product ships “finished” downloads, leave audio on; creators who want a trending sound can mute later.
  • Status machine. Expect something like queued → running → succeeded / failed. Success URLs are often short-lived signed links — download/rehost on your side before handing the file to the user.
  • Decent failure. On supply_unavailable or hard failures: refund credits, show a short human message, log the detailed upstream error server-side, optionally fall back to another Seedance tier.

Rough mental model for upstream cost (illustrative only — use your own usage fields and invoices):

tokens ≈ duration_sec × width × height × fps / 1024
cost   ≈ tokens × price_per_million_tokens
Enter fullscreen mode Exit fullscreen mode

Price the site after you measure a few real runs with retry margin, Stripe fees, and failed-job refunds — not from a spreadsheet fantasy of 0% failure.

Raindance-specific:

  • Duration must match the picker (3–10). Longer parts ⇒ higher upstream cost.
  • Reference image count — solo 1 / duet 2; head-swap vs whole-person changes how you describe the edit in the locked template prompt.
  • Source trend framing may lean 16:9 in places; still offer vertical exports where the UI says so.

Credits, Stripe, and short-clip math

Demo UIs are easy. The line between toy and product is:

  1. User hits Create → check credit balance.
  2. If short → Stripe Checkout Session (guest allowed).
  3. Webhook (plus a return-URL sync check) grants credits.
  4. Pre-debit / lock credits, create upstream task, persist task_id in D1.
  5. Poll until done; succeed → show MP4; fail → refund credits.

Two books of account stay separate: USD balance at TryAllAPI (your cost) vs site credits (what you sold). Mixing them in one mental ledger is how you underprice or invent “mysterious” losses.

When several products share one Stripe account, isolate webhooks by endpoint or by metadata (site / product). Callbacks pointed at the wrong apex domain are a classic multi-site footgun.

Secrets stay in Workers: TRYALLAPI_API_KEY, STRIPE_SECRET_KEY, webhook secret, auth secrets. The browser only ever sees publishable Stripe keys if needed.

Raindance’s lower entry (from $5.99) only works if short clips dominate, duration is explicit, and failure refunds are automatic. Measure COGS on 3s vs 10s before locking pack prices.

Deploy notes (Workers + D1)

Typical loop on this template family:

pnpm install
# wire D1 database_id, production env, custom domain in wrangler
pnpm cf:deploy
Enter fullscreen mode Exit fullscreen mode

Before calling a deploy “done”:

  • D1 binding is correct; shared DBs use table prefixes, not a new database per micro-idea (free-tier DB counts are limited).
  • AUTH_TRUSTED_ORIGINS and Stripe return / webhook URLs match the production HTTPS origin.
  • GA id is set for a coarse funnel (land → upload → pay → wait → download).
  • One real end-to-end path on production or a staging Worker: upload → pay → render → download.

Production origin: https://raindanceai.app.

Product rules that are not optional

Face-based generation is not “just another SaaS CRUD app”:

  • Require an explicit 18+ / rights-to-use confirmation on upload.
  • Block minors and refuse celebrity / stranger misuse in copy and policy.
  • Expect upstream safety refusals; refund and explain.
  • Keep privacy policy honest about retention; do not train on user media by default.
  • Market as an independent fan-style tool for a trend format — not as an official tie-in unless you actually have that deal.
  • Use your own sample renders in marketing.

Those constraints belong in the product, not in a footnote you add after the first dispute email.

What I would reuse on the next timeline-aware trend site

  1. Expose duration when the trend is a timeline, not a single gag.
  2. Force duration on every Seedance create.
  3. Aggregator keeps the Worker boring.
  4. Credits with automatic refund on failed generation.
  5. Measure the funnel before polishing prompt poetry.

Consumer: raindanceai.app. Builder: TryAllAPI, top up, prove create+poll, then wire credits. Pick the second, bill the second, poll until MP4.

Top comments (0)