# Laravel Jukebox API - Request/Response Examples

## 1. Authentication

### Register New User
**Request:**
```bash
POST /api/register
Content-Type: application/json

{
  "name": "John Doe",
  "email": "john@example.com",
  "password": "password123",
  "password_confirmation": "password123"
}
```

**Response (201 Created):**
```json
{
  "token": "1|abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
  "user": {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "role_id": 2,
    "created_at": "2026-05-07T10:05:00.000000Z",
    "updated_at": "2026-05-07T10:05:00.000000Z",
    "role": {
      "id": 2,
      "name": "user",
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z"
    }
  }
}
```

### Login
**Request:**
```bash
POST /api/login
Content-Type: application/json

{
  "email": "john@example.com",
  "password": "password123"
}
```

**Response (200 OK):**
```json
{
  "token": "2|abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890",
  "user": {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "role_id": 2,
    "created_at": "2026-05-07T10:05:00.000000Z",
    "updated_at": "2026-05-07T10:05:00.000000Z",
    "role": {
      "id": 2,
      "name": "user",
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z"
    }
  }
}
```

### Get Current User
**Request:**
```bash
GET /api/me
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com",
  "role_id": 2,
  "created_at": "2026-05-07T10:05:00.000000Z",
  "updated_at": "2026-05-07T10:05:00.000000Z",
  "role": {
    "id": 2,
    "name": "user",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  }
}
```

### Logout
**Request:**
```bash
POST /api/logout
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
{
  "message": "Logged out."
}
```

---

## 2. Browse (Read-Only) Endpoints

### List All Labels
**Request:**
```bash
GET /api/labels
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
[
  {
    "id": 1,
    "name": "Universal Music",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  },
  {
    "id": 2,
    "name": "Sony Music",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  }
]
```

### Get Single Label
**Request:**
```bash
GET /api/labels/1
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "name": "Universal Music",
  "created_at": "2026-04-21T00:00:00.000000Z",
  "updated_at": "2026-04-21T00:00:00.000000Z"
}
```

### List All Genres
**Request:**
```bash
GET /api/genres
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
[
  {
    "id": 1,
    "name": "Rock",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  },
  {
    "id": 2,
    "name": "Pop",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  }
]
```

### List All Artists
**Request:**
```bash
GET /api/artists
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
[
  {
    "id": 1,
    "name": "The Beatles",
    "cover_path": "/images/beatles.jpg",
    "release_date": "1960-01-01T00:00:00.000000Z",
    "label_id": 1,
    "duration": null,
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z",
    "label": {
      "id": 1,
      "name": "Universal Music",
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z"
    }
  }
]
```

### Get Single Artist (with Relations)
**Request:**
```bash
GET /api/artists/1
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "name": "The Beatles",
  "cover_path": "/images/beatles.jpg",
  "release_date": "1960-01-01T00:00:00.000000Z",
  "label_id": 1,
  "duration": null,
  "created_at": "2026-04-21T00:00:00.000000Z",
  "updated_at": "2026-04-21T00:00:00.000000Z",
  "label": {
    "id": 1,
    "name": "Universal Music",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  },
  "tracks": [
    {
      "id": 1,
      "title": "Hey Jude",
      "file_path": "/music/hey-jude.mp3",
      "duration_seconds": 427,
      "album_id": 1,
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z",
      "album": {
        "id": 1,
        "title": "Hey Jude",
        "cover_path": "/images/hey-jude.jpg",
        "release_date": "1968-08-26T00:00:00.000000Z",
        "duration_seconds": 427,
        "type": "single",
        "label_id": 1,
        "created_at": "2026-04-21T00:00:00.000000Z",
        "updated_at": "2026-04-21T00:00:00.000000Z"
      },
      "genres": [
        {
          "id": 1,
          "name": "Rock",
          "created_at": "2026-04-21T00:00:00.000000Z",
          "updated_at": "2026-04-21T00:00:00.000000Z",
          "pivot": {
            "track_id": 1,
            "genre_id": 1,
            "created_at": "2026-04-21T00:00:00.000000Z",
            "updated_at": "2026-04-21T00:00:00.000000Z"
          }
        }
      ]
    }
  ]
}
```

### List All Albums
**Request:**
```bash
GET /api/albums
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
[
  {
    "id": 1,
    "title": "Abbey Road",
    "cover_path": "/images/abbey-road.jpg",
    "release_date": "1969-09-26T00:00:00.000000Z",
    "duration_seconds": 3025,
    "type": "album",
    "label_id": 1,
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z",
    "label": {
      "id": 1,
      "name": "Universal Music",
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z"
    }
  }
]
```

### Get Single Album (with Relations)
**Request:**
```bash
GET /api/albums/1
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "title": "Abbey Road",
  "cover_path": "/images/abbey-road.jpg",
  "release_date": "1969-09-26T00:00:00.000000Z",
  "duration_seconds": 3025,
  "type": "album",
  "label_id": 1,
  "created_at": "2026-04-21T00:00:00.000000Z",
  "updated_at": "2026-04-21T00:00:00.000000Z",
  "label": {
    "id": 1,
    "name": "Universal Music",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  },
  "tracks": [
    {
      "id": 1,
      "title": "Come Together",
      "file_path": "/music/come-together.mp3",
      "duration_seconds": 259,
      "album_id": 1,
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z",
      "artists": [
        {
          "id": 1,
          "name": "The Beatles",
          "cover_path": "/images/beatles.jpg",
          "release_date": "1960-01-01T00:00:00.000000Z",
          "label_id": 1,
          "duration": null,
          "created_at": "2026-04-21T00:00:00.000000Z",
          "updated_at": "2026-04-21T00:00:00.000000Z",
          "pivot": {
            "track_id": 1,
            "artist_id": 1,
            "created_at": "2026-04-21T00:00:00.000000Z",
            "updated_at": "2026-04-21T00:00:00.000000Z"
          }
        }
      ],
      "genres": [
        {
          "id": 1,
          "name": "Rock",
          "created_at": "2026-04-21T00:00:00.000000Z",
          "updated_at": "2026-04-21T00:00:00.000000Z",
          "pivot": {
            "track_id": 1,
            "genre_id": 1,
            "created_at": "2026-04-21T00:00:00.000000Z",
            "updated_at": "2026-04-21T00:00:00.000000Z"
          }
        }
      ]
    }
  ]
}
```

### List All Tracks
**Request:**
```bash
GET /api/tracks
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
[
  {
    "id": 1,
    "title": "Come Together",
    "file_path": "/music/come-together.mp3",
    "duration_seconds": 259,
    "album_id": 1,
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z",
    "album": {
      "id": 1,
      "title": "Abbey Road",
      "cover_path": "/images/abbey-road.jpg",
      "release_date": "1969-09-26T00:00:00.000000Z",
      "duration_seconds": 3025,
      "type": "album",
      "label_id": 1,
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z"
    },
    "artists": [
      {
        "id": 1,
        "name": "The Beatles",
        "cover_path": "/images/beatles.jpg",
        "release_date": "1960-01-01T00:00:00.000000Z",
        "label_id": 1,
        "duration": null,
        "created_at": "2026-04-21T00:00:00.000000Z",
        "updated_at": "2026-04-21T00:00:00.000000Z",
        "pivot": {
          "track_id": 1,
          "artist_id": 1,
          "created_at": "2026-04-21T00:00:00.000000Z",
          "updated_at": "2026-04-21T00:00:00.000000Z"
        }
      }
    ],
    "genres": [
      {
        "id": 1,
        "name": "Rock",
        "created_at": "2026-04-21T00:00:00.000000Z",
        "updated_at": "2026-04-21T00:00:00.000000Z",
        "pivot": {
          "track_id": 1,
          "genre_id": 1,
          "created_at": "2026-04-21T00:00:00.000000Z",
          "updated_at": "2026-04-21T00:00:00.000000Z"
        }
      }
    ]
  }
]
```

### Get Single Track (with Relations)
**Request:**
```bash
GET /api/tracks/1
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "title": "Come Together",
  "file_path": "/music/come-together.mp3",
  "duration_seconds": 259,
  "album_id": 1,
  "created_at": "2026-04-21T00:00:00.000000Z",
  "updated_at": "2026-04-21T00:00:00.000000Z",
  "album": {
    "id": 1,
    "title": "Abbey Road",
    "cover_path": "/images/abbey-road.jpg",
    "release_date": "1969-09-26T00:00:00.000000Z",
    "duration_seconds": 3025,
    "type": "album",
    "label_id": 1,
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z",
    "label": {
      "id": 1,
      "name": "Universal Music",
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z"
    }
  },
  "artists": [
    {
      "id": 1,
      "name": "The Beatles",
      "cover_path": "/images/beatles.jpg",
      "release_date": "1960-01-01T00:00:00.000000Z",
      "label_id": 1,
      "duration": null,
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z",
      "pivot": {
        "track_id": 1,
        "artist_id": 1,
        "created_at": "2026-04-21T00:00:00.000000Z",
        "updated_at": "2026-04-21T00:00:00.000000Z"
      }
    }
  ],
  "genres": [
    {
      "id": 1,
      "name": "Rock",
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z",
      "pivot": {
        "track_id": 1,
        "genre_id": 1,
        "created_at": "2026-04-21T00:00:00.000000Z",
        "updated_at": "2026-04-21T00:00:00.000000Z"
      }
    }
  ]
}
```

---

## 3. User Likes/Favorites

### Get User's Liked Tracks
**Request:**
```bash
GET /api/me/likes
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
[
  {
    "id": 1,
    "title": "Come Together",
    "file_path": "/music/come-together.mp3",
    "duration_seconds": 259,
    "album_id": 1,
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z",
    "album": { ... },
    "artists": [ ... ],
    "genres": [ ... ]
  }
]
```

### Like a Track
**Request:**
```bash
POST /api/tracks/1/like
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
{
  "message": "Track liked."
}
```

### Unlike a Track
**Request:**
```bash
DELETE /api/tracks/1/like
Authorization: Bearer {token}
```

**Response (200 OK):**
```json
{
  "message": "Track unliked."
}
```

---

## 4. Admin CRUD Operations

### Create Label (Admin Only)
**Request:**
```bash
POST /api/labels
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "name": "Epic Records"
}
```

**Response (201 Created):**
```json
{
  "id": 3,
  "name": "Epic Records",
  "created_at": "2026-05-07T10:10:00.000000Z",
  "updated_at": "2026-05-07T10:10:00.000000Z"
}
```

### Update Label (Admin Only)
**Request:**
```bash
PUT /api/labels/3
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "name": "Epic Records Group"
}
```

**Response (200 OK):**
```json
{
  "id": 3,
  "name": "Epic Records Group",
  "created_at": "2026-05-07T10:10:00.000000Z",
  "updated_at": "2026-05-07T10:15:00.000000Z"
}
```

### Delete Label (Admin Only)
**Request:**
```bash
DELETE /api/labels/3
Authorization: Bearer {admin_token}
```

**Response (204 No Content):**
```
(Empty body)
```

### Create Genre (Admin Only)
**Request:**
```bash
POST /api/genres
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "name": "Jazz"
}
```

**Response (201 Created):**
```json
{
  "id": 3,
  "name": "Jazz",
  "created_at": "2026-05-07T10:10:00.000000Z",
  "updated_at": "2026-05-07T10:10:00.000000Z"
}
```

### Create Artist (Admin Only)
**Request:**
```bash
POST /api/artists
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "name": "Miles Davis",
  "cover_path": "/images/miles-davis.jpg",
  "release_date": "1926-05-26",
  "label_id": 1,
  "duration": null
}
```

**Response (201 Created):**
```json
{
  "id": 2,
  "name": "Miles Davis",
  "cover_path": "/images/miles-davis.jpg",
  "release_date": "1926-05-26T00:00:00.000000Z",
  "label_id": 1,
  "duration": null,
  "created_at": "2026-05-07T10:10:00.000000Z",
  "updated_at": "2026-05-07T10:10:00.000000Z",
  "label": {
    "id": 1,
    "name": "Universal Music",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  }
}
```

### Create Album (Admin Only)
**Request:**
```bash
POST /api/albums
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "title": "Kind of Blue",
  "cover_path": "/images/kind-of-blue.jpg",
  "release_date": "1959-03-02",
  "duration_seconds": 1975,
  "type": "album",
  "label_id": 1
}
```

**Response (201 Created):**
```json
{
  "id": 2,
  "title": "Kind of Blue",
  "cover_path": "/images/kind-of-blue.jpg",
  "release_date": "1959-03-02T00:00:00.000000Z",
  "duration_seconds": 1975,
  "type": "album",
  "label_id": 1,
  "created_at": "2026-05-07T10:10:00.000000Z",
  "updated_at": "2026-05-07T10:10:00.000000Z",
  "label": {
    "id": 1,
    "name": "Universal Music",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  }
}
```

### Create Track (Admin Only)
**Request:**
```bash
POST /api/tracks
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "title": "So What",
  "file_path": "/music/so-what.mp3",
  "duration_seconds": 567,
  "album_id": 2,
  "artist_ids": [2],
  "genre_ids": [3]
}
```

**Response (201 Created):**
```json
{
  "id": 2,
  "title": "So What",
  "file_path": "/music/so-what.mp3",
  "duration_seconds": 567,
  "album_id": 2,
  "created_at": "2026-05-07T10:10:00.000000Z",
  "updated_at": "2026-05-07T10:10:00.000000Z",
  "album": {
    "id": 2,
    "title": "Kind of Blue",
    "cover_path": "/images/kind-of-blue.jpg",
    "release_date": "1959-03-02T00:00:00.000000Z",
    "duration_seconds": 1975,
    "type": "album",
    "label_id": 1,
    "created_at": "2026-05-07T10:10:00.000000Z",
    "updated_at": "2026-05-07T10:10:00.000000Z"
  },
  "artists": [
    {
      "id": 2,
      "name": "Miles Davis",
      "cover_path": "/images/miles-davis.jpg",
      "release_date": "1926-05-26T00:00:00.000000Z",
      "label_id": 1,
      "duration": null,
      "created_at": "2026-05-07T10:10:00.000000Z",
      "updated_at": "2026-05-07T10:10:00.000000Z",
      "pivot": {
        "track_id": 2,
        "artist_id": 2,
        "created_at": "2026-05-07T10:10:00.000000Z",
        "updated_at": "2026-05-07T10:10:00.000000Z"
      }
    }
  ],
  "genres": [
    {
      "id": 3,
      "name": "Jazz",
      "created_at": "2026-05-07T10:10:00.000000Z",
      "updated_at": "2026-05-07T10:10:00.000000Z",
      "pivot": {
        "track_id": 2,
        "genre_id": 3,
        "created_at": "2026-05-07T10:10:00.000000Z",
        "updated_at": "2026-05-07T10:10:00.000000Z"
      }
    }
  ]
}
```

### Update Track (Admin Only)
**Request:**
```bash
PUT /api/tracks/2
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "title": "So What (Remastered)",
  "artist_ids": [2],
  "genre_ids": [1, 3]
}
```

**Response (200 OK):**
```json
{
  "id": 2,
  "title": "So What (Remastered)",
  "file_path": "/music/so-what.mp3",
  "duration_seconds": 567,
  "album_id": 2,
  "created_at": "2026-05-07T10:10:00.000000Z",
  "updated_at": "2026-05-07T10:20:00.000000Z",
  "album": { ... },
  "artists": [ ... ],
  "genres": [
    { "id": 1, "name": "Rock", ... },
    { "id": 3, "name": "Jazz", ... }
  ]
}
```

### Delete Track (Admin Only)
**Request:**
```bash
DELETE /api/tracks/2
Authorization: Bearer {admin_token}
```

**Response (204 No Content):**
```
(Empty body)
```

### List All Users (Admin Only)
**Request:**
```bash
GET /api/users
Authorization: Bearer {admin_token}
```

**Response (200 OK):**
```json
[
  {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "role_id": 2,
    "created_at": "2026-05-07T10:05:00.000000Z",
    "updated_at": "2026-05-07T10:05:00.000000Z",
    "role": {
      "id": 2,
      "name": "user",
      "created_at": "2026-04-21T00:00:00.000000Z",
      "updated_at": "2026-04-21T00:00:00.000000Z"
    }
  }
]
```

### Get Single User (Admin Only)
**Request:**
```bash
GET /api/users/1
Authorization: Bearer {admin_token}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com",
  "role_id": 2,
  "created_at": "2026-05-07T10:05:00.000000Z",
  "updated_at": "2026-05-07T10:05:00.000000Z",
  "role": {
    "id": 2,
    "name": "user",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  }
}
```

### Update User (Admin Only)
**Request:**
```bash
PUT /api/users/1
Authorization: Bearer {admin_token}
Content-Type: application/json

{
  "name": "Jane Doe",
  "email": "jane@example.com",
  "role_id": 1
}
```

**Response (200 OK):**
```json
{
  "id": 1,
  "name": "Jane Doe",
  "email": "jane@example.com",
  "role_id": 1,
  "created_at": "2026-05-07T10:05:00.000000Z",
  "updated_at": "2026-05-07T10:25:00.000000Z",
  "role": {
    "id": 1,
    "name": "admin",
    "created_at": "2026-04-21T00:00:00.000000Z",
    "updated_at": "2026-04-21T00:00:00.000000Z"
  }
}
```

### Delete User (Admin Only)
**Request:**
```bash
DELETE /api/users/1
Authorization: Bearer {admin_token}
```

**Response (204 No Content):**
```
(Empty body)
```

---

## 5. Error Responses

### Validation Error (400 Bad Request)
**Response:**
```json
{
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email has already been taken."],
    "password": ["The password must be at least 8 characters."]
  }
}
```

### Authentication Error (401 Unauthorized)
**Response:**
```json
{
  "message": "Unauthenticated."
}
```

### Authorization Error (403 Forbidden - User trying to access Admin endpoint)
**Response:**
```json
{
  "message": "Forbidden."
}
```

### Not Found Error (404)
**Response:**
```json
{
  "message": "No query results found for model [App\\Models\\Track] 999"
}
```

### Login Invalid Credentials (422 Unprocessable Content)
**Response:**
```json
{
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The provided credentials are incorrect."]
  }
}
```

---

## 6. Headers

### Required Headers
```
Authorization: Bearer {token}
Content-Type: application/json (for POST/PUT requests)
```

### Example with cURL
```bash
curl -X GET http://localhost/api/tracks \
  -H "Authorization: Bearer 1|abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890" \
  -H "Content-Type: application/json"
```

---

## 7. HTTP Status Codes

| Code | Meaning | Example |
|------|---------|---------|
| 200 | OK | Successful GET/POST/PUT |
| 201 | Created | Successful resource creation |
| 204 | No Content | Successful DELETE |
| 400 | Bad Request | Validation error |
| 401 | Unauthorized | Missing/invalid token |
| 403 | Forbidden | Admin-only endpoint + user role |
| 404 | Not Found | Resource doesn't exist |
| 422 | Unprocessable Content | Login with wrong credentials |

