Skip to main content
GET
/
royalty
/
consolidated
Get the unified master + publishing + neighbouring-rights view
curl --request GET \
  --url https://api.royalti.io/royalty/consolidated \
  --header 'Authorization: Bearer <token>'
import requests

url = "https://api.royalti.io/royalty/consolidated"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.text)
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

fetch('https://api.royalti.io/royalty/consolidated', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.royalti.io/royalty/consolidated",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"net/http"
"io"
)

func main() {

url := "https://api.royalti.io/royalty/consolidated"

req, _ := http.NewRequest("GET", url, nil)

req.Header.Add("Authorization", "Bearer <token>")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.get("https://api.royalti.io/royalty/consolidated")
.header("Authorization", "Bearer <token>")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.royalti.io/royalty/consolidated")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
{
  "results": [
    {
      "ISRC": "USRC17607839",
      "ISWC": "T-070.007.442-1",
      "Track_Title": "Hit Single",
      "Track_Artist": "Main Artist",
      "master": 1856.25,
      "masterSources": [
        {
          "label": "Spotify",
          "amount": 1200.1
        },
        {
          "label": "Apple Music",
          "amount": 656.15
        }
      ],
      "publishing": 340.5,
      "publishingSources": [
        {
          "label": "ASCAP",
          "amount": 340.5
        }
      ],
      "publishingApproximated": false,
      "neighbouring": {
        "rightsholder": 88.2,
        "performerPayout": 44.1,
        "sources": [
          {
            "label": "PPL — ER",
            "amount": 88.2
          }
        ]
      },
      "total": 2284.95
    }
  ],
  "unlinked": [
    {
      "iswc": "T-999.999.999-9",
      "workTitle": "Unmatched Work",
      "amount": 52,
      "reason": "no_iswc_crosswalk"
    }
  ],
  "totals": {
    "master": 1856.25,
    "publishing": 340.5,
    "neighbouring": 88.2,
    "performerPayout": 44.1,
    "unlinkedPublishing": 52,
    "total": 2284.95
  },
  "currency": "USD"
}
{
"status": "error",
"message": "Unauthorized"
}
{
"success": false,
"error": {
"code": "<string>",
"message": "<string>",
"details": [
"<string>"
]
}
}
This endpoint requires authentication. Include your Bearer token in the Authorization header.

Description

Get the unified master + publishing + neighbouring-rights view Shipped June 2026 (WP-08). Merges, per ISRC, master royalties (BigQuery v_sales_data), neighbouring-rights royalties (per-tenant f_neighbouring_rights fact table, split into rightsholder vs. performer payout), and publishing royalties (Postgres PublisherStatementLine, matched by ISWC and crosswalked to ISRC via the catalog). Publishing income that cannot be crosswalked to an ISRC is returned separately in unlinked rather than dropped. Only start, end, and user are honored by this endpoint — the other royalty-filter query params accepted by sibling endpoints (country, dsp, table_name, etc.) are not applied here. Authorization:
  • Required role: user or higher

Code Examples

const response = await fetch('https://api.royalti.io/royalty/consolidated', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`,
  },
});

const data = await response.json();
console.log(data);
import requests

response = requests.get(
  'https://api.royalti.io/royalty/consolidated',
  headers={
    'Authorization': f'Bearer {token}'
  },
)

data = response.json()
print(data)
curl -X GET https://api.royalti.io/royalty/consolidated \
  -H "Authorization: Bearer YOUR_TOKEN" \

Authorizations

Authorization
string
header
required

JWT Authorization header using the Bearer scheme. Format: "Bearer {token}"

Query Parameters

start
string<date>

Start date of the period (YYYY-MM-DD format)

end
string<date>

End date of the period (YYYY-MM-DD format)

user
string<uuid>

Filters the data by user. Specifies a user ID. A single UUID switches the response into per-member (splits-attributed, catalogue-scoped) mode

Response

Successfully retrieved the consolidated royalty view

Unified master + publishing + neighbouring-rights view per ISRC (shipped June 2026). Non-admin/member requests (single-UUID ?user=) are automatically scoped to that member's owned catalogue via splits, and fail closed (empty result) rather than falling back to tenant-wide data on any ownership-resolution error.

results
object[]
unlinked
object[]

Publishing income lines that could not be crosswalked to an ISRC

totals
object
currency
string