The API reference

Two reads, both under artists:read: the artists a person belongs to, and one artist by handle or number with its ETag. Every status code the API answers with.

For developers

GET /api/v1/artists

The artists the signed-in person is a member of, with their permission on each.

Token A token a person granted through Sign in with TAP, or a personal token.
Scope artists:read
Parameters None.
Returns A list of artists. Each carries permission: what the person may do on it.
GET /api/v1/artists
Authorization: Bearer {token}
Accept: application/json
{
  "data": [
    {
      "handle": "nightshift",
      "name": "Night Shift",
      "permission": "owner",
      "verified_at": "2026-09-03T14:02:11+00:00",
      "url": "https://…/nightshift",
      …
    }
  ]
}

GET /api/v1/artists/{identifier}

One artist, by handle or by artist number: id, handle, name, bio in Markdown and bio_html, intro, facts, avatar, hero, logo, favicon, images (the press photos), logos, riders, channels, shop, releases, quotes, videos, contacts, verified_at, the date TAP verified the artist or null, published_at and updated_at. It carries the artist's own addresses as well: url is the website, epk_url the EPK, and visibility answers who can see each of the four pages (website, links, music, epk), with null where the artist does not use that page. Each fact carries type, label and a list of values, in the order the artist set. Each release carries title, slug, kind, artists, release_date, release_date_precision, upc, links, artwork and url; upc is null until a platform agrees to the barcode, and the list is filled while the artist's music page is public and empty otherwise. The response itself carries no artist number: the number is a team-only reference, so work from the handle unless you already store one. Each contact carries name, company, role, email, phone, website and avatar, the same people the artist's own pages show. Each press quote carries quote, publication, author, published_on and url, in the order the artist set; only the quote and the publication are always there. Each video carries title, url and is_live, in the order the artist set; is_live marks a live set. shop carries label, tagline and url, or is null when the artist has no shop.

Token A user token, a personal token, or a client-credentials token from an approved app.
Scope artists:read
Headers If-None-Match with the ETag you were given. An unchanged artist answers 304 with no body.
Cache Private, max-age 60. The ETag changes when the artist changes.
Returns The artist. Riders stream through TAP; every other file carries a direct URL.
GET /api/v1/artists/nightshift
Authorization: Bearer {token}
Accept: application/json
If-None-Match: "8f3a1c"
200 OK
ETag: "b21e07"

{
  "handle": "nightshift",
  "name": "Night Shift",
  "url": "https://…/nightshift",
  "epk_url": "https://…/nightshift/epk",
  "visibility": {
    "website": "public",
    "links": "public",
    "music": "public",
    "epk": "unlisted"
  },
  "verified_at": "2026-09-03T14:02:11+00:00",
  "bio": "Night Shift is a Rotterdam duo playing slow, heavy techno…",
  "intro": "Rotterdam duo, slow and heavy, two hours at a time.",
  "facts": [
    {
      "type": "genre",
      "label": "Genre",
      "values": [{ "value": "hard techno", "label": "Hard techno" }]
    }
  ],
  "channels": [ … ],
  "releases": [
    {
      "title": "Osiris",
      "slug": "osiris",
      "kind": "single",
      "artists": ["Night Shift", "Break of Dawn"],
      "release_date": "2026-08-14",
      "release_date_precision": "day",
      "upc": "8718522301292",
      "links": { "spotify": "https://…" },
      "artwork": { "url": "https://…/osiris.jpg", "…": "…" },
      "url": "https://…/nightshift/music/osiris"
    }
  ],
  "quotes": [
    {
      "quote": "Two hours that never once looked back.",
      "publication": "Resident Advisor",
      "author": "Lena Bakker",
      "published_on": "2026-03-12",
      "url": "https://ra.co/reviews/night-shift"
    }
  ],
  "videos": [
    {
      "title": "Dekmantel 2026",
      "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
      "is_live": true
    }
  ],
  "contacts": [
    {
      "name": "Superform",
      "company": "Superform Agency",
      "role": "Booking",
      "roles": [{ "value": "agent", "label": "Agent" }],
      "territories": [{ "value": "europe", "label": "Europe" }],
      "email": "bookings@superform.example",
      "phone": "+31 10 123 4567",
      "website": "https://superform.example",
      "avatar": "https://…/superform.jpg"
    }
  ]
}

Contacts retain the existing role field. The additive roles and territories fields contain ordered {value, label} objects. An empty roles list means there are no selected roles; the original role text is retained separately for compatibility. Territories apply to contacts with the Agent role. Team-member contacts carry their single team role in roles and an empty territories list.

Each rider retains name, url, mime_type and size, and adds a nullable kind. The values are technical, stage_plot, hospitality and input_list. A null kind means the artist left the file as Rider.

What a token can be

Conditional requests

Every single-artist response carries an ETag. Send it back as If-None-Match and an unchanged artist answers 304, so polling stays cheap. Responses are private and good for 60 seconds.

Not found

For a server token, an artist that is not published, or suspended, answers 404, the same as an unknown handle. A person's token reads the artists they belong to whether those are published or not. Do not infer from a 404 that the artist exists.

Status codes

Code Meaning What to do
200 The artist, as JSON. Store the ETag from the response.
304 Unchanged since the ETag you sent. Keep what you have. No body follows.
401 No token, an expired token, or one TAP does not recognise. Get a new token. Personal tokens are revoked under API tokens in your account.
403 The token is valid but lacks the scope. Ask for the scope on the consent screen.
404 No artist at that handle or number, or one that is not published, suspended, or not yours to see. All of these answer the same.
429 More than 60 requests in a minute from one address. Wait for the window to pass. Conditional requests keep you far below it.

What it costs at volume is on the partners page.

Still stuck?

Write to us with the handle and what you tried. A person answers, usually the same day.

Write to us