Your media stops living on someone else's CDN
On v2 you sign a PUT per job and the render is written into your bucket. We keep no copy, so there is no expiring link to babysit and no third-party host in your delivery path.
Image-to-video over REST, no arbitrary content filters, and every render written straight into your own bucket.
# one call, one clip curl -X POST \ https://api.musebox.ai/api/v1/jobs \ -H "Authorization: Bearer $MBX_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "i2v", "modelId": "tmpl-i2v-classic", "inputUrl": "https://cdn.you/frame.jpg", "quality": "fast" }'
Every partner who moved here was blocked by one of these somewhere else.
General-purpose video APIs reject the work your product exists to do. We do not apply those creative filters. Illegal content stays prohibited and every account is bound by our terms, but the model does not second-guess your catalogue.
On v2 you sign a PUT per job and the render is written into your bucket. We keep no copy, so there is no expiring link to babysit and no third-party host in your delivery path.
We train custom LoRA models on your footage and expose them as private templates that only your keys can call.
This is not a beta waiting for its first integration. Partner accounts run through the same queue and the same GPU fleet every day.
The traffic comes from three kinds of product, and it is concentrated in the United States, Europe and Brazil.
The whole integration is one POST and one webhook handler. Everything else is optional.
POST /v1/jobs with a template id and a public image URL. You get a job id, a queue position, the credits charged and your balance after, all in the same response.
The job runs on dedicated GPU workers. Text-to-image lands at roughly 60 seconds p50 and 150 seconds p95 when there is queue depth. Poll if you have to, but webhooks are the intended path.
We sign the callback with your per-key secret and retry on failure. On v2 the file is already sitting in your bucket by the time the webhook arrives.
Each clip below is one call against a template every partner account can reach on day one.
You own the interface. One account and one key drive a storefront and a chat bot alike, because both are the same two calls underneath.







Your catalogue, your pricing, your credits. The API supplies the templates and the render.
One POST when the photo arrives, one webhook when the clip is ready. No polling loop to run.
On v1 the output sits in our storage behind a link that expires about 24 hours after the job finishes. On v2 you attach a presigned PUT to the job and the worker writes the finished file directly into your bucket. We keep nothing.
// add one block to any v2 job { "type": "i2v", "modelId": "tmpl-i2v-classic", "inputUrl": "https://your-cdn.com/frame.jpg", "delivery": { "url": "https://bucket.r2.cloudflarestorage.com/out.mp4?X-Amz-...", "method": "PUT", "headers": { "Content-Type": "video/mp4" } } } // the callback is a delivery receipt, not a download link { "jobId": "...", "delivery": { "status": "delivered" } }
Create a job, then verify the callback signature before you trust it. That is the entire contract.
curl -X POST https://api.musebox.ai/api/v1/jobs \ -H "Authorization: Bearer $MBX_KEY" \ -H "Content-Type: application/json" \ -d '{"type":"i2v","modelId":"tmpl-i2v-classic","inputUrl":"https://your-cdn.com/frame.jpg","quality":"fast"}' # poll only if you cannot take a webhook curl https://api.musebox.ai/api/v1/jobs/$JOB_ID \ -H "Authorization: Bearer $MBX_KEY"
import crypto from 'node:crypto'; const res = await fetch('https://api.musebox.ai/api/v1/jobs', { method: 'POST', headers: { Authorization: `Bearer ${process.env.MBX_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ type: 'i2v', modelId: 'tmpl-i2v-classic', inputUrl: 'https://your-cdn.com/frame.jpg', quality: 'fast', webhookUrl: 'https://you.example/hooks/musebox', }), }); const { data } = await res.json(); // reject anything you cannot verify function verify(rawBody, signature, secret) { const expected = crypto.createHmac('sha256', secret) .update(rawBody).digest('hex'); return crypto.timingSafeEqual( Buffer.from(expected), Buffer.from(signature) ); }
import os, hmac, hashlib, requests r = requests.post( "https://api.musebox.ai/api/v1/jobs", headers={"Authorization": f"Bearer {os.environ['MBX_KEY']}"}, json={ "type": "i2v", "modelId": "tmpl-i2v-classic", "inputUrl": "https://your-cdn.com/frame.jpg", "quality": "fast", "webhookUrl": "https://you.example/hooks/musebox", }, timeout=30, ) job = r.json()["data"] # reject anything you cannot verify def verify(raw_body: bytes, signature: str, secret: str) -> bool: expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, signature)
POST /v1/jobsPOST /v1/jobs/sequencePOST /v1/jobs/t2iGET /v1/models, no prompt engineering needed.RateLimit-* headers on every response.Plans differ by what you can call, how fast you can call it, and how many credits come with the month. We quote once we know your volume.
Credits never expire while the subscription is active, and stay usable for 30 days after a cancellation. Requests stop at a zero balance unless your plan carries overage, and quota warnings arrive at 80, 95 and 100 percent.
The catalogue matches what your audience already pays for, the renders land in your storage rather than ours, and USDT settlement keeps billing working when card processors will not.
One POST per user request and a webhook that fires when the file is ready. No long-lived connections and no polling loop to babysit while your bot serves thousands of chats.
Resell generation under your own brand. Cover tags let you present a catalogue that fits each regional audience, and private LoRA models keep your clients' characters yours.
Animate the same character consistently across a whole product. Train a private model once, then call it like any other template for as long as the account lives.
We do not apply the arbitrary creative filters that general-purpose video APIs use, which is the reason most partners move here. Illegal content is strictly prohibited, all use is bound by our Terms of Service, and we run a content removal process for reports.
On v1 the render lands in our storage and you download it from a link that expires about 24 hours after the job completes. On v2 you supply a presigned PUT per job, the worker writes the file straight into your bucket, and we keep no copy at all.
Anything that accepts a presigned PUT: AWS S3, Cloudflare R2, Google Cloud Storage, Azure Blob, Backblaze B2, and generic S3-compatible endpoints. The documentation carries a working presign recipe for each one, plus a self-test endpoint that proves your URL works before you spend credits on a real job.
Text-to-image runs at roughly 60 seconds p50 and 150 seconds p95 once there is queue depth. The first request after an idle period is slower while the model loads, then subsequent jobs run hot.
Keys are provisioned by hand after a short review of your project. Send an access request describing what you are building and your expected volume, and you receive a live key plus a webhook signing secret. There is no self-service signup, which is deliberate.
Plans are billed monthly and carry a credit allowance. Credits never expire while your subscription is active and remain usable for 30 days if you cancel. Requests hard-stop at a zero balance unless your plan includes overage.
Yes. We train custom LoRA models on your reference footage and expose them in your catalogue as private templates that only your keys can call.
Yes. USDT on TRC20 is the default rail for international partners, which matters for teams that traditional processors will not serve.
Send your project, your platform and your expected volume. We review access requests by hand and reply with a quote and a key.