> ## 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.

# Dashboard API Integration

> Integrate BeatPass dashboard metrics using the Artist Dashboard API endpoints. Retrieve plays, followers, upload insights, and collaboration data.

## Overview

The **Artist Dashboard API** provides programmatic access to producer analytics displayed in the Producer Dashboard. These endpoints return plays, followers, upload insights, and collaboration data for authenticated producers.

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

  **Authentication:** All endpoints require a valid Bearer token. The user must have a producer profile (be linked to an artist).
</Info>

***

## Authentication Requirements

All dashboard endpoints require:

* **Authentication:** User must include a valid Bearer token
* **Producer profile:** User must have an associated artist profile (created via the Producer Program)
* **Upload access:** Some endpoints (upload insights) additionally require the artist profile to have upload access enabled

### Response Format

All Dashboard API responses use a standard envelope:

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

On error, the envelope contains:

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "success": false,
  "message": "Error description"
}
```

***

## Endpoints

### Artist Profile Summary

**Endpoint:** `GET /api/v1/artist/profile`

Returns the active artist profile associated with the authenticated user.

#### Response Fields

<ResponseField name="id" type="integer" required>
  Artist ID associated with the current user.
</ResponseField>

<ResponseField name="name" type="string" required>
  Artist display name.
</ResponseField>

<ResponseField name="upload_access" type="boolean" required>
  Whether the profile can upload/manage tracks (gates upload health widgets).
</ResponseField>

<ResponseField name="total_tracks" type="integer" required>
  Count of tracks linked to the artist.
</ResponseField>

<ResponseField name="total_plays" type="integer" required>
  Aggregate plays across all linked tracks.
</ResponseField>

<ResponseField name="member_since" type="string" format="ISO8601" required>
  ISO timestamp when the artist profile was created.
</ResponseField>

<ResponseField name="bio" type="string">
  Current bio text.
</ResponseField>

<ResponseField name="website" type="string">
  Website URL if set.
</ResponseField>

<ResponseField name="social_links" type="object">
  Social handles/URLs (twitter, instagram, soundcloud, youtube).
</ResponseField>

***

### Update Artist Profile

**Endpoint:** `PUT /api/v1/artist/profile`

Update the authenticated artist's profile information.

#### Request Body

<ParamField body="bio" type="string">
  Artist bio text. Max 1,000 characters.
</ParamField>

<ParamField body="website" type="string">
  Website URL (must be a valid URL). Max 255 characters.
</ParamField>

<ParamField body="social_links" type="object">
  Social media handles/URLs.

  <Expandable title="Social links fields">
    <ParamField body="social_links.twitter" type="string">
      Twitter/X handle or URL. Max 255 characters.
    </ParamField>

    <ParamField body="social_links.instagram" type="string">
      Instagram handle or URL. Max 255 characters.
    </ParamField>

    <ParamField body="social_links.soundcloud" type="string">
      SoundCloud profile URL. Max 255 characters.
    </ParamField>

    <ParamField body="social_links.youtube" type="string">
      YouTube channel URL. Max 255 characters.
    </ParamField>
  </Expandable>
</ParamField>

#### Response

```json theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
{
  "success": true,
  "message": "Profile updated successfully",
  "data": {
    "bio": "Updated bio text",
    "website": "https://example.com",
    "social_links": {
      "twitter": "@producer",
      "instagram": "@producer"
    }
  }
}
```

***

### Dashboard Stats

**Endpoint:** `GET /api/v1/artist/dashboard-stats`

Retrieves headline metrics used on the Backstage dashboard.

#### Response Fields

<ResponseField name="total_tracks" type="integer" required>
  How many tracks the artist has published.
</ResponseField>

<ResponseField name="total_plays" type="integer" required>
  Total lifetime plays.
</ResponseField>

<ResponseField name="total_contribution" type="number" format="decimal" required>
  Sum of contribution values across tracks (used for earnings splits).
</ResponseField>

<ResponseField name="recent_uploads" type="integer" required>
  Tracks uploaded in the last 30 days.
</ResponseField>

<ResponseField name="play_growth_percentage" type="number" required>
  Month-over-month play growth percentage.
</ResponseField>

<ResponseField name="top_track" type="object">
  <Expandable title="Top track object">
    <ResponseField name="id" type="integer" required>
      Track ID with the most plays.
    </ResponseField>

    <ResponseField name="name" type="string" required>
      Track name.
    </ResponseField>

    <ResponseField name="plays" type="integer" required>
      Play count for the top track.
    </ResponseField>

    <ResponseField name="contribution_value" type="number" required>
      Contribution value for the top track.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="average_plays_per_track" type="integer" required>
  Rounded average plays per track.
</ResponseField>

<ResponseField name="tracks_with_plays" type="integer" required>
  How many tracks have at least one play.
</ResponseField>

***

### Track Performance

**Endpoint:** `GET /api/v1/artist/track-performance`

Returns the most recent 20 tracks with their performance signals for timeline charts.

#### Response Fields (Array)

<ResponseField name="[].track_id" type="integer" required>
  Track ID.
</ResponseField>

<ResponseField name="[].track_name" type="string" required>
  Track title.
</ResponseField>

<ResponseField name="[].plays" type="integer" required>
  Total plays for the track.
</ResponseField>

<ResponseField name="[].contribution_value" type="number" required>
  Contribution value for the track.
</ResponseField>

<ResponseField name="[].months_since_upload" type="integer" required>
  Age of the track in months (used for cohorting performance).
</ResponseField>

<ResponseField name="[].upload_date" type="string" format="ISO8601" required>
  Upload timestamp.
</ResponseField>

<ResponseField name="[].last_updated" type="string" format="ISO8601">
  When contribution was last recalculated (null if pending).
</ResponseField>

***

### Upload Insights

**Endpoint:** `GET /api/v1/artist/upload-insights`

Provides upload cadence analysis and recommendations for optimal release timing.

#### Response Fields

<ResponseField name="total_uploads" type="integer" required>
  Total tracks uploaded by the artist.
</ResponseField>

<ResponseField name="uploads_this_month" type="integer" required>
  Uploads in the current calendar month.
</ResponseField>

<ResponseField name="uploads_last_month" type="integer" required>
  Uploads in the previous calendar month.
</ResponseField>

<ResponseField name="average_plays_per_upload" type="integer" required>
  Rounded average plays per upload.
</ResponseField>

<ResponseField name="best_performing_month" type="object">
  <Expandable title="Best performing month object">
    <ResponseField name="month" type="string" required>
      Month key in `YYYY-MM` format.
    </ResponseField>

    <ResponseField name="total_plays" type="integer" required>
      Total plays earned that month.
    </ResponseField>

    <ResponseField name="track_count" type="integer" required>
      Number of tracks uploaded that month.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="upload_frequency_days" type="integer">
  Average days between uploads (null when fewer than two uploads exist).
</ResponseField>

<ResponseField name="recommended_upload_time" type="string" required>
  Text recommendation for how often to upload next.
</ResponseField>

<Warning>
  Returns `403 Forbidden` if `upload_access` is false on the artist profile.
</Warning>

***

### Collaborative Tracks

**Endpoint:** `GET /api/v1/artist/{artist}/collaborative-tracks`

Retrieves tracks where the artist has collaborated with other producers.

#### Path Parameters

<ParamField path="artist" type="integer" required>
  Artist ID to fetch collaborations for.
</ParamField>

#### Response Fields (Array)

<ResponseField name="[].track_id" type="integer" required>
  Collaborative track ID.
</ResponseField>

<ResponseField name="[].title" type="string" required>
  Track name.
</ResponseField>

<ResponseField name="[].primary_artist" type="string" required>
  Primary artist credit.
</ResponseField>

<ResponseField name="[].collaborators" type="array" required>
  List of collaborating artists on the track.
</ResponseField>

<ResponseField name="[].plays" type="integer">
  Play count for the collaborative track.
</ResponseField>

***

## Integration Example

```javascript theme={"theme":{"light":"github-light","dark":"one-dark-pro"}}
// Example: Fetch dashboard stats for authenticated producer
async function getDashboardStats() {
  const response = await fetch('https://open.beatpass.ca/api/v1/artist/dashboard-stats', {
    method: 'GET',
    headers: {
      'Accept': 'application/json',
      'Authorization': 'Bearer YOUR_TOKEN_HERE'
    }
  });
  
  if (!response.ok) {
    throw new Error(`Dashboard API error: ${response.status}`);
  }
  
  const stats = await response.json();
  return stats;
}
```

***

## Related Resources

<CardGroup cols={2}>
  <Card title="Authentication" icon="key" href="/developers/auth">
    Understand API authentication
  </Card>

  <Card title="Rate Limits" icon="gauge" href="/developers/rate-limits">
    Understand API rate limiting
  </Card>

  <Card title="Error Handling" icon="triangle-exclamation" href="/developers/error-catalog">
    Handle API errors properly
  </Card>

  <Card title="API Reference" icon="book" href="/developers/api-reference/overview">
    Browse the OpenAPI reference
  </Card>
</CardGroup>
