2025-12-25 01:48:06 +00:00
# Veza Backend API Documentation
## Table of Contents
1. [Overview ](#overview )
2. [Base URL ](#base-url )
3. [Authentication ](#authentication )
4. [Error Handling ](#error-handling )
5. [Rate Limiting ](#rate-limiting )
6. [Pagination ](#pagination )
7. [Endpoints ](#endpoints )
- [Authentication ](#authentication-endpoints )
- [Users ](#user-endpoints )
- [Tracks ](#track-endpoints )
- [Playlists ](#playlist-endpoints )
- [Marketplace ](#marketplace-endpoints )
- [Analytics ](#analytics-endpoints )
- [Webhooks ](#webhook-endpoints )
- [Chat ](#chat-endpoints )
- [Search ](#search-endpoints )
- [Comments ](#comment-endpoints )
- [Roles ](#role-endpoints )
- [Notifications ](#notification-endpoints )
- [Sessions ](#session-endpoints )
- [Uploads ](#upload-endpoints )
- [Audit ](#audit-endpoints )
- [Admin ](#admin-endpoints )
## Overview
The Veza Backend API is a RESTful API that provides endpoints for managing audio tracks, playlists, users, marketplace, analytics, and more. The API uses JSON for request and response payloads and follows REST conventions.
**API Version:** v1
**Base Path:** `/api/v1`
**Content-Type:** `application/json`
## Base URL
- **Production:** `https://api.veza.app`
- **Staging:** `https://staging-api.veza.app`
- **Development:** `http://localhost:8080`
## Authentication
Most endpoints require authentication using JWT (JSON Web Tokens). Include the access token in the `Authorization` header:
```
Authorization: Bearer < access_token >
```
### Getting an Access Token
1. Register a new user or login
2026-01-07 18:39:21 +00:00
2. Receive `access_token` in the response body
3. Receive `refresh_token` in an httpOnly cookie (automatically sent by browser)
4. Use `access_token` for authenticated requests
5. Use the refresh token cookie to get a new `access_token` when it expires
2025-12-25 01:48:06 +00:00
### Token Expiration
- **Access Token:** Valid for 24 hours
2026-01-07 18:39:21 +00:00
- **Refresh Token:** Valid for 30 days (or 90 days if "remember me" is selected)
### Authentication Cookies
#### Refresh Token Cookie
After successful login or token refresh, a `refresh_token` cookie is set with the following properties:
- **Name:** `refresh_token`
- **HttpOnly:** `true` (not accessible via JavaScript - prevents XSS attacks)
- **Secure:** `true` in production, `false` in development (HTTPS only in production)
- **SameSite:** `strict` in production, `lax` in development (prevents CSRF attacks)
- **Path:** `/`
- **Max-Age:** 30 days (or 90 days if "remember me" is selected)
**Important:** The refresh token is NOT returned in the JSON response body for security reasons. It is only available as an httpOnly cookie that is automatically sent by the browser with each request.
#### Using Refresh Token
To refresh your access token, make a POST request to `/auth/refresh` :
```bash
# The refresh token cookie is automatically sent by the browser
curl -X POST http://localhost:8080/api/v1/auth/refresh \
-H "Content-Type: application/json" \
--cookie "refresh_token=< token > " \
-b cookies.txt -c cookies.txt
```
The new access token will be returned in the response body, and a new refresh token cookie will be set automatically.
#### Cookie Configuration
The cookie security settings can be configured via environment variables:
- `COOKIE_SECURE` : `true` in production (HTTPS only), `false` in development
- `COOKIE_SAME_SITE` : `strict` (production), `lax` (development)
- `COOKIE_DOMAIN` : Domain for the cookie (empty for current domain)
- `COOKIE_HTTP_ONLY` : Always `true` for refresh tokens
- `COOKIE_PATH` : Cookie path (default: `/` )
**Note:** In development, cookies work with `http://localhost` when `COOKIE_SECURE=false` and `COOKIE_SAME_SITE=lax` .
2025-12-25 01:48:06 +00:00
## Error Handling
All errors follow a consistent format:
```json
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": []
}
}
```
### HTTP Status Codes
- `200 OK` - Request successful
- `201 Created` - Resource created successfully
- `400 Bad Request` - Invalid request parameters
- `401 Unauthorized` - Missing or invalid authentication
- `403 Forbidden` - Insufficient permissions
- `404 Not Found` - Resource not found
- `409 Conflict` - Resource conflict (e.g., duplicate)
- `422 Unprocessable Entity` - Validation error
- `429 Too Many Requests` - Rate limit exceeded
- `500 Internal Server Error` - Server error
## Rate Limiting
Rate limiting is applied to prevent abuse. Limits vary by endpoint:
- **Global:** 100 requests per minute per IP
- **Login/Register:** 5 requests per minute per IP
- **Email Verification:** 3 requests per hour per email
- **Upload:** 10 uploads per hour per user
Rate limit headers are included in responses:
```
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
```
## Pagination
List endpoints support pagination using query parameters:
- `page` - Page number (default: 1)
- `limit` - Items per page (default: 20, max: 100)
Response includes pagination metadata:
```json
{
"success": true,
"data": {
"items": [...],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"total_pages": 8
}
}
}
```
## Endpoints
### Authentication Endpoints
#### Register User
Create a new user account.
**Endpoint:** `POST /api/v1/auth/register`
**Request Body:**
```json
{
"username": "johndoe",
"email": "john@example.com",
"password": "SecurePassword123!",
"password_confirm": "SecurePassword123!"
}
```
**Response (201 Created):**
```json
{
"success": true,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"email": "john@example.com"
},
"token": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400
}
}
}
```
#### Login
Authenticate and receive tokens.
**Endpoint:** `POST /api/v1/auth/login`
**Request Body:**
```json
{
"email": "john@example.com",
"password": "SecurePassword123!",
"remember_me": false
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"email": "john@example.com"
},
"token": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400
},
"requires_2fa": false
}
}
```
#### Refresh Token
Get a new access token using refresh token.
**Endpoint:** `POST /api/v1/auth/refresh`
**Request Body:**
```json
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 86400
}
}
```
#### Logout
Revoke refresh token and current session.
**Endpoint:** `POST /api/v1/auth/logout`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Logged out successfully"
}
}
```
#### Get Current User
Get profile information of the currently logged-in user.
**Endpoint:** `GET /api/v1/auth/me`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"email": "john@example.com",
"role": "user"
}
}
```
#### Check Username Availability
Check if a username is available.
**Endpoint:** `GET /api/v1/auth/check-username?username=johndoe`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"username": "johndoe",
"available": true
}
}
```
#### Verify Email
Verify user email address using a token.
**Endpoint:** `POST /api/v1/auth/verify-email?token=verification_token_here`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Email verified successfully"
}
}
```
#### Resend Verification Email
Resend the email verification link.
**Endpoint:** `POST /api/v1/auth/resend-verification`
**Request Body:**
```json
{
"email": "john@example.com"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Verification email sent"
}
}
```
### User Endpoints
#### Get User Profile
Get public profile information for a user.
**Endpoint:** `GET /api/v1/users/{id}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"profile": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"email": "john@example.com",
"bio": "Music producer",
"avatar": "https://cdn.veza.app/avatars/user123.jpg",
"location": "Paris, France",
"created_at": "2025-01-01T00:00:00Z"
}
}
}
```
#### Get User Profile by Username
Get public profile information by username.
**Endpoint:** `GET /api/v1/users/by-username/{username}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"profile": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"bio": "Music producer",
"avatar": "https://cdn.veza.app/avatars/user123.jpg"
}
}
}
```
#### Update Profile
Update user profile details.
**Endpoint:** `PUT /api/v1/users/{id}`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"username": "johndoe",
"bio": "Updated bio",
"first_name": "John",
"last_name": "Doe",
"location": "New York, USA",
"gender": "Male"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"profile": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"bio": "Updated bio",
"first_name": "John",
"last_name": "Doe"
}
}
}
```
#### Get Profile Completion
Get profile completion percentage and missing fields.
**Endpoint:** `GET /api/v1/users/{id}/completion`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"completion_percentage": 75,
"missing_fields": ["bio", "avatar"]
}
}
```
### Track Endpoints
#### List Tracks
Get a paginated list of tracks with filters.
**Endpoint:** `GET /api/v1/tracks`
**Query Parameters:**
- `page` (optional) - Page number (default: 1)
- `limit` (optional) - Items per page (default: 20, max: 100)
- `user_id` (optional) - Filter by user ID
- `genre` (optional) - Filter by genre
- `format` (optional) - Filter by format (mp3, flac, wav)
- `sort_by` (optional) - Sort field (default: created_at)
- `sort_order` (optional) - Sort order: asc/desc (default: desc)
**Response (200 OK):**
```json
{
"success": true,
"data": {
"tracks": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Track",
"artist": "John Doe",
"duration": 180,
"format": "mp3",
"genre": "Electronic",
"is_public": true,
"created_at": "2025-01-01T00:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"total_pages": 8
}
}
}
```
#### Search Tracks
Search tracks with advanced filters.
**Endpoint:** `GET /api/v1/tracks/search`
**Query Parameters:**
- `q` (optional) - Search query
- `genre` (optional) - Filter by genre
- `format` (optional) - Filter by format
- `min_duration` (optional) - Minimum duration in seconds
- `max_duration` (optional) - Maximum duration in seconds
- `start_date` (optional) - Start date (RFC3339)
- `end_date` (optional) - End date (RFC3339)
- `sort_by` (optional) - Sort field (title, popularity, created_at)
- `sort_order` (optional) - Sort order (asc/desc)
- `page` (optional) - Page number
- `limit` (optional) - Items per page
**Response (200 OK):**
```json
{
"tracks": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Track",
"artist": "John Doe",
"duration": 180
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 50,
"total_pages": 3
}
}
```
#### Get Track
Get detailed information about a track.
**Endpoint:** `GET /api/v1/tracks/{id}`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"track": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Track",
"artist": "John Doe",
"album": "My Album",
"duration": 180,
"format": "mp3",
"file_size": 5242880,
"genre": "Electronic",
"year": 2025,
"is_public": true,
"like_count": 42,
"play_count": 150,
"created_at": "2025-01-01T00:00:00Z"
}
}
}
```
#### Upload Track
Upload a new track (audio file).
**Endpoint:** `POST /api/v1/tracks`
**Headers:**
- `Authorization: Bearer <token>`
- `Content-Type: multipart/form-data`
**Form Data:**
- `file` (required) - Audio file (MP3, WAV, FLAC, OGG)
**Response (201 Created):**
```json
{
"success": true,
"data": {
"track": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Track",
"status": "processing",
"created_at": "2025-01-01T00:00:00Z"
}
}
}
```
#### Update Track
Update track metadata.
**Endpoint:** `PUT /api/v1/tracks/{id}`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"title": "Updated Title",
"artist": "Updated Artist",
"album": "Updated Album",
"genre": "Rock",
"year": 2025,
"is_public": true
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"track": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Updated Title",
"artist": "Updated Artist"
}
}
}
```
#### Delete Track
Permanently delete a track.
**Endpoint:** `DELETE /api/v1/tracks/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Track deleted successfully"
}
}
```
#### Get Track Stats
Get statistics for a track.
**Endpoint:** `GET /api/v1/tracks/{id}/stats`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"stats": {
"total_plays": 150,
"unique_listeners": 45,
"average_duration": 165.5,
"completion_rate": 78.5
}
}
}
```
#### Download Track
Download a track file.
**Endpoint:** `GET /api/v1/tracks/{id}/download`
**Response (200 OK):**
- Binary file download with appropriate `Content-Type` header
#### Like Track
Like a track.
**Endpoint:** `POST /api/v1/tracks/{id}/like`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Track liked"
}
}
```
#### Unlike Track
Remove like from a track.
**Endpoint:** `DELETE /api/v1/tracks/{id}/like`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Track unliked"
}
}
```
#### Get Track Likes
Get list of users who liked a track.
**Endpoint:** `GET /api/v1/tracks/{id}/likes`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"likes": [
{
"user_id": "550e8400-e29b-41d4-a716-446655440000",
"username": "johndoe",
"liked_at": "2025-01-01T00:00:00Z"
}
],
"total": 42
}
}
```
#### Initiate Chunked Upload
Start a new chunked upload session.
**Endpoint:** `POST /api/v1/tracks/initiate`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"filename": "my-track.mp3",
"total_chunks": 10,
"total_size": 52428800
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"upload_id": "550e8400-e29b-41d4-a716-446655440000",
"message": "Upload session initiated"
}
}
```
#### Upload Chunk
Upload a single chunk of a file.
**Endpoint:** `POST /api/v1/tracks/chunk`
**Headers:**
- `Authorization: Bearer <token>`
- `Content-Type: multipart/form-data`
**Form Data:**
- `chunk` (required) - Chunk file data
- `upload_id` (required) - Upload session ID
- `chunk_number` (required) - Chunk number (1-based)
- `total_chunks` (required) - Total number of chunks
- `total_size` (required) - Total file size in bytes
- `filename` (required) - Original filename
**Response (200 OK):**
```json
{
"success": true,
"data": {
"upload_id": "550e8400-e29b-41d4-a716-446655440000",
"received_chunks": 5,
"progress": 50.0,
"message": "Chunk uploaded successfully"
}
}
```
#### Complete Chunked Upload
Finish upload session and assemble file.
**Endpoint:** `POST /api/v1/tracks/complete`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"upload_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
**Response (201 Created):**
```json
{
"success": true,
"data": {
"track": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "my-track",
"status": "processing"
},
"md5": "d41d8cd98f00b204e9800998ecf8427e",
"message": "Upload completed"
}
}
```
#### Get Upload Status
Get the processing status of an uploaded track.
**Endpoint:** `GET /api/v1/tracks/{id}/status`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"status": "processing",
"progress": 75
}
}
```
#### Get Upload Quota
Get remaining upload quota for the user.
**Endpoint:** `GET /api/v1/tracks/quota/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"quota": {
"used": 524288000,
"limit": 1073741824,
"remaining": 549453824,
"percentage_used": 48.8
}
}
}
```
#### Resume Upload
Get state of an interrupted upload.
**Endpoint:** `GET /api/v1/tracks/resume/{uploadId}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"upload_id": "550e8400-e29b-41d4-a716-446655440000",
"chunks_received": 7,
"total_chunks": 10
}
}
```
#### Batch Delete Tracks
Delete multiple tracks at once.
**Endpoint:** `POST /api/v1/tracks/batch/delete`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"track_ids": [
"550e8400-e29b-41d4-a716-446655440000",
"660e8400-e29b-41d4-a716-446655440001"
]
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"deleted": [
"550e8400-e29b-41d4-a716-446655440000",
"660e8400-e29b-41d4-a716-446655440001"
],
"failed": {}
}
}
```
#### Record Play
Record a track play event.
**Endpoint:** `POST /api/v1/tracks/{id}/play`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"duration": 120,
"device": "Chrome Browser"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Play event recorded",
"id": "550e8400-e29b-41d4-a716-446655440000"
}
}
```
### Playlist Endpoints
#### List Playlists
Get a paginated list of playlists.
**Endpoint:** `GET /api/v1/playlists`
**Headers:** `Authorization: Bearer <token>`
**Query Parameters:**
- `page` (optional) - Page number (default: 1)
- `limit` (optional) - Items per page (default: 20)
- `user_id` (optional) - Filter by user ID
**Response (200 OK):**
```json
{
"success": true,
"data": {
"playlists": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Playlist",
"description": "A great playlist",
"is_public": true,
"track_count": 10,
"follower_count": 5,
"created_at": "2025-01-01T00:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 50,
"total_pages": 3
}
}
}
```
#### Search Playlists
Search playlists with filters.
**Endpoint:** `GET /api/v1/playlists/search`
**Headers:** `Authorization: Bearer <token>`
**Query Parameters:**
- `q` (optional) - Search query
- `user_id` (optional) - Filter by user ID
- `is_public` (optional) - Filter by public status (true/false)
- `page` (optional) - Page number
- `limit` (optional) - Items per page
**Response (200 OK):**
```json
{
"success": true,
"data": {
"playlists": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Playlist",
"is_public": true
}
],
"total": 25,
"page": 1,
"limit": 20
}
}
```
#### Get Playlist
Get detailed information about a playlist.
**Endpoint:** `GET /api/v1/playlists/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"playlist": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Playlist",
"description": "A great playlist",
"is_public": true,
"track_count": 10,
"tracks": [
{
"id": "660e8400-e29b-41d4-a716-446655440001",
"title": "Track 1",
"position": 1
}
],
"created_at": "2025-01-01T00:00:00Z"
}
}
}
```
#### Create Playlist
Create a new playlist.
**Endpoint:** `POST /api/v1/playlists`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"title": "My New Playlist",
"description": "A great playlist",
"is_public": true
}
```
**Response (201 Created):**
```json
{
"success": true,
"data": {
"playlist": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My New Playlist",
"description": "A great playlist",
"is_public": true,
"track_count": 0,
"created_at": "2025-01-01T00:00:00Z"
}
}
}
```
#### Update Playlist
Update playlist metadata.
**Endpoint:** `PUT /api/v1/playlists/{id}`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"title": "Updated Playlist Title",
"description": "Updated description",
"is_public": false
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"playlist": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Updated Playlist Title",
"description": "Updated description"
}
}
}
```
#### Delete Playlist
Permanently delete a playlist.
**Endpoint:** `DELETE /api/v1/playlists/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Playlist deleted successfully"
}
}
```
#### Add Track to Playlist
Add a track to the playlist.
**Endpoint:** `POST /api/v1/playlists/{id}/tracks`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"track_id": "660e8400-e29b-41d4-a716-446655440001"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Track added to playlist"
}
}
```
#### Remove Track from Playlist
Remove a track from the playlist.
**Endpoint:** `DELETE /api/v1/playlists/{id}/tracks/{track_id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Track removed from playlist"
}
}
```
#### Reorder Tracks
Reorder tracks in the playlist.
**Endpoint:** `PUT /api/v1/playlists/{id}/tracks/reorder`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"track_ids": [
"660e8400-e29b-41d4-a716-446655440001",
"770e8400-e29b-41d4-a716-446655440002",
"880e8400-e29b-41d4-a716-446655440003"
]
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Tracks reordered successfully"
}
}
```
#### Get Playlist Recommendations
Get playlist recommendations.
**Endpoint:** `GET /api/v1/playlists/recommendations`
**Headers:** `Authorization: Bearer <token>`
**Query Parameters:**
- `limit` (optional) - Number of recommendations (default: 10)
**Response (200 OK):**
```json
{
"success": true,
"data": {
"playlists": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Recommended Playlist",
"is_public": true
}
]
}
}
```
#### Add Collaborator
Add a collaborator to a playlist.
**Endpoint:** `POST /api/v1/playlists/{id}/collaborators`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"user_id": "990e8400-e29b-41d4-a716-446655440004",
"permission": "write"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Collaborator added successfully"
}
}
```
#### Get Collaborators
Get list of collaborators for a playlist.
**Endpoint:** `GET /api/v1/playlists/{id}/collaborators`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"collaborators": [
{
"id": "990e8400-e29b-41d4-a716-446655440004",
"username": "collaborator",
"permission": "write",
"added_at": "2025-01-01T00:00:00Z"
}
]
}
}
```
#### Update Collaborator Permission
Update collaborator permission.
**Endpoint:** `PUT /api/v1/playlists/{id}/collaborators/{userId}`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"permission": "admin"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Collaborator permission updated"
}
}
```
#### Remove Collaborator
Remove a collaborator from a playlist.
**Endpoint:** `DELETE /api/v1/playlists/{id}/collaborators/{userId}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Collaborator removed successfully"
}
}
```
#### Create Share Link
Create a share link for a playlist.
**Endpoint:** `POST /api/v1/playlists/{id}/share`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"share_token": "abc123def456",
"share_url": "https://veza.app/playlists/shared/abc123def456",
"expires_at": "2025-12-31T23:59:59Z"
}
}
```
### Marketplace Endpoints
#### List Products
List marketplace products with filters.
**Endpoint:** `GET /api/v1/marketplace/products`
**Query Parameters:**
- `status` (optional) - Product status (draft, active, archived)
- `seller_id` (optional) - Filter by seller ID
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Product",
"description": "A great track for sale",
"price": 9.99,
"currency": "EUR",
"status": "active",
"product_type": "track",
"seller_id": "660e8400-e29b-41d4-a716-446655440001",
"created_at": "2025-01-01T00:00:00Z"
}
]
}
```
#### Create Product
Create a product (Track, Pack, Service) for sale.
**Endpoint:** `POST /api/v1/marketplace/products`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"title": "My Product",
"description": "A great track for sale",
"price": 9.99,
"product_type": "track",
"track_id": "770e8400-e29b-41d4-a716-446655440002",
"license_type": "standard"
}
```
**Response (201 Created):**
```json
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "My Product",
"price": 9.99,
"status": "active",
"created_at": "2025-01-01T00:00:00Z"
}
}
```
#### Update Product
Update product details (only seller can update).
**Endpoint:** `PUT /api/v1/marketplace/products/{id}`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"title": "Updated Product Title",
"price": 12.99,
"status": "active"
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Updated Product Title",
"price": 12.99
}
}
```
#### Create Order
Purchase products.
**Endpoint:** `POST /api/v1/marketplace/orders`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"items": [
{
"product_id": "550e8400-e29b-41d4-a716-446655440000"
}
]
}
```
**Response (201 Created):**
```json
{
"success": true,
"data": {
"id": "880e8400-e29b-41d4-a716-446655440003",
"buyer_id": "990e8400-e29b-41d4-a716-446655440004",
"total_amount": 9.99,
"currency": "EUR",
"status": "completed",
"items": [
{
"product_id": "550e8400-e29b-41d4-a716-446655440000",
"price": 9.99
}
],
"created_at": "2025-01-01T00:00:00Z"
}
}
```
#### List Orders
Get all orders for the authenticated user.
**Endpoint:** `GET /api/v1/marketplace/orders`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": "880e8400-e29b-41d4-a716-446655440003",
"total_amount": 9.99,
"status": "completed",
"created_at": "2025-01-01T00:00:00Z"
}
]
}
```
#### Get Order
Get details of a specific order.
**Endpoint:** `GET /api/v1/marketplace/orders/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"id": "880e8400-e29b-41d4-a716-446655440003",
"buyer_id": "990e8400-e29b-41d4-a716-446655440004",
"total_amount": 9.99,
"currency": "EUR",
"status": "completed",
"items": [
{
"product_id": "550e8400-e29b-41d4-a716-446655440000",
"price": 9.99
}
],
"created_at": "2025-01-01T00:00:00Z"
}
}
```
#### Get Download URL
Get a secure download URL for a purchased product.
**Endpoint:** `GET /api/v1/marketplace/download/{product_id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"url": "https://storage.example.com/download/track123.mp3?token=abc123"
}
}
```
### Analytics Endpoints
#### Record Analytics Event
Record a custom analytics event.
**Endpoint:** `POST /api/v1/analytics/events`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"event_name": "user_interaction",
"payload": {
"action": "button_click",
"page": "home"
}
}
```
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "event recorded",
"event_name": "user_interaction"
}
}
```
#### Get Track Analytics Dashboard
Get comprehensive analytics dashboard for a track.
**Endpoint:** `GET /api/v1/analytics/tracks/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"dashboard": {
"track_id": "550e8400-e29b-41d4-a716-446655440000",
"stats": {
"total_plays": 150,
"unique_listeners": 45,
"average_duration": 165.5,
"completion_rate": 78.5
},
"plays_over_time": [
{
"date": "2025-01-01T00:00:00Z",
"count": 10
}
],
"period": {
"start_date": "2024-12-01T00:00:00Z",
"end_date": "2025-01-01T00:00:00Z",
"days": 30
}
}
}
}
```
### Webhook Endpoints
#### Register Webhook
Register a new webhook.
**Endpoint:** `POST /api/v1/webhooks`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"url": "https://example.com/webhook",
"events": ["track.uploaded", "playlist.created"],
"secret": "webhook_secret_key"
}
```
**Response (201 Created):**
```json
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/webhook",
"api_key": "wh_abc123def456",
"created_at": "2025-01-01T00:00:00Z"
}
}
```
#### List Webhooks
Get all webhooks for the authenticated user.
**Endpoint:** `GET /api/v1/webhooks`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/webhook",
"events": ["track.uploaded"],
"created_at": "2025-01-01T00:00:00Z"
}
]
}
```
#### Delete Webhook
Delete a webhook.
**Endpoint:** `DELETE /api/v1/webhooks/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Webhook deleted successfully"
}
}
```
#### Test Webhook
Test a webhook by sending a test event.
**Endpoint:** `POST /api/v1/webhooks/{id}/test`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Test event sent",
"status": "delivered"
}
}
```
#### Get Webhook Stats
Get statistics for webhooks.
**Endpoint:** `GET /api/v1/webhooks/stats`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"total_webhooks": 5,
"total_events": 150,
"successful_deliveries": 145,
"failed_deliveries": 5
}
}
```
#### Regenerate API Key
Regenerate API key for a webhook.
**Endpoint:** `POST /api/v1/webhooks/{id}/regenerate-key`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"api_key": "wh_new_abc123def456"
}
}
```
### Chat Endpoints
#### Get Chat Token
Generate a short-lived token for chat authentication.
**Endpoint:** `GET /api/v1/chat/token`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"token": "chat_token_abc123"
}
}
```
#### Get Chat Stats
Get chat statistics.
**Endpoint:** `GET /api/v1/chat/stats`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"total_rooms": 10,
"total_messages": 500,
"active_users": 25
}
}
```
### Search Endpoints
Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy
Bloc A - Code mort:
- Suppression Studio (components, views, features)
- Suppression gamification + services mock (projectService, storageService, gamificationService)
- Mise à jour Sidebar, Navbar, locales
Bloc B - Frontend:
- Suppression modal.tsx deprecated, Modal.stories (doublon Dialog)
- Feature flags: PLAYLIST_SEARCH, PLAYLIST_RECOMMENDATIONS, ROLE_MANAGEMENT = true
- Suppression 19 tests orphelins, retrait exclusions vitest.config
Bloc C - Backend:
- Extraction routes_auth.go depuis router.go
Bloc D - Rust:
- Suppression security_legacy.rs (code mort, patterns déjà dans security/)
2026-02-14 16:23:32 +00:00
Search is **resource-specific** ; there is no unified `GET /api/v1/search` endpoint. Use the following:
2025-12-25 01:48:06 +00:00
Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy
Bloc A - Code mort:
- Suppression Studio (components, views, features)
- Suppression gamification + services mock (projectService, storageService, gamificationService)
- Mise à jour Sidebar, Navbar, locales
Bloc B - Frontend:
- Suppression modal.tsx deprecated, Modal.stories (doublon Dialog)
- Feature flags: PLAYLIST_SEARCH, PLAYLIST_RECOMMENDATIONS, ROLE_MANAGEMENT = true
- Suppression 19 tests orphelins, retrait exclusions vitest.config
Bloc C - Backend:
- Extraction routes_auth.go depuis router.go
Bloc D - Rust:
- Suppression security_legacy.rs (code mort, patterns déjà dans security/)
2026-02-14 16:23:32 +00:00
- **Tracks:** `GET /api/v1/tracks/search` — see [Search Tracks ](#search-tracks ) (query `q` , `page` , `limit` , etc.).
- **Playlists:** `GET /api/v1/playlists/search` — see [Search Playlists ](#search-playlists ) (query `q` , `user_id` , `is_public` , `page` , `limit` ).
- **Users:** `GET /api/v1/users/search` — query `q` , `page` , `limit` .
2025-12-25 01:48:06 +00:00
Phase 2 stabilisation: code mort, Modal→Dialog, feature flags, tests, router split, Rust legacy
Bloc A - Code mort:
- Suppression Studio (components, views, features)
- Suppression gamification + services mock (projectService, storageService, gamificationService)
- Mise à jour Sidebar, Navbar, locales
Bloc B - Frontend:
- Suppression modal.tsx deprecated, Modal.stories (doublon Dialog)
- Feature flags: PLAYLIST_SEARCH, PLAYLIST_RECOMMENDATIONS, ROLE_MANAGEMENT = true
- Suppression 19 tests orphelins, retrait exclusions vitest.config
Bloc C - Backend:
- Extraction routes_auth.go depuis router.go
Bloc D - Rust:
- Suppression security_legacy.rs (code mort, patterns déjà dans security/)
2026-02-14 16:23:32 +00:00
Pagination: `page` must be >= 1, `limit` between 1 and 100; otherwise the API returns 400 with a clear message.
2025-12-25 01:48:06 +00:00
### Comment Endpoints
#### Get Comments
Get comments for a track.
**Endpoint:** `GET /api/v1/tracks/{id}/comments`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"comments": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "660e8400-e29b-41d4-a716-446655440001",
"username": "johndoe",
"content": "Great track!",
"created_at": "2025-01-01T00:00:00Z"
}
]
}
}
```
#### Create Comment
Create a comment on a track.
**Endpoint:** `POST /api/v1/tracks/{id}/comments`
**Headers:** `Authorization: Bearer <token>`
**Request Body:**
```json
{
"content": "Great track!"
}
```
**Response (201 Created):**
```json
{
"success": true,
"data": {
"comment": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"content": "Great track!",
"created_at": "2025-01-01T00:00:00Z"
}
}
}
```
#### Delete Comment
Delete a comment.
**Endpoint:** `DELETE /api/v1/comments/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Comment deleted successfully"
}
}
```
### Role Endpoints
#### Get Roles
Get all available roles.
**Endpoint:** `GET /api/v1/roles`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"roles": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "admin",
"permissions": ["all"]
}
]
}
}
```
#### Get Role
Get details of a specific role.
**Endpoint:** `GET /api/v1/roles/{id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"role": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "admin",
"permissions": ["all"]
}
}
}
```
### Notification Endpoints
#### Get Notifications
Get notifications for the authenticated user.
**Endpoint:** `GET /api/v1/notifications`
**Headers:** `Authorization: Bearer <token>`
**Query Parameters:**
- `page` (optional) - Page number
- `limit` (optional) - Items per page
- `unread_only` (optional) - Filter unread only (true/false)
**Response (200 OK):**
```json
{
"success": true,
"data": {
"notifications": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "track_liked",
"message": "Your track was liked",
"read": false,
"created_at": "2025-01-01T00:00:00Z"
}
]
}
}
```
#### Mark Notification as Read
Mark a notification as read.
**Endpoint:** `POST /api/v1/notifications/{id}/read`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Notification marked as read"
}
}
```
#### Mark All Notifications as Read
Mark all notifications as read.
**Endpoint:** `POST /api/v1/notifications/read-all`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "All notifications marked as read"
}
}
```
### Session Endpoints
#### Get Sessions
Get all active sessions for the authenticated user.
**Endpoint:** `GET /api/v1/sessions`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"sessions": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"created_at": "2025-01-01T00:00:00Z",
"last_activity": "2025-01-01T12:00:00Z"
}
]
}
}
```
#### Logout Session
Logout from a specific session.
**Endpoint:** `POST /api/v1/sessions/logout`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Logged out successfully"
}
}
```
#### Logout All Sessions
Logout from all sessions.
**Endpoint:** `POST /api/v1/sessions/logout-all`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Logged out from all sessions"
}
}
```
#### Revoke Session
Revoke a specific session.
**Endpoint:** `DELETE /api/v1/sessions/{session_id}`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"message": "Session revoked successfully"
}
}
```
#### Get Session Stats
Get session statistics.
**Endpoint:** `GET /api/v1/sessions/stats`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"total_sessions": 5,
"active_sessions": 3
}
}
```
### Upload Endpoints
#### Upload File
Upload a file.
**Endpoint:** `POST /api/v1/uploads`
**Headers:**
- `Authorization: Bearer <token>`
- `Content-Type: multipart/form-data`
**Form Data:**
- `file` (required) - File to upload
**Response (201 Created):**
```json
{
"success": true,
"data": {
"upload_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing"
}
}
```
#### Get Upload Status
Get upload status.
**Endpoint:** `GET /api/v1/uploads/{id}/status`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"status": "completed",
"progress": 100
}
}
```
### Audit Endpoints
#### Search Audit Logs
Search audit logs.
**Endpoint:** `GET /api/v1/audit/logs`
**Headers:** `Authorization: Bearer <token>`
**Query Parameters:**
- `user_id` (optional) - Filter by user ID
- `action` (optional) - Filter by action
- `start_date` (optional) - Start date (RFC3339)
- `end_date` (optional) - End date (RFC3339)
- `page` (optional) - Page number
- `limit` (optional) - Items per page
**Response (200 OK):**
```json
{
"success": true,
"data": {
"logs": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "660e8400-e29b-41d4-a716-446655440001",
"action": "track.uploaded",
"ip_address": "192.168.1.1",
"created_at": "2025-01-01T00:00:00Z"
}
]
}
}
```
#### Get Audit Stats
Get audit statistics.
**Endpoint:** `GET /api/v1/audit/stats`
**Headers:** `Authorization: Bearer <token>`
**Response (200 OK):**
```json
{
"success": true,
"data": {
"total_logs": 1000,
"actions_count": {
"track.uploaded": 500,
"playlist.created": 300
}
}
}
```
### Admin Endpoints
All admin endpoints require admin role.
#### Get Audit Logs (Admin)
**Endpoint:** `GET /api/v1/admin/audit/logs`
**Headers:** `Authorization: Bearer <token>`
#### Get Audit Stats (Admin)
**Endpoint:** `GET /api/v1/admin/audit/stats`
**Headers:** `Authorization: Bearer <token>`
#### Detect Suspicious Activity (Admin)
**Endpoint:** `GET /api/v1/admin/audit/suspicious`
**Headers:** `Authorization: Bearer <token>`
## Additional Resources
- **Swagger UI:** `/swagger/index.html` - Interactive API documentation
- **ReDoc:** `/redoc` - Alternative API documentation
- **OpenAPI Spec:** `/swagger/doc.json` - OpenAPI 3.0 specification
## Support
For API support, please contact:
- **Email:** support@veza.app
- **Documentation:** https://docs.veza.app
- **Issues:** https://github.com/veza/veza-backend-api/issues