VYBE Library API v1

VYBE Library for developers

Bring real music from independent artists into your app, royalty-free. Every song comes with what you need to use it well: BPM, key, Camelot, energy, VYBEs, lyrics, credits, artwork and a waveform, all packed inside its .vybe file.

Artists opted in

Only songs whose artists switched on "Share with VYBE partner apps". Nothing else is ever returned.

Everything in the file

One .vybe file holds the audio in several codecs, a preview, the cover, the waveform and all metadata.

Built for mixing

Filter by VYBE, BPM range, key, Camelot and energy to build sets, game soundtracks or party queues.

Getting access

The VYBE Library is open to approved partner apps only. To apply, email [email protected] with your company, the app you want to use the music in, where it is available, and whether the use is commercial (for example in a paid product, a venue, or around ads). We review every request.

When you are approved we create your partner account and send you an API key. Using the API means you accept the VYBE Library API and Partner Terms. Commercial partners only receive songs whose artists also allowed commercial use.

Authentication

All requests go to the base URL below over HTTPS. Send your key in the Authorization header as a bearer token, or in an x-vybe-key header. There are three kinds of credentials:

CredentialLooks likeUse it
Secret keyvybe_pk_ + 40 charactersOn your server only. Full access, including whole .vybe files and making session tokens.
Publishable keyvybe_pub_ + 40 charactersIn websites and apps with the VYBE SDK. It only works from the websites (Origin) and app ids (x-vybe-app header) listed on the key, streams audio only, and is limited per listener.
Session tokenvybe_ct_...Made by your server for one signed-in user with POST /v1/sessions. Lasts up to 24 hours. Best for mobile apps.
BASEhttps://vybemusic.com/api/library/v1
curl https://vybemusic.com/api/library/v1/me \
  -H "Authorization: Bearer $VYBE_KEY"
Keep your secret key on your server. Call the API from your backend and pass only media links to your app. A key in a mobile app or web page can be copied, and you are responsible for every call made with it. If a key leaks, tell us and we will revoke it and issue a new one.

Errors

Errors use normal HTTP status codes and always have the same JSON shape:

Response
{ "error": { "code": "invalid_request", "message": "bpm_min must be a number between 20 and 400" } }
StatusCodeMeaning
400invalid_requestA parameter or the body is not valid. The message says which.
401missing_key, invalid_key, invalid_token, token_expiredNo key, a malformed or revoked key, or a session token that is not valid or has run out.
403origin_not_allowed, secret_key_requiredA publishable key used from a website or app that is not on the key, or a call that needs a secret key.
403partner_paused, partner_revokedYour access is paused or has ended.
404not_foundThe track or artist does not exist or is not shared with you (any more).
413too_largeThe body is over 512 KB.
429rate_limitedToo many requests. Wait for the number of seconds in Retry-After.
5xxunavailable, server_errorSomething went wrong on our side. Retry with backoff.

Rate limits

Each key has a per-minute request limit, set when you are approved (600 a minute unless agreed otherwise; /v1/me shows yours). Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (Unix seconds). Over the limit you get a 429 with a Retry-After header. Cache search results on your side instead of repeating the same query, and batch usage events.

POST/v1/sessions

Makes a session token for one of your users, so your app never holds a key. Call it from your server with your secret key. Body: user (your id for the user, optional; VYBE stores only a one-way hash) and hours (how long it lasts, 1 by default, at most 24). Plays made with the token are counted for that user, and its rate limit (120 a minute) is per user.

curl
curl -X POST https://vybemusic.com/api/library/v1/sessions \
  -H "Authorization: Bearer $VYBE_SECRET_KEY" -H "Content-Type: application/json" \
  -d '{"user":"user-42","hours":1}'

{ "token": "vybe_ct_...", "expires_at": "2026-10-21T12:00:00.000Z" }
GET/v1/me

Your partner account, its status and your rate limit.

Response
{
  "name": "Your App",
  "slug": "your-app",
  "status": "active",
  "commercial": false,
  "rate_limit": { "per_minute": 600 },
  "terms_version": "2026-10-21",
  "key": { "prefix": "vybe_pk_Ab3x", "label": "production" }
}
GET/v1/vybes

The VYBEs a song can belong to. Use the id in the vybe filter of /v1/tracks.

idName
euphoricHappy
chillChill
latenightLate Night
sunsetRoad Trip
focusFocus
dreamySleep
hypeParty
deepSad
fuelWorkout
crushLove
Response
{ "data": [ { "id": "hype", "name": "Party", "line": "Your living room is a club now. Act accordingly." }, ... ] }
GET/v1/tracks

Search and filter the songs shared with you, newest releases first. All parameters are optional and can be combined.

ParameterDescription
qText search in song titles and artist names.
vybeOne VYBE id, for example hype.
bpm_min, bpm_maxTempo range, 20 to 400.
keyMusical key as stored, for example A minor (case does not matter).
camelotCamelot code, 1A to 12B. Neighbouring codes mix well.
energy_min, energy_maxEnergy from 0 (calm) to 1 (intense).
genreGenre name, exact match, case does not matter.
explicitfalse for clean songs only, true for explicit only.
artistAn artist slug.
limit1 to 100, default 50.
cursorThe next_cursor from the previous page.
curl "https://vybemusic.com/api/library/v1/tracks?vybe=hype&bpm_min=120&bpm_max=128&camelot=8A&explicit=false&limit=20" \
  -H "Authorization: Bearer $VYBE_KEY"
Response
{
  "data": [
    {
      "id": "6c1f2a4e-8d3b-4f7a-9b21-0e5d7c9a1f30",
      "slug": "song-title",
      "title": "Song Title",
      "artist": { "name": "Artist Name", "slug": "artist-name", "avatar": "https://vybemusic.com/m/pub/a/.../image/avatar.webp", "verified": true, "url": "https://vybemusic.com/app/#/artist/artist-name" },
      "release": { "title": "Release Title", "kind": "ep" },
      "duration": 201.4,
      "bpm": 124,
      "key": "A minor",
      "camelot": "8A",
      "energy": 0.82,
      "loudness": -8.6,
      "vybes": ["hype", "fuel"],
      "genre": "House",
      "language": "en",
      "explicit": false,
      "isrc": "AEA0Q2600001",
      "cover": "https://vybemusic.com/m/pub/a/.../image/cover.webp",
      "waveform": [0.12, 0.34, 0.58, ...],
      "has_lyrics": true,
      "codecs": ["opus", "aac"],
      "released_at": "2026-10-01T00:00:00Z",
      "credits": [ { "name": "Artist Name", "role": "Main artist" }, { "name": "Producer Name", "role": "Producer" } ],
      "links": { "vybe": "https://vybemusic.com/app/#/track/song-title" },
      "attribution": "Music from VYBE: Song Title by Artist Name"
    }
  ],
  "next_cursor": "eyJvIjoyMH0"
}

When next_cursor is null there are no more results. A page can hold fewer items than limit; keep following next_cursor until it is null.

GET/v1/tracks/:id

One song by id (or slug), with everything from the list plus lyrics with their sections and the analysis made when the artist uploaded it.

Every song (in the list too) also carries who made it: display_artist ("Luna Waves & Ayo feat. Kai"), artists (each with role main, featured or remixer), credits (name, role id such as lyricist, producer, vocals, mixing_engineer, and role_label), people (main_artists, featured_artists, lyricists, composers, singers, producers, engineers), version ("Radio Edit"), label, year and copyright (c and p lines). The same fields are inside every .vybe file: see the format spec.

curl https://vybemusic.com/api/library/v1/tracks/6c1f2a4e-8d3b-4f7a-9b21-0e5d7c9a1f30 \
  -H "Authorization: Bearer $VYBE_KEY"
Extra fields
{
  ...,
  "lyrics": {
    "plain": "First line\nSecond line",
    "synced": [ { "t": 12.4, "line": "First line", "section": "Verse 1" }, { "t": 15.9, "line": "Second line", "section": "Verse 1" } ],
    "sections": [ { "type": "verse", "label": "Verse 1", "performer": "Nia", "start": 12.4, "end": 31.0, "lines": ["First line", "Second line"], "inferred": false } ],
    "structure": [ "Intro", "Verse 1", "Pre Hook", "Hook", "Drop", "Verse 2", "Pre Hook", "Hook", "Drop", "Bridge", "Hook", "Outro" ]
  },
  "analysis": {
    "beats": { "first": 0.42, "period": 0.48387, "downbeat": 0.42 },
    "sections": [ { "start": 0, "end": 30.9, "label": "intro" }, ... ],
    "drop": 61.8,
    "danceability": 0.78,
    "valence": 0.64,
    "energy_curve": [0.21, 0.25, ...]
  }
}

lyrics and analysis are null when the song has none. Beat times are in seconds: beat n is at first + n * period.

POST/v1/tracks/:id/stream

Get a media link for one song. Links work for 6 hours, support HTTP Range requests (seeking, iPhone players) and need no headers, so you can hand them straight to a player.

FieldDescription
formataudio (default): the full song as one playable audio file. vybe: the whole .vybe file, for the reader SDK.
userOptional. Your own opaque id for the listener (never an email, name or phone number). We store only a one-way hash.
countryOptional. The listener's country as a 2 letter ISO code, for example AE.
curl -X POST https://vybemusic.com/api/library/v1/tracks/6c1f2a4e-8d3b-4f7a-9b21-0e5d7c9a1f30/stream \
  -H "Authorization: Bearer $VYBE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"format":"audio","user":"u_83f1c2","country":"AE"}'
Response
{
  "format": "audio",
  "url": "https://vybemusic.com/m/4f9c...e21a",
  "meta_url": "https://vybemusic.com/m/4f9c...e21a?meta=1",
  "codecs": ["opus", "aac"],
  "stream_urls": { "opus": "https://vybemusic.com/m/4f9c...e21a?c=opus", "aac": "https://vybemusic.com/m/4f9c...e21a?c=aac" },
  "expires_at": "2026-10-21T18:00:00.000Z",
  "attribution": "Music from VYBE: Song Title by Artist Name"
}

For audio, the plain url picks a codec for the player (AAC for Apple devices, Opus elsewhere). Add ?c=opus, ?c=aac or ?c=mp3 to choose, and ?meta=1 to read the song's metadata (the META chunk) as JSON. For vybe, url is the whole file and meta_url is null; read the metadata with the SDK. Each call counts as one media link in your usage.

POST/v1/usage

Report what your listeners did. Up to 500 events per call.

FieldDescription
track_idThe song id.
eventstream, complete, skip or like.
secondsSeconds listened in this play (0 to 86400).
userOptional opaque listener id, hashed on arrival.
countryOptional 2 letter ISO country code.
curl -X POST https://vybemusic.com/api/library/v1/usage \
  -H "Authorization: Bearer $VYBE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"events":[{"track_id":"6c1f2a4e-8d3b-4f7a-9b21-0e5d7c9a1f30","event":"stream","seconds":187,"user":"u_83f1c2","country":"AE"}]}'
Response
{ "accepted": 1, "rejected": 0 }

Events for songs that are not shared with you are not counted and show up in rejected. Invalid events make the whole call fail with a 400 that names the event.

GET/v1/artists/:slug

An artist's public profile and the songs they share with you (newest first).

curl https://vybemusic.com/api/library/v1/artists/artist-name \
  -H "Authorization: Bearer $VYBE_KEY"
Response
{
  "name": "Artist Name",
  "slug": "artist-name",
  "avatar": "https://vybemusic.com/m/pub/a/.../image/avatar.webp",
  "cover": "https://vybemusic.com/m/pub/a/.../image/cover.webp",
  "city": "Dubai",
  "verified": true,
  "genres": ["House", "Afro House"],
  "url": "https://vybemusic.com/app/#/artist/artist-name",
  "tracks": [ { ...track } ]
}

The .vybe format

A .vybe file is one song in one file: metadata, cover art, one or more full length audio streams, preview clips and a waveform, packed as typed chunks behind a small index. All integers are little endian.

BytesField
0 to 3Magic, ASCII VYBE
4 to 5u16 version (1)
6 to 7u16 flags (bit 0: signed by VYBE)
8 to 11u32 number of chunks, N
12, 28 eachIndex entry per chunk: type (4 ASCII), u32 flags, u64 offset, u64 length, u32 CRC32

The index is always in the first bytes of the file, so a player can read it with one small Range request and then fetch only the chunks it needs.

ChunkContents
METAUTF-8 JSON metadata: title, artist, BPM, key, Camelot, energy, VYBEs, lyrics, credits, sections. Always first.
ARTWCover image (WebP or JPEG).
AOPS, AAAC, AMP3Full song as Ogg Opus, AAC (ADTS) or MP3.
POPS, PAAC, PMP3Preview clip in the same codecs.
PEAKWaveform, 2000 points from 0 to 255.
SIGNSignature written by VYBE. Opaque to clients.

Readers must ignore chunk types and META fields they do not know, so new ones can be added without breaking your app.

Reader SDK

vybe.js reads (and writes) .vybe files with no dependencies. It works in browsers, Web Workers, Cloudflare Workers and Node.

<script src="https://vybemusic.com/sdk/vybe.js"></script>
<script>
  // media.url from POST /v1/tracks/:id/stream with {"format":"vybe"}
  const song = await Vybe.open(media.url);              // reads only the index and META (Range requests)
  console.log(song.meta.title, song.meta.bpm);
  const audio = await song.audio({ prefer: ['opus', 'aac', 'mp3'] });   // best stream this device can play
  player.src = URL.createObjectURL(audio.blob);
  const peaks = await song.peaks();                      // Uint8Array waveform
  const lyrics = song.lyrics();                          // { plain, synced: [{ t, line }] } or null
</script>
CallReturns
Vybe.open(url, {fetch, headers})A remote file read with Range requests. Its get, audio, cover and peaks return promises.
Vybe.parse(arrayBuffer)A file held in memory: meta, chunks, has(type), get(type), cover(), audio({prefer, preview}), peaks(), lyrics(), verify().
Vybe.readIndex(bytes)Only the index, from the first bytes of a file.
Vybe.canPlay(codec)Whether this device can play opus, aac or mp3.
Vybe.pack({meta, chunks})Builds a .vybe file (for tools and tests).

Usage reporting rules

  • Send a stream event for every play that starts, with the seconds listened when it ends. Add complete when a song plays to the end, skip when a listener skips it, and like when they save or like it.
  • Send events in batches of up to 500, at least once a day. Sending them as they happen is fine too, within your rate limit.
  • Never send personal data. user must be an opaque id that means nothing outside your app; we store only a one-way hash of it. Leave it out if you do not need per-listener insights.
  • Artists see how their songs do in partner apps, so accurate reports help the artists who share music with you.

Attribution

  • Whenever a song plays or is listed, show "Music from VYBE" with the artist name and the song title. The attribution field gives you the exact text, for example Music from VYBE: Song Title by Artist Name.
  • Where your interface allows links, link to the artist or the song on VYBE (artist.url, links.vybe).
  • Keep credits, artwork, ISRC and other metadata intact. Do not suggest that an artist endorses your app.

Caching and removals

  • Stream only. Media links last 6 hours; ask for a new one when a link expires (it then answers 403). Do not store audio beyond the short buffering a player needs, and never offer downloads.
  • You may cache song metadata, but refresh it at least once a day. When a song or artist answers 404, it is no longer shared with you: remove it from your app, caches and saved lists within 30 days, or sooner if we ask.
  • Do not use any audio, lyrics, artwork or metadata to train or evaluate AI models.

The full rules are in the VYBE Library API and Partner Terms. Questions: [email protected].