Table of Contents

API Documentation

Everything you need to integrate the plynx Music Intelligence API.

Quick Start

Get your API key in 30 seconds. No sign-up form, no credit card.

1. Get your API key

curl
curl -X POST https://dashboard-ruddy-beta.vercel.app/api/v1/keys \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com"}'
Response
{
  "data": {
    "api_key": "plx_d89f0a400d0dc5058ce5cf04e23e9906",
    "tier": "free",
    "rate_limit": "100 requests/day",
    "note": "Save this key — it will not be shown again."
  }
}

2. Make your first request

curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/songs?page_size=2&genre=K-Pop" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "data": [
    {
      "id": 187251,
      "title": "Grown",
      "artist": "2PM",
      "genre_primary": "K-Pop",
      "mood_primary": "contemplative",
      "energy": 5,
      "valence": 6,
      "tempo_feel": "medium",
      "era_feel": "2010s"
    }
  ],
  "meta": {
    "page": 1,
    "page_size": 2,
    "total": 7726,
    "total_pages": 3863
  }
}

Free tier gives you 100 requests/day with basic song fields. Upgrade to Pro for interpretations and structured text, or Enterprise for embeddings and bulk export.

Authentication

Include your API key in the Authorization header with every request.

HTTP Header
Authorization: Bearer plx_d89f0a400d0dc5058ce5cf04e23e9906

All API keys start with plx_. Keys are shown only once at creation — save it immediately.

Endpoints

Base URL: https://dashboard-ruddy-beta.vercel.app/api/v1

MethodEndpointDescriptionMin Tier
GET/songsList songs with pagination and filtersFree
GET/songs/:idGet song by IDFree
GET/songs/searchSearch by title or artistFree
GET/songs/randomGet random songsFree
GET/songs/similarFind similar songs by vector similarityEnterprise
GET/statsCatalog statistics and distributionsFree
GET/exportBulk NDJSON downloadEnterprise
POST/keysCreate API keyNone

Response Format

All responses use a consistent envelope:

Success (list)
{
  "data": [ ... ],
  "meta": { "page": 1, "page_size": 24, "total": 56951, "total_pages": 2373 }
}
Success (single)
{
  "data": { ... }
}

Field Selection

Use the fields parameter to select specific fields. Only fields available to your tier are returned.

curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/songs?page_size=5&fields=title,artist,mood_primary,energy" \
  -H "Authorization: Bearer YOUR_API_KEY"

List Songs

GET/songs

Returns a paginated list of songs. Default 24 per page, max 100.

Query Parameters

pageintegerPage number (default: 1)
page_sizeintegerResults per page, 1-100 (default: 24)
genrestringFilter by genre_primary (exact match)
moodstringFilter by mood_primary (exact match)
erastringFilter by era_feel (exact match)
qstringSearch title or artist (case-insensitive)
energy_minintegerMin energy (1-10)
energy_maxintegerMax energy (1-10)
valence_minintegerMin valence (1-10)
valence_maxintegerMax valence (1-10)
sortstringSort by: created_at, title, artist, energy, valence (default: created_at)
orderstringSort order: asc, desc (default: desc)
fieldsstringComma-separated field list
curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/songs?genre=K-Pop&page_size=2&fields=id,title,artist,genre_primary,mood_primary,energy" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "data": [
    {
      "id": 187251,
      "title": "Grown",
      "artist": "2PM",
      "genre_primary": "K-Pop",
      "mood_primary": "contemplative",
      "energy": 5
    },
    {
      "id": 187252,
      "title": "Light of My Life",
      "artist": "2PM",
      "genre_primary": "K-Pop",
      "mood_primary": "romantic",
      "energy": 2
    }
  ],
  "meta": {
    "page": 1,
    "page_size": 2,
    "total": 7726,
    "total_pages": 3863
  }
}

Song Detail

GET/songs/:id

Returns full detail for a single song. Higher tiers get additional fields like interpretation and structured_text.

curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/songs/46232" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response (Pro tier)
{
  "data": {
    "id": 46232,
    "title": "Born in Chicago",
    "artist": "Paul Butterfield",
    "genre_primary": "Blues",
    "subgenre": "Electric Blues Rock",
    "mood_primary": "defiant",
    "energy": 9,
    "valence": 7,
    "danceability": 6,
    "acousticness": 1,
    "tempo_feel": "fast",
    "era_feel": "1960s",
    "sonic_texture": "raw, dense, electric",
    "cultural_context": "American Chicago blues, urban electric North Side tradition",
    "interpretation": "Paul Butterfield and his band announced themselves with this track as something the American music scene hadn't quite encountered: white musicians from Chicago's North Side playing the South Side's tradition with genuine authority...",
    "catalog_key": "borninchicago|||paulbutterfield"
  }
}
GET/songs/search

Case-insensitive search across song titles and artist names.

Query Parameters

qstring*Search query
pageintegerPage number (default: 1)
page_sizeintegerResults per page, 1-100 (default: 24)
fieldsstringComma-separated field list
curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/songs/search?q=BTS&page_size=3&fields=id,title,artist,genre_primary,mood_primary" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "data": [
    {
      "id": 10220,
      "title": "00:00 (Zero O'Clock)",
      "artist": "BTS",
      "genre_primary": "K-Pop",
      "mood_primary": "comforting"
    },
    {
      "id": 10191,
      "title": "134340",
      "artist": "BTS",
      "genre_primary": "K-Pop",
      "mood_primary": "melancholic"
    }
  ],
  "meta": {
    "page": 1,
    "page_size": 3,
    "total": 247,
    "total_pages": 83
  }
}

Random Songs

GET/songs/random

Returns random songs from the catalog. Useful for discovery features and testing.

Query Parameters

limitintegerNumber of songs, 1-50 (default: 10)
fieldsstringComma-separated field list
curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/songs/random?limit=3&fields=id,title,artist,genre_primary,mood_primary" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "data": [
    {
      "id": 121945,
      "title": "Robinson",
      "artist": "Spitz",
      "genre_primary": "J-Rock",
      "mood_primary": "nostalgic"
    },
    {
      "id": 35821,
      "title": "Breathe",
      "artist": "Lee Hi",
      "genre_primary": "K-Pop",
      "mood_primary": "melancholic"
    }
  ]
}

Similar Songs

GET/songs/similarEnterprise

Finds semantically similar songs using 768-dimensional embedding cosine similarity. Powered by pgvector HNSW index for fast approximate nearest neighbor search.

Query Parameters

song_idinteger*Source song ID (plynx song ID)
limitintegerMax results, 1-50 (default: 20)
fieldsstringComma-separated field list
curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/songs/similar?song_id=46232&limit=5" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "data": [
    {
      "id": 46198,
      "title": "Crossroads",
      "artist": "Cream",
      "genre_primary": "Blues",
      "mood_primary": "defiant",
      "similarity": 0.92
    },
    {
      "id": 46215,
      "title": "Red House",
      "artist": "Jimi Hendrix",
      "genre_primary": "Blues",
      "mood_primary": "sensual",
      "similarity": 0.87
    }
  ]
}

Export

GET/exportEnterprise

Bulk export the catalog as streaming NDJSON (newline-delimited JSON). Each line is a complete JSON object. Includes all fields available to your tier.

Query Parameters

genrestringFilter by genre
moodstringFilter by mood
fieldsstringComma-separated field list
curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/export?genre=K-Pop&fields=title,artist,genre_primary,mood_primary,interpretation" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o plynx_kpop.ndjson
Output format (NDJSON)
{"title":"Grown","artist":"2PM","genre_primary":"K-Pop","mood_primary":"contemplative","interpretation":"..."}
{"title":"Light of My Life","artist":"2PM","genre_primary":"K-Pop","mood_primary":"romantic","interpretation":"..."}
...

Stats

GET/stats

Returns catalog-wide statistics including genre, mood, and era distributions.

curl
curl "https://dashboard-ruddy-beta.vercel.app/api/v1/stats" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "data": {
    "catalog": {
      "totalSongs": 56951,
      "withCover": 29141,
      "withPreview": 29141,
      "uniqueArtists": 12053,
      "uniqueGenres": 596,
      "uniqueMoods": 528
    },
    "genres": [
      { "genre_primary": "K-Pop", "cnt": 7726 },
      { "genre_primary": "Hip-Hop", "cnt": 5166 },
      { "genre_primary": "R&B", "cnt": 3210 },
      ...
    ],
    "moods": [
      { "mood_primary": "melancholic", "cnt": 13428 },
      { "mood_primary": "romantic", "cnt": 5220 },
      ...
    ],
    "eras": [...],
    "attributes": {
      "energy": { "1": 643, "2": 7187, ... },
      "valence": { ... },
      "danceability": { ... },
      "acousticness": { ... }
    }
  }
}

Tier-Based Field Access

The fields included in API responses depend on your subscription tier. Use the fields parameter to select specific fields — any field outside your tier is silently excluded.

FieldFreeProEnterprise
id, title, artistYYY
genre_primary, genre_secondary, subgenreYYY
mood_primary, mood_secondaryYYY
energy, valence, danceability, acousticnessYYY
tempo_feel, era_feelYYY
album_cover_url, preview_url, album_titleYYY
created_atYYY
interpretation-YY
structured_text-YY
sonic_texture, cultural_context-YY
vocal_presence, similar_artists-YY
music_track_id, catalog_key-YY
embedding (768 dimensions)--Y

Rate Limits

Rate limits are enforced per API key on a rolling 24-hour window. Exceeding the limit returns 429 Too Many Requests.

TierDaily Limit
Free100 / day
Pro10,000 / day
Enterprise100,000 / day

Rate limit headers are included in every response:

Response Headers
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 91

Errors

The API returns standard HTTP status codes with a JSON error body.

Error Response
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Your free tier allows 100 requests per day.",
    "status": 429
  }
}
StatusCodeDescription
400VALIDATION_ERRORInvalid query parameters or request body
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENEndpoint requires a higher tier
404NOT_FOUNDSong ID does not exist
429RATE_LIMIT_EXCEEDEDDaily rate limit exceeded
500INTERNAL_ERRORServer error (retry with backoff)

Need help? Contact pukaworks@gmail.com