From 77f108e47aa26e2724ef093164208100ca7e0b60 Mon Sep 17 00:00:00 2001 From: Sidney Swift <158200036+sidneyswift@users.noreply.github.com> Date: Fri, 27 Mar 2026 14:47:56 -0400 Subject: [PATCH 01/16] docs: add Research API endpoints and CLI commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Documentation-first spec for the `recoup research` primitive — 16 API endpoints under /api/research/ covering artist search, metrics (14 platforms), audience demographics, cities, similar artists, playlists, discography, career, insights, discovery, genres, festivals, web search, and deep research. CLI docs cover all subcommands with flags, workflow examples, and links to the API reference. Provider-agnostic — no mention of underlying data sources. Made-with: Cursor --- api-reference/openapi.json | 573 ++++++++++++++++++++++++++- api-reference/research/albums.mdx | 4 + api-reference/research/audience.mdx | 4 + api-reference/research/career.mdx | 4 + api-reference/research/cities.mdx | 4 + api-reference/research/deep.mdx | 4 + api-reference/research/discover.mdx | 4 + api-reference/research/festivals.mdx | 4 + api-reference/research/genres.mdx | 4 + api-reference/research/insights.mdx | 4 + api-reference/research/metrics.mdx | 4 + api-reference/research/playlists.mdx | 4 + api-reference/research/profile.mdx | 4 + api-reference/research/search.mdx | 4 + api-reference/research/similar.mdx | 4 + api-reference/research/tracks.mdx | 4 + api-reference/research/web.mdx | 4 + cli.mdx | 168 ++++++++ docs.json | 21 + 19 files changed, 825 insertions(+), 1 deletion(-) create mode 100644 api-reference/research/albums.mdx create mode 100644 api-reference/research/audience.mdx create mode 100644 api-reference/research/career.mdx create mode 100644 api-reference/research/cities.mdx create mode 100644 api-reference/research/deep.mdx create mode 100644 api-reference/research/discover.mdx create mode 100644 api-reference/research/festivals.mdx create mode 100644 api-reference/research/genres.mdx create mode 100644 api-reference/research/insights.mdx create mode 100644 api-reference/research/metrics.mdx create mode 100644 api-reference/research/playlists.mdx create mode 100644 api-reference/research/profile.mdx create mode 100644 api-reference/research/search.mdx create mode 100644 api-reference/research/similar.mdx create mode 100644 api-reference/research/tracks.mdx create mode 100644 api-reference/research/web.mdx diff --git a/api-reference/openapi.json b/api-reference/openapi.json index 8fea02f..4ab1575 100644 --- a/api-reference/openapi.json +++ b/api-reference/openapi.json @@ -4855,6 +4855,472 @@ } ] } + }, + "/api/research/search": { + "get": { + "description": "Search the music industry database for artists by name. Returns matching artists with IDs you can use in all other research endpoints. Costs 5 credits per call.", + "parameters": [ + { + "name": "q", + "in": "query", + "required": true, + "description": "Artist name to search for.", + "schema": { "type": "string" } + }, + { + "name": "type", + "in": "query", + "required": false, + "description": "Entity type to search for.", + "schema": { + "type": "string", + "enum": ["artists", "tracks", "albums", "playlists", "curators", "stations"], + "default": "artists" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "description": "Maximum number of results.", + "schema": { "type": "integer", "default": 10 } + } + ], + "responses": { + "200": { + "description": "Search results", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchSearchResponse" } + } + } + }, + "402": { "description": "Insufficient credits" } + } + } + }, + "/api/research/artist/{id}": { + "get": { + "description": "Get a full artist profile from the music industry database — bio, genres, social URLs, label, career stage, and basic metrics. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Artist ID from the music industry database (returned by search).", + "schema": { "type": "integer" } + } + ], + "responses": { + "200": { + "description": "Artist profile", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/stat/{source}": { + "get": { + "description": "Get platform-specific metrics for an artist over time — followers, listeners, views, engagement. Supports 14 platforms. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Artist ID from the music industry database.", + "schema": { "type": "integer" } + }, + { + "name": "source", + "in": "path", + "required": true, + "description": "Platform to get metrics for.", + "schema": { + "type": "string", + "enum": ["spotify", "instagram", "tiktok", "twitter", "facebook", "youtube_channel", "youtube_artist", "soundcloud", "deezer", "twitch", "line", "melon", "wikipedia", "bandsintown"] + } + } + ], + "responses": { + "200": { + "description": "Platform metrics over time", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/where-people-listen": { + "get": { + "description": "Get the top cities where an artist's fans listen, ranked by listener concentration. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { "type": "integer" } + } + ], + "responses": { + "200": { + "description": "Top listener cities", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/{platform}-audience-stats": { + "get": { + "description": "Get audience demographics for an artist on a specific platform — age, gender, and country breakdown. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { "type": "integer" } + }, + { + "name": "platform", + "in": "path", + "required": true, + "description": "Platform to get audience demographics for.", + "schema": { + "type": "string", + "enum": ["instagram", "tiktok", "youtube"] + } + } + ], + "responses": { + "200": { + "description": "Audience demographics", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/neighboring-artists": { + "get": { + "description": "Find similar artists based on audience overlap, genre, mood, and musicality. Use for competitive analysis and collaboration discovery. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { "type": "integer" } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { "type": "integer", "default": 10 } + } + ], + "responses": { + "200": { + "description": "Similar artists with overlap scores", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/{platform}/{status}/playlists": { + "get": { + "description": "Get an artist's playlist placements — editorial, algorithmic, and indie playlists across platforms. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { "type": "integer" } + }, + { + "name": "platform", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": ["spotify", "applemusic", "deezer", "amazon", "youtube"], + "default": "spotify" + } + }, + { + "name": "status", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": ["current", "past"], + "default": "current" + } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { "type": "integer", "default": 20 } + }, + { + "name": "sort", + "in": "query", + "required": false, + "description": "Sort results by this field.", + "schema": { "type": "string" } + } + ], + "responses": { + "200": { + "description": "Playlist placements", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/albums": { + "get": { + "description": "Get an artist's full discography — albums, EPs, and singles with release dates. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { "type": "integer" } + } + ], + "responses": { + "200": { + "description": "Artist albums", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/tracks": { + "get": { + "description": "Get all tracks by an artist with popularity data. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { "type": "integer" } + } + ], + "responses": { + "200": { + "description": "Artist tracks", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/career": { + "get": { + "description": "Get an artist's career timeline — key milestones, trajectory, and career stage. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { "type": "integer" } + } + ], + "responses": { + "200": { + "description": "Career timeline", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/{id}/noteworthy-insights": { + "get": { + "description": "Get AI-generated insights about an artist — automatically surfaced trends, milestones, and observations. Costs 5 credits.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "schema": { "type": "integer" } + } + ], + "responses": { + "200": { + "description": "AI-generated insights", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/artist/list/filter": { + "get": { + "description": "Discover artists by criteria — filter by country, genre, listener count, follower count, growth rate, and more. Costs 5 credits.", + "parameters": [ + { + "name": "country", + "in": "query", + "required": false, + "description": "ISO country code (e.g., US, BR, GB).", + "schema": { "type": "string" } + }, + { + "name": "genre", + "in": "query", + "required": false, + "description": "Genre ID (use GET /api/research/genre to list).", + "schema": { "type": "integer" } + }, + { + "name": "sp_monthly_listeners_min", + "in": "query", + "required": false, + "schema": { "type": "integer" } + }, + { + "name": "sp_monthly_listeners_max", + "in": "query", + "required": false, + "schema": { "type": "integer" } + }, + { + "name": "sort", + "in": "query", + "required": false, + "description": "Sort field (e.g., weekly_diff.sp_monthly_listeners).", + "schema": { "type": "string" } + }, + { + "name": "limit", + "in": "query", + "required": false, + "schema": { "type": "integer", "default": 20 } + } + ], + "responses": { + "200": { + "description": "Filtered artist list", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/genre": { + "get": { + "description": "List all available genre IDs and names. Use these IDs with the discover endpoint. Costs 5 credits.", + "responses": { + "200": { + "description": "Genre list", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/festival/list": { + "get": { + "description": "List music festivals. Costs 5 credits.", + "responses": { + "200": { + "description": "Festival list", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + } + } + } + } + } + }, + "/api/research/web": { + "post": { + "description": "Search the web for real-time information. Returns ranked results with titles, URLs, and content snippets. Use for narrative context, press coverage, and cultural research that structured data endpoints don't cover. Costs 5 credits.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchWebRequest" } + } + } + }, + "responses": { + "200": { + "description": "Web search results", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchWebResponse" } + } + } + } + } + } + }, + "/api/research/deep": { + "post": { + "description": "Perform deep, comprehensive research on a topic. Browses multiple sources extensively and returns a cited report. Use for full artist deep dives, competitive analysis, and any research requiring synthesis across many sources. Costs 25 credits.", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchDeepRequest" } + } + } + }, + "responses": { + "200": { + "description": "Deep research report with citations", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/ResearchDeepResponse" } + } + } + } + } + } } }, "components": { @@ -11272,7 +11738,112 @@ } } }, - "securitySchemes": { + "ResearchSearchResponse": { + "type": "object", + "description": "Response from searching the music industry database for artists, tracks, or other entities.", + "properties": { + "status": { + "type": "string", + "enum": ["success", "error"] + }, + "results": { + "type": "array", + "description": "Array of matching entities with IDs, names, images, and basic metadata. Use the returned ID for subsequent research commands.", + "items": { + "type": "object" + } + } + } + }, + "ResearchProxyResponse": { + "type": "object", + "description": "Proxied response from the music industry data provider. The shape depends on the specific endpoint called. All responses are JSON.", + "properties": {} + }, + "ResearchWebRequest": { + "type": "object", + "required": ["query"], + "description": "Request body for web research.", + "properties": { + "query": { + "type": "string", + "description": "The search query — what you want to find on the web." + }, + "max_results": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "default": 10, + "description": "Maximum number of results to return." + }, + "country": { + "type": "string", + "minLength": 2, + "maxLength": 2, + "description": "ISO country code for regional results (e.g., 'US', 'GB')." + } + } + }, + "ResearchWebResponse": { + "type": "object", + "description": "Web search results with titles, URLs, and content snippets.", + "properties": { + "status": { + "type": "string", + "enum": ["success", "error"] + }, + "results": { + "type": "array", + "description": "Ranked web search results.", + "items": { + "type": "object", + "properties": { + "title": { "type": "string" }, + "url": { "type": "string" }, + "content": { "type": "string" } + } + } + }, + "formatted": { + "type": "string", + "description": "Results formatted as markdown for easy reading." + } + } + }, + "ResearchDeepRequest": { + "type": "object", + "required": ["query"], + "description": "Request body for deep research. Performs comprehensive multi-source analysis.", + "properties": { + "query": { + "type": "string", + "description": "The research question — be specific and detailed for best results." + } + } + }, + "ResearchDeepResponse": { + "type": "object", + "description": "Comprehensive research report with citations.", + "properties": { + "status": { + "type": "string", + "enum": ["success", "error"] + }, + "content": { + "type": "string", + "description": "The full research report as markdown." + }, + "citations": { + "type": "array", + "description": "Source URLs cited in the report.", + "items": { + "type": "string", + "format": "uri" + } + } + } + }, + "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" diff --git a/api-reference/research/albums.mdx b/api-reference/research/albums.mdx new file mode 100644 index 0000000..b64a3ff --- /dev/null +++ b/api-reference/research/albums.mdx @@ -0,0 +1,4 @@ +--- +title: 'Albums' +openapi: 'GET /api/research/artist/{id}/albums' +--- diff --git a/api-reference/research/audience.mdx b/api-reference/research/audience.mdx new file mode 100644 index 0000000..7be98e5 --- /dev/null +++ b/api-reference/research/audience.mdx @@ -0,0 +1,4 @@ +--- +title: 'Audience Demographics' +openapi: 'GET /api/research/artist/{id}/{platform}-audience-stats' +--- diff --git a/api-reference/research/career.mdx b/api-reference/research/career.mdx new file mode 100644 index 0000000..e838dc9 --- /dev/null +++ b/api-reference/research/career.mdx @@ -0,0 +1,4 @@ +--- +title: 'Career Timeline' +openapi: 'GET /api/research/artist/{id}/career' +--- diff --git a/api-reference/research/cities.mdx b/api-reference/research/cities.mdx new file mode 100644 index 0000000..a36ad45 --- /dev/null +++ b/api-reference/research/cities.mdx @@ -0,0 +1,4 @@ +--- +title: 'Listener Cities' +openapi: 'GET /api/research/artist/{id}/where-people-listen' +--- diff --git a/api-reference/research/deep.mdx b/api-reference/research/deep.mdx new file mode 100644 index 0000000..34bb0f3 --- /dev/null +++ b/api-reference/research/deep.mdx @@ -0,0 +1,4 @@ +--- +title: 'Deep Research' +openapi: 'POST /api/research/deep' +--- diff --git a/api-reference/research/discover.mdx b/api-reference/research/discover.mdx new file mode 100644 index 0000000..b9ab93f --- /dev/null +++ b/api-reference/research/discover.mdx @@ -0,0 +1,4 @@ +--- +title: 'Discover Artists' +openapi: 'GET /api/research/artist/list/filter' +--- diff --git a/api-reference/research/festivals.mdx b/api-reference/research/festivals.mdx new file mode 100644 index 0000000..f6ddbd1 --- /dev/null +++ b/api-reference/research/festivals.mdx @@ -0,0 +1,4 @@ +--- +title: 'Festivals' +openapi: 'GET /api/research/festival/list' +--- diff --git a/api-reference/research/genres.mdx b/api-reference/research/genres.mdx new file mode 100644 index 0000000..8f8902f --- /dev/null +++ b/api-reference/research/genres.mdx @@ -0,0 +1,4 @@ +--- +title: 'Genres' +openapi: 'GET /api/research/genre' +--- diff --git a/api-reference/research/insights.mdx b/api-reference/research/insights.mdx new file mode 100644 index 0000000..488cdf0 --- /dev/null +++ b/api-reference/research/insights.mdx @@ -0,0 +1,4 @@ +--- +title: 'AI Insights' +openapi: 'GET /api/research/artist/{id}/noteworthy-insights' +--- diff --git a/api-reference/research/metrics.mdx b/api-reference/research/metrics.mdx new file mode 100644 index 0000000..11fdc82 --- /dev/null +++ b/api-reference/research/metrics.mdx @@ -0,0 +1,4 @@ +--- +title: 'Platform Metrics' +openapi: 'GET /api/research/artist/{id}/stat/{source}' +--- diff --git a/api-reference/research/playlists.mdx b/api-reference/research/playlists.mdx new file mode 100644 index 0000000..98dacf8 --- /dev/null +++ b/api-reference/research/playlists.mdx @@ -0,0 +1,4 @@ +--- +title: 'Playlist Placements' +openapi: 'GET /api/research/artist/{id}/{platform}/{status}/playlists' +--- diff --git a/api-reference/research/profile.mdx b/api-reference/research/profile.mdx new file mode 100644 index 0000000..f564226 --- /dev/null +++ b/api-reference/research/profile.mdx @@ -0,0 +1,4 @@ +--- +title: 'Artist Profile' +openapi: 'GET /api/research/artist/{id}' +--- diff --git a/api-reference/research/search.mdx b/api-reference/research/search.mdx new file mode 100644 index 0000000..59f41d5 --- /dev/null +++ b/api-reference/research/search.mdx @@ -0,0 +1,4 @@ +--- +title: 'Search' +openapi: 'GET /api/research/search' +--- diff --git a/api-reference/research/similar.mdx b/api-reference/research/similar.mdx new file mode 100644 index 0000000..9e24c20 --- /dev/null +++ b/api-reference/research/similar.mdx @@ -0,0 +1,4 @@ +--- +title: 'Similar Artists' +openapi: 'GET /api/research/artist/{id}/neighboring-artists' +--- diff --git a/api-reference/research/tracks.mdx b/api-reference/research/tracks.mdx new file mode 100644 index 0000000..6e659e1 --- /dev/null +++ b/api-reference/research/tracks.mdx @@ -0,0 +1,4 @@ +--- +title: 'Tracks' +openapi: 'GET /api/research/artist/{id}/tracks' +--- diff --git a/api-reference/research/web.mdx b/api-reference/research/web.mdx new file mode 100644 index 0000000..20373b6 --- /dev/null +++ b/api-reference/research/web.mdx @@ -0,0 +1,4 @@ +--- +title: 'Web Search' +openapi: 'POST /api/research/web' +--- diff --git a/cli.mdx b/cli.mdx index 29394ea..e82d7b3 100644 --- a/cli.mdx +++ b/cli.mdx @@ -121,6 +121,174 @@ recoup tasks status --run --json |------|----------|-------------| | `--run ` | Yes | Trigger.dev run ID | +## research + +Music industry research — streaming metrics, audience demographics, playlist placements, competitive analysis, and web intelligence. All data is provider-agnostic and accessed through your `RECOUP_API_KEY`. + +Every structured data command costs 5 credits. Web search costs 5 credits. Deep research costs 25 credits. + +### Search for an artist + +Find an artist in the music industry database. Returns an ID you can use with all other research commands. + +```bash +recoup research "Drake" +recoup research "Phoebe Bridgers" --json +``` + +### Artist profile and career + +```bash +recoup research profile +recoup research career +recoup research insights +recoup research profile --json +``` + +| Subcommand | Description | API endpoint | +|------------|-------------|-------------| +| `profile ` | Full artist profile — bio, genres, social URLs, label | [`GET /api/research/artist/{id}`](/api-reference/research/profile) | +| `career ` | Career timeline and key milestones | [`GET /api/research/artist/{id}/career`](/api-reference/research/career) | +| `insights ` | AI-generated observations and trends | [`GET /api/research/artist/{id}/noteworthy-insights`](/api-reference/research/insights) | + +### Streaming and social metrics + +Get platform-specific metrics over time. Supports 14 platforms. + +```bash +recoup research metrics --source spotify +recoup research metrics --source instagram +recoup research metrics --source tiktok +recoup research metrics --source youtube_channel +``` + +Valid `--source` values: `spotify`, `instagram`, `tiktok`, `twitter`, `facebook`, `youtube_channel`, `youtube_artist`, `soundcloud`, `deezer`, `twitch`, `line`, `melon`, `wikipedia`, `bandsintown`. + +See [`GET /api/research/artist/{id}/stat/{source}`](/api-reference/research/metrics). + +### Audience and geography + +```bash +recoup research audience +recoup research audience --platform tiktok +recoup research audience --platform youtube +recoup research cities +``` + +| Subcommand | Description | API endpoint | +|------------|-------------|-------------| +| `audience ` | Age, gender, country breakdown (Instagram default) | [`GET /api/research/artist/{id}/{platform}-audience-stats`](/api-reference/research/audience) | +| `cities ` | Top cities by listener concentration | [`GET /api/research/artist/{id}/where-people-listen`](/api-reference/research/cities) | + +### Competitive landscape + +```bash +recoup research similar +recoup research similar --audience high --genre high --limit 20 +``` + +Configuration options: `--audience`, `--genre`, `--mood`, `--musicality` (values: `high`, `medium`, `low`). + +See [`GET /api/research/artist/{id}/neighboring-artists`](/api-reference/research/similar). + +### Playlists + +```bash +recoup research playlists +recoup research playlists --platform applemusic +recoup research playlists --editorial +recoup research playlists --status past --since 2025-01-01 +recoup research playlists --sort followers --limit 50 +``` + +| Flag | Description | +|------|-------------| +| `--platform

` | `spotify` (default), `applemusic`, `deezer`, `amazon`, `youtube` | +| `--editorial` | Only editorial playlists | +| `--status ` | `current` (default) or `past` | +| `--since ` | Filter by date (YYYY-MM-DD) | +| `--sort ` | Sort results (e.g., `followers`) | +| `--limit ` | Max results | + +See [`GET /api/research/artist/{id}/{platform}/{status}/playlists`](/api-reference/research/playlists). + +### Discography + +```bash +recoup research albums +recoup research tracks +``` + +### Discover artists + +Find artists by criteria — country, genre, listener ranges, growth rate. + +```bash +recoup research discover --country US --spotify-listeners 100000 500000 +recoup research discover --genre 86 --sort weekly_diff.sp_monthly_listeners +recoup research discover --tiktok-followers 1000000 10000000 --spotify-listeners 0 100000 +``` + +| Flag | Description | +|------|-------------| +| `--country ` | ISO country code (US, BR, GB, etc.) | +| `--genre ` | Genre ID (use `recoup research genres` to list) | +| `--spotify-listeners ` | Monthly listener range | +| `--tiktok-followers ` | TikTok follower range | +| `--sort ` | Sort field (e.g., `weekly_diff.sp_monthly_listeners`) | + +See [`GET /api/research/artist/list/filter`](/api-reference/research/discover). + +### Reference data + +```bash +recoup research genres +recoup research festivals +``` + +### Web research + +Search the web for narrative context, press coverage, and cultural information that structured data doesn't cover. + +```bash +recoup research web "Drake brand partnerships sync licensing" +recoup research web "Phoebe Bridgers fan community psychographics" +``` + +See [`POST /api/research/web`](/api-reference/research/web). + +### Deep research report + +Comprehensive multi-source research that synthesizes information from across the web into a cited report. + +```bash +recoup research report "Drake" +recoup research report "Tell me everything about Phoebe Bridgers — bio, streaming metrics, fan base, competitive landscape, and revenue opportunities" +``` + +See [`POST /api/research/deep`](/api-reference/research/deep). + +### Workflow example: full artist research + +```bash +# 1. Find the artist +recoup research "Phoebe Bridgers" --json +# → { id: 241089, name: "Phoebe Bridgers", ... } + +# 2. Pull structured data (run in parallel) +recoup research metrics 241089 --source spotify --json +recoup research audience 241089 --json +recoup research cities 241089 --json +recoup research similar 241089 --audience high --genre high --json +recoup research playlists 241089 --editorial --json + +# 3. Add web context +recoup research web "Phoebe Bridgers biography career milestones" --json +recoup research web "Phoebe Bridgers fan community brand partnerships" --json +``` + +--- + ## content Content-creation pipeline commands. Generate AI-powered social videos for artists. diff --git a/docs.json b/docs.json index 9a686e2..be0ac7c 100644 --- a/docs.json +++ b/docs.json @@ -147,6 +147,27 @@ "api-reference/workspaces/create" ] }, + { + "group": "Research", + "pages": [ + "api-reference/research/search", + "api-reference/research/profile", + "api-reference/research/metrics", + "api-reference/research/audience", + "api-reference/research/cities", + "api-reference/research/similar", + "api-reference/research/playlists", + "api-reference/research/albums", + "api-reference/research/tracks", + "api-reference/research/career", + "api-reference/research/insights", + "api-reference/research/discover", + "api-reference/research/genres", + "api-reference/research/festivals", + "api-reference/research/web", + "api-reference/research/deep" + ] + }, { "group": "Spotify", "pages": [ From 32a041dba478f72afdf5938666b1a93ed96414f0 Mon Sep 17 00:00:00 2001 From: Sidney Swift <158200036+sidneyswift@users.noreply.github.com> Date: Fri, 27 Mar 2026 15:02:17 -0400 Subject: [PATCH 02/16] fix: remove credit mentions, clean up ID descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow the same pattern as other API endpoints — no credit costs in descriptions. Remove "music industry database" references. ID params just say "returned by the search endpoint" without exposing the underlying provider. Made-with: Cursor --- api-reference/openapi.json | 52 +++++++++++++++++++------------------- cli.mdx | 4 +-- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/api-reference/openapi.json b/api-reference/openapi.json index 4ab1575..d70ceca 100644 --- a/api-reference/openapi.json +++ b/api-reference/openapi.json @@ -4858,7 +4858,7 @@ }, "/api/research/search": { "get": { - "description": "Search the music industry database for artists by name. Returns matching artists with IDs you can use in all other research endpoints. Costs 5 credits per call.", + "description": "Search for artists by name. Returns matching results with IDs you can use in all other research endpoints.", "parameters": [ { "name": "q", @@ -4901,13 +4901,13 @@ }, "/api/research/artist/{id}": { "get": { - "description": "Get a full artist profile from the music industry database — bio, genres, social URLs, label, career stage, and basic metrics. Costs 5 credits.", + "description": "Get a full artist profile — bio, genres, social URLs, label, career stage, and basic metrics.", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Artist ID from the music industry database (returned by search).", + "description": "Artist ID (returned by the search endpoint).", "schema": { "type": "integer" } } ], @@ -4925,13 +4925,13 @@ }, "/api/research/artist/{id}/stat/{source}": { "get": { - "description": "Get platform-specific metrics for an artist over time — followers, listeners, views, engagement. Supports 14 platforms. Costs 5 credits.", + "description": "Get platform-specific metrics for an artist over time — followers, listeners, views, engagement. Supports 14 platforms.", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Artist ID from the music industry database.", + "description": "Artist ID (returned by the search endpoint).", "schema": { "type": "integer" } }, { @@ -4959,7 +4959,7 @@ }, "/api/research/artist/{id}/where-people-listen": { "get": { - "description": "Get the top cities where an artist's fans listen, ranked by listener concentration. Costs 5 credits.", + "description": "Get the top cities where an artist's fans listen, ranked by listener concentration.", "parameters": [ { "name": "id", @@ -4982,7 +4982,7 @@ }, "/api/research/artist/{id}/{platform}-audience-stats": { "get": { - "description": "Get audience demographics for an artist on a specific platform — age, gender, and country breakdown. Costs 5 credits.", + "description": "Get audience demographics for an artist on a specific platform — age, gender, and country breakdown.", "parameters": [ { "name": "id", @@ -5015,7 +5015,7 @@ }, "/api/research/artist/{id}/neighboring-artists": { "get": { - "description": "Find similar artists based on audience overlap, genre, mood, and musicality. Use for competitive analysis and collaboration discovery. Costs 5 credits.", + "description": "Find similar artists based on audience overlap, genre, mood, and musicality. Use for competitive analysis and collaboration discovery.", "parameters": [ { "name": "id", @@ -5044,7 +5044,7 @@ }, "/api/research/artist/{id}/{platform}/{status}/playlists": { "get": { - "description": "Get an artist's playlist placements — editorial, algorithmic, and indie playlists across platforms. Costs 5 credits.", + "description": "Get an artist's playlist placements — editorial, algorithmic, and indie playlists across platforms.", "parameters": [ { "name": "id", @@ -5100,7 +5100,7 @@ }, "/api/research/artist/{id}/albums": { "get": { - "description": "Get an artist's full discography — albums, EPs, and singles with release dates. Costs 5 credits.", + "description": "Get an artist's full discography — albums, EPs, and singles with release dates.", "parameters": [ { "name": "id", @@ -5123,7 +5123,7 @@ }, "/api/research/artist/{id}/tracks": { "get": { - "description": "Get all tracks by an artist with popularity data. Costs 5 credits.", + "description": "Get all tracks by an artist with popularity data.", "parameters": [ { "name": "id", @@ -5146,7 +5146,7 @@ }, "/api/research/artist/{id}/career": { "get": { - "description": "Get an artist's career timeline — key milestones, trajectory, and career stage. Costs 5 credits.", + "description": "Get an artist's career timeline — key milestones, trajectory, and career stage.", "parameters": [ { "name": "id", @@ -5169,7 +5169,7 @@ }, "/api/research/artist/{id}/noteworthy-insights": { "get": { - "description": "Get AI-generated insights about an artist — automatically surfaced trends, milestones, and observations. Costs 5 credits.", + "description": "Get AI-generated insights about an artist — automatically surfaced trends, milestones, and observations.", "parameters": [ { "name": "id", @@ -5192,7 +5192,7 @@ }, "/api/research/artist/list/filter": { "get": { - "description": "Discover artists by criteria — filter by country, genre, listener count, follower count, growth rate, and more. Costs 5 credits.", + "description": "Discover artists by criteria — filter by country, genre, listener count, follower count, growth rate, and more.", "parameters": [ { "name": "country", @@ -5248,7 +5248,7 @@ }, "/api/research/genre": { "get": { - "description": "List all available genre IDs and names. Use these IDs with the discover endpoint. Costs 5 credits.", + "description": "List all available genre IDs and names. Use these IDs with the discover endpoint.", "responses": { "200": { "description": "Genre list", @@ -5263,7 +5263,7 @@ }, "/api/research/festival/list": { "get": { - "description": "List music festivals. Costs 5 credits.", + "description": "List music festivals.", "responses": { "200": { "description": "Festival list", @@ -5278,7 +5278,7 @@ }, "/api/research/web": { "post": { - "description": "Search the web for real-time information. Returns ranked results with titles, URLs, and content snippets. Use for narrative context, press coverage, and cultural research that structured data endpoints don't cover. Costs 5 credits.", + "description": "Search the web for real-time information. Returns ranked results with titles, URLs, and content snippets. Use for narrative context, press coverage, and cultural research that structured data endpoints don't cover.", "requestBody": { "required": true, "content": { @@ -5301,7 +5301,7 @@ }, "/api/research/deep": { "post": { - "description": "Perform deep, comprehensive research on a topic. Browses multiple sources extensively and returns a cited report. Use for full artist deep dives, competitive analysis, and any research requiring synthesis across many sources. Costs 25 credits.", + "description": "Perform deep, comprehensive research on a topic. Browses multiple sources extensively and returns a cited report. Use for full artist deep dives, competitive analysis, and any research requiring synthesis across many sources.", "requestBody": { "required": true, "content": { @@ -11736,11 +11736,10 @@ } } } - } - }, - "ResearchSearchResponse": { + }, + "ResearchSearchResponse": { "type": "object", - "description": "Response from searching the music industry database for artists, tracks, or other entities.", + "description": "Search results for artists, tracks, or other entities.", "properties": { "status": { "type": "string", @@ -11748,7 +11747,7 @@ }, "results": { "type": "array", - "description": "Array of matching entities with IDs, names, images, and basic metadata. Use the returned ID for subsequent research commands.", + "description": "Matching results with IDs, names, images, and basic metadata. Use the returned ID for all other research endpoints.", "items": { "type": "object" } @@ -11757,7 +11756,7 @@ }, "ResearchProxyResponse": { "type": "object", - "description": "Proxied response from the music industry data provider. The shape depends on the specific endpoint called. All responses are JSON.", + "description": "Response shape depends on the specific endpoint called. All responses are JSON.", "properties": {} }, "ResearchWebRequest": { @@ -11842,8 +11841,9 @@ } } } - }, - "securitySchemes": { + } + }, + "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" diff --git a/cli.mdx b/cli.mdx index e82d7b3..a702806 100644 --- a/cli.mdx +++ b/cli.mdx @@ -123,9 +123,7 @@ recoup tasks status --run --json ## research -Music industry research — streaming metrics, audience demographics, playlist placements, competitive analysis, and web intelligence. All data is provider-agnostic and accessed through your `RECOUP_API_KEY`. - -Every structured data command costs 5 credits. Web search costs 5 credits. Deep research costs 25 credits. +Music industry research — streaming metrics, audience demographics, playlist placements, competitive analysis, and web intelligence. All data is accessed through your `RECOUP_API_KEY`. ### Search for an artist From b5f810a7179bfd4f15eaa614ff894a5bf5c71765 Mon Sep 17 00:00:00 2001 From: Sidney Swift <158200036+sidneyswift@users.noreply.github.com> Date: Fri, 27 Mar 2026 15:22:44 -0400 Subject: [PATCH 03/16] =?UTF-8?q?fix:=20name-based=20lookups=20=E2=80=94?= =?UTF-8?q?=20no=20IDs=20exposed=20to=20users?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All research endpoints now accept an artist name, Recoup artist ID (UUID), or numeric ID. The API resolves the artist internally. Users never need to know about underlying provider IDs. CLI docs updated to show name-based examples throughout. Made-with: Cursor --- api-reference/openapi.json | 475 ++++++++++++++++++++++++++++--------- cli.mdx | 81 ++++--- 2 files changed, 409 insertions(+), 147 deletions(-) diff --git a/api-reference/openapi.json b/api-reference/openapi.json index d70ceca..85052bb 100644 --- a/api-reference/openapi.json +++ b/api-reference/openapi.json @@ -2369,7 +2369,7 @@ }, "/api/sandboxes/files": { "post": { - "description": "Upload one or more files to the authenticated account's sandbox GitHub repository. Accepts an array of file URLs and commits each file to the specified directory path within the repository. Supports submodule resolution — if the target path falls within a git submodule, the file is committed to the submodule's repository. Authentication is handled via the x-api-key header or Authorization Bearer token.", + "description": "Upload one or more files to the authenticated account's sandbox GitHub repository. Accepts an array of file URLs and commits each file to the specified directory path within the repository. Supports submodule resolution \u2014 if the target path falls within a git submodule, the file is committed to the submodule's repository. Authentication is handled via the x-api-key header or Authorization Bearer token.", "requestBody": { "description": "JSON body containing file URLs and target path", "required": true, @@ -4240,14 +4240,23 @@ "required": false, "schema": { "type": "string", - "enum": ["all", "daily", "weekly", "monthly"], + "enum": [ + "all", + "daily", + "weekly", + "monthly" + ], "default": "all" } } ], "security": [ - { "apiKeyAuth": [] }, - { "bearerAuth": [] } + { + "apiKeyAuth": [] + }, + { + "bearerAuth": [] + } ], "responses": { "200": { @@ -4256,11 +4265,19 @@ "application/json": { "schema": { "type": "object", - "required": ["status", "total", "total_pull_requests", "tags_with_pull_requests", "tags"], + "required": [ + "status", + "total", + "total_pull_requests", + "tags_with_pull_requests", + "tags" + ], "properties": { "status": { "type": "string", - "enum": ["success"], + "enum": [ + "success" + ], "description": "Status of the request" }, "total": { @@ -4283,7 +4300,14 @@ "description": "List of Slack tag events", "items": { "type": "object", - "required": ["user_id", "user_name", "prompt", "timestamp", "channel_id", "channel_name"], + "required": [ + "user_id", + "user_name", + "prompt", + "timestamp", + "channel_id", + "channel_name" + ], "properties": { "user_id": { "type": "string", @@ -4296,7 +4320,10 @@ "example": "Jane Smith" }, "user_avatar": { - "type": ["string", "null"], + "type": [ + "string", + "null" + ], "description": "URL of the Slack avatar", "example": "https://avatars.slack-edge.com/..." }, @@ -4329,7 +4356,9 @@ "format": "uri", "example": "https://github.com/recoupable/api/pull/42" }, - "example": ["https://github.com/recoupable/api/pull/42"] + "example": [ + "https://github.com/recoupable/api/pull/42" + ] } } } @@ -4343,7 +4372,9 @@ "description": "Unauthorized - missing or invalid credentials", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } }, @@ -4351,7 +4382,9 @@ "description": "Forbidden - authenticated account is not a Recoup admin", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } }, @@ -4359,7 +4392,9 @@ "description": "Internal server error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } } @@ -4377,14 +4412,23 @@ "required": false, "schema": { "type": "string", - "enum": ["all", "daily", "weekly", "monthly"], + "enum": [ + "all", + "daily", + "weekly", + "monthly" + ], "default": "all" } } ], "security": [ - { "apiKeyAuth": [] }, - { "bearerAuth": [] } + { + "apiKeyAuth": [] + }, + { + "bearerAuth": [] + } ], "responses": { "200": { @@ -4393,11 +4437,19 @@ "application/json": { "schema": { "type": "object", - "required": ["status", "total", "total_videos", "tags_with_videos", "tags"], + "required": [ + "status", + "total", + "total_videos", + "tags_with_videos", + "tags" + ], "properties": { "status": { "type": "string", - "enum": ["success"], + "enum": [ + "success" + ], "description": "Status of the request" }, "total": { @@ -4420,7 +4472,14 @@ "description": "List of Slack tag events", "items": { "type": "object", - "required": ["user_id", "user_name", "prompt", "timestamp", "channel_id", "channel_name"], + "required": [ + "user_id", + "user_name", + "prompt", + "timestamp", + "channel_id", + "channel_name" + ], "properties": { "user_id": { "type": "string", @@ -4433,7 +4492,10 @@ "example": "Jane Smith" }, "user_avatar": { - "type": ["string", "null"], + "type": [ + "string", + "null" + ], "description": "URL of the Slack avatar", "example": "https://avatars.slack-edge.com/..." }, @@ -4466,7 +4528,9 @@ "format": "uri", "example": "https://recoupable.com/v/abc123" }, - "example": ["https://recoupable.com/v/abc123"] + "example": [ + "https://recoupable.com/v/abc123" + ] } } } @@ -4480,7 +4544,9 @@ "description": "Unauthorized - missing or invalid credentials", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } }, @@ -4488,7 +4554,9 @@ "description": "Forbidden - authenticated account is not a Recoup admin", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } }, @@ -4496,7 +4564,9 @@ "description": "Internal server error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } } @@ -4526,8 +4596,12 @@ } ], "security": [ - { "apiKeyAuth": [] }, - { "bearerAuth": [] } + { + "apiKeyAuth": [] + }, + { + "bearerAuth": [] + } ], "responses": { "200": { @@ -4536,11 +4610,16 @@ "application/json": { "schema": { "type": "object", - "required": ["status", "pull_requests"], + "required": [ + "status", + "pull_requests" + ], "properties": { "status": { "type": "string", - "enum": ["success"], + "enum": [ + "success" + ], "description": "Status of the request" }, "pull_requests": { @@ -4548,7 +4627,10 @@ "description": "Status for each provided pull request URL", "items": { "type": "object", - "required": ["url", "status"], + "required": [ + "url", + "status" + ], "properties": { "url": { "type": "string", @@ -4558,7 +4640,11 @@ }, "status": { "type": "string", - "enum": ["open", "closed", "merged"], + "enum": [ + "open", + "closed", + "merged" + ], "description": "The current status of the pull request", "example": "merged" } @@ -4574,7 +4660,9 @@ "description": "Bad request - missing or invalid pull_requests parameter", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } }, @@ -4582,7 +4670,9 @@ "description": "Unauthorized - missing or invalid credentials", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } }, @@ -4590,7 +4680,9 @@ "description": "Forbidden - authenticated account is not a Recoup admin", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } }, @@ -4598,7 +4690,9 @@ "description": "Internal server error", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/AccountErrorResponse" } + "schema": { + "$ref": "#/components/schemas/AccountErrorResponse" + } } } } @@ -4727,7 +4821,9 @@ "required": true, "schema": { "type": "string", - "enum": ["slack"] + "enum": [ + "slack" + ] } } ], @@ -4738,7 +4834,7 @@ "application/json": { "schema": { "type": "object", - "description": "Slack Events API envelope — the shape depends on the event type" + "description": "Slack Events API envelope \u2014 the shape depends on the event type" } } } @@ -4767,7 +4863,7 @@ }, "/api/content-agent/callback": { "post": { - "description": "Internal callback endpoint for the `poll-content-run` Trigger.dev task. Receives content generation results and posts them back to the originating Slack thread. Authenticated via the `x-callback-secret` header.\n\nThis endpoint is not intended for external use — it is called automatically by the polling task when content runs complete, fail, or time out.", + "description": "Internal callback endpoint for the `poll-content-run` Trigger.dev task. Receives content generation results and posts them back to the originating Slack thread. Authenticated via the `x-callback-secret` header.\n\nThis endpoint is not intended for external use \u2014 it is called automatically by the polling task when content runs complete, fail, or time out.", "requestBody": { "description": "Content generation results from the polling task", "required": true, @@ -4775,7 +4871,10 @@ "application/json": { "schema": { "type": "object", - "required": ["threadId", "status"], + "required": [ + "threadId", + "status" + ], "properties": { "threadId": { "type": "string", @@ -4783,7 +4882,11 @@ }, "status": { "type": "string", - "enum": ["completed", "failed", "timeout"], + "enum": [ + "completed", + "failed", + "timeout" + ], "description": "Overall status of the content generation batch" }, "results": { @@ -4791,7 +4894,10 @@ "description": "Per-run results", "items": { "type": "object", - "required": ["runId", "status"], + "required": [ + "runId", + "status" + ], "properties": { "runId": { "type": "string", @@ -4799,7 +4905,11 @@ }, "status": { "type": "string", - "enum": ["completed", "failed", "timeout"] + "enum": [ + "completed", + "failed", + "timeout" + ] }, "videoUrl": { "type": "string", @@ -4858,14 +4968,16 @@ }, "/api/research/search": { "get": { - "description": "Search for artists by name. Returns matching results with IDs you can use in all other research endpoints.", + "description": "Search for artists by name. Returns matching results with profile summaries.", "parameters": [ { "name": "q", "in": "query", "required": true, "description": "Artist name to search for.", - "schema": { "type": "string" } + "schema": { + "type": "string" + } }, { "name": "type", @@ -4874,7 +4986,14 @@ "description": "Entity type to search for.", "schema": { "type": "string", - "enum": ["artists", "tracks", "albums", "playlists", "curators", "stations"], + "enum": [ + "artists", + "tracks", + "albums", + "playlists", + "curators", + "stations" + ], "default": "artists" } }, @@ -4883,7 +5002,10 @@ "in": "query", "required": false, "description": "Maximum number of results.", - "schema": { "type": "integer", "default": 10 } + "schema": { + "type": "integer", + "default": 10 + } } ], "responses": { @@ -4891,24 +5013,30 @@ "description": "Search results", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchSearchResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchSearchResponse" + } } } }, - "402": { "description": "Insufficient credits" } + "402": { + "description": "Insufficient credits" + } } } }, "/api/research/artist/{id}": { "get": { - "description": "Get a full artist profile — bio, genres, social URLs, label, career stage, and basic metrics.", + "description": "Get a full artist profile \u2014 bio, genres, social URLs, label, career stage, and basic metrics.", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Artist ID (returned by the search endpoint).", - "schema": { "type": "integer" } + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search.", + "schema": { + "type": "string" + } } ], "responses": { @@ -4916,7 +5044,9 @@ "description": "Artist profile", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -4925,14 +5055,16 @@ }, "/api/research/artist/{id}/stat/{source}": { "get": { - "description": "Get platform-specific metrics for an artist over time — followers, listeners, views, engagement. Supports 14 platforms.", + "description": "Get platform-specific metrics for an artist over time \u2014 followers, listeners, views, engagement. Supports 14 platforms.", "parameters": [ { "name": "id", "in": "path", "required": true, - "description": "Artist ID (returned by the search endpoint).", - "schema": { "type": "integer" } + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search.", + "schema": { + "type": "string" + } }, { "name": "source", @@ -4941,7 +5073,22 @@ "description": "Platform to get metrics for.", "schema": { "type": "string", - "enum": ["spotify", "instagram", "tiktok", "twitter", "facebook", "youtube_channel", "youtube_artist", "soundcloud", "deezer", "twitch", "line", "melon", "wikipedia", "bandsintown"] + "enum": [ + "spotify", + "instagram", + "tiktok", + "twitter", + "facebook", + "youtube_channel", + "youtube_artist", + "soundcloud", + "deezer", + "twitch", + "line", + "melon", + "wikipedia", + "bandsintown" + ] } } ], @@ -4950,7 +5097,9 @@ "description": "Platform metrics over time", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -4965,7 +5114,10 @@ "name": "id", "in": "path", "required": true, - "schema": { "type": "integer" } + "schema": { + "type": "string" + }, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search." } ], "responses": { @@ -4973,7 +5125,9 @@ "description": "Top listener cities", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -4982,13 +5136,16 @@ }, "/api/research/artist/{id}/{platform}-audience-stats": { "get": { - "description": "Get audience demographics for an artist on a specific platform — age, gender, and country breakdown.", + "description": "Get audience demographics for an artist on a specific platform \u2014 age, gender, and country breakdown.", "parameters": [ { "name": "id", "in": "path", "required": true, - "schema": { "type": "integer" } + "schema": { + "type": "string" + }, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search." }, { "name": "platform", @@ -4997,7 +5154,11 @@ "description": "Platform to get audience demographics for.", "schema": { "type": "string", - "enum": ["instagram", "tiktok", "youtube"] + "enum": [ + "instagram", + "tiktok", + "youtube" + ] } } ], @@ -5006,7 +5167,9 @@ "description": "Audience demographics", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5021,13 +5184,19 @@ "name": "id", "in": "path", "required": true, - "schema": { "type": "integer" } + "schema": { + "type": "string" + }, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search." }, { "name": "limit", "in": "query", "required": false, - "schema": { "type": "integer", "default": 10 } + "schema": { + "type": "integer", + "default": 10 + } } ], "responses": { @@ -5035,7 +5204,9 @@ "description": "Similar artists with overlap scores", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5044,13 +5215,16 @@ }, "/api/research/artist/{id}/{platform}/{status}/playlists": { "get": { - "description": "Get an artist's playlist placements — editorial, algorithmic, and indie playlists across platforms.", + "description": "Get an artist's playlist placements \u2014 editorial, algorithmic, and indie playlists across platforms.", "parameters": [ { "name": "id", "in": "path", "required": true, - "schema": { "type": "integer" } + "schema": { + "type": "string" + }, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search." }, { "name": "platform", @@ -5058,7 +5232,13 @@ "required": true, "schema": { "type": "string", - "enum": ["spotify", "applemusic", "deezer", "amazon", "youtube"], + "enum": [ + "spotify", + "applemusic", + "deezer", + "amazon", + "youtube" + ], "default": "spotify" } }, @@ -5068,7 +5248,10 @@ "required": true, "schema": { "type": "string", - "enum": ["current", "past"], + "enum": [ + "current", + "past" + ], "default": "current" } }, @@ -5076,14 +5259,19 @@ "name": "limit", "in": "query", "required": false, - "schema": { "type": "integer", "default": 20 } + "schema": { + "type": "integer", + "default": 20 + } }, { "name": "sort", "in": "query", "required": false, "description": "Sort results by this field.", - "schema": { "type": "string" } + "schema": { + "type": "string" + } } ], "responses": { @@ -5091,7 +5279,9 @@ "description": "Playlist placements", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5100,13 +5290,16 @@ }, "/api/research/artist/{id}/albums": { "get": { - "description": "Get an artist's full discography — albums, EPs, and singles with release dates.", + "description": "Get an artist's full discography \u2014 albums, EPs, and singles with release dates.", "parameters": [ { "name": "id", "in": "path", "required": true, - "schema": { "type": "integer" } + "schema": { + "type": "string" + }, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search." } ], "responses": { @@ -5114,7 +5307,9 @@ "description": "Artist albums", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5129,7 +5324,10 @@ "name": "id", "in": "path", "required": true, - "schema": { "type": "integer" } + "schema": { + "type": "string" + }, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search." } ], "responses": { @@ -5137,7 +5335,9 @@ "description": "Artist tracks", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5146,13 +5346,16 @@ }, "/api/research/artist/{id}/career": { "get": { - "description": "Get an artist's career timeline — key milestones, trajectory, and career stage.", + "description": "Get an artist's career timeline \u2014 key milestones, trajectory, and career stage.", "parameters": [ { "name": "id", "in": "path", "required": true, - "schema": { "type": "integer" } + "schema": { + "type": "string" + }, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search." } ], "responses": { @@ -5160,7 +5363,9 @@ "description": "Career timeline", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5169,13 +5374,16 @@ }, "/api/research/artist/{id}/noteworthy-insights": { "get": { - "description": "Get AI-generated insights about an artist — automatically surfaced trends, milestones, and observations.", + "description": "Get AI-generated insights about an artist \u2014 automatically surfaced trends, milestones, and observations.", "parameters": [ { "name": "id", "in": "path", "required": true, - "schema": { "type": "integer" } + "schema": { + "type": "string" + }, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search." } ], "responses": { @@ -5183,7 +5391,9 @@ "description": "AI-generated insights", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5192,46 +5402,59 @@ }, "/api/research/artist/list/filter": { "get": { - "description": "Discover artists by criteria — filter by country, genre, listener count, follower count, growth rate, and more.", + "description": "Discover artists by criteria \u2014 filter by country, genre, listener count, follower count, growth rate, and more.", "parameters": [ { "name": "country", "in": "query", "required": false, "description": "ISO country code (e.g., US, BR, GB).", - "schema": { "type": "string" } + "schema": { + "type": "string" + } }, { "name": "genre", "in": "query", "required": false, "description": "Genre ID (use GET /api/research/genre to list).", - "schema": { "type": "integer" } + "schema": { + "type": "integer" + } }, { "name": "sp_monthly_listeners_min", "in": "query", "required": false, - "schema": { "type": "integer" } + "schema": { + "type": "integer" + } }, { "name": "sp_monthly_listeners_max", "in": "query", "required": false, - "schema": { "type": "integer" } + "schema": { + "type": "integer" + } }, { "name": "sort", "in": "query", "required": false, "description": "Sort field (e.g., weekly_diff.sp_monthly_listeners).", - "schema": { "type": "string" } + "schema": { + "type": "string" + } }, { "name": "limit", "in": "query", "required": false, - "schema": { "type": "integer", "default": 20 } + "schema": { + "type": "integer", + "default": 20 + } } ], "responses": { @@ -5239,7 +5462,9 @@ "description": "Filtered artist list", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5254,7 +5479,9 @@ "description": "Genre list", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5269,7 +5496,9 @@ "description": "Festival list", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchProxyResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } } } } @@ -5283,7 +5512,9 @@ "required": true, "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchWebRequest" } + "schema": { + "$ref": "#/components/schemas/ResearchWebRequest" + } } } }, @@ -5292,7 +5523,9 @@ "description": "Web search results", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchWebResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchWebResponse" + } } } } @@ -5306,7 +5539,9 @@ "required": true, "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchDeepRequest" } + "schema": { + "$ref": "#/components/schemas/ResearchDeepRequest" + } } } }, @@ -5315,7 +5550,9 @@ "description": "Deep research report with citations", "content": { "application/json": { - "schema": { "$ref": "#/components/schemas/ResearchDeepResponse" } + "schema": { + "$ref": "#/components/schemas/ResearchDeepResponse" + } } } } @@ -10215,7 +10452,10 @@ "type": "array", "items": { "type": "object", - "required": ["url", "name"], + "required": [ + "url", + "name" + ], "properties": { "url": { "type": "string", @@ -11743,7 +11983,10 @@ "properties": { "status": { "type": "string", - "enum": ["success", "error"] + "enum": [ + "success", + "error" + ] }, "results": { "type": "array", @@ -11761,12 +12004,14 @@ }, "ResearchWebRequest": { "type": "object", - "required": ["query"], + "required": [ + "query" + ], "description": "Request body for web research.", "properties": { "query": { "type": "string", - "description": "The search query — what you want to find on the web." + "description": "The search query \u2014 what you want to find on the web." }, "max_results": { "type": "integer", @@ -11789,7 +12034,10 @@ "properties": { "status": { "type": "string", - "enum": ["success", "error"] + "enum": [ + "success", + "error" + ] }, "results": { "type": "array", @@ -11797,9 +12045,15 @@ "items": { "type": "object", "properties": { - "title": { "type": "string" }, - "url": { "type": "string" }, - "content": { "type": "string" } + "title": { + "type": "string" + }, + "url": { + "type": "string" + }, + "content": { + "type": "string" + } } } }, @@ -11811,12 +12065,14 @@ }, "ResearchDeepRequest": { "type": "object", - "required": ["query"], + "required": [ + "query" + ], "description": "Request body for deep research. Performs comprehensive multi-source analysis.", "properties": { "query": { "type": "string", - "description": "The research question — be specific and detailed for best results." + "description": "The research question \u2014 be specific and detailed for best results." } } }, @@ -11826,7 +12082,10 @@ "properties": { "status": { "type": "string", - "enum": ["success", "error"] + "enum": [ + "success", + "error" + ] }, "content": { "type": "string", @@ -11856,4 +12115,4 @@ } } } -} +} \ No newline at end of file diff --git a/cli.mdx b/cli.mdx index a702806..8374abb 100644 --- a/cli.mdx +++ b/cli.mdx @@ -125,9 +125,9 @@ recoup tasks status --run --json Music industry research — streaming metrics, audience demographics, playlist placements, competitive analysis, and web intelligence. All data is accessed through your `RECOUP_API_KEY`. -### Search for an artist +Every research command accepts an **artist name** or a **Recoup artist ID** (UUID). The API resolves the artist automatically. If the name is ambiguous (multiple matches), the API returns the top results for disambiguation. -Find an artist in the music industry database. Returns an ID you can use with all other research commands. +### Search for an artist ```bash recoup research "Drake" @@ -137,27 +137,26 @@ recoup research "Phoebe Bridgers" --json ### Artist profile and career ```bash -recoup research profile -recoup research career -recoup research insights -recoup research profile --json +recoup research profile "Drake" +recoup research career "Drake" +recoup research insights "Drake" ``` | Subcommand | Description | API endpoint | |------------|-------------|-------------| -| `profile ` | Full artist profile — bio, genres, social URLs, label | [`GET /api/research/artist/{id}`](/api-reference/research/profile) | -| `career ` | Career timeline and key milestones | [`GET /api/research/artist/{id}/career`](/api-reference/research/career) | -| `insights ` | AI-generated observations and trends | [`GET /api/research/artist/{id}/noteworthy-insights`](/api-reference/research/insights) | +| `profile` | Full artist profile — bio, genres, social URLs, label | [`GET /api/research/artist/{id}`](/api-reference/research/profile) | +| `career` | Career timeline and key milestones | [`GET /api/research/artist/{id}/career`](/api-reference/research/career) | +| `insights` | AI-generated observations and trends | [`GET /api/research/artist/{id}/noteworthy-insights`](/api-reference/research/insights) | ### Streaming and social metrics Get platform-specific metrics over time. Supports 14 platforms. ```bash -recoup research metrics --source spotify -recoup research metrics --source instagram -recoup research metrics --source tiktok -recoup research metrics --source youtube_channel +recoup research metrics "Drake" --source spotify +recoup research metrics "Drake" --source instagram +recoup research metrics "Drake" --source tiktok +recoup research metrics "Drake" --source youtube_channel ``` Valid `--source` values: `spotify`, `instagram`, `tiktok`, `twitter`, `facebook`, `youtube_channel`, `youtube_artist`, `soundcloud`, `deezer`, `twitch`, `line`, `melon`, `wikipedia`, `bandsintown`. @@ -167,22 +166,22 @@ See [`GET /api/research/artist/{id}/stat/{source}`](/api-reference/research/metr ### Audience and geography ```bash -recoup research audience -recoup research audience --platform tiktok -recoup research audience --platform youtube -recoup research cities +recoup research audience "Drake" +recoup research audience "Drake" --platform tiktok +recoup research audience "Drake" --platform youtube +recoup research cities "Drake" ``` | Subcommand | Description | API endpoint | |------------|-------------|-------------| -| `audience ` | Age, gender, country breakdown (Instagram default) | [`GET /api/research/artist/{id}/{platform}-audience-stats`](/api-reference/research/audience) | -| `cities ` | Top cities by listener concentration | [`GET /api/research/artist/{id}/where-people-listen`](/api-reference/research/cities) | +| `audience` | Age, gender, country breakdown (Instagram default) | [`GET /api/research/artist/{id}/{platform}-audience-stats`](/api-reference/research/audience) | +| `cities` | Top cities by listener concentration | [`GET /api/research/artist/{id}/where-people-listen`](/api-reference/research/cities) | ### Competitive landscape ```bash -recoup research similar -recoup research similar --audience high --genre high --limit 20 +recoup research similar "Drake" +recoup research similar "Drake" --audience high --genre high --limit 20 ``` Configuration options: `--audience`, `--genre`, `--mood`, `--musicality` (values: `high`, `medium`, `low`). @@ -192,11 +191,11 @@ See [`GET /api/research/artist/{id}/neighboring-artists`](/api-reference/researc ### Playlists ```bash -recoup research playlists -recoup research playlists --platform applemusic -recoup research playlists --editorial -recoup research playlists --status past --since 2025-01-01 -recoup research playlists --sort followers --limit 50 +recoup research playlists "Drake" +recoup research playlists "Drake" --platform applemusic +recoup research playlists "Drake" --editorial +recoup research playlists "Drake" --status past --since 2025-01-01 +recoup research playlists "Drake" --sort followers --limit 50 ``` | Flag | Description | @@ -213,8 +212,8 @@ See [`GET /api/research/artist/{id}/{platform}/{status}/playlists`](/api-referen ### Discography ```bash -recoup research albums -recoup research tracks +recoup research albums "Drake" +recoup research tracks "Drake" ``` ### Discover artists @@ -266,21 +265,25 @@ recoup research report "Tell me everything about Phoebe Bridgers — bio, stream See [`POST /api/research/deep`](/api-reference/research/deep). -### Workflow example: full artist research +### Using Recoup artist IDs + +If the artist is already on your Recoup roster, you can pass their Recoup artist ID (UUID) instead of a name. The API resolves it automatically. ```bash -# 1. Find the artist -recoup research "Phoebe Bridgers" --json -# → { id: 241089, name: "Phoebe Bridgers", ... } +recoup research metrics de05ba8c-7e29-4f1a-93a7-3635653599f6 --source spotify +``` -# 2. Pull structured data (run in parallel) -recoup research metrics 241089 --source spotify --json -recoup research audience 241089 --json -recoup research cities 241089 --json -recoup research similar 241089 --audience high --genre high --json -recoup research playlists 241089 --editorial --json +### Workflow example: full artist research -# 3. Add web context +```bash +# Pull structured data (all by name, run in parallel) +recoup research metrics "Phoebe Bridgers" --source spotify --json +recoup research audience "Phoebe Bridgers" --json +recoup research cities "Phoebe Bridgers" --json +recoup research similar "Phoebe Bridgers" --audience high --genre high --json +recoup research playlists "Phoebe Bridgers" --editorial --json + +# Add web context recoup research web "Phoebe Bridgers biography career milestones" --json recoup research web "Phoebe Bridgers fan community brand partnerships" --json ``` From 2fc73953f4ba72eebeba355547673819a83ccdcf Mon Sep 17 00:00:00 2001 From: Sidney Swift <158200036+sidneyswift@users.noreply.github.com> Date: Fri, 27 Mar 2026 15:36:18 -0400 Subject: [PATCH 04/16] feat: add 6 missing research endpoints from chartmetric skill MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lookup by URL, Social URLs, Instagram Posts, Track details, Playlist details, Curator details. Now at full parity with every script in the chartmetric skill — 22 endpoints total. Made-with: Cursor --- api-reference/openapi.json | 198 +++++++++++++++++++++ api-reference/research/curator.mdx | 4 + api-reference/research/instagram-posts.mdx | 4 + api-reference/research/lookup.mdx | 4 + api-reference/research/playlist.mdx | 4 + api-reference/research/track.mdx | 4 + api-reference/research/urls.mdx | 4 + cli.mdx | 53 ++++++ docs.json | 6 + 9 files changed, 281 insertions(+) create mode 100644 api-reference/research/curator.mdx create mode 100644 api-reference/research/instagram-posts.mdx create mode 100644 api-reference/research/lookup.mdx create mode 100644 api-reference/research/playlist.mdx create mode 100644 api-reference/research/track.mdx create mode 100644 api-reference/research/urls.mdx diff --git a/api-reference/openapi.json b/api-reference/openapi.json index 85052bb..3cc6a58 100644 --- a/api-reference/openapi.json +++ b/api-reference/openapi.json @@ -5558,6 +5558,204 @@ } } } + }, + "/api/research/artist/{id}/urls": { + "get": { + "description": "Get all social and streaming URLs for an artist \u2014 Spotify, Instagram, TikTok, YouTube, Twitter, SoundCloud, and more.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Social and streaming URLs", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } + } + } + } + } + } + }, + "/api/research/artist/{id}/instagram-posts": { + "get": { + "description": "Get an artist's top Instagram posts and reels \u2014 sorted by engagement.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Artist name, Recoup artist ID (UUID), or numeric ID from a previous search.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Top Instagram posts and reels", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } + } + } + } + } + } + }, + "/api/research/lookup": { + "get": { + "description": "Look up an artist by a platform URL or ID \u2014 Spotify URL, Spotify ID, Apple Music URL, etc. Returns the artist profile.", + "parameters": [ + { + "name": "url", + "in": "query", + "required": true, + "description": "Platform URL or ID (e.g., Spotify artist URL, Spotify ID).", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Artist profile matching the platform URL", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } + } + } + } + } + } + }, + "/api/research/track/{id}": { + "get": { + "description": "Get track metadata \u2014 title, artist, album, release date, popularity, and platform IDs.", + "parameters": [ + { + "name": "id", + "in": "path", + "required": true, + "description": "Track name, Spotify URL, or numeric ID from a previous search.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Track metadata", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } + } + } + } + } + } + }, + "/api/research/playlist/{platform}/{id}": { + "get": { + "description": "Get playlist metadata \u2014 name, description, follower count, track count, and curator info.", + "parameters": [ + { + "name": "platform", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": [ + "spotify", + "applemusic", + "deezer", + "amazon", + "youtube" + ] + } + }, + { + "name": "id", + "in": "path", + "required": true, + "description": "Playlist ID on the platform.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Playlist metadata", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } + } + } + } + } + } + }, + "/api/research/curator/{platform}/{id}": { + "get": { + "description": "Get curator profile \u2014 who curates a playlist, their other playlists, and follower reach.", + "parameters": [ + { + "name": "platform", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": [ + "spotify", + "applemusic", + "deezer", + "amazon", + "youtube" + ] + } + }, + { + "name": "id", + "in": "path", + "required": true, + "description": "Curator ID.", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Curator profile", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ResearchProxyResponse" + } + } + } + } + } + } } }, "components": { diff --git a/api-reference/research/curator.mdx b/api-reference/research/curator.mdx new file mode 100644 index 0000000..36c6368 --- /dev/null +++ b/api-reference/research/curator.mdx @@ -0,0 +1,4 @@ +--- +title: 'Curator' +openapi: 'GET /api/research/curator/{platform}/{id}' +--- diff --git a/api-reference/research/instagram-posts.mdx b/api-reference/research/instagram-posts.mdx new file mode 100644 index 0000000..e65e6ad --- /dev/null +++ b/api-reference/research/instagram-posts.mdx @@ -0,0 +1,4 @@ +--- +title: 'Instagram Posts' +openapi: 'GET /api/research/artist/{id}/instagram-posts' +--- diff --git a/api-reference/research/lookup.mdx b/api-reference/research/lookup.mdx new file mode 100644 index 0000000..bda5bc2 --- /dev/null +++ b/api-reference/research/lookup.mdx @@ -0,0 +1,4 @@ +--- +title: 'Lookup by URL' +openapi: 'GET /api/research/lookup' +--- diff --git a/api-reference/research/playlist.mdx b/api-reference/research/playlist.mdx new file mode 100644 index 0000000..8a10f59 --- /dev/null +++ b/api-reference/research/playlist.mdx @@ -0,0 +1,4 @@ +--- +title: 'Playlist' +openapi: 'GET /api/research/playlist/{platform}/{id}' +--- diff --git a/api-reference/research/track.mdx b/api-reference/research/track.mdx new file mode 100644 index 0000000..00adb39 --- /dev/null +++ b/api-reference/research/track.mdx @@ -0,0 +1,4 @@ +--- +title: 'Track' +openapi: 'GET /api/research/track/{id}' +--- diff --git a/api-reference/research/urls.mdx b/api-reference/research/urls.mdx new file mode 100644 index 0000000..9bf3856 --- /dev/null +++ b/api-reference/research/urls.mdx @@ -0,0 +1,4 @@ +--- +title: 'Social URLs' +openapi: 'GET /api/research/artist/{id}/urls' +--- diff --git a/cli.mdx b/cli.mdx index 8374abb..0bc961f 100644 --- a/cli.mdx +++ b/cli.mdx @@ -134,6 +134,17 @@ recoup research "Drake" recoup research "Phoebe Bridgers" --json ``` +### Lookup by platform URL + +Find an artist from a Spotify URL, Apple Music link, or any platform ID. + +```bash +recoup research lookup "https://open.spotify.com/artist/3TVXtAsR1Inumwj472S9r4" +recoup research lookup "3TVXtAsR1Inumwj472S9r4" +``` + +See [`GET /api/research/lookup`](/api-reference/research/lookup). + ### Artist profile and career ```bash @@ -177,6 +188,26 @@ recoup research cities "Drake" | `audience` | Age, gender, country breakdown (Instagram default) | [`GET /api/research/artist/{id}/{platform}-audience-stats`](/api-reference/research/audience) | | `cities` | Top cities by listener concentration | [`GET /api/research/artist/{id}/where-people-listen`](/api-reference/research/cities) | +### Social URLs + +Get all social and streaming links for an artist. + +```bash +recoup research urls "Drake" +``` + +See [`GET /api/research/artist/{id}/urls`](/api-reference/research/urls). + +### Instagram posts + +Get an artist's top Instagram posts and reels by engagement. + +```bash +recoup research instagram-posts "Drake" +``` + +See [`GET /api/research/artist/{id}/instagram-posts`](/api-reference/research/instagram-posts). + ### Competitive landscape ```bash @@ -216,6 +247,28 @@ recoup research albums "Drake" recoup research tracks "Drake" ``` +### Track details + +Get metadata for a specific track — look up by name or Spotify URL. + +```bash +recoup research track "God's Plan" +recoup research track "https://open.spotify.com/track/2grjqo0Frpf2..." +``` + +See [`GET /api/research/track/{id}`](/api-reference/research/track). + +### Playlist and curator details + +Get metadata for a specific playlist or its curator. + +```bash +recoup research playlist spotify 37i9dQZF1DXcBWIGoYBM5M +recoup research curator spotify 1 +``` + +See [`GET /api/research/playlist/{platform}/{id}`](/api-reference/research/playlist) and [`GET /api/research/curator/{platform}/{id}`](/api-reference/research/curator). + ### Discover artists Find artists by criteria — country, genre, listener ranges, growth rate. diff --git a/docs.json b/docs.json index be0ac7c..56ac591 100644 --- a/docs.json +++ b/docs.json @@ -151,16 +151,22 @@ "group": "Research", "pages": [ "api-reference/research/search", + "api-reference/research/lookup", "api-reference/research/profile", "api-reference/research/metrics", "api-reference/research/audience", "api-reference/research/cities", "api-reference/research/similar", + "api-reference/research/urls", + "api-reference/research/instagram-posts", "api-reference/research/playlists", "api-reference/research/albums", "api-reference/research/tracks", + "api-reference/research/track", "api-reference/research/career", "api-reference/research/insights", + "api-reference/research/playlist", + "api-reference/research/curator", "api-reference/research/discover", "api-reference/research/genres", "api-reference/research/festivals", From 479a38b83b722946e19c19b6a50f338e71f38efa Mon Sep 17 00:00:00 2001 From: Sidney Swift <158200036+sidneyswift@users.noreply.github.com> Date: Fri, 27 Mar 2026 15:39:21 -0400 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20add=20research=20templates=20?= =?UTF-8?q?=E2=80=94=20pre-built=20multi-step=20workflows?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 11 templates matching the chartmetric skill's advanced workflows: full-report, playlist-pitching, tiktok-pipeline, tour-routing, discovery, catalog-optimization, competitive-analysis, viral-autopsy, market-expansion, collaboration-finder, and release-timing. Two new endpoints: GET /api/research/templates (list them) and POST /api/research/run (execute one against an artist by name). CLI: recoup research templates + recoup research run