Cliplus makes Seedance video generation and AI MediaKit upscaling look like one OpenAI-shaped API. Your customers get a single key. They never learn there were two vendors behind it.
The video bytes never touch the hub — so the whole thing runs on infrastructure that is free permanently, not for a trial period.
Authorization: Bearer cl_15f19a4c7b2e… { "model": "seedance-2-5", "resolution": "1080p", "duration": 5, "prompt": "a drone shot over Marina Bay" }
resolutionThe routing rule
That is the entire policy, and it is the reason the economics work: the expensive native tiers are never used. A 4K request is generated at 480p — the cheapest tier Seedance sells — and then handed to MediaKit, which is priced per output minute rather than per pixel.
No enhancement leg, no MediaKit call, no second bill.
route: ["generate"]
One job id, one poll loop, one cost object.
route: ["generate","enhance"]
libx264 -pix_fmt yuv420p10le.Key masking
You hold one ModelArk key and one MediaKit key, set once as server secrets.
Each customer signs up, mints their own cl_… key, and calls your base
URL with it. Cliplus resolves that key to an account, then calls BytePlus with your
credentials — which never leave the server.
// mint: server-side, on the customer's Keys page. Shown once, never again.
const plaintext = `cl_${randomHex(40)}`;
await db.insert({ account_id, prefix: plaintext.slice(0, 9),
last4: plaintext.slice(-4), hash: sha256(plaintext) });
// resolve: on every request. The hub stores hashes, so a database leak
// yields nothing a caller could replay.
const row = await db.findByHash(sha256(presentedKey));
return row ? { account_id: row.account_id, key_id: row.id } : null;The plaintext key is returned
exactly once, at mint time, and never stored. Only a SHA-256 digest, a 9-character prefix
and the last 4 characters are kept — enough to show cl_15f19a…d185
in the UI, not enough to reconstruct.
Every key maps to one account, so usage, spend and upscale minutes are attributed per customer. Customers see only their own numbers; admins see across all accounts.
Because keys are rows, not containers, revoking one is instant and affects nobody else. No need to rotate your upstream BytePlus credentials to cut off a single customer.
Measured, not estimated
Benchmarked against a mock upstream on a single Node process, so the numbers describe the hub itself rather than BytePlus latency.
The binding constraint is never the hub — it is your BytePlus concurrency quota. See the ceiling calculation →
Get going
No npm install. No lockfile. No
node_modules. No registry access needed for the Docker build. It runs the same
on x86 and on Arm, which is what makes the free Arm VM in the hosting plan viable.
# Docker, nothing else installed
docker compose up --build
# or Node 18+, no Docker
node adapters/node/server.js
# then
open http://localhost:8787/demo # simulator + key minter
open http://localhost:8787/tester # 20-check conformance suite
open http://localhost:8787/console # usage dashboardPrefer to see it before installing anything? The live demo runs a complete simulated hub inside your browser tab.