docs(research): play-count snapshot contract — playcounts, snapshots, deltas + provenance
Merged
SW
4mo ago+454+454+012345678901234567890123456789-1-1-0123456789
What
The contract for recoupable/chat#1791 (Apify-first play counts behind a measurement store; Songstats → historic backfill only). Documentation-driven: this merges first, the api fulfills it.
Three new endpoints in research.json + frontmatter-only reference pages + nav:
GET /api/research/playcounts?spotify_album_id— latest snapshot counts for all tracks on an album (404 → "create one with POST /snapshots")POST /api/research/snapshots— async snapshot of a catalog / album list / ISRC list; 202 withsnapshot_id+estimated_cost_usdbefore any scraper spend; 429 at the per-org monthly capGET /api/research/track/playcount-deltas?isrc&since[&until]— change between nearest captures +run_rate_annualized; emptydeltas(not an error) when fewer than two captures exist
Additive provenance on the existing track endpoints:
ResearchTrackStatgainsdata_source+captured_at- historic
history[]items gain per-pointdata_source(apify_spotify_playcount/songstats/granted_analytics)
Naming & caveats (locked here, per the issue)
The count field is platform_displayed_play_count — never "streams". Schema descriptions carry the caveat verbatim: scraped from public pages, not a royalty-bearing stream count, calibrate against customer-granted analytics for transaction-grade numbers.
Verification
- Purely additive diff on
research.json(438+/0−), byte-safe round-trip before editing mint openapi-check(mintlify validate): OpenAPI definition is valid- MDX pages are frontmatter-only per repo convention;
docs.jsonnav updated (Catalog group)
Merge order
Second in the #1791 train (cleanup → docs → database → api).
🤖 Generated with Claude Code