๐ฏ Complete Album Creation Tutorial
Step-by-step guide to create a complete album with all its relationships using the limbo/API
What You'll Learn
This tutorial will guide you through creating a complete music album from scratch, including all necessary relationships and validations. By the end, you'll have created:
- โข 1 Record Label - Music distributor
- โข 4 Artists - Band members with unique roles
- โข 1 Album - With complete metadata
- โข 4 Album-Artist relationships - Different roles
- โข 3 Tracks - Album songs with lyrics
- โข Country associations - Distribution territories
- โข 4 DSP associations - Streaming platforms
- โข 1 Distribution Request - Submission workflow
- โข Complete validation - Error handling examples
- โข Final verification - Query complete data
๐ Prerequisites
Before starting:
- Valid API credentials (email and password)
- HTTP client (Postman, Insomnia, VS Code REST Client, etc.)
- Basic understanding of REST APIs and JSON
- Familiarity with JSON API specification (optional but helpful)
๐ Step 0: Authentication
Every API request requires authentication. Start by obtaining your Bearer token:
/oauth/token
{
"email": "user@example.com",
"password": "password123",
"grant_type": "password"
}
Success Response
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
"token_type": "Bearer",
"expires_in": 3000
}
๐ก Important
Save the access_token
- you'll need it for every subsequent request as: Authorization: Bearer {your_token}
๐ Step 1: Create Label
Every album needs a Label. Let's create one for our fictional band:
/labels
{
"data": {
"type": "labels",
"attributes": {
"name": "Label Records",
"description": "Independent record label specializing in alternative rock"
}
}
}
Success Response
{
"data": {
"type": "labels",
"id": "1",
"attributes": {
"name": "Label Records",
"description": "Independent record label specializing in alternative rock",
"created-at": "2024-08-19T10:00:00Z",
"updated-at": "2024-08-19T10:00:00Z"
}
}
}
๐ Note: Save the label ID (1) - you'll need it when creating the album.
๐ฅ Step 2: Create Artists
Our fictional band has 4 members. Let's create each artist:
๐ค Artist 1: Main Artist
/artists
{
"data": {
"type": "artists",
"attributes": {
"name": "James Carter",
"bio": "Lead vocalist with over 10 years of experience in alternative rock"
}
}
}
๐ธ Artist 2: Featured Artist
{
"data": {
"type": "artists",
"attributes": {
"name": "Lisa Thompson",
"bio": "Featured guitarist and composer, band founder. Influenced by 90s national rock"
}
}
}
๐ธ Artist 3: Producer
{
"data": {
"type": "artists",
"attributes": {
"name": "David Miller",
"bio": "Producer and bassist with classical training. Responsible for the album's sound production and arrangement"
}
}
}
๐ฅ Artist 4: Composer
{
"data": {
"type": "artists",
"attributes": {
"name": "Anna Roberts",
"bio": "Composer and drummer with experience in rock, jazz and Latin music. Main songwriter and rhythmic foundation of the band"
}
}
}
๐ก Smart Artist Creation
The API implements intelligent find-or-create logic. If an artist with the same name already exists for your user, the system will return the existing artist instead of creating a duplicate.
๐ Step 3: Explore Required Resources
Before creating an album, you need to identify valid IDs for required relationships. Let's explore the available options:
Required Relationships
- โข Primary Genre:
GET /genres
- โข Language:
GET /languages
- โข Album Format:
GET /album-formats
Optional Relationships
- โข Countries:
GET /countries
- โข Versions:
GET /versions
- โข Artist Roles:
GET /artist-roles
Example: Get Available Genres
/genres
{
"data": [
{
"type": "genres",
"id": "1",
"attributes": {
"name": "Rock"
}
},
{
"type": "genres",
"id": "2",
"attributes": {
"name": "Pop"
}
}
]
}
๐ For This Tutorial
We'll use these common IDs that typically exist in the system:
- Genre ID: 1 (Rock)
- Language ID: 2 (Spanish)
- Format ID: 1 (Album)
- Artist Role IDs: 1 (Main), 2 (Featured), 3 (Producer), 4 (Composer and Lyricist)
๐ฟ Step 4: Create the Album
Now let's create our album "Whispers in the Dark" with all required attributes and relationships:
/albums
{
"data": {
"type": "albums",
"attributes": {
"title": "Whispers in the Dark",
"artwork": "https://picsum.photos/3000/3000?random=1",
"is-explicit": false,
"original-release-date": "2024-12-15",
"digital-release-date": "2024-12-15",
"rights-owner-year": 2024,
"rights-owner-name": "Label Records"
},
"relationships": {
"label": {
"data": {
"type": "labels",
"id": "1"
}
},
"primary-genre": {
"data": {
"type": "genres",
"id": "1"
}
},
"language": {
"data": {
"type": "languages",
"id": "2"
}
},
"format": {
"data": {
"type": "album-formats",
"id": "1"
}
}
}
}
}
Success Response
{
"data": {
"type": "albums",
"id": "5",
"attributes": {
"title": "Whispers in the Dark",
"artwork": "https://storage.s3.amazonaws.com/albums/artwork/artwork-3000x3000.jpg",
"is-explicit": false,
"original-release-date": "2024-12-15",
"digital-release-date": "2024-12-15",
"rights-owner-year": 2024,
"rights-owner-name": "Label Records",
"description": "First studio album by the band...",
"created-at": "2024-08-19T10:00:00Z",
"updated-at": "2024-08-19T10:00:00Z"
}
}
}
๐ Note: Save the album ID (5) - you'll need it for creating relationships and tracks.
๐ญ Step 5: Create Album-Artist Relationships
Now we'll associate each artist with the album, assigning different roles to each band member:
James Carter - Main Artist
{
"data": {
"type": "album-artists",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"artist": {
"data": { "type": "artists", "id": "1" }
},
"artist-role": {
"data": { "type": "artist-roles", "id": "1" }
}
}
}
}
Lisa Thompson - Featured Artist
{
"data": {
"type": "album-artists",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"artist": {
"data": { "type": "artists", "id": "2" }
},
"artist-role": {
"data": { "type": "artist-roles", "id": "2" }
}
}
}
}
David Miller - Producer
{
"data": {
"type": "album-artists",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"artist": {
"data": { "type": "artists", "id": "3" }
},
"artist-role": {
"data": { "type": "artist-roles", "id": "4" }
}
}
}
}
Anna Roberts - Composer
{
"data": {
"type": "album-artists",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"artist": {
"data": { "type": "artists", "id": "4" }
},
"artist-role": {
"data": { "type": "artist-roles", "id": "5" }
}
}
}
}
Anna Roberts - Lyricist
{
"data": {
"type": "album-artists",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"artist": {
"data": { "type": "artists", "id": "4" }
},
"artist-role": {
"data": { "type": "artist-roles", "id": "6" }
}
}
}
}
All Album-Artist requests use the same endpoint:
/album-artists
๐ Step 6: Add Distribution Countries
Let's add countries where this album will be distributed. We'll use the special relationships endpoint:
/albums/5/relationships/countries
{
"data": [
{
"type": "countries",
"id": "1"
},
{
"type": "countries",
"id": "9"
},
{
"type": "countries",
"id": "39"
}
]
}
๐ก Important
Use the /relationships/countries
endpoint (not /countries
) for adding, updating, or removing country associations.
๐ฏ Step 7: Associate DSPs to Album
Before creating a distribution request, we need to associate the album with Digital Service Providers (DSPs). This tells the system which platforms should receive this album:
Spotify
{
"data": {
"type": "album-dsps",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"dsp": {
"data": { "type": "dsps", "id": "1" }
}
}
}
}
Apple Music
{
"data": {
"type": "album-dsps",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"dsp": {
"data": { "type": "dsps", "id": "2" }
}
}
}
}
Amazon Music
{
"data": {
"type": "album-dsps",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"dsp": {
"data": { "type": "dsps", "id": "3" }
}
}
}
}
YouTube Music
{
"data": {
"type": "album-dsps",
"relationships": {
"album": {
"data": { "type": "albums", "id": "5" }
},
"dsp": {
"data": { "type": "dsps", "id": "4" }
}
}
}
}
All Album-DSP requests use the same endpoint:
/album-dsps
๐ For This Tutorial
Common DSP IDs used in this tutorial:
- DSP ID 1: Spotify
- DSP ID 2: Apple Music
- DSP ID 3: Amazon Music
- DSP ID 4: YouTube Music
๐ต Step 8: Create Album Tracks
Now let's add 3 tracks to our album. Each track will have unique characteristics:
๐ต Track 1: "City Lights" (First Single)
/tracks
{
"data": {
"type": "tracks",
"attributes": {
"title": "City Lights",
"is-explicit": false,
"rights-owner-year": 2024,
"rights-owner-name": "Label Records",
"order": 1,
"full-audiofile-url": "https://storage.example.com/tracks/audio1.wav"
},
"relationships": {
"albums": {
"data": [
{
"type": "albums",
"id": "5"
}
]
},
"primary-genre": {
"data": {
"type": "genres",
"id": "1"
}
},
"language": {
"data": {
"type": "languages",
"id": "2"
}
}
}
}
}
๐ต Track 2: "Asphalt Memories" (Melancholic)
{
"data": {
"type": "tracks",
"attributes": {
"title": "Asphalt Memories",
"is-explicit": false,
"rights-owner-year": 2024,
"rights-owner-name": "Label Records",
"order": 2,
"full-audiofile-url": "https://storage.example.com/tracks/audio2.wav"
},
"relationships": {
"albums": {
"data": [{ "type": "albums", "id": "5" }]
},
"primary-genre": {
"data": { "type": "genres", "id": "1" }
},
"language": {
"data": { "type": "languages", "id": "2" }
}
}
}
}
๐ต Track 3: "Silent Revolution" (Explicit Content)
{
"data": {
"type": "tracks",
"attributes": {
"title": "Silent Revolution",
"is-explicit": true,
"rights-owner-year": 2024,
"rights-owner-name": "Label Records",
"order": 3,
"full-audiofile-url": "https://storage.example.com/tracks/audio3.wav"
},
"relationships": {
"albums": {
"data": [{ "type": "albums", "id": "5" }]
},
"primary-genre": {
"data": { "type": "genres", "id": "1" }
},
"language": {
"data": { "type": "languages", "id": "2" }
}
}
}
}
โ ๏ธ Explicit Content
Track 3 demonstrates explicit content handling. Set is-explicit: true
for tracks containing explicit language or mature themes.
๐ Step 8.5: Validate Album for Distribution
Why Validate Before Distribution?
Before creating a distribution request, it's crucial to validate that your album meets all the requirements for distribution. This prevents failed submissions and ensures your album will be accepted by digital service providers (DSPs).
โ Benefits of Validation
- โข Early detection of missing data
- โข Prevents failed distribution requests
- โข Saves time and API calls
- โข Ensures compliance with DSP requirements
โ Risks of Skipping Validation
- โข Distribution requests may be rejected
- โข Album status changes may fail
- โข Wasted processing resources
- โข Delays in getting music online
๐ Validation Request
Use the album validation endpoint to check if your album is ready for distribution:
/albums/{album_id}/validate
Replace {album_id}
with your actual album ID
๐ค Validation Responses
โ Album Ready for Distribution
When your album passes all validation checks:
HTTP 200 OK
{
"jsonapi": {
"version": "1.0"
},
"data": {
"type": "album-distribution-check",
"id": "1234",
"attributes": {
"valid_for_distribution": true,
"message": "Album is ready for distribution"
}
}
}
Meaning: Your album is complete and ready to create distribution requests. You can proceed to Step 9.
โ Album Needs Corrections
When validation fails, you'll receive detailed error information:
HTTP 200 OK (with errors)
{
"jsonapi": {
"version": "1.0"
},
"data": {
"type": "album-distribution-check",
"id": "1234",
"attributes": {
"valid_for_distribution": false,
"message": "Album is not ready for distribution",
"errors": [
{
"status": "422",
"title": "Validation error",
"detail": [
"Track 'Song Title': Track requires at least one composer",
"Track 'Another Song': Track requires at least one lyricist",
"Album artist 'Artist Name' with role 'composer' must also be assigned to at least one track with the same role"
]
}
]
}
}
}
Meaning: Your album has issues that must be fixed before distribution. The errors
array contains specific problems to address.
๐ก Pro Tip
Always validate your album before creating distribution requests. This saves time and prevents failed submissions that could affect your album's distribution status.
๐ค Step 9: Create Distribution Request
Finally, let's create a distribution request to submit our completed album for distribution to all the configured DSPs and countries:
/distribution-requests
{
"data": {
"type": "distribution-requests",
"attributes": {
"request-type": "delivery"
},
"relationships": {
"album": {
"data": {
"type": "albums",
"id": "5"
}
}
}
}
}
Success Response
{
"data": {
"type": "distribution-requests",
"id": "1",
"attributes": {
"date": "2024-08-21",
"request-type": "delivery",
"status": "pending",
"created-at": "2024-08-21T12:00:00Z",
"updated-at": "2024-08-21T12:00:00Z"
},
"relationships": {
"album": {
"data": {
"type": "albums",
"id": "5"
}
}
}
}
}
๐ What Happens Automatically
When you create a distribution request, the system automatically:
- Assigns the request to the authenticated user
- Sets the date to current date
- Sets status to "pending"
- Copies all Album-DSP relationships to the distribution request
- Updates the album status to indicate it's in distribution
- Creates a distribution batch for processing
๐ Step 10: Final Verification
Let's verify everything was created correctly by querying the complete album with all its relationships:
/albums/5?include=label,primary-genre,language,format,countries,artists,tracks,dsps
Expected Result
You should see your album with:
- โ Label relationship (Label Records)
- โ 4 Artist relationships with different roles
- โ 3 Tracks in order (1, 2, 3)
- โ Multiple country associations
- โ 4 DSP associations (Spotify, Apple Music, Amazon, YouTube)
- โ Genre, language, and format relationships
- โ Active distribution request
๐ Additional Verification Queries
- โข
GET /album-artists?include=album,artist,artist-role
- โข
GET /tracks?include=albums&sort=order
- โข
GET /labels/1?include=albums
- โข
GET /albums/5/countries
- โข
GET /album-dsps?include=album,dsp
- โข
GET /distribution-requests?include=album
๐งช Test Validations
Try these to see error handling:
- โข Create album without title (should fail)
- โข Create track without title (should fail)
- โข Create duplicate album-artist (should fail)
- โข Create duplicate distribution request (should fail)
- โข Use invalid relationship IDs (should fail)
๐ Congratulations!
What You've Accomplished
You've successfully created a complete music album using the limbo/API! Here's what you built:
๐ต "Whispers in the Dark" Album
- โข Complete metadata and artwork
- โข Associated with Label Records label
- โข Rock genre, Spanish language
- โข Multi-country distribution
- โข 4 major DSP associations
- โข Full rights management information
- โข Active distribution request
๐ญ Complete Band Setup
- โข 4 artists with unique biographies
- โข Different roles per artist
- โข 3 diverse tracks with lyrics
- โข Proper track ordering
- โข Explicit content handling
- โข Ready for distribution workflow
๐ Next Steps
- โข Monitor your distribution request status and approvals
- โข Explore delivery tracking and DSP-specific metadata
- โข Add more tracks or create additional albums
- โข Experiment with different DSP configurations
- โข Try the advanced filtering and search features
- โข Implement error handling in your applications
- โข Explore the analytics and reporting endpoints