Full Scenario
This tutorial details all the steps involved in putting an album online, from creating a Label to creating a SendTask (i.e., a delivery to a DSP).
🔑 Authenticate
First of all, let’s get a token to authenticate against the API.
require "rest-client"
require "json"
login = "Login"
password = "Password"
response = RestClient.post(
"https://api.idol.io/oauth/token",
{
grant_type: "password",
username: login,
password: password
}
)
token = JSON.parse(response)["access_token"] // => 'c90450...'
📣 Create Label
Each album has to be associated with a Label. Let's create a new Label and name it Demo label.
First, all labels are associated to a Company (called Contract in the Labelcamp UI ). In a standard delivery context, only a single Company is mandatory, to which you can associate all your Labels. We need to retrieve the available companies:
response = RestClient.get(
"https://api.idol.io/api/v2/companies",
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json"
)
JSON.parse(response)['data']
// => [{"id"=>"666", "type"=>"companies", "links"=>{"self"=>"https://api.idol.io/api/v2/companies/<ID>"}, "attributes"=>{"created-at"=>"2013-11-18T08:07:13.000+01:00", "updated-at"=>"2018-02-21T18:06:19.311+01:00", "name"=>"Record Company", "children-count"=>6, "label-manager"=>nil, "is-tva-applicable"=>true}, "relationships"=>{"distributor"=>{"links"=>{"self"=>"https://api.idol.io/api/v2/companies/<ID>/relationships/distributor", "related"=>"https://api.idol.io/api/v2/companies/<ID>/distributor"}, "data"=>{"type"=>"distributors", "id"=>"13"}},
The Company demo (id: 666) is the one available, we will use it to create our Label:
response = RestClient.post(
"https://api.idol.io/api/v2/labels",
{
"data": {
"attributes": {
"name": "My beautiful Label",
"cover-url": '',
"usage": {
"download": true,
"copy_scan": true,
"on_demand_stream": true,
"non_interactive_stream": true
}
},
"relationships": {
"rights": {
"data": []
},
"company": {
"data": {
"type": "companies",
"id": "<ID>"
}
},
},
"type": "labels"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer #{token}"
)
JSON.parse(response)['data']
// => [{"id"=>"555", "type"=>"labels"...}]
📀 Create Product
Now that we have the label (id : 555), we can create the Product:
response = RestClient.post(
"https://api.idol.io/api/v2/products",
{
"data": {
"attributes": {
"artist": [
"Artist demo"
],
"name": "Demo album",
"is-compilation": false,
"upc-code": "",
"copyright-line": "2025 Demo",
"production-line": "2025 Demo",
"production-year": 2025
},
"relationships":{
"label":{
"data":{
"type": "labels",
"id": "555"
}
}
},
"type": "products"
}
}.to_json,
"Authorization": "Bearer {token}",
"Content-Type": "application/vnd.api+json"
)
product = JSON.parse(response)['data']
// => [{"id"=>"214477", "type"=>"products"...}]
🎙️ Import Record
Each album contains one or more tracks. Let’s create a Track:
response = RestClient.post(
"https://api.idol.io/api/v2/tracks",
{
"data": {
"attributes": {
"title": "My title",
"artist": [
"My Artist"
],
"isrc-code": "AEA020900003",
"track-number": "3",
"volume-number": "1",
},
"relationships": {
"product": {
"data": {
"id": "214477",
"type": "products"
}
}
},
"type": "tracks"
}
}.to_json,
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json"
)
track = JSON.parse(response)['data']
// => [{"id"=>"1709847", "type"=>"tracks"...}]
Now, you need to associate a FLAC audio file with the Track. To do this, you must create an ImportTask and attach a download link to the record. The ImportTask will be processed asynchronously and will result in the creation of a new Record attached to the Track. Here is how to create an ImportTask:
response = RestClient.post(
"https://api.idol.io/api/v2/import-tasks",
{
"data": {
"id": <ID>,
"type": "import-tasks",
"attributes": {
"created-at": "2024-12-22T16:33:38.866+01:00",
"updated-at": "2024-12-22T16:33:38.866+01:00",
"precision": "24",
"master-type": "hd",
"status": "uploaded",
"url": 'https://<download_record_url>',
},
"relationships": {
"attachable": {
"data": {
"type": "products",
"id": "<ID>"
}
}
}
}
}.to_json,
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json"
)
import_task = JSON.parse(response)['data']
// => [{"id"=>"4372632", "type"=>"import-tasks"...}]
🌍 Add Rights
Our album must only be available on Apple Music and Spotify, with US rights.
We need to retrieve the Territory ID for US:
response = RestClient.get(
"https://api.idol.io/api/v2/territories?filter[code_alpha_2]=US",
Authorization: "Bearer <token>",
"Content-Type": 'application/vnd.api+json'
)
JSON.parse(response)['data'].first['id']
// => "223"
Then we need to retrieve our Distributor ID:
response = RestClient.get(
"https://api.idol.io/api/v2/distributors?filter[name]=Distributeur test",
Authorization: "Bearer <token>",
"Content-Type": "application/vnd.api+json"
)
JSON.parse(response)['data'].first['id']
// => "13"
We also need to retrieve the Apple Music and Spotify IDs:
response = RestClient.get(
"https://api.idol.io/api/v2/dsp-upload-identifications?include=dsp",
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
JSON.parse(response)['data']
// => [{"id"=>"374", "type"=>"dsp-upload-identifications", "links"=>{"self"=>"https://api.idol.io/api/v2/dsp-upload-identifications/<ID>"}, "attributes"=>{"created-at"=>"2012-12-13T18:50:17.000+01:00", "updated-at"=>"2018-05-30T11:30:59.837+02:00", "dsp-name"=>"Apple"}, "relationships"=>{"offers"=>{"links"=>{"self"=>"https://api.idol.io/api/v2/dsp-upload-identifications/<ID>/relationships/offers", "related"=>"https://api.idol.io/api/v2/dsp-upload-identifications/<ID>/offers"}}, "dsp"=>{"links"=>{"self"=>"https://api.idol.io/api/v2/dsp-upload-identifications/<ID>/relationships/dsp", "related"=>"https://api.idol.io/api/v2/dsp-upload-identifications/<ID>/dsp"}, "data"=>{"type"=>"dsps", "id"=>"3"}}}}...
Now, we have to set the distribution rules for this album. Let’s add the territories and DSPs information:
response = RestClient.post(
"https://api.idol.io/api/v2/rights",
{
"data": {
"attributes": {
"action": "add",
"user-email": "[email protected]"
},
"relationships": {
"dsps": {
"data": [{
"type": "dsps",
"id": "3"
},
{
"type": "dsps",
"id": "30"
}]
},
"territories": {
"data": [{
"type": "territories",
"id": "223"
}]
},
"distributor": {
"data": {
"type": "distributors",
"id": "13"
}
},
"distributed": {
"data": {
"type": "products",
"id": "214477"
}
}
},
"type": "rights"
}
}.to_json,
"Authorization": "Bearer <token>",
"Content-Type": "application/vnd.api+json"
)
✏️ Update and validate default Offer
When you create a product, a default Offer is associated to the Product (this default offer is not associated with any DspUploadIdentification).
You can retrieve the default Offer like this:
response = RestClient.get(
"https://api.idol.io/api/v2/offers?filter[product_id]=214477&filter[is_default]=true",
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
offer_id = JSON.parse(response)['data'].first['id']
// => 377099
Then, to retrieve our product and track Price Codes, we use the following request:
RestClient.get(
"https://api.idol.io/api/v2/distributor-price-codes",
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
In this example, we will use the product Price Code ID 10 and track Price Code ID 7.
Now, we use this request to retrieve the product's genre:
RestClient.get(
"https://api.idol.io/api/v2/distributor-product-subgenres",
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
In this example, we will use the Product Genre ID 1.
Then, we must validate the default Offer:
response = RestClient.put(
"https://api.idol.io/api/v2/offers/<ID>",
{
"data": {
"id": "377099",
"attributes": {
"status": "active",
"release-date": "2025-01-01",
"is-default": true
},
"relationships": {
"price-code": {
"data": {
"type": "distributor-price-codes",
"id": "10"
}
},
"track-price-code": {
"data": {
"type": "distributor-price-codes",
"id": "7"
}
},
"subgenre": {
"data": {
"type": "distributor-product-subgenres",
"id": "1"
}
},
"product":{
"data":{
"type": "products",
"id": "214477"
}
}
},
"type": "offers"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
🎵 Create specific Apple Music / iTunes Offer
You may want to create a specific Offer for Apple Music / iTunes, for example, to set a specific pre-order date:
response = RestClient.post(
"https://api.idol.io/api/v2/offers",
{
"data": {
"attributes": {
"status": "active",
"preorder-date": "2024-05-01T00:00:00.000+00:00",
"release-date": "2025-01-01",
"is-default": false
},
"relationships": {
"product": {
"data": {
"type": "products",
"id": "214477"
}
},
"dsp-upload-identifications": {
"data": [{
"type": "dsp-upload-identifications",
"id": "374"
}]
}
},
"type": "offers"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
itunes_offer_id = JSON.parse(response)['data']['id']
// => 377752
✅ Update and validate the Product
Before you can send deliveries to DSPs, a product must be updated and validated. To achieve this, the product status should be changed to 'active':
response = RestClient.put(
"https://api.idol.io/api/v2/products/214477",
{
"data": {
"id": "214477",
"attributes": {
"status": "active"
},
"type": "products"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
status = JSON.parse(response)['data']['attributes']['status']
// => "active"
🧑🎤 Create DSP Artist IDs
Setting the album to an 'active' status automatically creates Artists entities, which are linked to the Product through its associated Roles. More information on this process here.
You're now able to create platform-specific artist IDs, if and when required, e.g. a Spotify Artist URI or an Apple Artist ID.
First, we need to retrieve the artist linked to our Product:
response = RestClient.get(
"https://api.idol.io/api/v2/artists?filter[product_id]=214477
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
puts JSON.parse(response)['data']
// => [{ "id": "82372", "type": "artists", "links": { "self": "https://l-api.idol.io/api/v2/artists/1495354" }, "attributes": { "name": "Artist demo", "priority": 1 }}]}...
artist_id = JSON.parse(response)['data'].first['id']
// => 82372
Now that we've retrieved the artist, we'll create an artist ID for Spotify:
response = RestClient.post(
"https://api.idol.io/api/v2/availabilities",
{
"data":{
"attributes":{
"external":"spotify:artist:4XGbuIJBheaKE2UGZ33am9"
},
"relationships":{
"dsp":{
"data":{
"type":"dsps",
"id":"30"
}
},
"item":{
"data":{
"type":"artists",
"id":"3163837"
}
}
},
"type":"availabilities"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
And, for Apple:
response = RestClient.post(
"https://api.idol.io/api/v2/availabilities",
{
"data":{
"attributes":{
"external":"1798210185"
},
"relationships":{
"dsp":{
"data":{
"type":"dsps",
"id":"3"
}
},
"item":{
"data":{
"type":"artists",
"id":"3163837"
}
}
},
"type":"availabilities"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
🖥️ Deliver to Apple and Spotify
Finally, we must create a SendTask (called a 'Delivery' in our UI) to Apple Music for this album. Setting the deliverable attribute to 'true' will allow the system to enqueue its delivery to Apple:
response = RestClient.post(
"https://api.idol.io/api/v2/send-tasks",
{
"data": {
"attributes": {
"deliverable": "true",
"delivery-type": "delivery",
"priority": "normal"
},
"relationships": {
"product": {
"data": {
"type": "products",
"id": "214477"
}
},
"dsp-upload-identification": {
"data": {
"type": "dsp-upload-identifications",
"id": "374"
}
}
},
"type": "send-tasks"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
send_task_id = JSON.parse(response)['data'][id]
// => 7434479
We'll do the same for Spotify:
response = RestClient.post(
"https://api.idol.io/api/v2/send-tasks",
{
"data": {
"attributes": {
"deliverable": "true",
"delivery-type": "delivery",
"priority": "normal"
},
"relationships": {
"product": {
"data": {
"type": "products",
"id": "214477"
}
},
"dsp-upload-identification": {
"data": {
"type": "dsp-upload-identifications",
"id": "375"
}
}
},
"type": "send-tasks"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
send_task_id = JSON.parse(response)['data'][id]
// => 7434480
🚀 And your album is now ready to be delivered to Apple Music & Spotify, with US territory rights and a specific pre-order date on Apple Music / iTunes.
📡 Webhooks
To follow the status of your send_tasks, you can create a Webhook:
response = RestClient.post(
"https://api.idol.io/api/v2/webhooks",
{
"data": {
"attributes": {
"action": "send_task_status_update",
"url": "https://yourdomain.com/callbacks?id=<id>&value=<value>&updated_at=<time>"
},
"relationships": {
"distributor": {
"data": {
"type": "distributors",
"id": "13"
}
}
},
"type": "webhooks"
}
}.to_json,
"Content-Type": 'application/vnd.api+json',
"Authorization": "Bearer <token>"
)
We will then trigger an HTTP call on the URL:
POST https://yourdomain.com/callbacks
{
"id": "1",
"value": "1",
"time": "2022-09-12 00:00:00",
"kind": "action"
}
Last updated