API Reference

Partner Catalogue API

Pull your Songbox catalogue (tracks, metadata, writers, artwork and streaming) into your own website or system. Read-only, JSON over HTTPS, scoped to your account.

Base URL https://songbox.com/api/partner/v1

Overview

The Partner Catalogue API is a read-only HTTP API for pulling your own catalogue into an external site. It is separate from the Songbox apps: your site authenticates as a machine with an API key, not as a signed-in person.

  • Every request is scoped to the single account your key belongs to. You can never read another account's data.
  • All responses are UTF-8 JSON.
  • Only streaming audio is exposed, via short-lived signed URLs. Original masters and downloads are never available through the API.

Authentication

Send your API key as a Bearer token on every request:

http
Authorization: Bearer sbk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Keys are issued by the Songbox team and can be revoked at any time. Treat a key like a password: it grants read access to your whole catalogue. If a key leaks, ask us to revoke it and we'll issue a new one.

A missing, malformed or revoked key returns 401. A key whose account is no longer active returns 403. Confirm what your key can see with GET /me.

Conventions

  • Lists return { "data": [ ... ], "links": { ... }, "meta": { ... } } (standard pagination). Page with ?page= and ?per_page= (default 50, max 100), or follow links.next.
  • Single items return { "data": { ... } }.
  • Errors return { "error": "message" } with the matching HTTP status.
  • Rate limits: 120 requests/minute per key for catalogue endpoints, 60/minute for streaming. Over the limit returns 429.
  • Timestamps are ISO-8601. When you pass one as a query parameter, URL-encode it (the + in a timezone offset must be %2B).

Check your key

GET/me

Returns the account your key is scoped to and your limits. Useful as a health check.

curl
curl https://songbox.com/api/partner/v1/me \
  -H "Authorization: Bearer sbk_live_..."
json
{
  "data": {
    "account": { "token": "…", "name": "Acme Records" },
    "key": { "name": "Acme website", "prefix": "sbk_live_a1b2", "last_used_at": "…", "created_at": "…" },
    "limits": { "rate_limit_per_minute": 120, "stream_url_ttl_minutes": 10 }
  }
}

List artists

GET/artists

Your roster, paginated.

json
{
  "data": [
    {
      "token": "…",
      "name": "Artist Name",
      "image": "https://…",
      "socials": { "spotify": "…", "instagram": "…" },
      "track_count": 42
    }
  ],
  "links": { "next": "…" },
  "meta": { "current_page": 1, "per_page": 50, "total": 3, "last_page": 1 }
}

Get one artist

GET/artists/:token

One artist, including bio and onesheet. Returns 404 if the artist isn't in your account.

List tracks

GET/tracks

Your catalogue, paginated, most-recently-changed first.

ParameterDescription
artist_tokenOnly this roster artist's tracks. Must belong to your account, otherwise 404.
updated_sinceISO-8601 timestamp. Only tracks changed at or after it. Use for incremental sync. URL-encode it.
searchCase-insensitive match on title, metadata artist, or ISRC.
per_page1 to 100, default 50.
pagePage number.
curl
curl "https://songbox.com/api/partner/v1/tracks?per_page=100" \
  -H "Authorization: Bearer sbk_live_..."
json
{
  "token": "…",
  "title": "Song Title",
  "artist": { "token": "…", "name": "Artist Name" },
  "duration": 213,
  "duration_formatted": "03:33",
  "isrc": "US-ABC-25-00001",
  "iswc": null,
  "genre": "Pop",
  "year": 2025,
  "artwork": { "full": "https://…", "thumbs": { "small": "https://…", "large": "https://…" } },
  "processing_state": "ready",
  "is_streamable": true,
  "created_at": "2025-01-01T00:00:00+00:00",
  "updated_at": "2025-02-01T00:00:00+00:00"
}
Incremental sync. Store the newest updated_at you've seen, then poll GET /tracks?updated_since=<that timestamp> to fetch only what changed.

Get one track

GET/tracks/:token

Full detail: the summary fields plus metadata, rights, ai, lyrics, notes, play_count, writers, versions, cuts, waveform, and stream_url. Returns 404 if the track isn't in your account.

json
{
  "data": {
    "token": "…", "title": "…", "artist": { "token": "…", "name": "…" },
    "isrc": "…", "iswc": "…", "artwork": { "full": "https://…", "thumbs": { } },
    "metadata": {
      "meta_artist": "…", "album": "…", "mood": "…", "key": "…", "bpm": 120,
      "explicit": "clean", "languages": ["en"], "formats": ["wav"],
      "instruments": "…", "composer_details": "…", "upc": "…", "ean": "…"
    },
    "rights": {
      "rights_controlled": "master_and_publishing", "sync_clearance_status": "one_stop",
      "publisher": "…", "label": "…", "master_name": "…",
      "one_stop": true, "pre_cleared": false, "sync_history": "…"
    },
    "ai": {
      "primary_genre": "…", "secondary_genres": ["…"], "moods": ["…"],
      "instruments": ["…"], "tags": ["…"], "voice": "…", "energy": "…",
      "time_signature": "…", "valence": 0.6, "arousal": 0.4
    },
    "lyrics": "…", "notes": "…", "play_count": 128,
    "writers": [
      { "token": "…", "firstname": "Jane", "surname": "Writer", "name": "Jane Writer", "ipi": "…", "pro": "ASCAP", "split": 50 }
    ],
    "versions": [ { "version_number": 1, "note": "Original", "duration": 180, "created_at": "…" } ],
    "cuts": [ { "artist": "Cover Band", "year": "2021", "isrc": "…", "iswc": "…" } ],
    "waveform": [ -0.07, 0.06 ],
    "stream_url": "https://songbox.com/api/partner/v1/tracks/…/stream"
  }
}

Stream a track

GET/tracks/:token/stream

Returns a 302 redirect to a freshly-signed, short-lived (~10 minute) audio URL. Point an <audio> element straight at it, or follow the redirect yourself. A new signed URL is minted on every request, so don't cache the resolved URL; keep using the /stream endpoint (or the stream_url from the track detail response).

html
<audio controls
  src="https://songbox.com/api/partner/v1/tracks/TOKEN/stream">
</audio>
  • 409: the track isn't ready for streaming yet (still processing).
  • 404: the track isn't in your account, or has no streamable audio.

Field notes

  • isrc / iswc: a single resolved value each. If a track carries both an explicit code and one detected from its file, the explicit one is used.
  • artwork.thumbs: any of tiny / small / medium / large that exist; may be {} for older tracks. Use artwork.full as the reliable image.
  • processing_state: ready or processing. Only ready tracks are streamable (is_streamable).
  • waveform: an array of peak values for drawing a waveform, or null.

Errors

StatusMeaning
401Missing, malformed, unknown, or revoked key.
403The key's account is unavailable.
404The resource isn't in your account (or doesn't exist).
409Track not ready for streaming.
422Bad parameter (e.g. an unparseable updated_since).
429Rate limit exceeded.

Versioning

The v1 in the path is a stable contract. We add fields without notice; we won't remove or rename fields within v1. Breaking changes ship as a new version.

Need a key, or have a question? Get in touch.