# ORIGIN_API_SPECIFICATION.md

## 📋 RÉSUMÉ EXÉCUTIF

Ce document définit la spécification complète et définitive de toutes les APIs de la plateforme Veza. Il documente 500+ endpoints REST, 50+ événements WebSocket, et 20+ services gRPC avec leurs schémas de requête/réponse, codes d'erreur standardisés, authentication flows, rate limiting, et versioning. L'API suit les principes REST/RESTful, utilise JSON comme format d'échange, et implémente OAuth 2.0 + JWT pour l'authentification.

## 🎯 OBJECTIFS

### Objectif Principal
Définir une API complète, cohérente, documentée, et immuable qui servira de contrat entre frontend/backend/mobile pendant 24 mois sans breaking changes.

### Objectifs Secondaires
- Assurer la cohérence des schémas (naming, structure, types)
- Standardiser les codes d'erreur et messages
- Faciliter l'intégration (clients, partenaires, développeurs tiers)
- Garantir la scalabilité (rate limiting, caching, pagination)
- Supporter le versioning (v1 stable, v2 pour évolutions)

## 📖 TABLE DES MATIÈRES

1. [Design Principles](#1-design-principles)
2. [Authentication & Authorization](#2-authentication--authorization)
3. [Common Patterns](#3-common-patterns)
4. [Error Handling](#4-error-handling)
5. [Rate Limiting](#5-rate-limiting)
6. [Versioning](#6-versioning)
7. [REST API Endpoints](#7-rest-api-endpoints)
8. [WebSocket APIs](#8-websocket-apis)
9. [gRPC APIs](#9-grpc-apis)
10. [OpenAPI 3.0 Specification](#10-openapi-30-specification)

## 🔒 RÈGLES IMMUABLES

1. **URLs DOIVENT suivre le pattern** `/api/v{version}/{resource}`
2. **HTTP methods DOIVENT respecter REST** (GET=read, POST=create, PUT=replace, PATCH=update, DELETE=delete)
3. **Responses DOIVENT être JSON** avec `Content-Type: application/json`
4. **Dates DOIVENT être ISO 8601** (format: `2025-11-02T14:30:00Z`)
5. **IDs DOIVENT être UUID v4** (format: `550e8400-e29b-41d4-a716-446655440000`)
6. **Pagination OBLIGATOIRE** pour collections (cursor-based par défaut)
7. **Rate limiting OBLIGATOIRE** (headers: `X-RateLimit-*`)
8. **Authentication JWT** dans header `Authorization: Bearer {token}`
9. **Error codes STANDARDISÉS** (range 1000-9999, voir section 4)
10. **Breaking changes INTERDITS** dans v1 (créer v2 si nécessaire)

## 1. DESIGN PRINCIPLES

### 1.1 RESTful Architecture

**Resource-Oriented URLs**:
```
✅ Good: GET /api/v1/tracks/{id}
❌ Bad:  GET /api/v1/getTrackById?id={id}

✅ Good: POST /api/v1/tracks/{id}/like
❌ Bad:  POST /api/v1/likeTrack

✅ Good: GET /api/v1/users/{id}/tracks
❌ Bad:  GET /api/v1/getTracksForUser?userId={id}
```

**HTTP Method Semantics**:
```
GET    - Retrieve resource(s) (idempotent, cacheable)
POST   - Create new resource (non-idempotent)
PUT    - Replace entire resource (idempotent)
PATCH  - Partial update resource (idempotent)
DELETE - Delete resource (idempotent)
```

### 1.2 Consistency

**Naming Conventions**:
- **Resources**: Plural nouns (`tracks`, `users`, `playlists`)
- **Fields**: snake_case (`created_at`, `user_id`, `is_active`)
- **Enums**: lowercase with underscores (`public`, `unlisted`, `private`)

**Common Fields**:
```json
{
  "id": "uuid",
  "created_at": "ISO 8601 timestamp",
  "updated_at": "ISO 8601 timestamp",
  "deleted_at": "ISO 8601 timestamp | null"
}
```

### 1.3 HATEOAS (Optional)

**Include links for navigation**:
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "My Track",
  "_links": {
    "self": "/api/v1/tracks/550e8400-e29b-41d4-a716-446655440000",
    "creator": "/api/v1/users/123e4567-e89b-12d3-a456-426614174000",
    "likes": "/api/v1/tracks/550e8400-e29b-41d4-a716-446655440000/likes"
  }
}
```

## 2. AUTHENTICATION & AUTHORIZATION

### 2.1 JWT Authentication

**Login Flow**:
```
POST /api/v1/auth/login
Request:
{
  "email": "user@example.com",
  "password": "SecurePass123!"
}

Response:
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "dGhpc2lzYXJlZnJlc2h0b2tlbg...",
  "expires_in": 900,
  "token_type": "Bearer",
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "username": "johndoe",
    "role": "user"
  }
}
```

**JWT Claims**:
```json
{
  "sub": "550e8400-e29b-41d4-a716-446655440000",
  "email": "user@example.com",
  "role": "user",
  "token_version": 0,
  "iat": 1730556000,
  "exp": 1730559600
}
```

**Using Access Token**:
```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

**Refresh Token Flow**:
```
POST /api/v1/auth/refresh
Request:
{
  "refresh_token": "dGhpc2lzYXJlZnJlc2h0b2tlbg..."
}

Response:
{
  "access_token": "new_jwt_token...",
  "expires_in": 900
}
```

### 2.2 OAuth 2.0 (Social Login)

**Supported Providers**: Google, GitHub, Discord, Spotify

**OAuth Flow**:
```
1. GET /api/v1/auth/oauth/{provider}
   → Redirect to provider authorization URL

2. Provider redirects back to: /api/v1/auth/oauth/{provider}/callback?code=...

3. Backend exchanges code for tokens and returns JWT
```

### 2.3 Authorization (RBAC)

**Roles**:
- `user` - Standard user (default)
- `creator` - Content creator (verified)
- `premium` - Premium subscriber
- `moderator` - Community moderator
- `admin` - System administrator

**Permission Matrix** (examples):
| Action | user | creator | premium | moderator | admin |
|--------|------|---------|---------|-----------|-------|
| Upload track | ❌ | ✅ | ✅ | ✅ | ✅ |
| Delete own track | ❌ | ✅ | ✅ | ✅ | ✅ |
| Delete any track | ❌ | ❌ | ❌ | ✅ | ✅ |
| Create playlist | ✅ | ✅ | ✅ | ✅ | ✅ |
| Ban user | ❌ | ❌ | ❌ | ✅ | ✅ |
| Modify system config | ❌ | ❌ | ❌ | ❌ | ✅ |

**Checking Permissions** (backend):
```go
// Middleware example
func RequireRole(allowedRoles ...string) gin.HandlerFunc {
    return func(c *gin.Context) {
        user := GetCurrentUser(c)
        if !contains(allowedRoles, user.Role) {
            c.JSON(403, ErrorResponse{Code: 1003, Message: "Forbidden"})
            c.Abort()
            return
        }
        c.Next()
    }
}

// Usage
r.POST("/tracks", RequireRole("creator", "premium"), handlers.CreateTrack)
```

## 3. COMMON PATTERNS

### 3.1 Pagination

**Cursor-Based Pagination** (recommended for feeds):
```
GET /api/v1/tracks?limit=20&cursor=eyJpZCI6IjU1MGU4NDAwIn0

Response:
{
  "data": [ /* 20 tracks */ ],
  "pagination": {
    "next_cursor": "eyJpZCI6IjY2MWU5NTExIn0",
    "has_more": true,
    "limit": 20
  }
}
```

**Offset-Based Pagination** (for fixed pages):
```
GET /api/v1/tracks?page=2&per_page=20

Response:
{
  "data": [ /* 20 tracks */ ],
  "pagination": {
    "current_page": 2,
    "per_page": 20,
    "total_pages": 150,
    "total_count": 3000
  }
}
```

### 3.2 Filtering

**Query Parameters**:
```
GET /api/v1/tracks?genre=electronic&bpm_min=120&bpm_max=140&visibility=public

Supported operators:
- Equality: ?genre=electronic
- Range: ?bpm_min=120&bpm_max=140
- In: ?genre=electronic,house,techno
- Date range: ?created_after=2025-01-01&created_before=2025-12-31
```

### 3.3 Sorting

```
GET /api/v1/tracks?sort=-created_at,title

Format: 
- {field} for ascending
- -{field} for descending
- Multiple fields: comma-separated
```

### 3.4 Field Selection (Sparse Fieldsets)

```
GET /api/v1/tracks?fields=id,title,artist,duration

Response includes only requested fields (reduces payload size)
```

### 3.5 Embedding Related Resources

```
GET /api/v1/tracks/{id}?include=creator,likes

Response:
{
  "id": "uuid",
  "title": "Track Title",
  "creator": {
    "id": "uuid",
    "username": "johndoe",
    "avatar_url": "https://..."
  },
  "likes": [
    { "user_id": "uuid", "created_at": "2025-11-01T12:00:00Z" }
  ]
}
```

### 3.6 Bulk Operations

**Batch Create**:
```
POST /api/v1/tracks/batch
Request:
{
  "tracks": [
    { "title": "Track 1", "file_id": "uuid1" },
    { "title": "Track 2", "file_id": "uuid2" }
  ]
}

Response:
{
  "created": [
    { "id": "uuid", "title": "Track 1" },
    { "id": "uuid", "title": "Track 2" }
  ],
  "failed": []
}
```

**Batch Update**:
```
PATCH /api/v1/tracks/batch
Request:
{
  "updates": [
    { "id": "uuid1", "visibility": "private" },
    { "id": "uuid2", "title": "New Title" }
  ]
}
```

## 4. ERROR HANDLING

### 4.1 Error Response Format

```json
{
  "error": {
    "code": 1001,
    "message": "Validation failed",
    "details": [
      {
        "field": "email",
        "message": "Invalid email format"
      }
    ],
    "request_id": "550e8400-e29b-41d4-a716-446655440000",
    "timestamp": "2025-11-02T14:30:00Z"
  }
}
```

### 4.2 HTTP Status Codes

| Status | Usage |
|--------|-------|
| **200 OK** | Successful GET, PATCH, PUT |
| **201 Created** | Successful POST (resource created) |
| **204 No Content** | Successful DELETE |
| **400 Bad Request** | Invalid request (validation errors) |
| **401 Unauthorized** | Missing or invalid authentication |
| **403 Forbidden** | Authenticated but insufficient permissions |
| **404 Not Found** | Resource not found |
| **409 Conflict** | Resource conflict (duplicate, state) |
| **422 Unprocessable Entity** | Semantic errors |
| **429 Too Many Requests** | Rate limit exceeded |
| **500 Internal Server Error** | Server error |
| **503 Service Unavailable** | Temporary unavailable |

### 4.3 Error Codes (1000-9999)

**Authentication & Authorization (1000-1999)**:
```
1000 - Invalid credentials
1001 - Token expired
1002 - Token invalid
1003 - Insufficient permissions
1004 - Account not verified
1005 - Account suspended
1006 - Account banned
1007 - Two-factor authentication required
1008 - Invalid two-factor code
1009 - OAuth provider error
```

**Validation Errors (2000-2999)**:
```
2000 - Validation failed (generic)
2001 - Required field missing
2002 - Invalid field format
2003 - Field value out of range
2004 - Invalid enum value
2005 - Invalid UUID format
2006 - Invalid date format
2007 - Invalid email format
2008 - Invalid URL format
2009 - File too large
2010 - Unsupported file type
```

**Resource Errors (3000-3999)**:
```
3000 - Resource not found
3001 - Resource already exists
3002 - Resource conflict
3003 - Resource deleted
3004 - Resource locked
3005 - Resource quota exceeded
```

**Business Logic Errors (4000-4999)**:
```
4000 - Operation not allowed
4001 - Insufficient balance
4002 - Product out of stock
4003 - Order already paid
4004 - Cannot cancel order
4005 - Maximum upload limit reached
4006 - Duplicate track title
4007 - Playlist is full
4008 - Cannot unfollow yourself
4009 - Already following user
4010 - User blocked you
```

**Rate Limiting (5000-5099)**:
```
5000 - Rate limit exceeded
5001 - Daily quota exceeded
5002 - Monthly quota exceeded
5003 - Concurrent request limit
```

**External Services (6000-6999)**:
```
6000 - Payment provider error
6001 - File storage error
6002 - Email service error
6003 - SMS service error
6004 - CDN error
6005 - Search service error
```

**Internal Errors (9000-9999)**:
```
9000 - Internal server error
9001 - Database error
9002 - Cache error
9003 - Message queue error
9004 - Configuration error
```

## 5. RATE LIMITING

### 5.1 Rate Limits by Endpoint Type

| Endpoint Type | Limit | Window |
|---------------|-------|--------|
| **Authentication** | 10 requests | 1 minute |
| **Read (GET)** | 1000 requests | 1 hour |
| **Write (POST/PUT/PATCH)** | 100 requests | 1 hour |
| **File Upload** | 10 uploads | 1 hour |
| **Search** | 500 requests | 1 hour |
| **Streaming** | 10,000 plays | 1 day |

### 5.2 Rate Limit Headers

**Included in every response**:
```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 950
X-RateLimit-Reset: 1730559600
X-RateLimit-Window: 3600
```

**When rate limit exceeded (429)**:
```
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1730559600
Retry-After: 1800

{
  "error": {
    "code": 5000,
    "message": "Rate limit exceeded. Try again in 30 minutes."
  }
}
```

### 5.3 Premium User Limits

| Endpoint Type | Standard | Premium | Factor |
|---------------|----------|---------|--------|
| Read | 1,000/hr | 5,000/hr | 5x |
| Write | 100/hr | 500/hr | 5x |
| Upload | 10/hr | 50/hr | 5x |
| Search | 500/hr | 2,500/hr | 5x |

## 6. VERSIONING

### 6.1 URL Versioning

**Current version**: v1  
**Format**: `/api/v{major_version}/{resource}`

```
/api/v1/tracks
/api/v2/tracks  (future)
```

### 6.2 Version Lifecycle

| Version | Status | Support End |
|---------|--------|-------------|
| **v1** | ✅ Stable | Q4 2026 minimum |
| **v2** | 🔄 Planned | TBD |

### 6.3 Breaking vs Non-Breaking Changes

**Non-Breaking (allowed in v1)**:
- Adding new endpoints
- Adding optional query parameters
- Adding new fields to responses (clients should ignore unknown fields)
- Adding new enum values (if gracefully handled)
- Adding new error codes

**Breaking (require v2)**:
- Removing endpoints
- Removing fields from responses
- Changing field types
- Changing required/optional status of fields
- Changing URL structure
- Changing authentication method

### 6.4 Deprecation Process

1. **Announce** deprecation (6 months notice minimum)
2. **Add header** `Deprecation: true` to deprecated endpoints
3. **Provide migration guide** in docs
4. **Monitor usage** of deprecated endpoints
5. **Remove** in next major version

## 7. REST API ENDPOINTS

### 7.1 Module: Authentication

#### `POST /api/v1/auth/register`
**Description**: Register new user account.

**Request**:
```json
{
  "email": "user@example.com",
  "username": "johndoe",
  "password": "SecurePass123!",
  "first_name": "John",
  "last_name": "Doe"
}
```

**Response** (201 Created):
```json
{
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "username": "johndoe",
    "role": "user",
    "is_active": true,
    "created_at": "2025-11-02T14:30:00Z"
  },
  "message": "Registration successful. Please verify your email."
}
```

**Errors**:
- `400` - Validation failed (2000)
- `409` - Email/username already exists (3001)

---

#### `POST /api/v1/auth/login`
**Description**: Login with email/password.

**Request**:
```json
{
  "email": "user@example.com",
  "password": "SecurePass123!"
}
```

**Response** (200 OK):
```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "dGhpc2lzYXJlZnJlc2h0b2tlbg...",
  "expires_in": 900,
  "token_type": "Bearer",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "username": "johndoe",
    "role": "creator"
  }
}
```

**Errors**:
- `400` - Invalid credentials (1000)
- `403` - Account suspended (1005)

---

#### `POST /api/v1/auth/logout`
**Description**: Logout (invalidate refresh token).

**Headers**: `Authorization: Bearer {token}`

**Request**: Empty

**Response** (204 No Content)

---

#### `POST /api/v1/auth/refresh`
**Description**: Refresh access token.

**Request**:
```json
{
  "refresh_token": "dGhpc2lzYXJlZnJlc2h0b2tlbg..."
}
```

**Response** (200 OK):
```json
{
  "access_token": "new_jwt_token...",
  "expires_in": 900
}
```

**Errors**:
- `401` - Invalid refresh token (1002)

---

#### `POST /api/v1/auth/forgot-password`
**Description**: Request password reset email.

**Request**:
```json
{
  "email": "user@example.com"
}
```

**Response** (200 OK):
```json
{
  "message": "Password reset email sent if account exists."
}
```

---

#### `POST /api/v1/auth/reset-password`
**Description**: Reset password with token.

**Request**:
```json
{
  "token": "reset_token_from_email",
  "new_password": "NewSecurePass456!"
}
```

**Response** (200 OK):
```json
{
  "message": "Password reset successful."
}
```

**Errors**:
- `400` - Invalid or expired token (1002)

---

#### `POST /api/v1/auth/verify-email`
**Description**: Verify email with token.

**Request**:
```json
{
  "token": "email_verification_token"
}
```

**Response** (200 OK):
```json
{
  "message": "Email verified successfully."
}
```

---

#### `GET /api/v1/auth/me`
**Description**: Get current authenticated user.

**Headers**: `Authorization: Bearer {token}`

**Response** (200 OK):
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "user@example.com",
  "username": "johndoe",
  "role": "creator",
  "is_active": true,
  "is_verified": true,
  "profile": {
    "bio": "Music producer from NYC",
    "avatar_url": "https://cdn.veza.io/avatars/...",
    "follower_count": 1250,
    "following_count": 450
  },
  "created_at": "2024-01-15T10:00:00Z"
}
```

**Errors**:
- `401` - Unauthorized (1002)

---

### 7.2 Module: Users

#### `GET /api/v1/users/{id}`
**Description**: Get user profile by ID.

**Parameters**:
- `id` (path, required) - User UUID
- `include` (query, optional) - Related resources (`profile,stats,badges`)

**Response** (200 OK):
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "username": "johndoe",
  "display_name": "John Doe",
  "role": "creator",
  "profile": {
    "bio": "Music producer from NYC",
    "avatar_url": "https://cdn.veza.io/avatars/...",
    "banner_url": "https://cdn.veza.io/banners/...",
    "location": "New York, USA",
    "website_url": "https://johndoe.com"
  },
  "stats": {
    "follower_count": 1250,
    "following_count": 450,
    "track_count": 85,
    "playlist_count": 12
  },
  "badges": [
    {
      "name": "Verified Creator",
      "icon_url": "https://cdn.veza.io/badges/verified.svg",
      "rarity": "rare"
    }
  ],
  "created_at": "2024-01-15T10:00:00Z"
}
```

**Errors**:
- `404` - User not found (3000)

---

#### `PATCH /api/v1/users/{id}`
**Description**: Update user profile.

**Headers**: `Authorization: Bearer {token}`

**Permissions**: Own profile or admin

**Request**:
```json
{
  "display_name": "Johnny Doe",
  "profile": {
    "bio": "Award-winning music producer",
    "location": "Los Angeles, USA",
    "website_url": "https://johnnydoe.com"
  }
}
```

**Response** (200 OK): Same as GET

**Errors**:
- `403` - Forbidden (1003)

---

#### `GET /api/v1/users/{id}/tracks`
**Description**: Get user's tracks.

**Parameters**:
- `id` (path, required) - User UUID
- `limit` (query, optional, default=20) - Page size
- `cursor` (query, optional) - Pagination cursor
- `sort` (query, optional, default=-created_at) - Sort field
- `visibility` (query, optional) - Filter by visibility

**Response** (200 OK):
```json
{
  "data": [
    {
      "id": "track-uuid",
      "title": "Summer Vibes",
      "artist": "johndoe",
      "duration": 245,
      "genre": "Electronic",
      "cover_art_url": "https://...",
      "play_count": 12500,
      "like_count": 850,
      "created_at": "2025-06-15T10:00:00Z"
    }
  ],
  "pagination": {
    "next_cursor": "eyJpZCI6IjY2MWU5NTExIn0",
    "has_more": true,
    "limit": 20
  }
}
```

---

#### `GET /api/v1/users/{id}/followers`
**Description**: Get user's followers.

**Response** (200 OK):
```json
{
  "data": [
    {
      "id": "follower-uuid",
      "username": "jane_smith",
      "display_name": "Jane Smith",
      "avatar_url": "https://...",
      "followed_at": "2025-10-01T12:00:00Z"
    }
  ],
  "pagination": { /* ... */ }
}
```

---

#### `GET /api/v1/users/{id}/following`
**Description**: Get users followed by user.

**Response**: Same format as followers

---

#### `POST /api/v1/users/{id}/follow`
**Description**: Follow a user.

**Headers**: `Authorization: Bearer {token}`

**Response** (201 Created):
```json
{
  "message": "Successfully followed user.",
  "followed_at": "2025-11-02T14:30:00Z"
}
```

**Errors**:
- `409` - Already following (4009)
- `400` - Cannot follow yourself (4008)

---

#### `DELETE /api/v1/users/{id}/follow`
**Description**: Unfollow a user.

**Response** (204 No Content)

---

#### `POST /api/v1/users/{id}/block`
**Description**: Block a user.

**Request**:
```json
{
  "reason": "Spam"
}
```

**Response** (201 Created)

---

#### `DELETE /api/v1/users/{id}/block`
**Description**: Unblock a user.

**Response** (204 No Content)

---

### 7.3 Module: Tracks

#### `GET /api/v1/tracks`
**Description**: List all public tracks (discovery feed).

**Parameters**:
- `limit` (query, optional, default=20) - Page size
- `cursor` (query, optional) - Pagination cursor
- `genre` (query, optional) - Filter by genre
- `bpm_min`, `bpm_max` (query, optional) - BPM range
- `duration_min`, `duration_max` (query, optional) - Duration range (seconds)
- `sort` (query, optional, default=-created_at) - Sort field
- `search` (query, optional) - Full-text search

**Response** (200 OK):
```json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "title": "Midnight Dreams",
      "artist": "DJ Nova",
      "duration": 245,
      "genre": "Electronic",
      "bpm": 128,
      "musical_key": "Am",
      "cover_art_url": "https://cdn.veza.io/covers/...",
      "waveform_url": "https://cdn.veza.io/waveforms/...",
      "creator": {
        "id": "creator-uuid",
        "username": "djnova",
        "avatar_url": "https://..."
      },
      "play_count": 12500,
      "like_count": 850,
      "comment_count": 42,
      "visibility": "public",
      "is_downloadable": false,
      "published_at": "2025-10-15T10:00:00Z",
      "created_at": "2025-10-15T09:45:00Z"
    }
  ],
  "pagination": {
    "next_cursor": "eyJpZCI6IjY2MWU5NTExIn0",
    "has_more": true,
    "limit": 20
  }
}
```

---

#### `POST /api/v1/tracks`
**Description**: Upload a new track.

**Headers**: 
- `Authorization: Bearer {token}`
- `Content-Type: multipart/form-data`

**Permissions**: `creator`, `premium`, `admin`

**Request** (multipart/form-data):
```
title: "Midnight Dreams"
artist: "DJ Nova"
description: "A dreamy electronic track..."
genre: "Electronic"
bpm: 128
musical_key: "Am"
visibility: "public"
is_downloadable: false
file: (audio file)
cover_art: (image file, optional)
```

**Response** (201 Created):
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "title": "Midnight Dreams",
  "status": "processing",
  "message": "Track uploaded successfully. Processing waveform and metadata..."
}
```

**Errors**:
- `403` - Insufficient permissions (1003)
- `400` - Invalid file type (2010)
- `400` - File too large (2009)
- `400` - Upload limit reached (4005)

---

#### `GET /api/v1/tracks/{id}`
**Description**: Get track details.

**Parameters**:
- `id` (path, required) - Track UUID
- `include` (query, optional) - Related resources (`creator,stats,comments`)

**Response** (200 OK): Same as list item + full metadata

---

#### `PATCH /api/v1/tracks/{id}`
**Description**: Update track metadata.

**Headers**: `Authorization: Bearer {token}`

**Permissions**: Track owner or admin

**Request**:
```json
{
  "title": "Midnight Dreams (Remix)",
  "description": "Updated description",
  "genre": "House",
  "visibility": "private"
}
```

**Response** (200 OK): Updated track object

---

#### `DELETE /api/v1/tracks/{id}`
**Description**: Delete track (soft delete).

**Headers**: `Authorization: Bearer {token}`

**Permissions**: Track owner or admin

**Response** (204 No Content)

---

#### `GET /api/v1/tracks/{id}/stream`
**Description**: Get streaming URL for track.

**Headers**: `Authorization: Bearer {token}` (optional for public tracks)

**Response** (200 OK):
```json
{
  "stream_url": "https://cdn.veza.io/streams/550e8400.m3u8",
  "format": "hls",
  "bitrates": [128, 256, 320],
  "expires_at": "2025-11-02T15:30:00Z"
}
```

---

#### `POST /api/v1/tracks/{id}/like`
**Description**: Like a track.

**Headers**: `Authorization: Bearer {token}`

**Response** (201 Created):
```json
{
  "message": "Track liked successfully.",
  "liked_at": "2025-11-02T14:30:00Z"
}
```

---

#### `DELETE /api/v1/tracks/{id}/like`
**Description**: Unlike a track.

**Response** (204 No Content)

---

#### `GET /api/v1/tracks/{id}/likes`
**Description**: Get users who liked track.

**Response** (200 OK):
```json
{
  "data": [
    {
      "user": {
        "id": "uuid",
        "username": "jane_doe",
        "avatar_url": "https://..."
      },
      "liked_at": "2025-11-01T12:00:00Z"
    }
  ],
  "pagination": { /* ... */ }
}
```

---

#### `GET /api/v1/tracks/{id}/comments`
**Description**: Get track comments.

**Parameters**:
- `timestamp` (query, optional) - Filter by waveform timestamp

**Response** (200 OK):
```json
{
  "data": [
    {
      "id": "comment-uuid",
      "user": {
        "id": "uuid",
        "username": "commenter",
        "avatar_url": "https://..."
      },
      "content": "Love the drop at 2:30!",
      "timestamp_seconds": 150,
      "created_at": "2025-11-01T14:00:00Z"
    }
  ],
  "pagination": { /* ... */ }
}
```

---

#### `POST /api/v1/tracks/{id}/comments`
**Description**: Add comment to track.

**Headers**: `Authorization: Bearer {token}`

**Request**:
```json
{
  "content": "Amazing track!",
  "timestamp_seconds": 150
}
```

**Response** (201 Created): Comment object

---

### 7.4 Module: Playlists

#### `GET /api/v1/playlists`
**Description**: List public playlists.

**Response**: Similar to tracks list

---

#### `POST /api/v1/playlists`
**Description**: Create playlist.

**Request**:
```json
{
  "name": "My Favorites",
  "description": "Best tracks of 2025",
  "visibility": "public",
  "is_collaborative": false
}
```

**Response** (201 Created):
```json
{
  "id": "playlist-uuid",
  "name": "My Favorites",
  "description": "Best tracks of 2025",
  "visibility": "public",
  "is_collaborative": false,
  "track_count": 0,
  "duration_seconds": 0,
  "created_at": "2025-11-02T14:30:00Z"
}
```

---

#### `GET /api/v1/playlists/{id}`
**Description**: Get playlist details with tracks.

**Response** (200 OK):
```json
{
  "id": "playlist-uuid",
  "name": "My Favorites",
  "description": "Best tracks of 2025",
  "owner": {
    "id": "uuid",
    "username": "johndoe"
  },
  "tracks": [
    {
      "id": "track-uuid",
      "title": "Track Title",
      "position": 1,
      "added_at": "2025-11-01T12:00:00Z"
    }
  ],
  "track_count": 15,
  "duration_seconds": 3675,
  "created_at": "2025-10-01T10:00:00Z"
}
```

---

#### `POST /api/v1/playlists/{id}/tracks`
**Description**: Add track to playlist.

**Request**:
```json
{
  "track_id": "550e8400-e29b-41d4-a716-446655440000",
  "position": 1
}
```

**Response** (201 Created)

**Errors**:
- `409` - Track already in playlist (3002)
- `400` - Playlist is full (4007)

---

#### `DELETE /api/v1/playlists/{id}/tracks/{track_id}`
**Description**: Remove track from playlist.

**Response** (204 No Content)

---

#### `PATCH /api/v1/playlists/{id}/tracks/reorder`
**Description**: Reorder tracks in playlist.

**Request**:
```json
{
  "positions": [
    { "track_id": "uuid1", "position": 1 },
    { "track_id": "uuid2", "position": 2 }
  ]
}
```

**Response** (200 OK)

---

### 7.5 Module: Chat & Messaging

#### `GET /api/v1/rooms`
**Description**: List user's chat rooms.

**Headers**: `Authorization: Bearer {token}`

**Response** (200 OK):
```json
{
  "data": [
    {
      "id": "room-uuid",
      "name": "General Chat",
      "room_type": "public",
      "member_count": 1250,
      "last_message": {
        "content": "Hello everyone!",
        "sender": {
          "username": "jane_doe"
        },
        "created_at": "2025-11-02T14:25:00Z"
      },
      "unread_count": 5
    }
  ]
}
```

---

#### `POST /api/v1/rooms`
**Description**: Create chat room.

**Request**:
```json
{
  "name": "My Private Room",
  "room_type": "private",
  "max_members": 50
}
```

**Response** (201 Created): Room object

---

#### `GET /api/v1/rooms/{id}/messages`
**Description**: Get room messages.

**Parameters**:
- `limit` (query, optional, default=50)
- `before` (query, optional) - Message ID for pagination

**Response** (200 OK):
```json
{
  "data": [
    {
      "id": "message-uuid",
      "sender": {
        "id": "uuid",
        "username": "jane_doe",
        "avatar_url": "https://..."
      },
      "content": "Hello everyone!",
      "message_type": "text",
      "created_at": "2025-11-02T14:25:00Z"
    }
  ],
  "pagination": { /* ... */ }
}
```

---

#### `POST /api/v1/rooms/{id}/messages`
**Description**: Send message to room.

**Request**:
```json
{
  "content": "Hello everyone!",
  "message_type": "text",
  "reply_to_id": "optional-message-uuid"
}
```

**Response** (201 Created): Message object

---

#### `GET /api/v1/direct-messages`
**Description**: List direct message conversations.

**Response**: List of conversations with last message

---

#### `POST /api/v1/direct-messages`
**Description**: Send direct message.

**Request**:
```json
{
  "recipient_id": "550e8400-e29b-41d4-a716-446655440000",
  "content": "Hey, how are you?",
  "message_type": "text"
}
```

**Response** (201 Created): Message object

---

### 7.6 Module: Marketplace

#### `GET /api/v1/products`
**Description**: List marketplace products.

**Parameters**:
- `category` (query, optional) - Filter by category
- `price_min`, `price_max` (query, optional) - Price range
- `genre` (query, optional) - Filter by genre
- `sort` (query, optional) - Sort field

**Response** (200 OK):
```json
{
  "data": [
    {
      "id": "product-uuid",
      "name": "EDM Sample Pack Vol. 1",
      "slug": "edm-sample-pack-vol-1",
      "description": "100+ high-quality EDM samples",
      "category": "sample",
      "price": 29.99,
      "currency": "USD",
      "seller": {
        "id": "uuid",
        "username": "producer_pro"
      },
      "thumbnail_url": "https://...",
      "preview_file_url": "https://...",
      "sale_count": 450,
      "average_rating": 4.8,
      "review_count": 120
    }
  ],
  "pagination": { /* ... */ }
}
```

---

#### `POST /api/v1/products`
**Description**: Create product listing.

**Headers**: `Authorization: Bearer {token}`

**Permissions**: `creator`, `admin`

**Request**:
```json
{
  "name": "EDM Sample Pack Vol. 1",
  "description": "100+ high-quality EDM samples...",
  "category": "sample",
  "price": 29.99,
  "currency": "USD",
  "tags": ["edm", "samples", "electronic"],
  "download_file_ids": ["uuid1", "uuid2"],
  "license_type": "Royalty-Free"
}
```

**Response** (201 Created): Product object

---

#### `GET /api/v1/products/{id}`
**Description**: Get product details.

**Response** (200 OK): Full product object with reviews

---

#### `POST /api/v1/cart/items`
**Description**: Add product to cart.

**Request**:
```json
{
  "product_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

**Response** (201 Created): Cart object

---

#### `GET /api/v1/cart`
**Description**: Get current user's cart.

**Response** (200 OK):
```json
{
  "id": "cart-uuid",
  "items": [
    {
      "product": {
        "id": "uuid",
        "name": "Sample Pack",
        "price": 29.99
      },
      "added_at": "2025-11-02T14:00:00Z"
    }
  ],
  "item_count": 3,
  "subtotal": 89.97,
  "tax_total": 7.20,
  "total": 97.17,
  "currency": "USD"
}
```

---

#### `POST /api/v1/orders`
**Description**: Create order from cart (checkout).

**Request**:
```json
{
  "payment_method": "stripe",
  "billing_email": "user@example.com",
  "discount_code": "SUMMER25"
}
```

**Response** (201 Created):
```json
{
  "order_id": "order-uuid",
  "order_number": "ORD-2025-00001",
  "status": "pending",
  "total": 97.17,
  "payment_intent_id": "pi_1234567890",
  "client_secret": "pi_1234567890_secret_..."
}
```

---

#### `GET /api/v1/orders/{id}`
**Description**: Get order details.

**Response** (200 OK): Full order object with items

---

#### `GET /api/v1/orders`
**Description**: List user's orders.

**Response** (200 OK): List of orders

---

### 7.7 Module: Search

#### `GET /api/v1/search`
**Description**: Global search (tracks, users, playlists, products).

**Parameters**:
- `q` (query, required) - Search query
- `type` (query, optional) - Filter by type (`tracks`, `users`, `playlists`, `products`)
- `limit` (query, optional, default=20)

**Response** (200 OK):
```json
{
  "tracks": {
    "data": [ /* track objects */ ],
    "total": 150
  },
  "users": {
    "data": [ /* user objects */ ],
    "total": 25
  },
  "playlists": {
    "data": [ /* playlist objects */ ],
    "total": 40
  },
  "products": {
    "data": [ /* product objects */ ],
    "total": 30
  }
}
```

---

### 7.8 Module: Analytics

#### `POST /api/v1/analytics/events`
**Description**: Track analytics event (client-side tracking).

**Request**:
```json
{
  "event_type": "track_play",
  "event_data": {
    "track_id": "uuid",
    "duration_played": 120,
    "completion_percentage": 50
  },
  "metadata": {
    "user_agent": "...",
    "referrer": "..."
  }
}
```

**Response** (204 No Content)

---

#### `GET /api/v1/analytics/tracks/{id}`
**Description**: Get track analytics.

**Headers**: `Authorization: Bearer {token}`

**Permissions**: Track owner or admin

**Response** (200 OK):
```json
{
  "track_id": "uuid",
  "plays_total": 12500,
  "plays_unique": 8500,
  "likes_total": 850,
  "comments_total": 42,
  "plays_by_country": {
    "US": 5000,
    "UK": 2500,
    "CA": 1500
  },
  "plays_by_day": [
    { "date": "2025-11-01", "plays": 450 },
    { "date": "2025-11-02", "plays": 520 }
  ]
}
```

---

*[7.9-7.15 Other modules follow similar patterns]*

## 8. WEBSOCKET APIS

### 8.1 Connection

**URL**: `wss://api.veza.io/ws`

**Authentication**: Send JWT in first message
```json
{
  "type": "auth",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

**Response**:
```json
{
  "type": "auth_success",
  "user_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

### 8.2 Message Types

#### Client → Server

**Join Room**:
```json
{
  "type": "join_room",
  "room_id": "room-uuid"
}
```

**Leave Room**:
```json
{
  "type": "leave_room",
  "room_id": "room-uuid"
}
```

**Send Message**:
```json
{
  "type": "message",
  "room_id": "room-uuid",
  "content": "Hello!",
  "message_type": "text"
}
```

**Typing Indicator**:
```json
{
  "type": "typing_start",
  "room_id": "room-uuid"
}
```

#### Server → Client

**New Message**:
```json
{
  "type": "message",
  "room_id": "room-uuid",
  "message": {
    "id": "message-uuid",
    "sender": { /* user object */ },
    "content": "Hello!",
    "created_at": "2025-11-02T14:30:00Z"
  }
}
```

**User Joined**:
```json
{
  "type": "user_joined",
  "room_id": "room-uuid",
  "user": { /* user object */ }
}
```

**User Left**:
```json
{
  "type": "user_left",
  "room_id": "room-uuid",
  "user_id": "uuid"
}
```

**Typing Indicator**:
```json
{
  "type": "typing",
  "room_id": "room-uuid",
  "user": { /* user object */ },
  "is_typing": true
}
```

**Presence Update**:
```json
{
  "type": "presence",
  "user_id": "uuid",
  "status": "online",
  "last_seen_at": "2025-11-02T14:30:00Z"
}
```

### 8.3 Error Handling

**Error Message**:
```json
{
  "type": "error",
  "error": {
    "code": 1002,
    "message": "Invalid token"
  }
}
```

### 8.4 Heartbeat

**Client sends**:
```json
{ "type": "ping" }
```

**Server responds**:
```json
{ "type": "pong" }
```

Interval: Every 30 seconds

## 9. GRPC APIS

### 9.1 Service: StreamService

**Proto Definition**:
```protobuf
syntax = "proto3";

package veza.stream.v1;

service StreamService {
  rpc GetStreamURL(GetStreamURLRequest) returns (GetStreamURLResponse);
  rpc RecordPlayback(RecordPlaybackRequest) returns (RecordPlaybackResponse);
  rpc GetWaveform(GetWaveformRequest) returns (GetWaveformResponse);
}

message GetStreamURLRequest {
  string track_id = 1;
  string user_id = 2;
  int32 bitrate = 3; // optional, default 320
}

message GetStreamURLResponse {
  string stream_url = 1;
  int32 bitrate = 2;
  string format = 3;
  int64 expires_at = 4;
}
```

### 9.2 Service: ChatService

```protobuf
service ChatService {
  rpc SendMessage(SendMessageRequest) returns (SendMessageResponse);
  rpc GetMessages(GetMessagesRequest) returns (stream Message);
  rpc GetRoomPresence(GetRoomPresenceRequest) returns (GetRoomPresenceResponse);
}
```

*[Additional gRPC services defined for inter-service communication]*

## 10. OPENAPI 3.0 SPECIFICATION

### 10.1 Metadata

```yaml
openapi: 3.0.3
info:
  title: Veza API
  version: 1.0.0
  description: |
    Veza platform API - Collaborative audio streaming, marketplace, and social network.
    
    **Authentication**: JWT Bearer token in `Authorization` header.
    
    **Rate Limiting**: Varies by endpoint (see headers).
    
    **Support**: api@veza.io
  contact:
    name: Veza API Support
    email: api@veza.io
    url: https://docs.veza.io
  license:
    name: Proprietary
servers:
  - url: https://api.veza.io/api/v1
    description: Production
  - url: https://staging-api.veza.io/api/v1
    description: Staging
  - url: http://localhost:8080/api/v1
    description: Local Development
```

### 10.2 Security Schemes

```yaml
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT access token obtained from /auth/login
```

### 10.3 Common Schemas

```yaml
components:
  schemas:
    UUID:
      type: string
      format: uuid
      example: "550e8400-e29b-41d4-a716-446655440000"
    
    Timestamp:
      type: string
      format: date-time
      example: "2025-11-02T14:30:00Z"
    
    Error:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: integer
          example: 1001
        message:
          type: string
          example: "Token expired"
        details:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
        request_id:
          $ref: '#/components/schemas/UUID'
        timestamp:
          $ref: '#/components/schemas/Timestamp'
    
    Pagination:
      type: object
      properties:
        next_cursor:
          type: string
          nullable: true
        has_more:
          type: boolean
        limit:
          type: integer
```

### 10.4 Example Endpoint Definition

```yaml
paths:
  /tracks:
    get:
      summary: List tracks
      description: Get a paginated list of public tracks
      operationId: listTracks
      tags:
        - Tracks
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 100
        - name: cursor
          in: query
          schema:
            type: string
        - name: genre
          in: query
          schema:
            type: string
        - name: sort
          in: query
          schema:
            type: string
            default: "-created_at"
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Track'
                  pagination:
                    $ref: '#/components/schemas/Pagination'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
    
    post:
      summary: Upload track
      description: Upload a new audio track
      operationId: createTrack
      tags:
        - Tracks
      security:
        - BearerAuth: []
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required:
                - title
                - file
              properties:
                title:
                  type: string
                  minLength: 1
                  maxLength: 255
                artist:
                  type: string
                  maxLength: 255
                genre:
                  type: string
                file:
                  type: string
                  format: binary
                cover_art:
                  type: string
                  format: binary
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Track'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
```

*[Full OpenAPI 3.0 spec with all 500+ endpoints would be ~5,000 lines - included in separate YAML file]*

## ✅ CHECKLIST DE VALIDATION

### API Completeness
- [ ] 500+ endpoints documentés pour tous les modules
- [ ] Request/Response schemas complets
- [ ] Authentication flows documentés
- [ ] Error codes standardisés (1000-9999)
- [ ] WebSocket protocol spécifié
- [ ] gRPC services définis

### Consistency
- [ ] Naming conventions respectées (snake_case, plural resources)
- [ ] HTTP methods utilisés correctement
- [ ] Dates format ISO 8601
- [ ] UUIDs pour tous les IDs
- [ ] Pagination cohérente (cursor-based)

### Security
- [ ] JWT authentication implémentée
- [ ] Rate limiting sur tous les endpoints
- [ ] Permission checks documentés
- [ ] Sensitive data jamais en query params

### Performance
- [ ] Pagination obligatoire pour collections
- [ ] Field selection supportée
- [ ] Caching headers définis
- [ ] Compression activée (gzip)

## 📊 MÉTRIQUES DE SUCCÈS

### Performance Targets
- **API Response Time p95**: < 100ms
- **API Response Time p99**: < 500ms
- **Throughput**: 10,000 req/s
- **Availability**: 99.95%

### Developer Experience
- **Time to First API Call**: < 5 minutes
- **Documentation Completeness**: 100%
- **API Error Rate**: < 0.1%
- **Breaking Changes**: 0 in v1

## 🔄 HISTORIQUE DES VERSIONS

| Version | Date | Changements |
|---------|------|-------------|
| 1.0.0 | 2025-11-02 | Version initiale - API REST complète |

---

## ⚠️ AVERTISSEMENT

**CETTE SPÉCIFICATION EST IMMUABLE**

L'API v1 définie ici est **VERROUILLÉE**. Toute modification nécessite:

1. **RFC API Change** avec impact analysis
2. **Backward compatibility** garantie
3. **Deprecation notice** (6 mois minimum)
4. **Migration guide** pour clients existants
5. **Approbation CTO**

**Breaking changes INTERDITS en v1** - Créer v2 si nécessaire.

---

**Document créé par**: API Team + Architecture  
**Date de création**: 2025-11-02  
**Prochaine révision**: Phase 4 (Q3 2026)  
**Propriétaire**: Lead Backend Engineer

**Statut**: ✅ **APPROUVÉ ET VERROUILLÉ**
