Recoup

Get started with Recoup.

API REFERENCE

Track Playlists

On this page
GET/api/research/track/playlists

Read available track playlist and activity entries. Supply a selected track id, or a track name q with optional artist. Name resolution selects the first Spotify match and resolves its research ID; id takes precedence. Filtering and pagination support depend on the data connection. With no filter flags, editorial, indie, majorCurator and popularIndie default to true. Track-name resolution can add separately charged lookup calls; reuse a selected ID to avoid them.

Use your Recoup API key (x-api-key) or supported bearer credential. Successful artist and track research reads cost $0.05 (50,000 micro-dollar credits). Recoup manages the data connections. Coverage and rate limits vary; see Research availability.

Authentication

See the authentication guide for API key and account access requirements.

Request

cURL
curl --request GET \
  --url 'https://api.recoupable.dev/api/research/track/playlists' \
  --header 'x-api-key: YOUR_API_KEY'

Replace the YOUR_ placeholders with your values. Required query parameters are included; optional parameters are listed below.

Try it

Fill in the fields, send the request from your browser, and read the live response. The curl below updates as you type.

Kept in this browser tab only and cleared when it closes.

cURL for this request
curl --request GET \
  --url 'https://recoup-api.vercel.app/api/research/track/playlists'

Parameters

Query parameters

idstring

Exact provider track ID; required unless q is supplied. Takes precedence over q. Recoup does not validate its format here.

qstring

Track name to look up. Required if id is not provided. Combine with artist to narrow the match.

artiststring

Optional artist name to narrow Spotify track-name matching. Ignored when id is supplied.

platformstring · enum

Streaming platform to return playlists for. Defaults to spotify.

Values: "spotify", "applemusic", "deezer", "amazon"

Default: "spotify"

statusstring · enum

Return current or past playlist placements. Defaults to current.

Values: "current", "past"

Default: "current"

limitstring

Maximum number of placements to return. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

offsetstring

Pagination offset. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

sincestring

ISO date lower bound for placements. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

untilstring

ISO date upper bound for placements. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

sortstring

Sort column. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

editorialstring

Include editorial playlists. When no filter flags are set, defaults to true along with indie, majorCurator, popularIndie. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

indiestring

Include indie playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

majorCuratorstring

Include major-curator playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

popularIndiestring

Include popular indie playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

personalizedstring

Include personalized playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

chartstring

Include chart playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

newMusicFridaystring

Include New Music Friday playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

thisIsstring

Include "This Is" artist playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

radiostring

Include algorithmic radio playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

brandstring

Include brand playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.

Responses

200Playlist placements for the track.

application/json

statusstring · enumrequired

Values: "success"

placementsarray<object>required

Playlist placement objects returned by the configured provider (shape varies per platform).

Item properties for placements

object

400Validation error — missing id/q, invalid platform, or invalid status.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

401Authentication failed — invalid or missing API key.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

402Insufficient research credits. The response includes a static billingUrl; no checkout session is created.

application/json

errorstring · enumrequired

Values: "insufficient_credits"

remaining_creditsintegerrequired
required_creditsintegerrequired
billingUrlstringrequired

Static link to the Recoup app, where a human can save a card and buy credits. It is a constant, not a freshly minted Stripe Checkout Session, so a credit-gated endpoint that keeps returning 402 creates nothing. To buy credits programmatically, call POST /api/credits/sessions.

403Credential, account or provider permission denied.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

404Artist/track resolution or requested provider data was not found. A failed name search may be reported as 404; retry with an exact provider ID when known.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

429Provider rate or quota limit. The adapter returns an error status but does not forward provider Retry-After headers. Avoid an unbounded retry loop.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

500Missing provider configuration, transport failure or internal error.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

501The configured research data source does not support this endpoint or data shape.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

501 example
{
  "status": "error",
  "error": "Request failed with status 501"
}

502Upstream provider failed.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

504the configured research data connection request timed out.

application/json

statusstring · enumrequired

Values: "error"

errorstringrequired

Human-readable error message describing what went wrong.

Full specification

Download the OpenAPI file for complete schemas, constraints, and examples.

Download research.json
View operation source
json
{
  "description": "Read available track playlist and activity entries. Supply a selected track `id`, or a track name `q` with optional `artist`. Name resolution selects the first Spotify match and resolves its research ID; `id` takes precedence. Filtering and pagination support depend on the data connection. With no filter flags, editorial, indie, majorCurator and popularIndie default to true. Track-name resolution can add separately charged lookup calls; reuse a selected ID to avoid them.\n\nUse your Recoup API key (`x-api-key`) or supported bearer credential. Successful artist and track research reads cost $0.05 (50,000 micro-dollar credits). Recoup manages the data connections. Coverage and rate limits vary; see [Research availability](/research-availability).",
  "parameters": [
    {
      "name": "id",
      "in": "query",
      "description": "Exact provider track ID; required unless q is supplied. Takes precedence over q. Recoup does not validate its format here.",
      "schema": {
        "type": "string",
        "example": "track_123"
      }
    },
    {
      "name": "q",
      "in": "query",
      "description": "Track name to look up. Required if `id` is not provided. Combine with `artist` to narrow the match.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "artist",
      "in": "query",
      "description": "Optional artist name to narrow Spotify track-name matching. Ignored when id is supplied.",
      "schema": {
        "type": "string"
      },
      "required": false
    },
    {
      "name": "platform",
      "in": "query",
      "description": "Streaming platform to return playlists for. Defaults to `spotify`.",
      "schema": {
        "type": "string",
        "enum": [
          "spotify",
          "applemusic",
          "deezer",
          "amazon"
        ],
        "default": "spotify"
      }
    },
    {
      "name": "status",
      "in": "query",
      "description": "Return current or past playlist placements. Defaults to `current`.",
      "schema": {
        "type": "string",
        "enum": [
          "current",
          "past"
        ],
        "default": "current"
      }
    },
    {
      "name": "limit",
      "in": "query",
      "description": "Maximum number of placements to return. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "offset",
      "in": "query",
      "description": "Pagination offset. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "since",
      "in": "query",
      "description": "ISO date lower bound for placements. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "until",
      "in": "query",
      "description": "ISO date upper bound for placements. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "sort",
      "in": "query",
      "description": "Sort column. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "editorial",
      "in": "query",
      "description": "Include editorial playlists. When no filter flags are set, defaults to `true` along with `indie`, `majorCurator`, `popularIndie`. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "indie",
      "in": "query",
      "description": "Include indie playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "majorCurator",
      "in": "query",
      "description": "Include major-curator playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "popularIndie",
      "in": "query",
      "description": "Include popular indie playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "personalized",
      "in": "query",
      "description": "Include personalized playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "chart",
      "in": "query",
      "description": "Include chart playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "newMusicFriday",
      "in": "query",
      "description": "Include New Music Friday playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "thisIs",
      "in": "query",
      "description": "Include \"This Is\" artist playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "radio",
      "in": "query",
      "description": "Include algorithmic radio playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    },
    {
      "name": "brand",
      "in": "query",
      "description": "Include brand playlists. Forwarded unchanged as a raw string; Recoup does not validate its range, date format or boolean value. Provider support applies.",
      "schema": {
        "type": "string"
      }
    }
  ],
  "responses": {
    "200": {
      "description": "Playlist placements for the track.",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "required": [
              "status",
              "placements"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "success"
                ],
                "example": "success"
              },
              "placements": {
                "type": "array",
                "description": "Playlist placement objects returned by the configured provider (shape varies per platform).",
                "items": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "400": {
      "description": "Validation error — missing `id`/`q`, invalid `platform`, or invalid `status`.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchErrorResponse"
          }
        }
      }
    },
    "401": {
      "description": "Authentication failed — invalid or missing API key.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchErrorResponse"
          }
        }
      }
    },
    "402": {
      "description": "Insufficient research credits. The response includes a static billingUrl; no checkout session is created.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchInsufficientCreditsResponse"
          }
        }
      }
    },
    "403": {
      "description": "Credential, account or provider permission denied.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchErrorResponse"
          }
        }
      }
    },
    "404": {
      "description": "Artist/track resolution or requested provider data was not found. A failed name search may be reported as 404; retry with an exact provider ID when known.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchErrorResponse"
          }
        }
      }
    },
    "429": {
      "description": "Provider rate or quota limit. The adapter returns an error status but does not forward provider Retry-After headers. Avoid an unbounded retry loop.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchErrorResponse"
          }
        }
      }
    },
    "500": {
      "description": "Missing provider configuration, transport failure or internal error.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchErrorResponse"
          }
        }
      }
    },
    "501": {
      "$ref": "#/components/responses/ResearchDataSourceUnsupported"
    },
    "502": {
      "description": "Upstream provider failed.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchErrorResponse"
          }
        }
      }
    },
    "504": {
      "description": "the configured research data connection request timed out.",
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResearchErrorResponse"
          }
        }
      }
    }
  }
}