# dev.openplaylist.defs

> Published by [openplaylist.dev](https://lexicon.garden/identity/did:plc:giakgvcvljtnasoyluh3pf5a)

✓ This is the authoritative definition for this NSID.

## Description

Shared object definitions for Open Playlist records. Track metadata field names follow fm.teal.feed.defs so teal.fm and Rocksky tooling can read them without a mapping layer.

## Links

- [View on Lexicon Garden](https://lexicon.garden/lexicon/did:plc:giakgvcvljtnasoyluh3pf5a/dev.openplaylist.defs)
- [Documentation](https://lexicon.garden/lexicon/did:plc:giakgvcvljtnasoyluh3pf5a/dev.openplaylist.defs/docs)
- [Examples](https://lexicon.garden/lexicon/did:plc:giakgvcvljtnasoyluh3pf5a/dev.openplaylist.defs/examples)

## Definitions

### `dev.openplaylist.defs#artist`

**Type**: `object`

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `artistMbId` | `string` (uri) | No | MusicBrainz artist id, formatted as mbid:<uuid>. |
| `artistName` | `string` | Yes | The name of the artist. |

### `dev.openplaylist.defs#artwork`

**Type**: `object`

One cover art candidate. Either url or image must be present.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `height` | `integer` | No |  |
| `image` | `blob` | No | A cached copy of the artwork stored in the hosting repo, so the record survives every external service going away. |
| `provider` | `string` | Yes | Who serves this image. 'self' means the image blob is stored in this repo. |
| `url` | `string` (uri) | No | Public image URL. |
| `width` | `integer` | No |  |

### `dev.openplaylist.defs#contributor`

**Type**: `object`

Who added something. Anonymous contributors have only a display name; signed-in contributors also carry their DID.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `did` | `string` (did) | No | The contributor's ATProto identity, when they were signed in. |
| `displayName` | `string` | Yes | Name typed or chosen by the contributor. |

### `dev.openplaylist.defs#mirror`

**Type**: `object`

A native playlist on a music service that mirrors this record. The record is the source of truth; mirrors are downstream and append-only.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `externalId` | `string` | No | The service's playlist id. |
| `hostDid` | `string` (did) | No | DID of the account whose service login owns the mirror. Absent means the Open Playlist app account hosts it. |
| `service` | `string` | Yes | Service identifier. |
| `syncedAt` | `string` (datetime) | No | When the mirror was last brought up to date with this record. |
| `url` | `string` (uri) | Yes | Public, followable URL of the mirrored playlist. |

### `dev.openplaylist.defs#source`

**Type**: `object`

A location for a track on a specific music service.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `externalId` | `string` | No | The service's own track identifier, e.g. a Spotify track id or an Apple Music catalog id. |
| `region` | `string` | No | ISO 3166-1 alpha-2 storefront code when the externalId is region-specific, as Apple Music catalog ids are. |
| `service` | `string` | Yes | Service identifier. Unknown values must be preserved by readers. |
| `url` | `string` (uri) | Yes | Public URL of the track on that service. |

### `dev.openplaylist.defs#track`

**Type**: `object`

A catalog track. Identity is carried by isrc and MusicBrainz ids; per-service locations live in sources. Nothing here depends on a single music service.

| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `artists` | `array` | No | Artists in order of original appearance. |
| `artwork` | `array` | No | Cover art candidates in preference order. Readers fall through on load failure. |
| `duration` | `integer` | No | The length of the track in seconds. |
| `isrc` | `string` | No | International Standard Recording Code. The primary cross-service identifier; both Spotify and Apple Music return it. |
| `recordingMbId` | `string` (uri) | No | MusicBrainz recording id, formatted as mbid:<uuid>. |
| `releaseDiscriminant` | `string` | No | Distinguishing information for release variants, e.g. 'Deluxe Edition', '2023 Remaster'. |
| `releaseGroupMbId` | `string` (uri) | No | MusicBrainz release-group id, formatted as mbid:<uuid>. Used to fetch art from the Cover Art Archive. |
| `releaseMbId` | `string` (uri) | No | MusicBrainz release id, formatted as mbid:<uuid>. |
| `releaseName` | `string` | No | The name of the release or album. |
| `sources` | `array` | No | Where this track can be played, one entry per service. Readers pick the entry matching the listener's service, or resolve a missing one from isrc. |
| `trackDiscriminant` | `string` | No | Distinguishing information for track variants, e.g. 'Live at Wembley', 'Radio Edit'. |
| `trackName` | `string` | Yes | The name of the track. |

## Raw Schema

```json
{
  "$type": "com.atproto.lexicon.schema",
  "defs": {
    "artist": {
      "properties": {
        "artistMbId": {
          "description": "MusicBrainz artist id, formatted as mbid:<uuid>.",
          "format": "uri",
          "type": "string"
        },
        "artistName": {
          "description": "The name of the artist.",
          "maxGraphemes": 256,
          "maxLength": 2560,
          "minLength": 1,
          "type": "string"
        }
      },
      "required": [
        "artistName"
      ],
      "type": "object"
    },
    "artwork": {
      "description": "One cover art candidate. Either url or image must be present.",
      "properties": {
        "height": {
          "minimum": 1,
          "type": "integer"
        },
        "image": {
          "accept": [
            "image/*"
          ],
          "description": "A cached copy of the artwork stored in the hosting repo, so the record survives every external service going away.",
          "maxSize": 1000000,
          "type": "blob"
        },
        "provider": {
          "description": "Who serves this image. 'self' means the image blob is stored in this repo.",
          "knownValues": [
            "spotify",
            "appleMusic",
            "coverArtArchive",
            "youtube",
            "self"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "url": {
          "description": "Public image URL.",
          "format": "uri",
          "type": "string"
        },
        "width": {
          "minimum": 1,
          "type": "integer"
        }
      },
      "required": [
        "provider"
      ],
      "type": "object"
    },
    "contributor": {
      "description": "Who added something. Anonymous contributors have only a display name; signed-in contributors also carry their DID.",
      "properties": {
        "did": {
          "description": "The contributor's ATProto identity, when they were signed in.",
          "format": "did",
          "type": "string"
        },
        "displayName": {
          "description": "Name typed or chosen by the contributor.",
          "maxGraphemes": 64,
          "maxLength": 640,
          "minLength": 1,
          "type": "string"
        }
      },
      "required": [
        "displayName"
      ],
      "type": "object"
    },
    "mirror": {
      "description": "A native playlist on a music service that mirrors this record. The record is the source of truth; mirrors are downstream and append-only.",
      "properties": {
        "externalId": {
          "description": "The service's playlist id.",
          "maxLength": 256,
          "type": "string"
        },
        "hostDid": {
          "description": "DID of the account whose service login owns the mirror. Absent means the Open Playlist app account hosts it.",
          "format": "did",
          "type": "string"
        },
        "service": {
          "description": "Service identifier.",
          "knownValues": [
            "spotify",
            "appleMusic",
            "youtube"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "syncedAt": {
          "description": "When the mirror was last brought up to date with this record.",
          "format": "datetime",
          "type": "string"
        },
        "url": {
          "description": "Public, followable URL of the mirrored playlist.",
          "format": "uri",
          "type": "string"
        }
      },
      "required": [
        "service",
        "url"
      ],
      "type": "object"
    },
    "source": {
      "description": "A location for a track on a specific music service.",
      "properties": {
        "externalId": {
          "description": "The service's own track identifier, e.g. a Spotify track id or an Apple Music catalog id.",
          "maxLength": 256,
          "type": "string"
        },
        "region": {
          "description": "ISO 3166-1 alpha-2 storefront code when the externalId is region-specific, as Apple Music catalog ids are.",
          "maxLength": 2,
          "minLength": 2,
          "type": "string"
        },
        "service": {
          "description": "Service identifier. Unknown values must be preserved by readers.",
          "knownValues": [
            "spotify",
            "appleMusic",
            "youtube",
            "youtubeMusic",
            "tidal",
            "deezer",
            "bandcamp",
            "soundcloud",
            "musicbrainz"
          ],
          "maxLength": 64,
          "type": "string"
        },
        "url": {
          "description": "Public URL of the track on that service.",
          "format": "uri",
          "type": "string"
        }
      },
      "required": [
        "service",
        "url"
      ],
      "type": "object"
    },
    "track": {
      "description": "A catalog track. Identity is carried by isrc and MusicBrainz ids; per-service locations live in sources. Nothing here depends on a single music service.",
      "properties": {
        "artists": {
          "description": "Artists in order of original appearance.",
          "items": {
            "ref": "#artist",
            "type": "ref"
          },
          "maxLength": 20,
          "type": "array"
        },
        "artwork": {
          "description": "Cover art candidates in preference order. Readers fall through on load failure.",
          "items": {
            "ref": "#artwork",
            "type": "ref"
          },
          "maxLength": 10,
          "type": "array"
        },
        "duration": {
          "description": "The length of the track in seconds.",
          "minimum": 0,
          "type": "integer"
        },
        "isrc": {
          "description": "International Standard Recording Code. The primary cross-service identifier; both Spotify and Apple Music return it.",
          "maxLength": 15,
          "type": "string"
        },
        "recordingMbId": {
          "description": "MusicBrainz recording id, formatted as mbid:<uuid>.",
          "format": "uri",
          "type": "string"
        },
        "releaseDiscriminant": {
          "description": "Distinguishing information for release variants, e.g. 'Deluxe Edition', '2023 Remaster'.",
          "maxGraphemes": 128,
          "maxLength": 1280,
          "type": "string"
        },
        "releaseGroupMbId": {
          "description": "MusicBrainz release-group id, formatted as mbid:<uuid>. Used to fetch art from the Cover Art Archive.",
          "format": "uri",
          "type": "string"
        },
        "releaseMbId": {
          "description": "MusicBrainz release id, formatted as mbid:<uuid>.",
          "format": "uri",
          "type": "string"
        },
        "releaseName": {
          "description": "The name of the release or album.",
          "maxGraphemes": 256,
          "maxLength": 2560,
          "type": "string"
        },
        "sources": {
          "description": "Where this track can be played, one entry per service. Readers pick the entry matching the listener's service, or resolve a missing one from isrc.",
          "items": {
            "ref": "#source",
            "type": "ref"
          },
          "maxLength": 20,
          "type": "array"
        },
        "trackDiscriminant": {
          "description": "Distinguishing information for track variants, e.g. 'Live at Wembley', 'Radio Edit'.",
          "maxGraphemes": 128,
          "maxLength": 1280,
          "type": "string"
        },
        "trackName": {
          "description": "The name of the track.",
          "maxGraphemes": 256,
          "maxLength": 2560,
          "minLength": 1,
          "type": "string"
        }
      },
      "required": [
        "trackName"
      ],
      "type": "object"
    }
  },
  "description": "Shared object definitions for Open Playlist records. Track metadata field names follow fm.teal.feed.defs so teal.fm and Rocksky tooling can read them without a mapping layer.",
  "id": "dev.openplaylist.defs",
  "lexicon": 1
}
```
