Overview
The Royalti.io API supports advanced metadata fields for both Products (albums/releases) and Assets (tracks) aligned with the DDEX MEAD (Music Enrichment and Description) standard. These fields enable rich metadata delivery to Digital Service Providers (DSPs), improving discoverability and providing comprehensive release information.
When to Use MEAD Fields
Reissues and Special Editions : Track original release dates, edition types, and reissue status
Chart-Eligible Releases : Include chart history and sequence information
Professional Productions : Document recording/mastering locations, producers, and engineers
Multi-Disc Releases : Specify disc counts and track totals
Catalog Variants : Link related releases via parent release IDs
Track-Level Enrichment : Add musical attributes like tempo, key, and mood to assets
Product MEAD Fields
Field Type Description Example editionstring Edition designation ”Deluxe”, “Remastered”, “Anniversary” reissueboolean Whether this is a reissue trueoriginalReleaseDatedate Original release date (for reissues) “1985-06-15” packageTypestring Physical/digital package type ”Album”, “EP”, “Compilation” totalTracksinteger Total track count 12 totalDiscsinteger Total disc count 2 sequenceNumberinteger Position in series/discography 5 parentReleaseIduuid Parent release for variants ”550e8400-e29b-41d4-a716-446655440000”
Production Credits
Field Type Description Example producerarray Producer name(s) [“Rick Rubin”, “Dr. Dre”] engineerarray Engineer name(s) [“Bob Clearmountain”] recordingLocationstring Recording studio/location ”Abbey Road Studios, London” masteringLocationstring Mastering facility ”Sterling Sound, NYC”
Field Type Description chartHistoryarray Historical chart positions
Chart History Object:
{
"chart" : "Billboard Hot 100" ,
"position" : 1 ,
"date" : "2024-03-15"
}
Field Type Description Example c_line_yearinteger Copyright line year 2024 p_line_yearinteger Phonogram line year 2024 copyrightstring Copyright holder ”XYZ Records Inc” publisherstring Publisher name ”XYZ Publishing” languagestring Primary language (ISO 639-1) “en”
Asset MEAD Fields
Assets (tracks) support their own set of MEAD enhancement fields for track-level metadata.
Musical Attributes
Field Type Description Example temponumber Tempo in BPM 120 keystring Musical key ”C major”, “A minor” moodarray Mood descriptors [“Energetic”, “Uplifting”]
Field Type Description Example recordingLocationstring Recording studio/location ”Electric Lady Studios, NYC” recordingDatedate Date of recording ”2024-03-15” productionYearinteger Year of production 2024 copyrightOwnerstring Copyright owner ”XYZ Records Inc”
Classification
Field Type Description Example genrearray Genre classifications [“Pop”, “Electronic”] subGenrearray Sub-genre classifications [“Synth-pop”, “Dance”] rhythmStylearray Rhythm style descriptors [“Four-on-the-floor”] instrumentationarray Instruments used [“Synthesizer”, “Drums”, “Bass”] languagestring Lyric language (ISO 639-1) “en”
Field Type Description Example alternativeTitlesarray Alternative track titles [“Radio Edit”, “Club Mix”] chartPositionsarray Historical chart positions See chart object below
Quick Start
Creating a Product with MEAD Fields
curl -X POST https://api.royalti.io/product \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Greatest Hits (Remastered)",
"upc": "123456789012",
"displayArtist": "Example Artist",
"releaseDate": "2024-06-01",
"edition": "Remastered",
"reissue": true,
"originalReleaseDate": "1995-03-15",
"c_line_year": 2024,
"p_line_year": 1995,
"copyright": "Legacy Records LLC",
"publisher": "Legacy Records LLC",
"totalTracks": 16,
"totalDiscs": 1,
"recordingLocation": "Sunset Sound, Los Angeles",
"masteringLocation": "Bernie Grundman Mastering",
"producer": ["Original Producer Name"],
"engineer": ["Remaster Engineer Name"]
}'
const response = await fetch ( 'https://api.royalti.io/product' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
title: 'Greatest Hits (Remastered)' ,
upc: '123456789012' ,
displayArtist: 'Example Artist' ,
releaseDate: '2024-06-01' ,
edition: 'Remastered' ,
reissue: true ,
originalReleaseDate: '1995-03-15' ,
c_line_year: 2024 ,
p_line_year: 1995 ,
copyright: 'Legacy Records LLC' ,
publisher: 'Legacy Records LLC' ,
totalTracks: 16 ,
totalDiscs: 1 ,
recordingLocation: 'Sunset Sound, Los Angeles' ,
masteringLocation: 'Bernie Grundman Mastering' ,
producer: [ 'Original Producer Name' ],
engineer: [ 'Remaster Engineer Name' ]
})
});
const { data } = await response . json ();
console . log ( 'Product created:' , data . id );
import requests
response = requests.post(
'https://api.royalti.io/product' ,
headers = {
'Authorization' : f 'Bearer { API_TOKEN } ' ,
'Content-Type' : 'application/json'
},
json = {
'title' : 'Greatest Hits (Remastered)' ,
'upc' : '123456789012' ,
'displayArtist' : 'Example Artist' ,
'releaseDate' : '2024-06-01' ,
'edition' : 'Remastered' ,
'reissue' : True ,
'originalReleaseDate' : '1995-03-15' ,
'c_line_year' : 2024 ,
'p_line_year' : 1995 ,
'copyright' : 'Legacy Records LLC' ,
'publisher' : 'Legacy Records LLC' ,
'totalTracks' : 16 ,
'totalDiscs' : 1 ,
'recordingLocation' : 'Sunset Sound, Los Angeles' ,
'masteringLocation' : 'Bernie Grundman Mastering' ,
'producer' : [ 'Original Producer Name' ],
'engineer' : [ 'Remaster Engineer Name' ]
}
)
data = response.json()[ 'data' ]
print ( f "Product created: { data[ 'id' ] } " )
Creating an Asset with MEAD Fields
curl -X POST https://api.royalti.io/asset \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Summer Nights",
"isrc": "USRC12345678",
"displayArtist": "Example Artist",
"tempo": 128,
"key": "G major",
"mood": ["Energetic", "Happy", "Summer"],
"genre": ["Pop", "Dance"],
"subGenre": ["Synth-pop"],
"recordingLocation": "Electric Lady Studios, NYC",
"recordingDate": "2024-02-15",
"productionYear": 2024,
"copyrightOwner": "XYZ Records Inc",
"instrumentation": ["Synthesizer", "Drums", "Bass", "Vocals"],
"language": "en"
}'
const response = await fetch ( 'https://api.royalti.io/asset' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
title: 'Summer Nights' ,
isrc: 'USRC12345678' ,
displayArtist: 'Example Artist' ,
tempo: 128 ,
key: 'G major' ,
mood: [ 'Energetic' , 'Happy' , 'Summer' ],
genre: [ 'Pop' , 'Dance' ],
subGenre: [ 'Synth-pop' ],
recordingLocation: 'Electric Lady Studios, NYC' ,
recordingDate: '2024-02-15' ,
productionYear: 2024 ,
copyrightOwner: 'XYZ Records Inc' ,
instrumentation: [ 'Synthesizer' , 'Drums' , 'Bass' , 'Vocals' ],
language: 'en'
})
});
const { data } = await response . json ();
console . log ( 'Asset created:' , data . id );
import requests
response = requests.post(
'https://api.royalti.io/asset' ,
headers = {
'Authorization' : f 'Bearer { API_TOKEN } ' ,
'Content-Type' : 'application/json'
},
json = {
'title' : 'Summer Nights' ,
'isrc' : 'USRC12345678' ,
'displayArtist' : 'Example Artist' ,
'tempo' : 128 ,
'key' : 'G major' ,
'mood' : [ 'Energetic' , 'Happy' , 'Summer' ],
'genre' : [ 'Pop' , 'Dance' ],
'subGenre' : [ 'Synth-pop' ],
'recordingLocation' : 'Electric Lady Studios, NYC' ,
'recordingDate' : '2024-02-15' ,
'productionYear' : 2024 ,
'copyrightOwner' : 'XYZ Records Inc' ,
'instrumentation' : [ 'Synthesizer' , 'Drums' , 'Bass' , 'Vocals' ],
'language' : 'en'
}
)
data = response.json()[ 'data' ]
print ( f "Asset created: { data[ 'id' ] } " )
Common Use Cases
Product: Reissued Album
When re-releasing a classic album with new mastering:
{
"title" : "Thriller (40th Anniversary Edition)" ,
"releaseDate" : "2022-11-18" ,
"edition" : "40th Anniversary" ,
"reissue" : true ,
"originalReleaseDate" : "1982-11-30" ,
"c_line_year" : 2022 ,
"p_line_year" : 1982 ,
"masteringLocation" : "Capitol Studios, Hollywood" ,
"producer" : [ "Quincy Jones" ],
"engineer" : [ "Matt Hennessy" ]
}
For reissues, p_line_year typically reflects the original recording year, while c_line_year reflects the new release year.
Product: Deluxe Edition with Bonus Tracks
When releasing an expanded version of an album:
{
"title" : "Album Name (Deluxe Edition)" ,
"edition" : "Deluxe" ,
"totalTracks" : 18 ,
"totalDiscs" : 2 ,
"parentReleaseId" : "original-album-uuid" ,
"sequenceNumber" : 2
}
Product: Multi-Disc Box Set
For comprehensive anthology releases:
{
"title" : "Complete Studio Albums Box Set" ,
"packageType" : "Box Set" ,
"totalDiscs" : 8 ,
"totalTracks" : 96 ,
"edition" : "Collector's Edition" ,
"recordingLocation" : "Various Studios" ,
"producer" : [ "Producer A" , "Producer B" , "Producer C" ]
}
Product: Chart-Eligible Release with History
Including historical chart performance:
{
"title" : "Hit Single" ,
"chartHistory" : [
{
"chart" : "Billboard Hot 100" ,
"position" : 1 ,
"date" : "2023-08-15"
},
{
"chart" : "UK Singles Chart" ,
"position" : 3 ,
"date" : "2023-08-18"
}
]
}
Asset: Electronic Dance Track
Rich metadata for DJ and playlist curation:
{
"title" : "Midnight Drive" ,
"isrc" : "USRC98765432" ,
"displayArtist" : "DJ Example" ,
"tempo" : 126 ,
"key" : "A minor" ,
"mood" : [ "Dark" , "Driving" , "Atmospheric" ],
"genre" : [ "Electronic" , "House" ],
"subGenre" : [ "Tech House" , "Progressive" ],
"rhythmStyle" : [ "Four-on-the-floor" ],
"instrumentation" : [ "Synthesizer" , "Drum Machine" , "Bass Synthesizer" ],
"language" : "en"
}
Asset: Acoustic Recording
Capturing performance details:
{
"title" : "Unplugged Session" ,
"isrc" : "USRC11223344" ,
"displayArtist" : "Singer Songwriter" ,
"recordingLocation" : "Village Studios, Los Angeles" ,
"recordingDate" : "2024-01-20" ,
"productionYear" : 2024 ,
"copyrightOwner" : "Indie Label LLC" ,
"mood" : [ "Intimate" , "Melancholic" , "Reflective" ],
"instrumentation" : [ "Acoustic Guitar" , "Vocals" , "Piano" ],
"key" : "E minor" ,
"tempo" : 72
}
Updating Existing Products
Add MEAD fields to existing products using the PUT endpoint:
curl -X PUT https://api.royalti.io/product/prod-123 \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"edition": "Deluxe",
"totalTracks": 15,
"producer": ["New Producer"],
"recordingLocation": "Studio Name"
}'
const response = await fetch ( 'https://api.royalti.io/product/prod-123' , {
method: 'PUT' ,
headers: {
'Authorization' : `Bearer ${ API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
edition: 'Deluxe' ,
totalTracks: 15 ,
producer: [ 'New Producer' ],
recordingLocation: 'Studio Name'
})
});
const { data } = await response . json ();
console . log ( 'Product updated:' , data );
response = requests.put(
'https://api.royalti.io/product/prod-123' ,
headers = {
'Authorization' : f 'Bearer { API_TOKEN } ' ,
'Content-Type' : 'application/json'
},
json = {
'edition' : 'Deluxe' ,
'totalTracks' : 15 ,
'producer' : [ 'New Producer' ],
'recordingLocation' : 'Studio Name'
}
)
data = response.json()[ 'data' ]
print ( f "Product updated: { data } " )
Updating Existing Assets
Add MEAD fields to existing assets using the PUT endpoint:
curl -X PUT https://api.royalti.io/asset/asset-123 \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"tempo": 128,
"key": "C major",
"mood": ["Uplifting", "Energetic"],
"copyrightOwner": "New Rights Holder LLC"
}'
const response = await fetch ( 'https://api.royalti.io/asset/asset-123' , {
method: 'PUT' ,
headers: {
'Authorization' : `Bearer ${ API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
tempo: 128 ,
key: 'C major' ,
mood: [ 'Uplifting' , 'Energetic' ],
copyrightOwner: 'New Rights Holder LLC'
})
});
const { data } = await response . json ();
console . log ( 'Asset updated:' , data );
response = requests.put(
'https://api.royalti.io/asset/asset-123' ,
headers = {
'Authorization' : f 'Bearer { API_TOKEN } ' ,
'Content-Type' : 'application/json'
},
json = {
'tempo' : 128 ,
'key' : 'C major' ,
'mood' : [ 'Uplifting' , 'Energetic' ],
'copyrightOwner' : 'New Rights Holder LLC'
}
)
data = response.json()[ 'data' ]
print ( f "Asset updated: { data } " )
Bulk Operations
Update multiple products with MEAD fields efficiently:
curl -X POST https://api.royalti.io/product/bulk \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"products": [
{
"title": "Album One",
"upc": "111111111111",
"displayArtist": "Artist",
"releaseDate": "2024-01-01",
"edition": "Standard",
"c_line_year": 2024,
"p_line_year": 2024
},
{
"title": "Album One (Deluxe)",
"upc": "222222222222",
"displayArtist": "Artist",
"releaseDate": "2024-03-01",
"edition": "Deluxe",
"c_line_year": 2024,
"p_line_year": 2024,
"totalTracks": 18
}
]
}'
const response = await fetch ( 'https://api.royalti.io/product/bulk' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ API_TOKEN } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
products: [
{
title: 'Album One' ,
upc: '111111111111' ,
displayArtist: 'Artist' ,
releaseDate: '2024-01-01' ,
edition: 'Standard' ,
c_line_year: 2024 ,
p_line_year: 2024
},
{
title: 'Album One (Deluxe)' ,
upc: '222222222222' ,
displayArtist: 'Artist' ,
releaseDate: '2024-03-01' ,
edition: 'Deluxe' ,
c_line_year: 2024 ,
p_line_year: 2024 ,
totalTracks: 18
}
]
})
});
const { data } = await response . json ();
console . log ( `Created ${ data . created } products` );
response = requests.post(
'https://api.royalti.io/product/bulk' ,
headers = {
'Authorization' : f 'Bearer { API_TOKEN } ' ,
'Content-Type' : 'application/json'
},
json = {
'products' : [
{
'title' : 'Album One' ,
'upc' : '111111111111' ,
'displayArtist' : 'Artist' ,
'releaseDate' : '2024-01-01' ,
'edition' : 'Standard' ,
'c_line_year' : 2024 ,
'p_line_year' : 2024
},
{
'title' : 'Album One (Deluxe)' ,
'upc' : '222222222222' ,
'displayArtist' : 'Artist' ,
'releaseDate' : '2024-03-01' ,
'edition' : 'Deluxe' ,
'c_line_year' : 2024 ,
'p_line_year' : 2024 ,
'totalTracks' : 18
}
]
}
)
data = response.json()[ 'data' ]
print ( f "Created { data[ 'created' ] } products" )
DSP Delivery Integration
MEAD fields are automatically included when delivering products to DSPs that support rich metadata.
Supported Providers
DSPs that accept MEAD enhancement fields:
Provider Edition Reissue Info Production Credits Chart Data Spotify Yes Yes Yes No Apple Music Yes Yes Yes No YouTube Music Yes Yes Partial No Tidal Yes Yes Yes Yes Deezer Yes Yes Partial No Amazon Music Yes Yes Yes No
Validation Before Delivery
When delivering products, MEAD fields are validated against provider requirements:
curl -X POST https://api.royalti.io/product/prod-123/deliveries/validate \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"providers": ["spotify-ddex-sftp", "apple-ddex-api"]
}'
The validation response includes warnings for MEAD fields that may not transfer to specific providers.
Best Practices
Copyright Year Accuracy Use p_line_year for original recording year and c_line_year for the current release compilation/mastering year.
Link Related Releases Use parentReleaseId and sequenceNumber to maintain catalog relationships between standard and deluxe editions.
Production Credits Include all relevant producers and engineers for proper attribution and improved DSP discoverability.
Reissue Documentation Always set originalReleaseDate when reissue is true for accurate release history.
Troubleshooting
MEAD fields not appearing in DSP delivery
Cause: The delivery provider may not support specific MEAD fields.Solution:
Check the provider’s supported fields in the Product Delivery guide
Verify the fields are set before delivery
Some fields are DDEX MEAD-specific and may not transfer via CSV delivery methods
Invalid c_line_year or p_line_year
Error: Year must be between 1900 and 2100Solution: Ensure year values are 4-digit integers within the valid range:{
"c_line_year" : 2024 ,
"p_line_year" : 1985
}
chartHistory validation error
Error: Invalid chart history formatSolution: Each chart history entry must include chart, position, and date:{
"chartHistory" : [
{
"chart" : "Billboard Hot 100" ,
"position" : 1 ,
"date" : "2024-01-15"
}
]
}
Error: Tempo must be a positive numberSolution: Tempo should be a positive integer representing BPM (beats per minute), typically between 60-200:
Asset mood or genre not appearing in DSP
Cause: Some DSPs have their own genre/mood taxonomies and may not accept custom values.Solution:
Use standardized mood and genre terms where possible
Check DSP-specific documentation for accepted values
Asset classification fields like mood, genre, and subGenre are best-effort mappings