docs(research): play-count snapshot contract — playcounts, snapshots, deltas + provenance

Merged
SW
4mo ago
+454-1

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 with snapshot_id + estimated_cost_usd before any scraper spend; 429 at the per-org monthly cap
  • GET /api/research/track/playcount-deltas?isrc&since[&until] — change between nearest captures + run_rate_annualized; empty deltas (not an error) when fewer than two captures exist

Additive provenance on the existing track endpoints:

  • ResearchTrackStat gains data_source + captured_at
  • historic history[] items gain per-point data_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.json nav updated (Catalog group)

Merge order

Second in the #1791 train (cleanup → docs → database → api).

🤖 Generated with Claude Code