Playlist Pilot API
Programmatic access to a curated playlist network — AI matching, pitch generation, and bot detection.
Overview
All endpoints return JSON. The base URL for all requests is:
https://playlistpilotapp.com/api/v1
Authentication
All endpoints require a Bearer token in the Authorization header.
Add this header to every request:
Authorization: Bearer your_api_key_here
curl -X GET \
https://playlistpilotapp.com/api/v1/genres \
-H "Authorization: Bearer your_api_key_here"
Rate Limits
Rate limits are per API key, per endpoint, on a sliding 1-hour window. Exceeding limits returns 429 RateLimitExceeded.
| Endpoint | Limit / hour | Notes |
|---|---|---|
| POST /match | 60 | Scores against our curator network |
| POST /expand-artists | 20 | AI-powered — higher latency |
| GET /playlists/{id} | 120 | Live fetch — works for any public playlist |
| GET /playlists/{id}/similar | 60 | Requires ID from match results |
| GET /playlists/{id}/contacts | 30 | Always live — fresh scrape + AI extraction |
| GET /playlists/{id}/bot-check | 20 | Live analysis |
| POST /playlists/{id}/pitch | 30 | AI-powered — higher latency |
| GET /genres | 120 | Cached in-memory |
Error Reference
| HTTP Code | Error Type | Meaning |
|---|---|---|
| 200 | — | Success |
| 400 | BadRequest | Missing or invalid request parameters |
| 401 | Unauthorized | Missing, invalid, or revoked API key |
| 404 | NotFound | Playlist ID not found in database |
| 429 | RateLimitExceeded | Hourly rate limit reached for this endpoint |
| 500 | InternalError | Server-side failure — try again shortly |
Matching
AI-powered playlist matching. Returns the top playlists from the curator network ranked by genre and artist overlap.
| Field | Type | Description | Required |
|---|---|---|---|
| genres | string[] | Song genres (e.g. ["indie pop", "bedroom pop"]) | required* |
| artists | string[] | Artist names for audience overlap | required* |
| similar_artists | string[] | Similar/comparable artists | optional |
| follower_min | integer | Minimum playlist followers (default: 50) | optional |
| follower_max | integer | Maximum playlist followers (default: 2,027,415) | optional |
| limit | integer | Number of results, max 50 (default: 10) | optional |
* At least one of genres or artists is required.
{ "genres": ["indie pop"], "artists": ["Phoebe Bridgers"], "follower_min": 1000, "limit": 5 }
{ "success": true, "total_found": 247, "returned": 5, "matches": [{ "playlist_id": "...", "playlist_name": "Indie Vibes", "followers": 42500, "match_score": 94.2, "spotify_url": "https://open.spotify.com/playlist/..." }] }
Parameters
Response
AI artist intelligence. Provide a comma-separated string or an array of artist names and receive inferred genres and tiered similar artists — optimised for use as genres and similar_artists inputs to the match endpoint.
{ "artists": "Billie Eilish, Lorde" }
// or
{ "artists": ["Billie Eilish", "Lorde"] }{
"success": true,
"genres": ["alt pop", "dark pop", "indie pop"],
"tier1_artists": ["Olivia Rodrigo", "Gracie Abrams", ...],
"tier2_artists": ["Halsey", "Charli XCX", ...]
}Parameters
Response
Playlist Data
Full metadata for a single playlist, fetched live. Works for any public playlist ID — not limited to our curator network.
Path Parameters
Response
Returns playlists most similar to the specified playlist, based on genre and artist overlap.
Parameters
Response
All unique genres present in our curator network, sorted by playlist count. Returns a flat array of strings. Useful for building genre pickers or validating inputs before a match call. Response is cached in-memory.
GET /api/v1/genres{ "success": true, "genres": ["hip hop", "indie pop", "r&b", ...] }No Parameters
Response
Contacts
Extract verified curator contact details — email addresses, Instagram handles, Twitter/X profiles, TikTok accounts, and personal websites. Results are cached in the Playlist Pilot database, so repeat lookups are instant.
Fetches the curator's contact info fresh on every request — no stale cache. Any email, Instagram, Twitter/X, TikTok, or website is extracted and returned. Results are written to cache after extraction but never read from it, so you always get the latest data. The response includes a contact_url ready to open directly.
| Field | Type | Description |
|---|---|---|
| contact_type | string | email, instagram, twitter, tiktok, website, or other |
| contact_raw | string | Raw value — just the username (no URL prefix) for social platforms, full email address, or URL for websites |
| contact_display | string | Human-readable label, e.g. Instagram: @indievibes |
| contact_url | string | Ready-to-use URL: mailto:x@y.com, https://www.instagram.com/user, etc. |
GET /api/v1/playlists/37i9dQZF1DXcBWIGoYBM5M/contacts
{
"success": true,
"playlist_id": "37i9dQZF1DXcBWIGoYBM5M",
"spotify_url": "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M",
"contact_found": true,
"contact": {
"contact_type": "instagram",
"contact_raw": "indievibes",
"contact_display": "Instagram: @indievibes",
"contact_url": "https://www.instagram.com/indievibes"
}
}
Parameters
Response
Trust & Safety
Live bot-detection analysis. Returns a trust score (0–100), a badge, and the individual signals that contributed to the result.
Trusted (score ≥ 70) · Caution (40–69) · Risky (below 40)Path Parameters
Response
Pitch Generation
Generate a personalised AI pitch for a specific playlist, contextualised using the playlist's genre profile and your song metadata.
| Field | Type | Description | Required |
|---|---|---|---|
| artist_name | string | Artist or band name | required |
| song_name | string | Song/track title | required |
| song_url | string | Streaming link for the track | optional |
| genres | string[] | Song genres | optional |
| similar_artists | string[] | Comparable artists | optional |
| tone | string | professional · casual · enthusiastic | optional |
| mood | string | respectful · bold · humble | optional |
| language | string | Output language (default: english) | optional |
| custom_instructions | string | Freeform instructions woven into the pitch — e.g. "mention we have 50k monthly listeners" or "keep it under 100 words" | optional |
Parameters
Response
Internal · Owner Only
Not available to partner accounts. Requires the private owner key, not a partner API key. Used by our own marketing pipeline.
Returns the most recent users bucketed into lifecycle segments (max 50 groups) so a marketing pipeline can send one tailored email per group. Only opted-in, active users are included — opted-out and disabled accounts are never returned. Each user includes a signed unsubscribe_url: embed it in the email footer so recipients can opt out in one click. Once they do, they drop out of every future response automatically.
| Field | Type | Description | Required |
|---|---|---|---|
| limit | integer | Number of most-recent users to scan, max 5000 (default: 1000) | optional |
GET /api/v1/segments?limit=1000
Authorization: Bearer <owner_key>
{ "success": true, "generated_at": "2026-06-26T12:00:00+00:00", "total_users": 1000, "group_count": 8, "max_groups": 50, "groups": [ { "key": "signed_up_idle", "label": "Signed up, did nothing", "description": "...", "count": 240, "users": [ { "email": "a@b.com", "first_name": "Alex", "plan": "free", "days_since_signup": 3, "unsubscribe_url": "https://playlistpilotapp.com/unsubscribe?uid=42&token=..." } ] } ] }