Stems splitsen, in Node.js.
Een typed Node- en TypeScript-client voor AI Stem Splitter. Installeer vanaf npm of JSR, draai op Node, Bun of Deno, en ship een werkende functie voor stemscheiding in letterlijk een script van 12 regels — dien een track in, poll tot hij klaar is en schrijf de 4 stems naar disk vóór de volgende standup-demo.
Installeren
Authenticeren
Genereer een sleutel vanuit je developer settings, zet die in je environment als AISTEMSPLITTER_API_KEY en geef hem door aan de client constructor. De SDK logt de sleutel nooit en de pagina rendert nooit meer dan de public-safe ast_live_-prefix in tooltips.
import { AiStemSplitter } from "@aistemsplitter/sdk";
const client = new AiStemSplitter({
apiKey: process.env.AISTEMSPLITTER_API_KEY!,
});Hello world
Twaalf regels, end-to-end. Dien een track in, wacht tot het htdemucs_ft-model klaar is en schrijf de vier stems — vocals, drums, bass, other — naar disk. Plak dit in één .mjs-bestand, zet je sleutel en draai het vóór de standup-demo.
import { AiStemSplitter } from "@aistemsplitter/sdk";
import { writeFile } from "node:fs/promises";
const client = new AiStemSplitter({
apiKey: process.env.AISTEMSPLITTER_API_KEY!,
});
// 1. Submit a split job
const job = await client.createSplit({
input: { type: "direct_url", url: "https://example.com/song.mp3" },
stemModel: "htdemucs_ft",
});
// 2. Wait until completion (polls under the hood)
const result = await client.waitForSplit(job.id);
// 3. Download all six stems
for (const [name, url] of Object.entries(result.stems)) {
const audio = await fetch(url).then((r) => r.arrayBuffer());
await writeFile(`./${name}.wav`, Buffer.from(audio));
}Methoden
Zes typed methods dekken de volledige job lifecycle. Elke methode is een echte TypeScript-signature op het gepubliceerde package — autocomplete in je editor, geen fetch-wrappers om te schrijven, geen schema om te onthouden.
Dien een nieuwe split-job in; retourneert een job-id en queued-status.
Haal de huidige status van een split-job op.
Poll totdat de job slaagt, faalt of de timeout verstrijkt.
Gepagineerde lijst met recente split-jobs voor de API-sleutel.
Krijg een vooraf ondertekende PUT-URL voor directe browser-/serveruploads.
Verifieer de HMAC-SHA256-signature op een inkomende webhook-payload.
Webhooks
Polling brengt je tot de demo. Webhooks brengen je naar productie. Zet een signed callback URL in createSplit en verifieer daarna de HMAC-SHA256-signature met één SDK-call in je bestaande Express- of Hono-handler.
import { AiStemSplitter } from "@aistemsplitter/sdk";
import { Hono } from "hono";
const app = new Hono();
const client = new AiStemSplitter({
apiKey: process.env.AISTEMSPLITTER_API_KEY!,
});
app.post("/webhooks/aistemsplitter", async (c) => {
const raw = await c.req.text();
const event = client.verifyWebhook(c.req.header(), raw); // throws if invalid
switch (event.type) {
case "split.succeeded":
// event.data.stems → six URLs
break;
case "split.failed":
// event.data.error → { code, message }
break;
}
return c.text("ok");
});FAQ
Does @aistemsplitter/sdk work in Bun and Deno without polyfills?
Yes. The package is dual-published to npm and JSR, so Bun installs via `bun add jsr:@aistemsplitter/sdk` and Deno via `deno add jsr:@aistemsplitter/sdk`. There are no @types/node polyfills, no Buffer shimming required, and no node:fs imports in the client core — the typed surface uses the Web Fetch + Web Streams APIs, which Node 18+, Bun, and Deno all implement natively.
How do I verify webhook signatures in Express, Hono, or Next.js?
Call ast.verifyWebhook({ headers, body }) — it computes the HMAC-SHA256 over the raw body, constant-time-compares against the aistemsplitter-signature header, and throws on tamper. The Webhooks section above shows runnable Express and Hono handlers; for Next.js App Router, use the Hono pattern in a route.ts handler with `await request.text()` to read the raw body before verification.
Is the TypeScript surface real, or `any` everywhere?
Real. Every method on AistemsplitterClient has a typed input + Promise return: createSplit(input: CreateSplitInput) → Promise<Split>, getSplit(id: string) → Promise<Split>, waitForSplit, listSplits, presignUpload, verifyWebhook. The Split + Stem + WebhookEvent types are exported from the package root, so you can import them into your own handlers and storage layer without re-deriving the shape.
How do I handle errors and retries from the SDK?
All methods throw typed errors: AistemsplitterApiError (4xx/5xx with code + message + requestId), AistemsplitterRateLimitError (429 with retryAfter seconds), AistemsplitterNetworkError (transport-level). waitForSplit retries polls automatically with exponential backoff until the SDK timeout (default 5 min) — wrap createSplit / presignUpload in your own retry helper if you need at-least-once submission semantics.
Can I run this in the browser?
No — the SDK is a server-side client. Browser use would expose your API key (any code that reaches the user's machine can read it) and run into CORS on the upload endpoints. Mint a short-lived signed URL on your server with presignUpload and hand only that URL to the browser; do the actual createSplit + waitForSplit calls from a server route, n8n workflow, or background worker.
Werkt @aistemsplitter/sdk in Bun en Deno zonder polyfills?
Ja. Het package wordt dubbel gepubliceerd naar npm en JSR, dus Bun installeert via `bun add jsr:@aistemsplitter/sdk` en Deno via `deno add jsr:@aistemsplitter/sdk`. Er zijn geen @types/node-polyfills, geen Buffer-shimming vereist en geen node:fs-imports in de client core — het typed oppervlak gebruikt de Web Fetch + Web Streams APIs, die Node 18+, Bun en Deno allemaal native implementeren.
Hoe verifieer ik webhook-signatures in Express, Hono of Next.js?
Roep ast.verifyWebhook({ headers, body }) aan — die berekent de HMAC-SHA256 over de raw body, vergelijkt in constant time met de aistemsplitter-signature header en throwt bij manipulatie. De Webhooks-sectie hierboven toont runnable Express- en Hono-handlers; voor Next.js App Router gebruik je het Hono-patroon in een route.ts-handler met `await request.text()` om de raw body te lezen vóór verificatie.
Is het TypeScript-oppervlak echt, of overal `any`?
Echt. Elke methode op AistemsplitterClient heeft typed input + Promise-return: createSplit(input: CreateSplitInput) → Promise<Split>, getSplit(id: string) → Promise<Split>, waitForSplit, listSplits, presignUpload, verifyWebhook. De Split + Stem + WebhookEvent types worden geëxporteerd vanuit de package root, zodat je ze in je eigen handlers en storage layer kunt importeren zonder de shape opnieuw af te leiden.
Hoe ga ik om met errors en retries vanuit de SDK?
Alle methoden throwen typed errors: AistemsplitterApiError (4xx/5xx met code + message + requestId), AistemsplitterRateLimitError (429 met retryAfter-seconden), AistemsplitterNetworkError (transport-level). waitForSplit retryt polls automatisch met exponential backoff tot de SDK-timeout (default 5 min) — wrap createSplit / presignUpload in je eigen retry-helper als je at-least-once submission semantics nodig hebt.
Kan ik dit in de browser draaien?
Nee — de SDK is een server-side client. Browsergebruik zou je API-sleutel blootstellen (elke code die de machine van de gebruiker bereikt kan hem lezen) en tegen CORS op de upload-endpoints aanlopen. Maak op je server een kortlevende signed URL met presignUpload en geef alleen die URL aan de browser; doe de echte createSplit + waitForSplit-calls vanuit een serverroute, n8n-workflow of background worker.
Volgende stappen
Ship 4 stems vóór de standup.
Gratis aanmelden, geen creditcard. Creditpakketten die nooit verlopen — $0.08–$0.14 per minuut, afhankelijk van volume.