# API Reference Comprehensive API documentation for Sonic Cloud platform endpoints. --- ## Authentication Endpoints API endpoints for user registration, login, and password recovery. ### POST /api/auth/register **Description**: Register a new user account on the platform. **Authentication**: Not required
🔧 Technical Details **Request Body**: ```json { "email": "user@example.com", "password": "securePassword123", "username": "username", "displayName": "Display Name" // Optional } ``` **Response** (201 Created): ```json { "user": { "id": "uuid", "email": "user@example.com", "username": "username", "displayName": "Display Name", "role": "USER" }, "token": "jwt_token_string" } ``` **Error Responses**: - 400 Bad Request: Missing required fields or invalid email format - 409 Conflict: Email or username already exists **Implementation**: `app/api/auth/register/route.ts`
--- ### POST /api/auth/login **Description**: Authenticate user credentials and receive a session token. **Authentication**: Not required
🔧 Technical Details **Request Body**: ```json { "email": "user@example.com", "password": "securePassword123" } ``` **Response** (200 OK): ```json { "user": { "id": "uuid", "email": "user@example.com", "username": "username", "displayName": "Display Name", "role": "USER" }, "token": "jwt_token_string" } ``` **Error Responses**: - 400 Bad Request: Missing email or password - 401 Unauthorized: Invalid credentials **Implementation**: `app/api/auth/login/route.ts`
--- ### POST /api/auth/forgot-password **Description**: Initiate password reset process by sending reset token via email. **Authentication**: Not required
🔧 Technical Details **Request Body**: ```json { "email": "user@example.com" } ``` **Response** (200 OK): ```json { "message": "Password reset email sent" } ``` **Error Responses**: - 400 Bad Request: Missing email - 404 Not Found: User with email not found **Implementation**: `app/api/auth/forgot-password/route.ts` **Note**: Reset token is generated and stored with expiration timestamp. Token is sent via email (email service integration required).
--- ### POST /api/auth/reset-password **Description**: Reset user password using a valid reset token from email. **Authentication**: Not required
🔧 Technical Details **Request Body**: ```json { "token": "reset_token_from_email", "newPassword": "newSecurePassword123" } ``` **Response** (200 OK): ```json { "message": "Password reset successful" } ``` **Error Responses**: - 400 Bad Request: Missing token or newPassword - 401 Unauthorized: Invalid or expired token - 404 Not Found: User not found **Implementation**: `app/api/auth/reset-password/route.ts`
--- ## User Endpoints API endpoints for managing user profile information. ### GET /api/users/me **Description**: Retrieve the current authenticated user's profile information. **Authentication**: Required (JWT token)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **Response** (200 OK): ```json { "id": "uuid", "email": "user@example.com", "username": "username", "displayName": "Display Name", "bio": "User biography text", "avatarUrl": "https://example.com/avatar.jpg", "websiteUrl": "https://example.com", "role": "USER", "createdAt": "2025-01-01T00:00:00.000Z", "artist": { "id": "uuid", "name": "Artist Name" } // If user is an artist } ``` **Error Responses**: - 401 Unauthorized: Missing or invalid token - 404 Not Found: User not found **Implementation**: `app/api/users/me/route.ts`
--- ### PUT /api/users/me **Description**: Update the current authenticated user's profile information. **Authentication**: Required (JWT token)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **Request Body** (all fields optional): ```json { "displayName": "New Display Name", "bio": "Updated biography", "avatarUrl": "https://example.com/new-avatar.jpg", "websiteUrl": "https://example.com" } ``` **Response** (200 OK): ```json { "id": "uuid", "email": "user@example.com", "username": "username", "displayName": "New Display Name", "bio": "Updated biography", "avatarUrl": "https://example.com/new-avatar.jpg", "websiteUrl": "https://example.com", "role": "USER" } ``` **Error Responses**: - 401 Unauthorized: Missing or invalid token - 404 Not Found: User not found **Implementation**: `app/api/users/me/route.ts`
--- ## Artist Endpoints API endpoints for managing artist profiles, songs, and albums. ### POST /api/artists **Description**: Create a new artist profile for the authenticated user. **Authentication**: Required (JWT token)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **Request Body**: ```json { "name": "Artist Name", "bio": "Artist biography", "avatarUrl": "https://example.com/avatar.jpg", "bannerUrl": "https://example.com/banner.jpg", "websiteUrl": "https://example.com", "spotifyUrl": "https://open.spotify.com/artist/...", "instagramUrl": "https://instagram.com/artist" } ``` **Response** (201 Created): ```json { "id": "uuid", "userId": "uuid", "name": "Artist Name", "slug": "artist-name", "bio": "Artist biography", "verified": false, "createdAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 400 Bad Request: Missing required fields or user already has artist profile - 401 Unauthorized: Missing or invalid token **Implementation**: `app/api/artists/route.ts` **Note**: Slug is auto-generated from artist name for URL-friendly identifiers.
--- ### GET /api/artists/{id} **Description**: Retrieve detailed information about a specific artist including statistics and relationships. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Artist UUID **Response** (200 OK): ```json { "id": "uuid", "name": "Artist Name", "slug": "artist-name", "bio": "Artist biography", "avatarUrl": "https://example.com/avatar.jpg", "bannerUrl": "https://example.com/banner.jpg", "verified": true, "websiteUrl": "https://example.com", "spotifyUrl": "https://open.spotify.com/artist/...", "instagramUrl": "https://instagram.com/artist", "createdAt": "2025-01-01T00:00:00.000Z", "_count": { "songs": 42, "albums": 5 }, "label": { "id": "uuid", "name": "Label Name" } // If artist is signed to label } ``` **Error Responses**: - 404 Not Found: Artist not found **Implementation**: `app/api/artists/[id]/route.ts`
--- ### PUT /api/artists/{id} **Description**: Update artist profile information. Only the artist owner can perform this action. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Artist UUID **Request Body** (all fields optional): ```json { "name": "Updated Artist Name", "bio": "Updated biography", "avatarUrl": "https://example.com/new-avatar.jpg", "bannerUrl": "https://example.com/new-banner.jpg", "websiteUrl": "https://example.com", "spotifyUrl": "https://open.spotify.com/artist/...", "instagramUrl": "https://instagram.com/artist" } ``` **Response** (200 OK): ```json { "id": "uuid", "name": "Updated Artist Name", "slug": "updated-artist-name", "bio": "Updated biography", "verified": true } ``` **Error Responses**: - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the artist owner - 404 Not Found: Artist not found **Implementation**: `app/api/artists/[id]/route.ts`
--- ### GET /api/artists/{id}/songs **Description**: Retrieve all public songs by a specific artist. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Artist UUID **Response** (200 OK): ```json [ { "id": "uuid", "title": "Song Title", "duration": 240, "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "playCount": 1234, "isPublic": true, "createdAt": "2025-01-01T00:00:00.000Z", "album": { "id": "uuid", "title": "Album Title" }, "genres": [ { "name": "Rock", "slug": "rock" } ] } ] ``` **Error Responses**: - 404 Not Found: Artist not found **Implementation**: `app/api/artists/[id]/songs/route.ts` **Note**: Only returns songs where `isPublic = true`.
--- ### GET /api/artists/{id}/albums **Description**: Retrieve all albums by a specific artist, sorted by release date (newest first). **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Artist UUID **Response** (200 OK): ```json [ { "id": "uuid", "title": "Album Title", "coverUrl": "https://example.com/cover.jpg", "releaseDate": "2025-01-01T00:00:00.000Z", "albumType": "ALBUM", // or "EP", "SINGLE" "_count": { "songs": 12 } } ] ``` **Error Responses**: - 404 Not Found: Artist not found **Implementation**: `app/api/artists/[id]/albums/route.ts`
--- ## Song Endpoints API endpoints for uploading, managing, and tracking song playback. ### POST /api/songs/upload **Description**: Upload a new song to the platform. Only users with artist profiles can upload songs. **Authentication**: Required (JWT token, artist only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **Request Body**: ```json { "title": "Song Title", "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "duration": 240, // in seconds "albumId": "uuid", // Optional "isPublic": true, "genres": ["rock", "indie"] // Array of genre slugs } ``` **Response** (201 Created): ```json { "id": "uuid", "artistId": "uuid", "title": "Song Title", "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "duration": 240, "playCount": 0, "isPublic": true, "createdAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 400 Bad Request: Missing required fields - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not an artist **Implementation**: `app/api/songs/upload/route.ts`
--- ### GET /api/songs/{id} **Description**: Retrieve detailed information about a specific song. Public songs are always accessible, private songs only accessible to owner. **Authentication**: Optional (required for private songs)
🔧 Technical Details **URL Parameters**: - `id` (string): Song UUID **Request Headers** (optional for public songs): ``` Authorization: Bearer jwt_token_string ``` **Response** (200 OK): ```json { "id": "uuid", "title": "Song Title", "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "duration": 240, "playCount": 1234, "isPublic": true, "createdAt": "2025-01-01T00:00:00.000Z", "artist": { "id": "uuid", "name": "Artist Name", "slug": "artist-name", "verified": true }, "album": { "id": "uuid", "title": "Album Title", "coverUrl": "https://example.com/album-cover.jpg" }, "genres": [ { "id": "uuid", "name": "Rock", "slug": "rock", "color": "#FF0000" } ] } ``` **Error Responses**: - 403 Forbidden: Song is private and user is not owner - 404 Not Found: Song not found **Implementation**: `app/api/songs/[id]/route.ts`
--- ### PUT /api/songs/{id} **Description**: Update song information. Only the song owner (artist) can perform this action. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Song UUID **Request Body** (all fields optional): ```json { "title": "Updated Song Title", "coverUrl": "https://example.com/new-cover.jpg", "isPublic": false, "albumId": "uuid", "genres": ["rock", "pop"] } ``` **Response** (200 OK): ```json { "id": "uuid", "title": "Updated Song Title", "coverUrl": "https://example.com/new-cover.jpg", "isPublic": false, "updatedAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the song owner - 404 Not Found: Song not found **Implementation**: `app/api/songs/[id]/route.ts`
--- ### DELETE /api/songs/{id} **Description**: Delete a song from the platform. Only the song owner (artist) can perform this action. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Song UUID **Response** (204 No Content) **Error Responses**: - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the song owner - 404 Not Found: Song not found **Implementation**: `app/api/songs/[id]/route.ts` **Note**: Deleting a song also removes it from all playlists and deletes associated share links.
--- ### POST /api/songs/{id}/play **Description**: Increment the play count for a song. Used for tracking song popularity. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Song UUID **Response** (200 OK): ```json { "playCount": 1235 } ``` **Error Responses**: - 404 Not Found: Song not found **Implementation**: `app/api/songs/[id]/play/route.ts` **Note**: This endpoint is called each time a song starts playing. It's rate-limited per user to prevent abuse.
--- ## Album Endpoints API endpoints for creating and managing music albums. ### POST /api/albums **Description**: Create a new album. Only users with artist profiles can create albums. **Authentication**: Required (JWT token, artist only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **Request Body**: ```json { "title": "Album Title", "coverUrl": "https://example.com/cover.jpg", "releaseDate": "2025-01-01", "albumType": "ALBUM", // or "EP", "SINGLE" "description": "Album description text" } ``` **Response** (201 Created): ```json { "id": "uuid", "artistId": "uuid", "title": "Album Title", "coverUrl": "https://example.com/cover.jpg", "releaseDate": "2025-01-01T00:00:00.000Z", "albumType": "ALBUM", "description": "Album description text", "createdAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 400 Bad Request: Missing required fields - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not an artist **Implementation**: `app/api/albums/route.ts`
--- ### GET /api/albums/{id} **Description**: Retrieve album details including all songs in the album. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Album UUID **Response** (200 OK): ```json { "id": "uuid", "title": "Album Title", "coverUrl": "https://example.com/cover.jpg", "releaseDate": "2025-01-01T00:00:00.000Z", "albumType": "ALBUM", "description": "Album description text", "artist": { "id": "uuid", "name": "Artist Name", "slug": "artist-name", "verified": true }, "songs": [ { "id": "uuid", "title": "Song Title", "duration": 240, "trackNumber": 1, "audioUrl": "https://example.com/audio.mp3", "playCount": 1234 } ] } ``` **Error Responses**: - 404 Not Found: Album not found **Implementation**: `app/api/albums/[id]/route.ts`
--- ### PUT /api/albums/{id} **Description**: Update album information. Only the album owner (artist) can perform this action. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Album UUID **Request Body** (all fields optional): ```json { "title": "Updated Album Title", "coverUrl": "https://example.com/new-cover.jpg", "description": "Updated description", "albumType": "EP" } ``` **Response** (200 OK): ```json { "id": "uuid", "title": "Updated Album Title", "coverUrl": "https://example.com/new-cover.jpg", "description": "Updated description", "albumType": "EP", "updatedAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the album owner - 404 Not Found: Album not found **Implementation**: `app/api/albums/[id]/route.ts`
--- ### DELETE /api/albums/{id} **Description**: Delete an album from the platform. Only the album owner (artist) can perform this action. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Album UUID **Response** (204 No Content) **Error Responses**: - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the album owner - 404 Not Found: Album not found **Implementation**: `app/api/albums/[id]/route.ts` **Note**: Deleting an album does NOT delete the songs in the album. Songs become album-less but remain on the platform.
--- ## Playlist Endpoints API endpoints for creating and managing user playlists. ### GET /api/playlists **Description**: Retrieve all playlists created by the authenticated user. **Authentication**: Required (JWT token)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **Response** (200 OK): ```json [ { "id": "uuid", "title": "Playlist Title", "description": "Playlist description", "coverUrl": "https://example.com/cover.jpg", "isPublic": true, "createdAt": "2025-01-01T00:00:00.000Z", "_count": { "songs": 24 } } ] ``` **Error Responses**: - 401 Unauthorized: Missing or invalid token **Implementation**: `app/api/playlists/route.ts`
--- ### POST /api/playlists **Description**: Create a new playlist for the authenticated user. **Authentication**: Required (JWT token)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **Request Body**: ```json { "title": "Playlist Title", "description": "Playlist description", "coverUrl": "https://example.com/cover.jpg", "isPublic": true } ``` **Response** (201 Created): ```json { "id": "uuid", "userId": "uuid", "title": "Playlist Title", "description": "Playlist description", "coverUrl": "https://example.com/cover.jpg", "isPublic": true, "createdAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 400 Bad Request: Missing title - 401 Unauthorized: Missing or invalid token **Implementation**: `app/api/playlists/route.ts`
--- ### GET /api/playlists/{id} **Description**: Retrieve playlist details with all songs. Public playlists are accessible to everyone, private playlists only to owner. **Authentication**: Optional (required for private playlists)
🔧 Technical Details **URL Parameters**: - `id` (string): Playlist UUID **Request Headers** (optional for public playlists): ``` Authorization: Bearer jwt_token_string ``` **Response** (200 OK): ```json { "id": "uuid", "title": "Playlist Title", "description": "Playlist description", "coverUrl": "https://example.com/cover.jpg", "isPublic": true, "createdAt": "2025-01-01T00:00:00.000Z", "user": { "id": "uuid", "username": "username", "displayName": "Display Name" }, "songs": [ { "id": "uuid", "song": { "id": "uuid", "title": "Song Title", "duration": 240, "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "artist": { "id": "uuid", "name": "Artist Name" } }, "position": 1, "addedAt": "2025-01-01T00:00:00.000Z" } ] } ``` **Error Responses**: - 403 Forbidden: Playlist is private and user is not owner - 404 Not Found: Playlist not found **Implementation**: `app/api/playlists/[id]/route.ts`
--- ### PUT /api/playlists/{id} **Description**: Update playlist information. Only the playlist owner can perform this action. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Playlist UUID **Request Body** (all fields optional): ```json { "title": "Updated Playlist Title", "description": "Updated description", "coverUrl": "https://example.com/new-cover.jpg", "isPublic": false } ``` **Response** (200 OK): ```json { "id": "uuid", "title": "Updated Playlist Title", "description": "Updated description", "coverUrl": "https://example.com/new-cover.jpg", "isPublic": false, "updatedAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the playlist owner - 404 Not Found: Playlist not found **Implementation**: `app/api/playlists/[id]/route.ts`
--- ### DELETE /api/playlists/{id} **Description**: Delete a playlist. Only the playlist owner can perform this action. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Playlist UUID **Response** (204 No Content) **Error Responses**: - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the playlist owner - 404 Not Found: Playlist not found **Implementation**: `app/api/playlists/[id]/route.ts` **Note**: Deleting a playlist does NOT delete the songs in it, only the playlist container.
--- ### POST /api/playlists/{id}/songs **Description**: Add a song to a playlist. Only the playlist owner can add songs. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Playlist UUID **Request Body**: ```json { "songId": "uuid" } ``` **Response** (200 OK): ```json { "id": "uuid", "playlistId": "uuid", "songId": "uuid", "position": 5, "addedAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 400 Bad Request: Missing songId or song already in playlist - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the playlist owner - 404 Not Found: Playlist or song not found **Implementation**: `app/api/playlists/[id]/songs/route.ts` **Note**: Position is automatically assigned as the last position in the playlist.
--- ### PUT /api/playlists/{id}/reorder **Description**: Reorder songs within a playlist. Only the playlist owner can reorder songs. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Playlist UUID **Request Body**: ```json { "songIds": ["uuid1", "uuid2", "uuid3"] } ``` **Response** (200 OK): ```json { "message": "Playlist reordered successfully" } ``` **Error Responses**: - 400 Bad Request: Missing songIds array or songIds don't match playlist - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the playlist owner - 404 Not Found: Playlist not found **Implementation**: `app/api/playlists/[id]/reorder/route.ts` **Note**: All songs in the playlist must be included in the songIds array in the desired order.
--- ## Discovery Endpoints API endpoints for discovering trending music, new releases, and browsing by genre. ### GET /api/discover/trending **Description**: Retrieve trending public songs sorted by play count. **Authentication**: Not required
🔧 Technical Details **Query Parameters**: - `limit` (number, optional): Number of results to return (default: 20, max: 100) **Response** (200 OK): ```json [ { "id": "uuid", "title": "Song Title", "duration": 240, "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "playCount": 5432, "artist": { "id": "uuid", "name": "Artist Name", "slug": "artist-name", "verified": true }, "genres": [ { "name": "Rock", "slug": "rock", "color": "#FF0000" } ] } ] ``` **Implementation**: `app/api/discover/trending/route.ts` **Note**: Only returns songs where `isPublic = true`, sorted by `playCount` descending.
--- ### GET /api/discover/new-releases **Description**: Retrieve recently uploaded public songs sorted by creation date. **Authentication**: Not required
🔧 Technical Details **Query Parameters**: - `limit` (number, optional): Number of results to return (default: 20, max: 100) **Response** (200 OK): ```json [ { "id": "uuid", "title": "Song Title", "duration": 240, "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "createdAt": "2025-01-01T00:00:00.000Z", "artist": { "id": "uuid", "name": "Artist Name", "slug": "artist-name", "verified": true }, "genres": [ { "name": "Pop", "slug": "pop", "color": "#00FF00" } ] } ] ``` **Implementation**: `app/api/discover/new-releases/route.ts` **Note**: Only returns songs where `isPublic = true`, sorted by `createdAt` descending.
--- ### GET /api/discover/genres **Description**: Retrieve all available genres with song counts. **Authentication**: Not required
🔧 Technical Details **Response** (200 OK): ```json [ { "id": "uuid", "name": "Rock", "slug": "rock", "description": "Rock music genre", "color": "#FF0000", "_count": { "songs": 142 } }, { "id": "uuid", "name": "Pop", "slug": "pop", "description": "Pop music genre", "color": "#00FF00", "_count": { "songs": 98 } } ] ``` **Implementation**: `app/api/discover/genres/route.ts`
--- ### GET /api/discover/genres/{slug} **Description**: Retrieve all public songs in a specific genre. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `slug` (string): Genre slug (e.g., "rock", "pop", "jazz") **Query Parameters**: - `limit` (number, optional): Number of results to return (default: 50, max: 100) **Response** (200 OK): ```json { "genre": { "id": "uuid", "name": "Rock", "slug": "rock", "description": "Rock music genre", "color": "#FF0000" }, "songs": [ { "id": "uuid", "title": "Song Title", "duration": 240, "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "playCount": 1234, "artist": { "id": "uuid", "name": "Artist Name", "verified": true } } ] } ``` **Error Responses**: - 404 Not Found: Genre not found **Implementation**: `app/api/discover/genres/[slug]/route.ts`
--- ## Label Endpoints API endpoints for managing record label profiles and artist rosters. ### POST /api/labels **Description**: Create a new record label profile for the authenticated user. **Authentication**: Required (JWT token)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **Request Body**: ```json { "name": "Label Name", "description": "Label description", "logoUrl": "https://example.com/logo.png", "websiteUrl": "https://example.com", "contactEmail": "contact@label.com" } ``` **Response** (201 Created): ```json { "id": "uuid", "userId": "uuid", "name": "Label Name", "slug": "label-name", "description": "Label description", "logoUrl": "https://example.com/logo.png", "websiteUrl": "https://example.com", "contactEmail": "contact@label.com", "createdAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 400 Bad Request: Missing required fields or user already has label profile - 401 Unauthorized: Missing or invalid token **Implementation**: `app/api/labels/route.ts`
--- ### GET /api/labels/{id} **Description**: Retrieve label details with artist roster list. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Label UUID **Response** (200 OK): ```json { "id": "uuid", "name": "Label Name", "slug": "label-name", "description": "Label description", "logoUrl": "https://example.com/logo.png", "websiteUrl": "https://example.com", "contactEmail": "contact@label.com", "createdAt": "2025-01-01T00:00:00.000Z", "artists": [ { "id": "uuid", "name": "Artist Name", "slug": "artist-name", "verified": true, "avatarUrl": "https://example.com/avatar.jpg" } ] } ``` **Error Responses**: - 404 Not Found: Label not found **Implementation**: `app/api/labels/[id]/route.ts`
--- ### PUT /api/labels/{id} **Description**: Update label profile information. Only the label owner can perform this action. **Authentication**: Required (JWT token, owner only)
🔧 Technical Details **Request Headers**: ``` Authorization: Bearer jwt_token_string ``` **URL Parameters**: - `id` (string): Label UUID **Request Body** (all fields optional): ```json { "name": "Updated Label Name", "description": "Updated description", "logoUrl": "https://example.com/new-logo.png", "websiteUrl": "https://example.com", "contactEmail": "newcontact@label.com" } ``` **Response** (200 OK): ```json { "id": "uuid", "name": "Updated Label Name", "slug": "updated-label-name", "description": "Updated description", "logoUrl": "https://example.com/new-logo.png", "updatedAt": "2025-01-01T00:00:00.000Z" } ``` **Error Responses**: - 401 Unauthorized: Missing or invalid token - 403 Forbidden: User is not the label owner - 404 Not Found: Label not found **Implementation**: `app/api/labels/[id]/route.ts`
--- ### GET /api/labels/{id}/stats **Description**: Retrieve statistical information about a label including artist count, total songs, albums, and play counts. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Label UUID **Response** (200 OK): ```json { "artistCount": 15, "totalSongs": 342, "totalAlbums": 48, "totalPlays": 123456 } ``` **Error Responses**: - 404 Not Found: Label not found **Implementation**: `app/api/labels/[id]/stats/route.ts`
--- ### GET /api/labels/{id}/artists **Description**: Retrieve all artists signed to a specific label. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Label UUID **Response** (200 OK): ```json [ { "id": "uuid", "name": "Artist Name", "slug": "artist-name", "bio": "Artist biography", "avatarUrl": "https://example.com/avatar.jpg", "verified": true, "_count": { "songs": 24, "albums": 3 } } ] ``` **Error Responses**: - 404 Not Found: Label not found **Implementation**: `app/api/labels/[id]/artists/route.ts`
--- ## Search Endpoint Full-text search across songs, artists, and albums. ### GET /api/search **Description**: Search for songs, artists, and albums across the platform using full-text search. **Authentication**: Not required
🔧 Technical Details **Query Parameters**: - `q` (string, required): Search query text - `type` (string, optional): Filter by type ("song", "artist", "album", or omit for all) - `limit` (number, optional): Max results per type (default: 10, max: 50) **Response** (200 OK): ```json { "songs": [ { "id": "uuid", "title": "Song Title", "duration": 240, "audioUrl": "https://example.com/audio.mp3", "coverUrl": "https://example.com/cover.jpg", "playCount": 1234, "artist": { "id": "uuid", "name": "Artist Name", "verified": true } } ], "artists": [ { "id": "uuid", "name": "Artist Name", "slug": "artist-name", "bio": "Artist biography", "avatarUrl": "https://example.com/avatar.jpg", "verified": true, "_count": { "songs": 24 } } ], "albums": [ { "id": "uuid", "title": "Album Title", "coverUrl": "https://example.com/cover.jpg", "releaseDate": "2025-01-01T00:00:00.000Z", "albumType": "ALBUM", "artist": { "id": "uuid", "name": "Artist Name" }, "_count": { "songs": 12 } } ] } ``` **Error Responses**: - 400 Bad Request: Missing search query parameter **Implementation**: `app/api/search/route.ts` **Note**: - Search is case-insensitive - Only returns public songs (isPublic = true) - Searches in song titles, artist names, album titles, and artist bios - Results are relevance-sorted by database full-text search
--- ## Sharing Endpoints API endpoints for creating and tracking shareable links for content. ### POST /api/share/song/{id} **Description**: Create a shareable link for a song that can be distributed on social media or messaging. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Song UUID **Response** (200 OK): ```json { "token": "unique_share_token", "url": "https://sonic-cloud.com/s/unique_share_token" } ``` **Error Responses**: - 404 Not Found: Song not found **Implementation**: `app/api/share/song/[id]/route.ts` **Note**: Share tokens are unique 10-character alphanumeric strings. Multiple share links can be created for the same song.
--- ### POST /api/share/playlist/{id} **Description**: Create a shareable link for a playlist. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Playlist UUID **Response** (200 OK): ```json { "token": "unique_share_token", "url": "https://sonic-cloud.com/s/unique_share_token" } ``` **Error Responses**: - 404 Not Found: Playlist not found - 403 Forbidden: Playlist is private **Implementation**: `app/api/share/playlist/[id]/route.ts` **Note**: Only public playlists can be shared.
--- ### POST /api/share/album/{id} **Description**: Create a shareable link for an album. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `id` (string): Album UUID **Response** (200 OK): ```json { "token": "unique_share_token", "url": "https://sonic-cloud.com/s/unique_share_token" } ``` **Error Responses**: - 404 Not Found: Album not found **Implementation**: `app/api/share/album/[id]/route.ts`
--- ### GET /api/share/{token} **Description**: Resolve a share token and retrieve the shared content details. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `token` (string): Share token from shareable link **Response** (200 OK): ```json { "type": "SONG", // or "PLAYLIST", "ALBUM" "targetId": "uuid", "clickCount": 42, "content": { "id": "uuid", "title": "Song/Playlist/Album Title", "coverUrl": "https://example.com/cover.jpg", "artist": { "id": "uuid", "name": "Artist Name" } // Additional fields based on type } } ``` **Error Responses**: - 404 Not Found: Share token not found or expired **Implementation**: `app/api/share/[token]/route.ts`
--- ### POST /api/share/{token}/click **Description**: Track when a share link is clicked. Used for analytics. **Authentication**: Not required
🔧 Technical Details **URL Parameters**: - `token` (string): Share token **Response** (200 OK): ```json { "clickCount": 43 } ``` **Error Responses**: - 404 Not Found: Share token not found **Implementation**: `app/api/share/[token]/click/route.ts` **Note**: This endpoint is automatically called when a user opens a share link. It increments the click counter for analytics.
--- ## Authentication & Authorization ### JWT Token Format All authenticated endpoints require a JWT token in the Authorization header: ``` Authorization: Bearer ``` Tokens are issued on successful login or registration and contain: - User ID - Email - Role - Expiration timestamp ### Token Expiration JWT tokens expire after 7 days by default. After expiration, users must log in again to receive a new token. ### Permission Levels | Role | Permissions | |------|-------------| | **USER** | Create playlists, like songs, follow artists | | **ARTIST** | USER permissions + upload songs, create albums, manage artist profile | | **LABEL** | USER permissions + manage label profile, invite artists | | **ADMIN** | All permissions + verify artists, moderate content | --- ## Rate Limiting All API endpoints are subject to rate limiting to prevent abuse: | Endpoint Type | Rate Limit | |---------------|------------| | Authentication | 5 requests per minute per IP | | Song upload | 10 requests per hour per user | | Play tracking | 1 request per song per user per minute | | Search | 30 requests per minute per IP | | General API | 100 requests per minute per user | Rate limit headers are included in responses: ``` X-RateLimit-Limit: 100 X-RateLimit-Remaining: 95 X-RateLimit-Reset: 1609459200 ``` --- ## Error Response Format All error responses follow a consistent format: ```json { "error": { "message": "Human-readable error message", "code": "ERROR_CODE", "details": { "field": "Additional context" } } } ``` ### Common HTTP Status Codes | Code | Meaning | |------|---------| | 200 | Success | | 201 | Created | | 204 | No Content (successful deletion) | | 400 | Bad Request (invalid input) | | 401 | Unauthorized (missing or invalid token) | | 403 | Forbidden (insufficient permissions) | | 404 | Not Found (resource doesn't exist) | | 409 | Conflict (duplicate resource) | | 429 | Too Many Requests (rate limit exceeded) | | 500 | Internal Server Error | --- ## Data Types & Formats ### Date/Time Format All timestamps use ISO 8601 format: ``` 2025-01-01T00:00:00.000Z ``` ### UUID Format All entity IDs use UUID v4: ``` 123e4567-e89b-12d3-a456-426614174000 ``` ### Duration Format Song durations are in seconds (integer): ```json { "duration": 240 // 4 minutes } ``` ### URL Format All URLs must be valid HTTPS URLs: ``` https://example.com/file.mp3 ``` --- ## API Versioning Current API version: **v1** The API is versioned in the URL path. Future versions will be released as: ``` /api/v2/... ``` Version 1 endpoints will be supported for at least 12 months after v2 release. --- ## SDK & Client Libraries Official client libraries are in development for: - JavaScript/TypeScript (Browser & Node.js) - Python - Swift (iOS) - Kotlin (Android) Community-maintained libraries may be available. Check the [GitHub repository](https://github.com/sonic-cloud) for updates. --- ## Support & Resources - **API Status**: [status.sonic-cloud.com](https://status.sonic-cloud.com) - **Documentation**: [docs.sonic-cloud.com](https://docs.sonic-cloud.com) - **GitHub Issues**: [github.com/sonic-cloud/issues](https://github.com/sonic-cloud/issues) - **Developer Discord**: [discord.gg/sonic-cloud](https://discord.gg/sonic-cloud) --- **Last Updated**: December 18, 2025 **API Version**: v1.0.0