@mirelo/sdk
v1.0.4
Published
Official Mirelo API SDK
Readme
mirelo
Official JavaScript/TypeScript SDK for the Mirelo API v2.
Works in any environment that supports fetch and Uint8Array: Node.js, browsers, Adobe UXP, Deno, Bun, and more — no Node.js-specific APIs are used.
API reference: api.mirelo.ai/docs
Installation
npm install @mirelo/sdk
# or
bun add @mirelo/sdkQuick start
import { MireloClient, Video, MireloError } from "@mirelo/sdk";
const client = new MireloClient("sk-your-key");
// From a URL — no upload needed
const video = Video.fromUrl("https://example.com/clip.mp4");
// From bytes — works in every environment
// const video = Video.fromBytes(uint8ArrayData, "video/mp4");
const req = client.videoToSfx(video, { durationMs: 5000 });
try {
// Check cost before generating
const cost = await req.preflight();
console.log(`${cost.credits} credits, ~${cost.estimatedMs}ms`);
// Submit a job (recommended — avoids HTTP timeout risk)
const job = await req.submitJob();
// Check status once
const status = await job.status();
console.log(status.status); // "processing" | "succeeded" | "errored"
// Or wait until done
const result = await job.wait({ pollIntervalMs: 1000 });
console.log(result.resultUrls);
} catch (e) {
if (e instanceof MireloError) {
console.error(`${e.code} (${e.httpStatus}): ${e.message}`);
}
}Client options
const client = new MireloClient("sk-your-key", {
host: "api.mirelo.ai", // default
timeoutMs: 600_000, // default: 10 minutes, applied to every request
retries: 3, // default: 0 (disabled); only retries non-4xx errors
backoffMs: 1_000, // base for exponential backoff: backoffMs * 2^attempt
});Methods
client.me()
Returns account info including available credits.
const me = await client.me();
console.log(me.creditsAvailable, me.overageEnabled);client.textToSfx(params)
Generate sound effects from a text prompt.
const req = client.textToSfx({
prompt: "dramatic thunderclap",
durationMs: 4000, // optional, default 10000
numSamples: 2, // optional, default 1 (max 4)
});client.videoToSfx(video, params)
Generate sound effects from a video.
const req = client.videoToSfx(video, {
durationMs: 5000, // required
startOffsetMs: 1000, // optional
numSamples: 1, // optional
output: "audio", // optional: "audio" (default) | "video"
});GenerationRequest
Every generation method returns a GenerationRequest with three terminal methods:
.preflight()
Check the credit cost and estimated time without generating anything.
const { credits, estimatedMs } = await req.preflight();.submitJob()
Submit a background job and return a Job object. This is the recommended approach — it is not affected by HTTP proxy timeouts.
const job = await req.submitJob();.syncIAcceptHttpTimeoutRisk()
Call the synchronous endpoint, which blocks until generation completes. The deliberately alarming name is intentional: any proxy or load balancer with a timeout shorter than the generation time will cut this request off. Use submitJob() instead for production.
const result = await req.syncIAcceptHttpTimeoutRisk();Job
const job = await req.submitJob();
// Single status check
const status = await job.status();
if (status.status === "processing") {
console.log(`${status.progressPercent}% done`);
}
// Poll until complete (throws MireloError if errored or timed out)
const result = await job.wait({ pollIntervalMs: 500 }); // default 500ms
console.log(result.resultUrls);Video
// From a public URL — no upload required
const video = Video.fromUrl("https://example.com/clip.mp4");
// From raw bytes — works everywhere (Node.js, browsers, UXP, etc.)
// Node.js Buffer extends Uint8Array and works here directly.
const video = Video.fromBytes(bytes, "video/mp4");When fromBytes is used, the SDK automatically:
- Calls
POST /v2/assetsto get a presigned upload URL - Uploads the bytes via
PUT - Caches the resulting
asset_idon theVideoinstance for subsequent calls
Error handling
All errors throw MireloError:
try {
const result = await req.syncIAcceptHttpTimeoutRisk();
} catch (e) {
if (e instanceof MireloError) {
e.code; // e.g. "insufficient_credits", "invalid_video", "timeout"
e.httpStatus; // e.g. 402, 422, 408
e.message; // human-readable description
}
}