docs: /research/track becomes pure id-proxy; /research/playlist clarified#139
Conversation
…fied Follow-up to #138. The api PR (recoupable/api#366) is being simplified to strictly one-upstream-call-per-endpoint so credit charges are predictable and ambiguity never gets silently swallowed by composite resolution. /research/track - Drop q and artist query params; require numeric `id` instead. - Description reframes the endpoint as a thin /track/:id proxy and points callers at GET /api/research?type=tracks&beta=true for discovery. - 400 now refers to id validation, 404 refers to unknown Chartmetric id. /research/playlist - No schema change (still takes platform + id), but the description now explicitly names this a /playlist/:platform/:id proxy and points callers at GET /api/research for name-based discovery. - id description calls out that format varies by platform. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughUpdated OpenAPI spec Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 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.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
api-reference/openapi/research.json (1)
1886-1908:⚠️ Potential issue | 🟠 MajorDocument
betaon/api/researchor stop sending users there withbeta=true.Lines 1886 and 2354 make
GET /api/research?...&beta=truethe recommended discovery path, but the/api/researchoperation at Lines 805-845 still only documentsq,type, andlimit, and its description still says artist-name search only. That leaves the new migration flow undocumented in the same spec. Either add thebetaparameter and non-artist discovery wording to/api/research, or removebeta=truefrom these descriptions.Also applies to: 2354-2364
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/research.json` around lines 1886 - 1908, The /api/research OpenAPI operation is inconsistent with other docs that advertise using ?beta=true for non-artist discovery; update the /api/research operation (the GET /api/research path) to include a "beta" query parameter (boolean) and expand its description to mention non-artist discovery (playlists, albums, etc. via q & type), or alternatively remove all mentions of "beta=true" from other endpoint descriptions (e.g., the playlist detail description that references GET /api/research?q=<name>&type=playlists&beta=true) so the spec stays consistent; target the GET /api/research operation and the playlist detail description strings when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Outside diff comments:
In `@api-reference/openapi/research.json`:
- Around line 1886-1908: The /api/research OpenAPI operation is inconsistent
with other docs that advertise using ?beta=true for non-artist discovery; update
the /api/research operation (the GET /api/research path) to include a "beta"
query parameter (boolean) and expand its description to mention non-artist
discovery (playlists, albums, etc. via q & type), or alternatively remove all
mentions of "beta=true" from other endpoint descriptions (e.g., the playlist
detail description that references GET
/api/research?q=<name>&type=playlists&beta=true) so the spec stays consistent;
target the GET /api/research operation and the playlist detail description
strings when making the change.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 00911c78-de2f-40b9-9805-23cdaf8abf07
📒 Files selected for processing (1)
api-reference/openapi/research.json
Verified against preview of recoupable/api#366: GET /playlist?platform=spotify&id=37i9dQZF1DXcBWIGoYBM5M → 400 GET /playlist?platform=spotify&id=848051 → 200 RapCaviar Chartmetric's /playlist/:platform/:id accepts Chartmetric's own numeric playlist IDs, not the streaming platform's native IDs. Search results already expose the correct `id` field, so the workflow is: search via /api/research, feed `id` into /research/playlist. - Param description now explicitly calls out "not the native ID" - Added pattern ^[1-9][0-9]*$ + example 848051 - Endpoint description leads with "Chartmetric's own numeric playlist ID" Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 1 file
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:1886">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**
The new endpoint descriptions reference an undocumented/nonexistent `beta` query param on `GET /api/research`, which violates Rule 4’s “references that do not exist” clause and makes the API docs internally inconsistent.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
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:1908">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**
Rule 4 violation ("Docs/comments/config claim behavior not implemented by the change"): this update rewrites `/api/research/playlist` `id` as Chartmetric numeric-only, contradicting the PR’s stated platform-native `platform + id` contract and no-schema-change scope. This is a major API-doc contract mismatch for clients.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| "description": "Chartmetric playlist ID (positive integer). This is **not** the streaming platform's native ID — e.g. Spotify's base62 ID `37i9dQZF1DXcBWIGoYBM5M` for RapCaviar maps to Chartmetric ID `848051`. Obtain via `GET /api/research?type=playlists&beta=true`.", | ||
| "schema": { | ||
| "type": "string" | ||
| "type": "string", | ||
| "pattern": "^[1-9][0-9]*$", | ||
| "example": "848051" |
There was a problem hiding this comment.
P1: Custom agent: Flag AI Slop and Fabricated Changes
Rule 4 violation ("Docs/comments/config claim behavior not implemented by the change"): this update rewrites /api/research/playlist id as Chartmetric numeric-only, contradicting the PR’s stated platform-native platform + id contract and no-schema-change scope. This is a major API-doc contract mismatch for clients.
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 1908:
<comment>Rule 4 violation ("Docs/comments/config claim behavior not implemented by the change"): this update rewrites `/api/research/playlist` `id` as Chartmetric numeric-only, contradicting the PR’s stated platform-native `platform + id` contract and no-schema-change scope. This is a major API-doc contract mismatch for clients.</comment>
<file context>
@@ -1899,15 +1899,17 @@
"in": "query",
"required": true,
- "description": "Platform-native playlist ID. Format varies by platform — Spotify base62 (e.g. `37i9dQZF1DXcBWIGoYBM5M`), Apple/Deezer numeric, Amazon ASIN-style.",
+ "description": "Chartmetric playlist ID (positive integer). This is **not** the streaming platform's native ID — e.g. Spotify's base62 ID `37i9dQZF1DXcBWIGoYBM5M` for RapCaviar maps to Chartmetric ID `848051`. Obtain via `GET /api/research?type=playlists&beta=true`.",
"schema": {
- "type": "string"
</file context>
| "description": "Chartmetric playlist ID (positive integer). This is **not** the streaming platform's native ID — e.g. Spotify's base62 ID `37i9dQZF1DXcBWIGoYBM5M` for RapCaviar maps to Chartmetric ID `848051`. Obtain via `GET /api/research?type=playlists&beta=true`.", | |
| "schema": { | |
| "type": "string" | |
| "type": "string", | |
| "pattern": "^[1-9][0-9]*$", | |
| "example": "848051" | |
| "description": "Platform-native playlist ID. Format varies by platform — Spotify base62 (e.g. `37i9dQZF1DXcBWIGoYBM5M`), Apple/Deezer numeric, Amazon ASIN-style.", | |
| "schema": { | |
| "type": "string" | |
| } |
Mirrors the api change in recoupable/api#366 (cb6152b2). The handler no longer does a composite name→artist_id→discography resolve (which was returning wrong data for artist=Drake and artist=Taylor Swift on the preview), so the spec is updated: - Param renamed `artist` → `artist_id` - Typed as positive-integer string (pattern ^[1-9][0-9]*$), example 3380 - Description points callers at GET /api/research?type=artists&beta=true for discovery - 400 description specific to the new validation No change needed for /research/charts — the spec already enumerates `type` to {regional, viral}, `interval` to {daily, weekly}; the api change tightens the validator to actually enforce those at our layer (turning opaque upstream 400s into specific ones). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
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:889">
P2: The new discovery URL example is missing required `q`, so it documents an invalid request for fetching artist IDs.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| "in": "query", | ||
| "required": true, | ||
| "description": "Artist name or Recoup artist ID (UUID).", | ||
| "description": "Chartmetric artist ID (positive integer). Obtain via `GET /api/research?type=artists&beta=true` — the `id` field in each result is the Chartmetric ID to pass here.", |
There was a problem hiding this comment.
P2: The new discovery URL example is missing required q, so it documents an invalid request for fetching artist IDs.
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 889:
<comment>The new discovery URL example is missing required `q`, so it documents an invalid request for fetching artist IDs.</comment>
<file context>
@@ -880,15 +880,17 @@
"in": "query",
"required": true,
- "description": "Artist name or Recoup artist ID (UUID).",
+ "description": "Chartmetric artist ID (positive integer). Obtain via `GET /api/research?type=artists&beta=true` — the `id` field in each result is the Chartmetric ID to pass here.",
"schema": {
- "type": "string"
</file context>
| "description": "Chartmetric artist ID (positive integer). Obtain via `GET /api/research?type=artists&beta=true` — the `id` field in each result is the Chartmetric ID to pass here.", | |
| "description": "Chartmetric artist ID (positive integer). Obtain via `GET /api/research?q=<name>&type=artists&beta=true` — the `id` field in each result is the Chartmetric ID to pass here.", |
Mirrors api change in recoupable/api#366 (969f5f8a). The api now sends isPrimary=true by default to Chartmetric so /artist/:id/albums returns the artist's own discography (not features, soundtracks, DJ mixes). Spec additions: - `is_primary` (default "true") — opt into features with "false" - `limit` (positive integer) — pagination page size - `offset` (non-negative integer) — pagination offset Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
api-reference/openapi/research.json (1)
959-959:⚠️ Potential issue | 🟡 MinorDocument response for unknown
artist_idin/api/research/albums.
/api/research/albumslacks a404response definition in the spec, while/api/research/track(line 2434) and/api/research/curator(line 1282) both document404for non-existent IDs. Since/api/research/albumsis a proxy acceptingartist_idand can receive syntactically valid but non-existent IDs, add either a404response or explicitly document the actual behavior (e.g., returns200with an emptyalbumsarray).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/research.json` at line 959, The OpenAPI spec for the endpoint "/api/research/albums" is missing a documented response for a non-existent artist_id; update the operation object for "/api/research/albums" to either add a 404 response entry (matching the style used by "/api/research/track" and "/api/research/curator") describing the error schema and example, or explicitly document the actual behavior (for example a 200 response with an empty "albums" array) in the responses section; modify the responses block for the "/api/research/albums" operation to include the chosen 404 or clarifying 200 description and example so clients know how missing artist IDs are represented.
🧹 Nitpick comments (6)
api-reference/openapi/research.json (6)
1917-1981: Consider documenting404for/api/research/playlisttoo.Parallel to the
/research/trackchange that added a404for unknown Chartmetric IDs,/research/playlistis now explicitly framed as a/playlist/:platform/:idproxy but still only documents200/400/401. If the upstream returns 404 for a valid-shaped but non-existent Chartmetric playlist id (or an unsupported platform/id combo), add it here for symmetry with/research/trackand/research/curator.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/research.json` around lines 1917 - 1981, Add a 404 response for the "/api/research/playlist" GET operation to document upstream "not found" cases: in the operation's "responses" object add a "404" entry with a short description like "Chartmetric playlist not found or unsupported platform/id" and the same application/json schema referencing "#/components/schemas/ResearchErrorResponse" (mirror the 404 added for /api/research/track and /api/research/curator so clients get consistent error semantics for ResearchPlaylistResponse lookups).
2387-2446: Breaking change — call out theq/artist→idmigration for consumers.The required query parameter changed from
q(name/URL) toid(numeric), and optionalartistwas removed. Existing callers will start getting400s with no hint of the rename. Consider either:
- Adding a short "Breaking change" note at the top of the description (e.g., "Previously accepted
qandartist; both removed in favor ofid. UseGET /api/research?...&type=tracksfor name discovery."), or- Publishing a migration note in the changelog / deprecation section so SDK consumers can find it.
Pure docs suggestion — no code change needed beyond the description.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/research.json` around lines 2387 - 2446, The OpenAPI description for the "/api/research/track" GET endpoint no longer accepts the old q/artist parameters and now requires a numeric id, which will cause existing callers to receive 400s without guidance; update the operation description for "/api/research/track" to include a clear "Breaking change" migration note stating that q and artist were removed in favor of required query parameter id (positive integer) and point callers to using GET /api/research?type=tracks (beta=true) for name-based discovery, or alternatively add an explicit migration/deprecation entry referencing this endpoint and the ResearchTrackResponse/ResearchErrorResponse contract so SDK consumers can find the change.
896-906: Considertype: booleanforis_primaryto match other boolean flags in this spec.
is_primaryis modeled as a string enum["true","false"]with default"true", while similar boolean flags elsewhere in this file (e.g./api/research/chartslatestat Line 1133-1135, and the numerous boolean flags on/api/research/playlistsand/api/research/track/playlists) usetype: boolean. If this string-enum shape is intentional because the upstream parser is string-based, it's worth a one-line note in the description; otherwise aligning totype: booleanwithdefault: truewould be more consistent and play nicer with generated clients.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/research.json` around lines 896 - 906, The parameter "is_primary" is defined as a string enum ["true","false"] but should be a boolean to match other flags (e.g., `latest`) and generated clients; update the parameter schema for name "is_primary" so "schema" uses "type": "boolean" and "default": true, and adjust the description to use true/false (or, if the upstream parser requires strings, add one concise sentence to the description noting that values are parsed as strings); locate and edit the parameter block for "is_primary" to make this change.
911-911: Document the effective max forlimit.The description says "Defaults to Chartmetric's default (100) when omitted" but doesn't state the maximum the proxy accepts. If the upstream enforces an upper bound (Chartmetric typically caps at ~100 for artist albums), surfacing it here (and/or as a
maximum/pattern ceiling) will save callers a 400 round-trip.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/research.json` at line 911, Update the OpenAPI specification for the "limit" parameter in research.json to document the effective maximum accepted by the proxy: add an OpenAPI "maximum": 100 (or the actual upstream cap if different) and update the "description" to state both the default (100) and the maximum allowed (e.g., "Defaults to Chartmetric's default (100) when omitted; maximum accepted by this proxy is 100"). Locate the "limit" parameter entry in the JSON (search for the "description" string shown) and add/update the "maximum" field and the description text accordingly.
2638-2640: Downstream inconsistency:/api/research/track/playlistsstill acceptsq+artist.The PR's stated rationale for
/research/trackis to avoid composite search-then-detail behavior for predictable single-upstream-call semantics./api/research/track/playlists(below) still supportsqandartistfor search-then-playlist lookups, with a404described as "Track not found when resolving viaq+artist." Not a bug in this PR, but worth deciding whether that endpoint should follow the same simplification in a follow-up (requireid, push discovery back to/api/research). Flagging so it doesn't get missed.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/research.json` around lines 2638 - 2640, The OpenAPI entry for "/api/research/track/playlists" still documents and supports composite lookup via query params `q` + `artist` and a 404 for "Track not found when resolving via `q` + `artist`"; to align with the PR's simplification, remove the search-then-detail behavior and require a single upstream Chartmetric `id` for this endpoint: update the operation description to state `id` is required and that discovery should be done via `/api/research/track`, remove any `q` and `artist` parameters and the related 404 text from the responses, and ensure the runtime handler that serves "/api/research/track/playlists" validates presence of `id` and returns the appropriate error when missing (instead of attempting `q`+`artist` resolution).
907-926:limit/offsettyped asstringwhile other endpoints useinteger.
/api/research/discover(Lines 1392-1400) and/api/research/track/playlists(Lines 2694-2708) declarelimit/offsetastype: integerwithminimum/maximumconstraints. Here they'retype: stringwith regex patterns. Functionally fine for raw query strings, but the inconsistency will surface in generated SDKs (typed asstringvsnumber). Considertype: integerwithminimum: 1forlimitandminimum: 0foroffset, unless the handler strictly requires string input. If the current shape is deliberate to match howartist_idis also stringly typed, that's worth documenting.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/research.json` around lines 907 - 926, The limit and offset query parameters in research.json are declared as type: string with regex patterns causing SDKs to generate strings; update the schemas for the parameters named "limit" and "offset" in the /api/research/* endpoints (the entries shown in the diff) to use "type": "integer" and add "minimum": 1 for limit and "minimum": 0 for offset (and optional "maximum" if desired) to match the other endpoints (/api/research/discover and /api/research/track/playlists); if the endpoint truly requires string input instead of integers, add a short description to the parameter explaining why string typing is deliberate so generated SDKs/users are aware.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@api-reference/openapi/research.json`:
- Line 883: The /api/research discovery hint references an undocumented beta
flag; either document the beta query parameter on the /api/research endpoint
(add a boolean query parameter named "beta" to the /api/research operation with
a short description and default false so callers know it enables beta search
behavior) and mirror that same parameter description for the
/api/research/playlist and /api/research/track operations, or remove
"&beta=true" from the descriptive text in the Chartmetric album/playlist/track
endpoint descriptions (the strings referencing "GET
/api/research?q=<name>&type=artists&beta=true") so the hint no longer points to
an undocumented flag; update the OpenAPI operation for the /api/research path to
include the new "beta" parameter if you choose the first option.
---
Outside diff comments:
In `@api-reference/openapi/research.json`:
- Line 959: The OpenAPI spec for the endpoint "/api/research/albums" is missing
a documented response for a non-existent artist_id; update the operation object
for "/api/research/albums" to either add a 404 response entry (matching the
style used by "/api/research/track" and "/api/research/curator") describing the
error schema and example, or explicitly document the actual behavior (for
example a 200 response with an empty "albums" array) in the responses section;
modify the responses block for the "/api/research/albums" operation to include
the chosen 404 or clarifying 200 description and example so clients know how
missing artist IDs are represented.
---
Nitpick comments:
In `@api-reference/openapi/research.json`:
- Around line 1917-1981: Add a 404 response for the "/api/research/playlist" GET
operation to document upstream "not found" cases: in the operation's "responses"
object add a "404" entry with a short description like "Chartmetric playlist not
found or unsupported platform/id" and the same application/json schema
referencing "#/components/schemas/ResearchErrorResponse" (mirror the 404 added
for /api/research/track and /api/research/curator so clients get consistent
error semantics for ResearchPlaylistResponse lookups).
- Around line 2387-2446: The OpenAPI description for the "/api/research/track"
GET endpoint no longer accepts the old q/artist parameters and now requires a
numeric id, which will cause existing callers to receive 400s without guidance;
update the operation description for "/api/research/track" to include a clear
"Breaking change" migration note stating that q and artist were removed in favor
of required query parameter id (positive integer) and point callers to using GET
/api/research?type=tracks (beta=true) for name-based discovery, or alternatively
add an explicit migration/deprecation entry referencing this endpoint and the
ResearchTrackResponse/ResearchErrorResponse contract so SDK consumers can find
the change.
- Around line 896-906: The parameter "is_primary" is defined as a string enum
["true","false"] but should be a boolean to match other flags (e.g., `latest`)
and generated clients; update the parameter schema for name "is_primary" so
"schema" uses "type": "boolean" and "default": true, and adjust the description
to use true/false (or, if the upstream parser requires strings, add one concise
sentence to the description noting that values are parsed as strings); locate
and edit the parameter block for "is_primary" to make this change.
- Line 911: Update the OpenAPI specification for the "limit" parameter in
research.json to document the effective maximum accepted by the proxy: add an
OpenAPI "maximum": 100 (or the actual upstream cap if different) and update the
"description" to state both the default (100) and the maximum allowed (e.g.,
"Defaults to Chartmetric's default (100) when omitted; maximum accepted by this
proxy is 100"). Locate the "limit" parameter entry in the JSON (search for the
"description" string shown) and add/update the "maximum" field and the
description text accordingly.
- Around line 2638-2640: The OpenAPI entry for "/api/research/track/playlists"
still documents and supports composite lookup via query params `q` + `artist`
and a 404 for "Track not found when resolving via `q` + `artist`"; to align with
the PR's simplification, remove the search-then-detail behavior and require a
single upstream Chartmetric `id` for this endpoint: update the operation
description to state `id` is required and that discovery should be done via
`/api/research/track`, remove any `q` and `artist` parameters and the related
404 text from the responses, and ensure the runtime handler that serves
"/api/research/track/playlists" validates presence of `id` and returns the
appropriate error when missing (instead of attempting `q`+`artist` resolution).
- Around line 907-926: The limit and offset query parameters in research.json
are declared as type: string with regex patterns causing SDKs to generate
strings; update the schemas for the parameters named "limit" and "offset" in the
/api/research/* endpoints (the entries shown in the diff) to use "type":
"integer" and add "minimum": 1 for limit and "minimum": 0 for offset (and
optional "maximum" if desired) to match the other endpoints
(/api/research/discover and /api/research/track/playlists); if the endpoint
truly requires string input instead of integers, add a short description to the
parameter explaining why string typing is deliberate so generated SDKs/users are
aware.
🪄 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: f3808098-7c41-425b-b495-0d93241e6eda
📒 Files selected for processing (1)
api-reference/openapi/research.json
…hema Mirrors the api change in recoupable/api#366 (a28deb25). /api/research has been the discovery primitive for the research endpoints since that commit, but the spec still described it as "Search for artists by name" and didn't advertise the new passthrough params. Spec additions: - Description now frames /api/research as the discovery primitive for /track, /playlist, /albums (via type=tracks/playlists/artists). - Recommends beta=true for ambiguous queries, citing the upstream bug where default-engine returns 1 low-quality match for common terms like "Hotline Bling" or "Flowers". - New params: beta (enum "true"/"false"), platforms (comma-separated, beta-only), offset (non-negative integer for pagination). - ResearchSearchResult schema loosened to reflect reality: the default engine and beta engine return different shapes, and default-engine shape varies by type. Common fields enumerated; additionalProperties: true keeps engine-specific fields passing through without over-specifying. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The discovery-then-detail flow is core to the new "one call per endpoint" design, so the references between endpoints should be clickable — both for humans reading the docs and for LLMs using the .md sitemap. Per the existing convention (e.g. the chat endpoints already use [text](/api-reference/chat/update)), updated: - /research/playlist: link to /api-reference/research/search in both the endpoint description and the `id` param description - /research/track: same, in both places - /research/albums: same, in both places - /api/research (search): forward-links to the three detail endpoints (/albums, /track, /playlist) in the endpoint description Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Audit of Chartmetric-id params after 15bee59 found two more endpoints that require a numeric Chartmetric ID but didn't link to the discovery endpoint: - /research/curator (id): now links to GET /api/research?type=curators&beta=true. Kept the existing hint about finding curators via /research/playlists as a secondary path. - /research/track/playlists (id): now links to GET /api/research?type=tracks&beta=true. (Note: this endpoint still has a composite `q`/`artist` name-lookup fallback with the same wrong-match risk as the old /research/track behavior; KISS-ifying it is a separate follow-up.) All five endpoints that reference a Chartmetric id now point callers at the same discovery primitive: /research/albums (artist_id) ✓ /research/curator (id) ✓ /research/playlist (id) ✓ /research/track (id) ✓ /research/track/playlists (id) ✓ Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Follow-up to #138. The api PR recoupable/api#366 is being simplified to strictly one upstream Chartmetric call per endpoint so credit charges are predictable and ambiguity never gets silently swallowed by composite resolution.
/research/track
/research/playlist
Why
While dogfooding the original review-comment-driven fix on the preview of recoupable/api#366, we found Chartmetric's default search engine is broken for common track queries (returns a single low-quality match). `beta=true` fixes the search-quality problem, but wiring a search-then-detail composite into `/research/track` produces asymmetric behavior between artist-present and artist-absent callers and makes credit-per-request non-deterministic. The KISS move is: `/research` does search, `/research/track` does detail-lookup, callers compose.
Test plan
🤖 Generated with Claude Code
Summary by cubic
Made the research endpoints pure Chartmetric ID proxies and positioned
/api/researchas the single discovery entry point. Clarified that playlist IDs are Chartmetric numeric IDs and added cross-links (including curator and track→playlists) to guide search→detail.New Features
/api/research: discovery fortype=artists|tracks|playlists; recommendbeta=truefor ambiguous queries; now cross-links to/api/research/albums,/api/research/track, and/api/research/playlist.beta,platforms, andoffsetparams; result schema documents default vs beta shapes, allowsidas int or string, and describesmatch_strength/target/platform./api/research/curatorand/api/research/track/playliststo/api/research?type=...&beta=trueso all Chartmetric-ID endpoints share the same discovery flow.Migration
/api/research/track: numericidonly; droppedqandartist; 400 for invalidid, 404 for unknown Chartmetricid./api/research/albums: numericartist_id; addedis_primary(default "true"),limit,offset; removed name-based lookups./api/research/playlist: stillplatform+ Chartmetric numericid(e.g.,848051); native platform IDs are rejected.Written for commit 9aa8f61. Summary will update on new commits.
Summary by CodeRabbit