docs / introduction

Introduction

SongAPI is a REST API for generating full AI songs — vocals, instruments, and all — from text prompts. All endpoints live under a single base URL:

base URL
https://api.songapi.dev

Generation is asynchronous. Submission endpoints (/v1/generate, /v1/extend, /v1/cover, /v1/add-vocals, /v1/lyrics) return 202 Accepted immediately with a generation object in status queued. Poll GET /v1/generations/:id until status is "complete", or set a webhook_url and get a webhook when the track is ready. Statuses move queued → processing → complete | failed.

A first request, end to end:

quickstartbash
# 1. submit
curl https://api.songapi.dev/v1/generate \
  -H "Authorization: Bearer $SONGAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "upbeat indie pop song about summer road trips"}'
# → 202 { "id": "gen_…", "status": "queued", … }

# 2. poll until status is "complete"
curl https://api.songapi.dev/v1/generations/gen_… \
  -H "Authorization: Bearer $SONGAPI_KEY"
# → 200 { "status": "complete", "audio_url": "…", "clips": [ … ] }

## Authentication

Every /v1 request needs an API key passed as a bearer token. Keys are created on the dashboard and shown in full only once, at creation.

authorization header
Authorization: Bearer sk_live_…   # live — bills credits
Authorization: Bearer sk_test_…   # sandbox — free

Keep keys out of client-side code — call SongAPI from your backend. A missing, malformed, or revoked key returns 401 unauthorized.

## Sandbox

Every account includes a sandbox key (sk_test_…). Sandbox requests are free, use the exact same endpoints and schemas as live, and complete a few seconds after submission with silent placeholder audio — so you can build and test your whole integration (including webhooks) before spending a credit. Sandbox and live generations are separate: a live key never sees sandbox jobs, and vice versa.

## Errors

Errors return a JSON body with a stable error code and, usually, a human-readable message:

error shapejson
{
  "error": "invalid_input",
  "message": "prompt: String must contain at most 3000 character(s)",
  "details": ["prompt: String must contain at most 3000 character(s)"]
}

details is only present on validation failures — one entry per invalid field.

STATUSCODEWHEN
400invalid_inputBody isn't JSON, or a field failed validation (see details).
401unauthorizedMissing, malformed, unknown, or revoked API key.
402insufficient_creditsLive key with a balance below the request's cost — top up to continue.
404not_foundUnknown generation id or route.
429rate_limitedOver 300 requests per minute on one key.
500internal_errorSomething failed on our side — safe to retry.

Failed live generations are refunded automatically: credits are debited when a job is accepted and returned in full if it ends in status failed.

## Rate limits

Each API key can make 300 requests per minute; beyond that, requests return 429 rate_limited until the window resets.

Generation throughput is governed separately by per-account concurrency — how many music jobs can render at once (lyrics jobs don't count against it). Submissions above the cap are never rejected: they queue and dispatch as slots free up.

TIERCONCURRENT GENERATIONS
Default2
After a single $500 purchase30
After a single $1,250 purchase60