API REFERENCE
Track measurements
On this page
/api/research/tracks/{id}/measurementsTime-series of a track's measured counts.
Authentication
See the authentication guide for API key and account access requirements.
Request
curl --request GET \
--url 'https://api.recoupable.dev/api/research/tracks/YOUR_ID/measurements' \
--header 'x-api-key: YOUR_API_KEY'Replace the YOUR_ placeholders with your values. Required query parameters are included; optional parameters are listed below.
Try it
Fill in the fields, send the request from your browser, and read the live response. The curl below updates as you type.
Kept in this browser tab only and cleared when it closes.
curl --request GET \
--url 'https://recoup-api.vercel.app/api/research/tracks/{id}/measurements'Parameters
Path parameters
idstringrequiredProvider-neutral track id — ISRC or Spotify track id.
Query parameters
platformstringPlatform to read. Currently spotify.
Default: "spotify"
metricstringMetric to read.
Default: "platform_displayed_play_count"
fromstringInclusive start date (ISO) for the series.
tostringInclusive end date (ISO) for the series.
granularitystring · enumSeries granularity. daily returns the per-day cumulative series.
Values: "daily"
Default: "daily"
aggregatestring · enumReturn a derived aggregate instead of the raw series. run_rate returns the trailing-window annualized run-rate (a projection of the series).
Values: "run_rate"
windowstringTrailing window for aggregate=run_rate (e.g. 365d).
Default: "365d"
Responses
200The measurement series (or the requested aggregate).+
application/json
statusstringidstringThe provider-neutral track id queried.
platformstringmetricstringseriesarray<ResearchMeasurementPoint>Present unless aggregate is set.
Item properties for series
datestringformat: date
valuenumberCumulative metric value as of date.
data_sourcestringaggregateobjectnullablePresent when aggregate=run_rate.
Properties for aggregate
kindstringwindow_daysintegerdeltanumberrun_rate_annualizednumber400Validation error — bad identifier or query param.+
application/json
statusstring · enumrequiredValues: "error"
errorstringrequiredHuman-readable error message describing what went wrong.
401Authentication failed — invalid or missing API key.+
application/json
statusstring · enumrequiredValues: "error"
errorstringrequiredHuman-readable error message describing what went wrong.
402Insufficient credits.+
application/json
errorstring · enumrequiredValues: "insufficient_credits"
remaining_creditsintegerrequiredrequired_creditsintegerrequiredbillingUrlstringrequiredStatic link to the Recoup app, where a human can save a card and buy credits. It is a constant, not a freshly minted Stripe Checkout Session, so a credit-gated endpoint that keeps returning 402 creates nothing. To buy credits programmatically, call POST /api/credits/sessions.
404No measurements for this track yet — create a current measurement job to capture it.+
application/json
statusstring · enumrequiredValues: "error"
errorstringrequiredHuman-readable error message describing what went wrong.
Full specification
Download the OpenAPI file for complete schemas, constraints, and examples.
Download research.jsonView operation source
{
"summary": "Track measurements",
"description": "Time-series of a track's measured counts.",
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "Provider-neutral track id — ISRC or Spotify track id."
},
{
"name": "platform",
"in": "query",
"schema": {
"type": "string",
"default": "spotify"
},
"description": "Platform to read. Currently `spotify`."
},
{
"name": "metric",
"in": "query",
"schema": {
"type": "string",
"default": "platform_displayed_play_count"
},
"description": "Metric to read."
},
{
"name": "from",
"in": "query",
"schema": {
"type": "string",
"format": "date"
},
"description": "Inclusive start date (ISO) for the series."
},
{
"name": "to",
"in": "query",
"schema": {
"type": "string",
"format": "date"
},
"description": "Inclusive end date (ISO) for the series."
},
{
"name": "granularity",
"in": "query",
"schema": {
"type": "string",
"enum": [
"daily"
],
"default": "daily"
},
"description": "Series granularity. `daily` returns the per-day cumulative series."
},
{
"name": "aggregate",
"in": "query",
"schema": {
"type": "string",
"enum": [
"run_rate"
]
},
"description": "Return a derived aggregate instead of the raw series. `run_rate` returns the trailing-window annualized run-rate (a projection of the series)."
},
{
"name": "window",
"in": "query",
"schema": {
"type": "string",
"default": "365d"
},
"description": "Trailing window for `aggregate=run_rate` (e.g. `365d`)."
}
],
"responses": {
"200": {
"description": "The measurement series (or the requested aggregate).",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResearchMeasurementsResponse"
}
}
}
},
"400": {
"description": "Validation error — bad identifier or query param.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResearchErrorResponse"
}
}
}
},
"401": {
"description": "Authentication failed — invalid or missing API key.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResearchErrorResponse"
}
}
}
},
"402": {
"description": "Insufficient credits.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResearchInsufficientCreditsResponse"
}
}
}
},
"404": {
"description": "No measurements for this track yet — create a `current` measurement job to capture it.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResearchErrorResponse"
}
}
}
}
}
}