Uh oh!
There was an error while loading. Please reload this page.
docs(research): add GET /api/research/track/stats — per-track Songstats stats - #236
Conversation
…s stats) Contract-first for recoupable/app#1789. Adds the OpenAPI path + ResearchTrackStatsResponse/ResearchTrackStat schemas (mirrors /api/research/metrics, scoped to one track), the reference page, and the Catalog nav entry (surfaces in the generated llms.txt). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds a new ChangesTrack Stats Research Endpoint
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api-reference/openapi/research.json`:
- Around line 4681-4682: The "data" field description in the OpenAPI fragment
incorrectly references an optional "reposters[]" array even though this endpoint
does not expose a corresponding with_reposters query toggle; update the schema
description for the "data" property to remove or correct the mention of
"reposters[]" so it matches the actual query toggles exposed by the endpoint
(i.e., only list arrays that are produced when the real with_* toggles exist),
referencing the "data" property in this OpenAPI fragment to locate and edit the
description text.
- Around line 2628-2669: Add the standard 501 response to the GET
/api/research/track/stats endpoint responses: include a "501" entry with a brief
description (e.g., "Unsupported data source") and the same application/json
content/schema as the other error responses by referencing the existing
ResearchErrorResponse schema; update the responses object for this endpoint so
it matches sibling research endpoints that return 501 for unsupported data
sources.
In `@api-reference/research/track-stats.mdx`:
- Line 3: Replace the non-standard frontmatter value with the required
API-reference frontmatter format: change the openapi entry from openapi:
"/api-reference/openapi/research.json GET /api/research/track/stats" to openapi:
'GET /api/research/track/stats' and ensure the MDX file is frontmatter-only (no
other content outside the YAML frontmatter block).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 78578c38-6417-4d43-b778-fddf6fc696e9
📒 Files selected for processing (3)
api-reference/openapi/research.jsonapi-reference/research/track-stats.mdxdocs.json
| "responses": { | ||
| "200": { | ||
| "description": "Per-track current stats, one entry per requested source.", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/ResearchTrackStatsResponse" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "400": { | ||
| "description": "Validation error — missing identifier or `source`.", | ||
| "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" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "404": { | ||
| "description": "No track matched the supplied identifier.", | ||
| "content": { | ||
| "application/json": { | ||
| "schema": { | ||
| "$ref": "#/components/schemas/ResearchErrorResponse" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Add the standard 501 unsupported-data-source response for this research endpoint.
GET /api/research/track/stats is missing the 501 response used by sibling research endpoints in this spec, which leaves generated docs/SDKs with an incomplete error contract.
Proposed fix
"responses": {
"200": {
"description": "Per-track current stats, one entry per requested source.",
"content": {
"application/json": {
"schema": {
"$ref": "`#/components/schemas/ResearchTrackStatsResponse`"
}
}
}
},
"400": {
"description": "Validation error — missing identifier or `source`.",
"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`"
}
}
}
},
"404": {
"description": "No track matched the supplied identifier.",
"content": {
"application/json": {
"schema": {
"$ref": "`#/components/schemas/ResearchErrorResponse`"
}
}
}
+ },+ "501": {+ "$ref": "`#/components/responses/ResearchDataSourceUnsupported`"
}
}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@api-reference/openapi/research.json` around lines 2628 - 2669, Add the
standard 501 response to the GET /api/research/track/stats endpoint responses:
include a "501" entry with a brief description (e.g., "Unsupported data source")
and the same application/json content/schema as the other error responses by
referencing the existing ResearchErrorResponse schema; update the responses
object for this endpoint so it matches sibling research endpoints that return
501 for unsupported data sources.
Uh oh!
There was an error while loading. Please reload this page.
| @@ -0,0 +1,4 @@ | |||
| --- | |||
| title: 'Track Stats' | |||
| openapi: "/api-reference/openapi/research.json GET /api/research/track/stats" | |||
There was a problem hiding this comment.
Use the required API-reference openapi frontmatter format.
Line 3 uses a non-standard openapi value format for this repo’s API-reference pages.
Proposed fix
-openapi: "/api-reference/openapi/research.json GET /api/research/track/stats"+openapi: 'GET /api/research/track/stats'As per coding guidelines, API reference MDX pages must be frontmatter-only and use openapi: 'METHOD /path'.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| openapi: "/api-reference/openapi/research.json GET /api/research/track/stats" | |
| openapi: 'GET /api/research/track/stats' |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@api-reference/research/track-stats.mdx` at line 3, Replace the non-standard
frontmatter value with the required API-reference frontmatter format: change the
openapi entry from openapi: "/api-reference/openapi/research.json GET
/api/research/track/stats" to openapi: 'GET /api/research/track/stats' and
ensure the MDX file is frontmatter-only (no other content outside the YAML
frontmatter block).
Source: Coding guidelines
There was a problem hiding this comment.
2 issues found across 3 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="api-reference/openapi/research.json">
<violation number="1" location="api-reference/openapi/research.json:2628">
P2: Missing `501` `ResearchDataSourceUnsupported` response — all other research endpoints include it, and this endpoint is subject to the same data-source configuration constraints.</violation>
<violation number="2" location="api-reference/openapi/research.json:4681">
P2: The `data` field description references `reposters[]` but there is no `with_reposters` query parameter. The actual toggles are `with_playlists`, `with_charts`, `with_stations`, `with_videos`, and `with_links` — the description should list `stations[]` / `videos[]` / `links[]` instead of `reposters[]`.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| } | ||
| } | ||
| ], | ||
| "responses": { |
There was a problem hiding this comment.
P2: Missing 501ResearchDataSourceUnsupported response — all other research endpoints include it, and this endpoint is subject to the same data-source configuration constraints.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At api-reference/openapi/research.json, line 2628:
<comment>Missing `501` `ResearchDataSourceUnsupported` response — all other research endpoints include it, and this endpoint is subject to the same data-source configuration constraints.</comment>
<file context>
@@ -2500,6 +2500,174 @@
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Per-track current stats, one entry per requested source.",
</file context>
| }, | ||
| "data": { | ||
| "type": "object", | ||
| "description": "Per-source counters for this track. `streams_total` is the absolute play count. Keys vary by `source`; optional `playlists[]` / `charts[]` / `reposters[]` arrays appear when the matching `with_*` toggle is set.", |
There was a problem hiding this comment.
P2: The data field description references reposters[] but there is no with_reposters query parameter. The actual toggles are with_playlists, with_charts, with_stations, with_videos, and with_links — the description should list stations[] / videos[] / links[] instead of reposters[].
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At api-reference/openapi/research.json, line 4681:
<comment>The `data` field description references `reposters[]` but there is no `with_reposters` query parameter. The actual toggles are `with_playlists`, `with_charts`, `with_stations`, `with_videos`, and `with_links` — the description should list `stations[]` / `videos[]` / `links[]` instead of `reposters[]`.</comment>
<file context>
@@ -4472,6 +4640,65 @@
+ },
+ "data": {
+ "type": "object",
+ "description": "Per-source counters for this track. `streams_total` is the absolute play count. Keys vary by `source`; optional `playlists[]` / `charts[]` / `reposters[]` arrays appear when the matching `with_*` toggle is set.",
+ "additionalProperties": true,
+ "example": {
</file context>
| "description": "Per-source counters for this track. `streams_total` is the absolute play count. Keys vary by `source`; optional `playlists[]` / `charts[]` / `reposters[]` arrays appear when the matching `with_*` toggle is set.", | |
| "description": "Per-source counters for this track. `streams_total` is the absolute play count. Keys vary by `source`; optional `playlists[]` / `charts[]` / `stations[]` / `videos[]` / `links[]` fields can appear based on the corresponding `with_*` toggles.", |
…ponse Verified GET /api/research/track/stats against the api#653 preview with the real Mac Miller ISRC (USQY51771120). Adjusted the contract to match reality: - add top-level `source_ids` (response returns it; superset of `stats` sources) - add `songstats_track_id` to ResearchTrackInfo (track_info returns it) - round out the stat example with editorial-playlist counters 404-on-unknown-ISRC confirmed accurate (kept as documented). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sweetmantech
commented
Jun 9, 2026
Verified against the live api#653 preview — contract reconciledRan
Doc fixes from verification
Left as-is (consistent with sibling research endpoints)
Contract now matches the implementation in api#653. |
| } | ||
| } | ||
| }, | ||
| "/api/research/track/stats": { |
There was a problem hiding this comment.
Does this endpoint structure follow REST best practices?
There was a problem hiding this comment.
Yes — it follows the established convention: /api/research/track/playlists ("Track Playlists") is the direct precedent for a track/<sub-resource> endpoint, and like the rest of the research family it takes the identifier as a query param (?isrc=) rather than a path param. So /api/research/track/stats mirrors /api/research/track/playlists exactly — no change.
| }, | ||
| "/api/research/track/stats": { | ||
| "get": { | ||
| "description": "Get per-track, per-source current stats by ISRC (or Songstats/Spotify/Apple Music track id) — absolute `streams_total` plus playlist and chart reach. Thin passthrough to Songstats Get Track Current Stats; mirrors the `stats[].data` envelope of `GET /api/research/metrics`, but scoped to a single recording instead of the whole artist catalog.", |
There was a problem hiding this comment.
KISS - how could this description be simplified to better follow neighboring docs? Be as concise as possible.
There was a problem hiding this comment.
Simplified in 352e87c to neighbor brevity (cf. "Get all tracks by an artist with popularity data."): now "Get per-track, per-source current stats by ISRC or track id — absolute \streams_total`, playlist reach, and chart counts."` — dropped the passthrough/envelope/artist-catalog detail.
| "name": "isrc", | ||
| "in": "query", | ||
| "required": false, | ||
| "description": "Track ISRC. Provide exactly one of `isrc`, `songstats_track_id`, `spotify_track_id`, or `apple_music_track_id`.", |
There was a problem hiding this comment.
KISS - how could this description be simplified to better follow neighboring docs? Be as concise as possible.
There was a problem hiding this comment.
Simplified in 352e87c. The full "exactly one of [4 ids]" list was repeated on every identifier param; now isrc reads "Track ISRC. Provide exactly one track identifier." and the others just name themselves ("Spotify track id.", etc.).
…ors) Address review: trim the endpoint description to neighbor brevity (drop passthrough/envelope/comparison detail) and shorten the identifier params (state 'exactly one' once on isrc instead of repeating the full list). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contract-first docs for the per-track stats passthrough tracked in recoupable/app#1789 (step 1 of docs → api).
Adds
GET /api/research/track/stats— per-track, per-source current stats byisrc(orsongstats_track_id/spotify_track_id/apple_music_track_id), returning the samestats[].dataenvelope asGET /api/research/metricsbut scoped to a single recording (sodata.streams_totalis per-track, not artist-wide).Changes
api-reference/openapi/research.json— new path +ResearchTrackStatsResponse/ResearchTrackStatschemas (reusesResearchTrackInfofortrack_info,ResearchErrorResponsefor 400/401/404). Params mirror Songstatsenterprise/v1/tracks/stats1:1 (sourcerequired;with_playlists/charts/stations/videos/links,only_current,limit,offset).api-reference/research/track-stats.mdx— reference page (frontmatter-only, per house style).docs.json— adds the page under Research → Catalog (surfaces in the generatedllms.txt).Notes
securityblock / no new credential — matches the sibling/research/metrics(research endpoints document a 401 response; auth isx-api-key/Bearer). Server-side Songstatsapikeyis never part of the contract./research/metrics).Source: Songstats Get Track Current Stats (verified 2026-06-09) — https://docs.songstats.com/docs/api/6659134e76415-get-track-current-stats
🤖 Generated with Claude Code
Summary by cubic
Adds contract-first docs for
GET /api/research/track/stats— per-source current stats for a single track byisrcor platform IDs. MirrorsGET /api/research/metricsdata shape, scoped to one recording, and aligned with the live API.New Features
isrc,songstats_track_id,spotify_track_id,apple_music_track_id), requiredsource, and toggles (with_playlists,with_charts,with_stations,with_videos,with_links,only_current,limit,offset). AddsResearchTrackStatsResponse(includesstats[],track_info,source_ids) andResearchTrackStat; addssongstats_track_idtoResearchTrackInfo; 200/400/401/404.api-reference/research/track-stats.mdxand updatesdocs.jsonunder Research → Catalog.Refactors
isrc; removed passthrough/envelope copy).Written for commit 352e87c. Summary will update on new commits.
Summary by CodeRabbit
Release Notes