Node.js quickstart

Generate your first AI song from Node.js in about five minutes. Uses the official @musicapi/sdk TypeScript client (zero runtime deps, ESM + CommonJS, Node 18+).

1. Get an API key

Sign in to the MusicAPI dashboard, open API Keys, and copy your key. New accounts get free credits to test with.

2. Install the SDK

npm install @musicapi/sdk
# or
pnpm add @musicapi/sdk
# or
bun add @musicapi/sdk

3. Set the key in your environment

export MUSICAPI_KEY="your_key_here"

4. Check your credit balance

A one-call sanity check that confirms the key works:

import { MusicAPI } from "@musicapi/sdk"

const client = new MusicAPI({ apiKey: process.env.MUSICAPI_KEY! })

const { credits, extra_credits } = await client.credits.get()
console.log({ credits, extra_credits })

5. Generate your first song

generateAndWait submits the generation and polls until the song(s) are ready:

import { MusicAPI } from "@musicapi/sdk"

const client = new MusicAPI({ apiKey: process.env.MUSICAPI_KEY! })

const result = await client.sonic.generateAndWait(
  {
    custom_mode: false,
    mv: "sonic-v5",
    gpt_description_prompt: "uplifting synthwave with female vocals",
  },
  { pollIntervalMs: 5000, timeoutMs: 300_000 },
)

for (const song of result.data) {
  console.log(song.title, song.audio_url)
}

Two songs come back per generation — the model always returns a pair, and you can pick the one you like.

6. Or submit and poll yourself

If you want to drive the workflow (background queue, webhooks, parallel work), submit the job and poll it on your own schedule:

const { task_id } = await client.sonic.create({
  custom_mode: true,
  mv: "sonic-v5",
  prompt: "[Verse]\nCity lights, neon dreams\n[Chorus]\nDrive on, drive on…",
  title: "Night Drive",
  tags: "synthwave, retro, energetic",
})

// Poll until terminal. The API returns HTTP 202 / { type: "not_ready" } while running.
let task
do {
  await new Promise((r) => setTimeout(r, 5000))
  task = await client.sonic.getTask(task_id)
} while (task.code !== 200)

console.log(task.data[0].audio_url)

Or, easier — pass webhook_url in the create call and the API will POST the finished task to you (signed with webhook_secret if you set one). No polling needed.

7. Handle errors cleanly

Every non-2xx response throws a MusicAPIError:

import { MusicAPI, MusicAPIError } from "@musicapi/sdk"

try {
  await client.sonic.generateAndWait({
    custom_mode: false,
    mv: "sonic-v5",
    gpt_description_prompt: "lofi hip hop for studying",
  })
} catch (err) {
  if (err instanceof MusicAPIError) {
    if (err.isAuthError)     console.error("API key invalid or missing")
    else if (err.isCreditError)  console.error("Out of credits / no subscription")
    else if (err.isRateLimited)  console.error("Rate limited — back off")
    else                         console.error(err.status, err.code, err.message)
  } else {
    throw err
  }
}

429 and 5xx are retried automatically with exponential backoff (max 3 retries, honoring Retry-After). Other 4xx are terminal and throw immediately. If a job fails after submission, the API automatically refunds your credits — you don't need to handle that.

What's next