Overview

The Tunearo Music Distribution API is a white‑label REST API that allows you to build your own music distribution platform. You can manage artists, releases, tracks, analytics, takedown requests, and notifications using a secure, Supabase‑powered backend.

Base URL: https://<project>.supabase.co/rest/v1/

Your unique project URL will be provided upon purchase and onboarding.

Authentication

The API uses Supabase Auth with JWTs. Every request must include a valid access token.

Headers

apikey: <your-anon-key>
Authorization: Bearer <user-jwt>
        
  • anon key – used in public clients (browser, mobile) with Row Level Security (RLS) enforced.
  • user JWT – generated via Supabase Auth; represents a logged‑in user.
  • service role key – server‑side only, full access, never expose to clients.

RLS policies control which rows each user can access. We configure these per customer during onboarding.

Data Model

The core entities in the Tunearo API are:

  • artist_profiles – artists on your platform.
  • releases – albums, EPs, singles.
  • tracks – individual tracks belonging to releases.
  • release_analytics – aggregated performance metrics per release.
  • track_analytics – performance metrics per track.
  • takedown_requests – DSP takedown requests.
  • notifications – system notifications for your users.

Additional internal tables (e.g. organization_settings, add_on_settings, tickets, ticket_replies, custom_scripts, whitelabel_payments, partners, api_keys, users) are used by Tunearo to operate your white‑label platform and are not typically accessed directly by your end‑users.

Endpoints

Artist Profiles

Manage artists on your platform.

List artists

GET /artist_profiles
          

Create artist

POST /artist_profiles
Content-Type: application/json

{
  "name": "Artist Name",
  "bio": "Short bio",
  "spotify_id": "string",
  "apple_id": "string"
}
          

Releases

Represents albums, EPs, and singles.

List releases

GET /releases?artist_id=eq.<artist_uuid>
          

Create release

POST /releases
Content-Type: application/json

{
  "title": "My Album",
  "artist_id": "uuid",
  "release_date": "2025-03-01",
  "status": "draft"
}
          

Update release

PATCH /releases?id=eq.<release_uuid>
Content-Type: application/json

{
  "status": "submitted"
}
          

Delete release

DELETE /releases?id=eq.<release_uuid>
          

Tracks

Tracks belong to releases and contain ISRC and duration metadata.

List tracks for a release

GET /tracks?release_id=eq.<release_uuid>
          

Create track

POST /tracks
Content-Type: application/json

{
  "release_id": "uuid",
  "title": "Track Name",
  "isrc": "US1234567890",
  "duration": 180
}
          

Update track

PATCH /tracks?id=eq.<track_uuid>
Content-Type: application/json

{
  "title": "New Track Title"
}
          

Release Analytics

Aggregated performance metrics per release (streams, downloads, revenue, etc.).

Get analytics for a release

GET /release_analytics?release_id=eq.<release_uuid>
          

Track Analytics

Performance metrics per track.

Get analytics for a track

GET /track_analytics?track_id=eq.<track_uuid>
          

Takedown Requests

Used to request removal of content from DSPs for legal or policy reasons.

List takedown requests

GET /takedown_requests
          

Create takedown request

POST /takedown_requests
Content-Type: application/json

{
  "release_id": "uuid",
  "reason": "Copyright claim",
  "status": "pending"
}
          

Notifications

System notifications for your users (e.g. release approved, DSP updates, takedown status).

List notifications for a user

GET /notifications?user_id=eq.<user_uuid>
          

Mark notification as read

PATCH /notifications?id=eq.<notification_uuid>
Content-Type: application/json

{
  "read": true
}
          

Release Workflow

A typical release flow on your white‑label platform:

  1. Create an artist in artist_profiles.
  2. Create a release in releases linked to that artist.
  3. Add tracks in tracks linked to the release.
  4. Upload audio and artwork via your storage integration (outside this REST spec).
  5. Update the release status to submitted.
  6. Tunearo’s backend handles DSP delivery.
  7. Analytics appear in release_analytics and track_analytics.
  8. Notifications are created in notifications for key events.

Takedown Workflow

  1. Your user or team identifies content that must be removed.
  2. You create a record in takedown_requests with a reason and status pending.
  3. Tunearo processes the request and updates the status (e.g. processing, completed).
  4. Notifications can be sent via notifications to inform users of progress.

Error Handling

Errors follow a standard JSON structure from PostgREST / Supabase.

{
  "code": "PGRST301",
  "message": "Row level security policy violation",
  "details": null,
  "hint": null
}
        

Common HTTP Status Codes

  • 400 Bad Request – malformed request or invalid parameters.
  • 401 Unauthorized – missing or invalid JWT / apikey.
  • 403 Forbidden – RLS blocked access to the resource.
  • 404 Not Found – resource or endpoint not found.
  • 409 Conflict – unique constraint violation or conflicting data.
  • 500 Internal Server Error – unexpected server error.

Common Mistakes & Fixes

  • Missing Authorization header – ensure you send both apikey and Authorization.
  • Invalid UUID – IDs must be valid UUID strings.
  • RLS violation – user may not have access to that row; check your user’s role and policies.
  • Missing required fields – ensure required fields like title, artist_id, release_id are present.
  • Wrong filter syntax – use PostgREST filters like ?field=eq.value.

Testing Guide

You can test the API using cURL, Postman, or your own scripts.

Example: List releases (cURL)

curl "https://<project>.supabase.co/rest/v1/releases" \
  -H "apikey: <your-anon-key>" \
  -H "Authorization: Bearer <user-jwt>"
        

Example: Create release (cURL)

curl -X POST "https://<project>.supabase.co/rest/v1/releases" \
  -H "apikey: <your-anon-key>" \
  -H "Authorization: Bearer <user-jwt>" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "My Album",
    "artist_id": "uuid",
    "release_date": "2025-03-01",
    "status": "draft"
  }'
        

Rate Limits

Tunearo enforces reasonable rate limits to ensure platform stability. Exact limits may depend on your plan and usage profile. If you anticipate high traffic or bulk operations, contact us to discuss scaling options.

Versioning

The current API is considered v1. Breaking changes will be introduced via:

  • New endpoints or fields added in a backwards‑compatible way.
  • New versions exposed via separate schemas or paths if needed.
  • Advance notice for any breaking changes.

SDK Examples

JavaScript (Supabase client)

import { createClient } from "@supabase/supabase-js";

const supabase = createClient("https://<project>.supabase.co", "<anon-key>");

// List releases
const { data, error } = await supabase
  .from("releases")
  .select("*")
  .eq("artist_id", "artist-uuid");
        

Python

import requests

url = "https://<project>.supabase.co/rest/v1/releases"
headers = {
  "apikey": "<your-anon-key>",
  "Authorization": "Bearer <user-jwt>"
}

res = requests.get(url, headers=headers, params={"artist_id": "eq.artist-uuid"})
print(res.json())
        

cURL

curl "https://<project>.supabase.co/rest/v1/artist_profiles" \
  -H "apikey: <your-anon-key>" \
  -H "Authorization: Bearer <user-jwt>"
        

Support

For technical issues, integration questions, or feature requests, you can contact our team:

Email: support@tunearo.com

We aim to respond as quickly as possible and work with you to ensure a smooth integration experience.