> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beatpass.ca/llms.txt
> Use this file to discover all available pages before exploring further.

# Social & Following API

> User following, artist following, reposts, and library management endpoints.

## Overview

The Social API covers the platform's social graph — following users and artists, reposting content, and managing the user's personal library of liked tracks, albums, and artists.

<Info>
  **Base URL:** `https://open.beatpass.ca/api/v1`

  **Authentication:** Write operations require a valid Bearer token. Read operations on public profiles use optional auth.
</Info>

***

## User Following

### Follow User

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/users/{user}/follow
```

### Unfollow User

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/users/{user}/unfollow
```

### Check Follow Status

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/follow-status
```

### Get User's Followers

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/followers
```

### Get User's Followed Users

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/followed-users
```

***

## Artist Following

### Follow Artist

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/artists/{artistId}/follow
```

### Unfollow Artist

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/artists/{artistId}/unfollow
```

### Check Artist Follow Status

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/artists/{artistId}/follow-status
```

### Get Artist's Followers

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/artists/{artistId}/followers
```

***

## Follow Limits

<CardGroup cols={3}>
  <Card title="Max Following" icon="user-plus" color="#3b82f6">
    <Badge color="blue">5,000 users</Badge>
    Maximum accounts a user can follow
  </Card>

  <Card title="Follow Rate" icon="gauge" color="#f59e0b">
    <Badge color="orange">Rate limited</Badge>
    Too many follows in quick succession triggers 429
  </Card>

  <Card title="Self-Follow" icon="ban" color="#ef4444">
    <Badge color="red">Not allowed</Badge>
    Cannot follow your own account
  </Card>
</CardGroup>

***

## Reposts

### Toggle Repost

Toggle repost status for a track. If already reposted, it removes the repost.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/reposts/toggle
```

<ParamField body="track_id" type="integer" required>
  Track ID to repost or un-repost.
</ParamField>

### Get User's Reposts

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/reposts
```

### Repost Limits

| Limit               | Value       |
| ------------------- | ----------- |
| Daily repost limit  | 100 per day |
| Hourly repost limit | 20 per hour |
| Self-repost         | Not allowed |

***

## User Library

### Add to Library

Add a track to the authenticated user's library (liked tracks).

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/users/me/add-to-library
```

### Remove from Library

Remove a track from the user's library.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/users/me/remove-from-library
```

### Get Liked Tracks

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/liked-tracks
```

### Get Liked Albums

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/liked-albums
```

### Get Liked Artists

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/liked-artists
```

### Library Limits

| Limit                   | Value  |
| ----------------------- | ------ |
| Max saved items         | 10,000 |
| Max playlists           | 100    |
| Max tracks per playlist | 500    |

***

## Collections

Collections are curated groupings of content. All collection endpoints require authentication.

### List Collections

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/collections
```

### Featured Collections

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/collections/featured
```

### User Collections

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/collections/user
```

### Collection Recommendations

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/collections/recommendations
```

### Create Collection

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/collections
```

### Get Collection

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/collections/{id}
```

### Update Collection

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
PUT /api/v1/collections/{id}
```

### Delete Collection

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
DELETE /api/v1/collections/{id}
```

### Play Collection

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/collections/{id}/play
```

***

## User Profile

### Get User Profile

Retrieve a user's public profile. Enhanced data returned when authenticated.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/user-profile/{user}
```

### Update Profile

Update the authenticated user's profile.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
PUT /api/v1/users/profile/update
```

### Get User's Playlists

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/playlists
```

### Get Upload Minutes Remaining

Check how many upload minutes a user has remaining on their current plan.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/minutes-left
```

<ParamField path="user" type="integer" required>
  User ID.
</ParamField>

**Response:**

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "status": "success",
  "minutesLeft": 120
}
```

<Note>
  Returns `null` for `minutesLeft` if the user's plan has no minute-based upload restriction.
</Note>

### Get Contact Info

Retrieve a user's contact information. Rate limited to 30 requests per minute.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/{user}/contact-info
```

### Search Users

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/users/search
```

***

## Notification Preferences

Manage notification delivery channels for the authenticated user. Each notification type (for example new follower, comment reply, or analytics report) has independent channel toggles for `email`, `in_app`, and `mobile`.

<Note>
  Use `me` for the authenticated user route, or pass the authenticated user's numeric ID. The backend resolves both forms.
</Note>

### Channel Keys

* `email` — Email notifications
* `in_app` — Notification center storage and live activity in open tabs
* `mobile` — FCM-backed push delivery for registered devices, including supported browsers and mobile apps

### Get Notification Subscriptions

Retrieve the authenticated user's notification configuration, available channels, saved selections, and role-based context.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
GET /api/v1/notifications/me/subscriptions
```

**Response:**

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "status": "success",
  "available_channels": ["email", "in_app", "mobile"],
  "subscriptions": [
    {
      "group_name": "Messages",
      "subscriptions": [
        {
          "name": "Direct Messages",
          "notif_id": "new_message",
          "description": "When you receive a direct message"
        }
      ]
    }
  ],
  "user_selections": [
    {
      "notif_id": "new_message",
      "channels": {
        "email": true,
        "in_app": true,
        "mobile": true
      }
    }
  ],
  "user_context": {
    "is_artist": true,
    "is_verified_artist": false
  }
}
```

### Update Notification Subscriptions

Update one or more notification channel preferences.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
PUT /api/v1/notifications/me/subscriptions
```

<ParamField body="selections" type="array" required>
  Array of notification preference updates.
</ParamField>

<ParamField body="selections[].notif_id" type="string" required>
  Notification identifier to update, such as `new_message`.
</ParamField>

<ParamField body="selections[].channels" type="object" required>
  Channel state object keyed by `email`, `in_app`, and/or `mobile`.
</ParamField>

**Response:**

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "status": "success"
}
```

<Note>
  Use the exact backend channel keys in update payloads: `email`, `in_app`, and `mobile`. The legacy `browser` key is no longer part of the notification settings contract.
</Note>

***

## FCM Device Tokens

Register and manage Firebase Cloud Messaging device tokens for the authenticated user. The API stores tokens only; obtaining the token is the responsibility of the client app through the Firebase SDK.

### Register or Refresh FCM Token

Store or refresh an FCM token for the authenticated user.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
POST /api/v1/fcm-tokens
```

<ParamField body="token" type="string" required>
  FCM registration token returned by the Firebase client SDK.
</ParamField>

<ParamField body="platform" type="string">
  Device platform. Supported values: `web`, `android`, `ios`. Defaults to `web`.
</ParamField>

<ParamField body="device_name" type="string">
  Optional device label, typically the user agent or app/device name.
</ParamField>

**Response:**

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "status": "ok"
}
```

<Note>
  Tokens are upserted by token value. Re-registering the same token refreshes its metadata and ownership. These FCM token endpoints currently return `{ "status": "ok" }`, while the notification subscription endpoints above use the standard `{ "status": "success" }` response envelope.
</Note>

### Delete FCM Token

Remove an FCM token for the authenticated user, for example during logout.

```http theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
DELETE /api/v1/fcm-tokens
```

<ParamField body="token" type="string" required>
  FCM registration token to remove.
</ParamField>

**Response:**

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "status": "ok"
}
```

<Note>
  This endpoint currently expects the FCM token in a JSON request body. Some HTTP clients or intermediaries strip bodies from `DELETE` requests, so use a client path that preserves the JSON payload. Keeping the token out of the URL also avoids encoding and length issues with long FCM tokens.
</Note>

***

## Related Resources

<CardGroup cols={2}>
  <Card title="Content API" icon="record-vinyl" href="/developers/api-reference/content">
    Track, album, and artist management.
  </Card>

  <Card title="Error Catalog" icon="triangle-exclamation" href="/developers/error-catalog">
    Social and following error codes.
  </Card>
</CardGroup>
