Artificial Streams
Artificial streams are streams that DSPs identify as coming from automated or fraudulent sources—bots, scripts, or click farms—rather than genuine listeners. These endpoints report how many artificial streams were detected, how many assets were flagged, and the fines applied as a result, so you can find and address problem content.
Artificial Streams endpoints are available to organizations only. Client and portal accounts receive
403 Forbidden.
For the date range, pagination, sorting, and shared filters, see the Analytics Overview.
Moving from the V1.0 API? Responses are unchanged—only the route and a few parameters differ. See Migrating from the V1.0 API.
How Artificial Streams Are Reported
Artificial streams are identified and reported by the DSPs, not by Revelator. Their determinations are final—Revelator passes the data on but does not mediate disputes.
- Coverage: only reports from DSPs that Revelator distributes to on your behalf are included. Streams from deals you hold directly with a DSP are not.
- Freshness: Deezer reports daily. Spotify, Apple Music, and Amazon Music report monthly, with a delay of about one month, so recent months may be incomplete.
To learn what causes artificial streaming, what the consequences are, and how to avoid it, see What is artificial streaming and how to avoid it. For the dashboard in the Revelator web app, which is built on the same data, see Understanding and using the Artificial Streaming Dashboard.
Metrics
| Metric | Meaning |
|---|---|
artificialStreamsCount | Number of streams the DSPs flagged as artificial. |
flaggedAssetsCount | Number of assets (tracks or releases) the DSPs flagged as suspicious. |
finesAmount | Amount withheld from the next royalty run because of artificial streams detected in the period. |
Dimensions
| Dimension | Groups by | Populated metadata fields |
|---|---|---|
track | Track. | id, name, version, imageId |
release | Release. | id, name, version, imageId |
artist | Artist. | id, name, imageId |
label | Label. | id, name, imageId |
country | Listener country. | id, iso2Code |
distributor | DSP. | id, name |
client | Client. | id, name |
date | Nothing. Returns totals for the whole range, or a time series with dateGranularity. | None |
Artificial streams support dateGranularity values monthly and all.
With dimension=date and dateGranularity=monthly, the response has a single item whose metrics array holds one
entry per month, and totalItemsCount equals the number of months rather than the number of items. See
Pagination.
Sorting
orderByProperty accepts a metric column (artificialstreamscount, flaggedassetscount, or finesamount),
eventdate, or a column of the requested dimension. For how sorting works, see the
Analytics Overview.
| Dimension | Dimension columns |
|---|---|
track | trackid, trackname, trackversion |
release | releaseid, releasename, releaseversion |
artist | artistid, artistname |
label | labelid, labelname |
country | countryid, iso2code |
distributor | distributorid, distributorname |
client | clientid, clientname |
date | None |
Without orderByProperty and dateGranularity, results are ordered by artificialstreamscount, descending.
Get Artificial Streams
/analytics/v1/artificial-streams Retrieves artificial stream counts, flagged assets, and fines grouped by the requested dimension.
Query Parameters
| Parameter | Description |
|---|---|
dimension * string | How to group the results (case-insensitive). See the Dimensions section above. Examples: track, artist, country, client, date |
clientIds integer[] | Restrict to these clients. |
countryIds integer[] | Restrict to these listener countries. Retrieved from GET /common/lookup/countries on the V1.0 API. |
distributorIds integer[] | Restrict to these DSPs. Use the |
excludeDistributorIds integer[] | Leave out these DSPs. Use the |
excludeTikTok boolean | Leave out TikTok. Equivalent to adding TikTok to |
releaseIds integer[] | Restrict to these releases. |
trackIds integer[] | Restrict to these tracks. |
artistIds integer[] | Restrict to these artists. |
labelIds integer[] | Restrict to these labels. |
dateGranularity string | With Examples: monthly, all |
onlyNew boolean | Return only data first loaded today. Cannot be combined with |
orderByProperty string | Sort column (case-insensitive). The accepted values depend on Examples: artificialstreamscount, flaggedassetscount, finesamount, eventdate |
orderByDescending boolean | Sort in descending order. Defaults to |
pageSize integer | Items per page. Defaults to 2000, which is also the maximum. |
pageNumber integer | 1-based page number. Defaults to 1. |
fromDate string | Inclusive start date ( |
toDate string | Inclusive end date ( |
targetEnterpriseId integer | Scope the request to a single client by passing its ID. |
Responses
object totals ArtificialStreamsTotalsModel artificialStreamsCount integer | null flaggedAssetsCount integer | null finesAmount number | null fromDate string | null YYYY-MM-DD) after defaults were applied. toDate string | null YYYY-MM-DD) after defaults were applied. totalItemsCount integer pageNumber integer | null pageSize integer | null totalPagesCount number items ArtificialStreamsListModel[] metadata ArtificialStreamsMetadataModel null. See the Dimensions section above. id integer | null track, a client ID for client, and so on). name string | null version string | null imageId string | null iso2Code string | null country dimension. metrics ArtificialStreamsMetricModel[] | null dateGranularity=monthly (months without data are zero-filled). artificialStreamsCount integer | null flaggedAssetsCount integer | null finesAmount number | null eventDate string (date-time) | null dateGranularity=monthly; null otherwise./analytics/v1/artificial-streams curl -X GET "https://platform.revelator.com/analytics/v1/artificial-streams?dimension=track&orderByProperty=artificialstreamscount&orderByDescending=true&pageSize=2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" curl -X GET "https://platform.revelator.com/analytics/v1/artificial-streams?dimension=track&orderByProperty=artificialstreamscount&orderByDescending=true&pageSize=2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" Example response 200
{
"totals": {
"artificialStreamsCount": 4620,
"flaggedAssetsCount": 156,
"finesAmount": 0.00
},
"fromDate": "2026-07-22",
"toDate": "2026-10-22",
"totalItemsCount": 156,
"pageNumber": 1,
"pageSize": 2,
"totalPagesCount": 78,
"items": [
{
"metadata": {
"id": 5889901,
"name": "Track Title",
"version": null,
"imageId": null,
"iso2Code": null
},
"metrics": [
{ "artificialStreamsCount": 1137, "flaggedAssetsCount": 1, "finesAmount": 0.00, "eventDate": null }
]
},
{
"metadata": {
"id": 5898129,
"name": "Another Track",
"version": null,
"imageId": null,
"iso2Code": null
},
"metrics": [
{ "artificialStreamsCount": 1128, "flaggedAssetsCount": 1, "finesAmount": 0.00, "eventDate": null }
]
}
]
} {
"totals": {
"artificialStreamsCount": 4620,
"flaggedAssetsCount": 156,
"finesAmount": 0.00
},
"fromDate": "2026-07-22",
"toDate": "2026-10-22",
"totalItemsCount": 156,
"pageNumber": 1,
"pageSize": 2,
"totalPagesCount": 78,
"items": [
{
"metadata": {
"id": 5889901,
"name": "Track Title",
"version": null,
"imageId": null,
"iso2Code": null
},
"metrics": [
{ "artificialStreamsCount": 1137, "flaggedAssetsCount": 1, "finesAmount": 0.00, "eventDate": null }
]
},
{
"metadata": {
"id": 5898129,
"name": "Another Track",
"version": null,
"imageId": null,
"iso2Code": null
},
"metrics": [
{ "artificialStreamsCount": 1128, "flaggedAssetsCount": 1, "finesAmount": 0.00, "eventDate": null }
]
}
]
} Artificial Streams Dashboard
The dashboard groups artificial streams by client and compares them against an earlier period, so you can see which clients are improving and which are getting worse.
Comparison Period
Pass previousFromDate and previousToDate together to compare against an earlier period. The previous period must
start before fromDate and end before toDate. Sending only one of the two returns 400 Bad Request.
The comparison fields (previousArtificialStreamsCount, artificialStreamsChange, artificialStreamsChangePct, and
increase) are only calculated when:
- both
previousFromDateandpreviousToDateare provided, and dateGranularityis omitted or set toall.
Otherwise, they are null on each item and 0 in totals.
Sorting
orderByProperty accepts artificialstreamscount, previousartificialstreamscount, artificialstreamschange,
artificialstreamschangepct, eventdate, clientid, and clientname. Without orderByProperty and
dateGranularity, results are ordered by artificialstreamscount, descending.
/analytics/v1/artificial-streams/dashboard Retrieves artificial streams per client, optionally compared against a previous period.
Query Parameters
| Parameter | Description |
|---|---|
dimension * string | How to group the results (case-insensitive). Example: client |
previousFromDate string | Start of the comparison period ( |
previousToDate string | End of the comparison period ( |
clientIds integer[] | Restrict to these clients. |
countryIds integer[] | Restrict to these listener countries. Retrieved from GET /common/lookup/countries on the V1.0 API. |
distributorIds integer[] | Restrict to these DSPs. Use the |
excludeDistributorIds integer[] | Leave out these DSPs. Use the |
excludeTikTok boolean | Leave out TikTok. Equivalent to adding TikTok to |
releaseIds integer[] | Restrict to these releases. |
trackIds integer[] | Restrict to these tracks. |
artistIds integer[] | Restrict to these artists. |
labelIds integer[] | Restrict to these labels. |
dateGranularity string | With Examples: monthly, all |
onlyNew boolean | Return only data first loaded today. Cannot be combined with |
orderByProperty string | Sort column (case-insensitive). See the Sorting section above for the accepted values. Examples: artificialstreamscount, previousartificialstreamscount, artificialstreamschange, artificialstreamschangepct, eventdate |
orderByDescending boolean | Sort in descending order. Defaults to |
pageSize integer | Items per page. Defaults to 2000, which is also the maximum. |
pageNumber integer | 1-based page number. Defaults to 1. |
fromDate string | Inclusive start date of the current period ( |
toDate string | Inclusive end date of the current period ( |
targetEnterpriseId integer | Scope the request to a single client by passing its ID. |
Responses
object totals ArtificialStreamsDashboardTotalsModel artificialStreamsCount integer | null previousArtificialStreamsCount integer | null 0 when no comparison is calculated. artificialStreamsChange integer | null 0 when no comparison is calculated. artificialStreamsChangePct number | null 0 when no comparison is calculated. fromDate string | null YYYY-MM-DD) after defaults were applied. toDate string | null YYYY-MM-DD) after defaults were applied. totalItemsCount integer pageNumber integer | null pageSize integer | null totalPagesCount number items ArtificialStreamsDashboardListModel[] metadata ArtificialStreamsMetadataModel id integer | null name string | null version string | null null. imageId string | null null. iso2Code string | null null. metrics ArtificialStreamsDashboardMetricModel[] | null dateGranularity=monthly. artificialStreamsCount integer | null previousArtificialStreamsCount integer | null artificialStreamsChange integer | null artificialStreamsChangePct number | null null when the comparison period has no artificial streams. increase boolean | null true if artificial streams increased, false if they decreased, null when unchanged or not compared. eventDate string (date-time) | null dateGranularity=monthly; null otherwise./analytics/v1/artificial-streams/dashboard curl -X GET "https://platform.revelator.com/analytics/v1/artificial-streams/dashboard?dimension=client&fromDate=2026-07-01&toDate=2026-09-30&previousFromDate=2026-04-01&previousToDate=2026-06-30&orderByProperty=artificialstreamscount&orderByDescending=true&pageSize=2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" curl -X GET "https://platform.revelator.com/analytics/v1/artificial-streams/dashboard?dimension=client&fromDate=2026-07-01&toDate=2026-09-30&previousFromDate=2026-04-01&previousToDate=2026-06-30&orderByProperty=artificialstreamscount&orderByDescending=true&pageSize=2" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" Example response 200
{
"totals": {
"artificialStreamsCount": 8466,
"previousArtificialStreamsCount": 13590,
"artificialStreamsChange": -5124,
"artificialStreamsChangePct": -37.70
},
"fromDate": "2026-07-01",
"toDate": "2026-09-30",
"totalItemsCount": 29,
"pageNumber": 1,
"pageSize": 2,
"totalPagesCount": 15,
"items": [
{
"metadata": {
"id": 559630,
"name": "Client Name",
"version": null,
"imageId": null,
"iso2Code": null
},
"metrics": [
{
"artificialStreamsCount": 5111,
"previousArtificialStreamsCount": 11936,
"artificialStreamsChange": -6825,
"artificialStreamsChangePct": -57.18,
"increase": false,
"eventDate": null
}
]
},
{
"metadata": {
"id": 293319,
"name": "Another Client",
"version": null,
"imageId": null,
"iso2Code": null
},
"metrics": [
{
"artificialStreamsCount": 2442,
"previousArtificialStreamsCount": 1419,
"artificialStreamsChange": 1023,
"artificialStreamsChangePct": 72.09,
"increase": true,
"eventDate": null
}
]
}
]
} {
"totals": {
"artificialStreamsCount": 8466,
"previousArtificialStreamsCount": 13590,
"artificialStreamsChange": -5124,
"artificialStreamsChangePct": -37.70
},
"fromDate": "2026-07-01",
"toDate": "2026-09-30",
"totalItemsCount": 29,
"pageNumber": 1,
"pageSize": 2,
"totalPagesCount": 15,
"items": [
{
"metadata": {
"id": 559630,
"name": "Client Name",
"version": null,
"imageId": null,
"iso2Code": null
},
"metrics": [
{
"artificialStreamsCount": 5111,
"previousArtificialStreamsCount": 11936,
"artificialStreamsChange": -6825,
"artificialStreamsChangePct": -57.18,
"increase": false,
"eventDate": null
}
]
},
{
"metadata": {
"id": 293319,
"name": "Another Client",
"version": null,
"imageId": null,
"iso2Code": null
},
"metrics": [
{
"artificialStreamsCount": 2442,
"previousArtificialStreamsCount": 1419,
"artificialStreamsChange": 1023,
"artificialStreamsChangePct": 72.09,
"increase": true,
"eventDate": null
}
]
}
]
} Migrating from the V1.0 API
These endpoints replace the V1.0 GET /analytics/artificialStreams/{aggregation} and
GET /analytics/artificialStreams/dashboard/byClient routes. The V1.0 routes are deprecated: after November 25, 2026, they are no longer supported and may stop working
without prior notice.
The responses are identical, field for field, and you
keep using the same access token. Only the route changes: the path is now artificial-streams, and the by… path
segment becomes the dimension query parameter.
| V1.0 | V2.0 |
|---|---|
https://api.revelator.com/analytics/artificialStreams/by{Aggregation} | https://platform.revelator.com/analytics/v1/artificial-streams?dimension={dimension} |
https://api.revelator.com/analytics/artificialStreams/dashboard/byClient | https://platform.revelator.com/analytics/v1/artificial-streams/dashboard?dimension=client |
| V1.0 aggregation | dimension |
|---|---|
byTrack | track |
byRelease | release |
byArtist | artist |
byLabel | label |
byCountry | country |
byDistributor | distributor |
byClient | client |
byDate | date |
All other query parameters—fromDate, toDate, previousFromDate, previousToDate, dateGranularity, pagination,
sorting, and filters—keep their names and behavior.
- GET https://api.revelator.com/analytics/artificialStreams/byTrack?fromDate=2026-07-01&toDate=2026-09-30
+ GET https://platform.revelator.com/analytics/v1/artificial-streams?dimension=track&fromDate=2026-07-01&toDate=2026-09-30