API reference
Artists
Artists, songwriters and composers, and their store profiles.
Base address https://api.stillmoregroup.com/api/v1. Every answer is JSON; errors have one shape.
| Endpoint | What it does |
|---|---|
GET /artists | List artists |
POST /artists | Add an artist to the roster |
GET /artists/{artistId} | Read an artist |
PATCH /artists/{artistId} | Change an artist |
List artists#
GET /artists · scope artists:read
Query parameters#
limitinteger- From 1 to 100. Default
25. cursorstring- nextCursor from the previous page. Up to 200 characters.
updatedSincestring (date-time)- Only records changed at or after this ISO 8601 time.
externalIdstring- Your own identifier for this record, unique within the organization. 1 to 100 characters.
statusstring- One of
ACTIVE,ARCHIVED. searchstring- Up to 160 characters.
Headers#
Stillmore-Organization- A sub-label to act for, when the key may (see Sub-labels).
Example request#
curl "https://api.stillmoregroup.com/api/v1/artists?limit=25" \
-H "Authorization: Bearer $STILLMORE_API_KEY"Response 200#
A page: data holds the items below, hasMore says whether another page follows, and nextCursor is the cursor for it.
idstringnamestringstatusstring- One of
ACTIVE,ARCHIVED. rolesstring[]- Each one of
PERFORMER,SONGWRITER,COMPOSER. countryCodestring or nullprofilesobjectprofiles.string or nullspotify profiles.string or nullappleMusic
Show 6 more fieldsHide 6 fields
profiles.string or nullyoutube externalIdstring or null- Your own id for it, when you set one.
metadatamap of string- Your own keys and values, as you sent them.
createdAtstring- ISO 8601 timestamp in UTC.
updatedAtstring- ISO 8601 timestamp in UTC.
revisionstring- Changes whenever the record does; send it back in If-Match to refuse an update when someone else changed it first.
{
"data": [
{
"id": "6731c2a1b3c4d5e6f7a8b9c0",
"name": "June Hale",
"status": "ACTIVE",
"roles": [
"PERFORMER"
],
"countryCode": "GB",
"profiles": {
"spotify": "…",
"appleMusic": "…",
"youtube": "…"
},
"externalId": "6731c2a1b3c4d5e6f7a8b9c0",
"metadata": {
"catalogueId": "1042"
},
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z",
"revision": "…"
}
],
"hasMore": false,
"nextCursor": null
}Add an artist to the roster#
POST /artists · scope artists:write
Body#
namestringRequired- 1 to 160 characters.
countryCodestring- 2 to 2 characters.
rolesstring[]- PERFORMER by default; SONGWRITER and COMPOSER entries are credits and don't count against the artist limit. Each one of
PERFORMER,SONGWRITER,COMPOSER. 1 to 3 items. profilesobject- The artist's store profiles, so releases land on the right artist page.
profiles.string or nullspotify - A Spotify artist id or the artist's open.spotify.com link.
profiles.string or nullappleMusic - An Apple Music artist id or the artist's music.apple.com link.
profiles.string or nullyoutube - The artist's YouTube channel. Up to 120 characters.
externalIdstring- Your own identifier for this record, unique within the organization. 1 to 100 characters.
metadatamap of string- Key-value pairs you attach for your own use.
Headers#
Idempotency-Key- Any unique value, such as a UUID: a retry with the same key and body gets the first answer again for 24 hours.
Stillmore-Organization- A sub-label to act for, when the key may (see Sub-labels).
Example request#
curl -X POST "https://api.stillmoregroup.com/api/v1/artists" \
-H "Authorization: Bearer $STILLMORE_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "June Hale",
"countryCode": "GB",
"roles": [
"PERFORMER"
]
}'Response 201#
data holds the object below.
idstringnamestringstatusstring- One of
ACTIVE,ARCHIVED. rolesstring[]- Each one of
PERFORMER,SONGWRITER,COMPOSER. countryCodestring or nullprofilesobjectprofiles.string or nullspotify profiles.string or nullappleMusic
Show 6 more fieldsHide 6 fields
profiles.string or nullyoutube externalIdstring or null- Your own id for it, when you set one.
metadatamap of string- Your own keys and values, as you sent them.
createdAtstring- ISO 8601 timestamp in UTC.
updatedAtstring- ISO 8601 timestamp in UTC.
revisionstring- Changes whenever the record does; send it back in If-Match to refuse an update when someone else changed it first.
{
"data": {
"id": "6731c2a1b3c4d5e6f7a8b9c0",
"name": "June Hale",
"status": "ACTIVE",
"roles": [
"PERFORMER"
],
"countryCode": "GB",
"profiles": {
"spotify": "…",
"appleMusic": "…",
"youtube": "…"
},
"externalId": "6731c2a1b3c4d5e6f7a8b9c0",
"metadata": {
"catalogueId": "1042"
},
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z",
"revision": "…"
}
}Errors#
| Code | What it means |
|---|---|
EXTERNAL_ID_IN_USE | Another record of the same kind in your organization already has this externalId. |
PLAN_QUOTA_REACHED | From the workspace rule behind this endpoint; message says what to change. |
DUPLICATE_EXTERNAL_ARTIST_ID | From the workspace rule behind this endpoint; message says what to change. |
Every endpoint can also give the errors every call can give, such as VALIDATION_ERROR, INSUFFICIENT_SCOPE and RATE_LIMITED.
Read an artist#
GET /artists/{artistId} · scope artists:read
Path parameters#
artistIdstring- An id.
Headers#
Stillmore-Organization- A sub-label to act for, when the key may (see Sub-labels).
Example request#
curl "https://api.stillmoregroup.com/api/v1/artists/{artistId}" \
-H "Authorization: Bearer $STILLMORE_API_KEY"Response 200#
data holds the object below.
idstringnamestringstatusstring- One of
ACTIVE,ARCHIVED. rolesstring[]- Each one of
PERFORMER,SONGWRITER,COMPOSER. countryCodestring or nullprofilesobjectprofiles.string or nullspotify profiles.string or nullappleMusic
Show 6 more fieldsHide 6 fields
profiles.string or nullyoutube externalIdstring or null- Your own id for it, when you set one.
metadatamap of string- Your own keys and values, as you sent them.
createdAtstring- ISO 8601 timestamp in UTC.
updatedAtstring- ISO 8601 timestamp in UTC.
revisionstring- Changes whenever the record does; send it back in If-Match to refuse an update when someone else changed it first.
{
"data": {
"id": "6731c2a1b3c4d5e6f7a8b9c0",
"name": "June Hale",
"status": "ACTIVE",
"roles": [
"PERFORMER"
],
"countryCode": "GB",
"profiles": {
"spotify": "…",
"appleMusic": "…",
"youtube": "…"
},
"externalId": "6731c2a1b3c4d5e6f7a8b9c0",
"metadata": {
"catalogueId": "1042"
},
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z",
"revision": "…"
}
}Errors#
| Code | What it means |
|---|---|
ARTIST_NOT_FOUND | From the workspace rule behind this endpoint; message says what to change. |
Every endpoint can also give the errors every call can give, such as VALIDATION_ERROR, INSUFFICIENT_SCOPE and RATE_LIMITED.
Change an artist#
PATCH /artists/{artistId} · scope artists:write
Path parameters#
artistIdstring- An id.
Body#
namestring- 1 to 160 characters.
countryCodestring or null- 2 to 2 characters.
rolesstring[]- PERFORMER by default; SONGWRITER and COMPOSER entries are credits and don't count against the artist limit. Each one of
PERFORMER,SONGWRITER,COMPOSER. 1 to 3 items. profilesobject- The artist's store profiles, so releases land on the right artist page.
profiles.string or nullspotify - A Spotify artist id or the artist's open.spotify.com link.
profiles.string or nullappleMusic - An Apple Music artist id or the artist's music.apple.com link.
profiles.string or nullyoutube - The artist's YouTube channel. Up to 120 characters.
externalIdstring or null- Your own identifier for this record, unique within the organization. 1 to 100 characters.
metadatamap of string- Key-value pairs you attach for your own use.
statusstring- One of
ACTIVE,ARCHIVED.
Headers#
Idempotency-Key- Any unique value, such as a UUID: a retry with the same key and body gets the first answer again for 24 hours.
If-Match- The revision you read; when the object changed since, the answer is 412 REVISION_MISMATCH.
Stillmore-Organization- A sub-label to act for, when the key may (see Sub-labels).
Example request#
curl -X PATCH "https://api.stillmoregroup.com/api/v1/artists/{artistId}" \
-H "Authorization: Bearer $STILLMORE_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"countryCode": "GB",
"roles": [
"PERFORMER"
]
}'Response 200#
data holds the object below.
idstringnamestringstatusstring- One of
ACTIVE,ARCHIVED. rolesstring[]- Each one of
PERFORMER,SONGWRITER,COMPOSER. countryCodestring or nullprofilesobjectprofiles.string or nullspotify profiles.string or nullappleMusic
Show 6 more fieldsHide 6 fields
profiles.string or nullyoutube externalIdstring or null- Your own id for it, when you set one.
metadatamap of string- Your own keys and values, as you sent them.
createdAtstring- ISO 8601 timestamp in UTC.
updatedAtstring- ISO 8601 timestamp in UTC.
revisionstring- Changes whenever the record does; send it back in If-Match to refuse an update when someone else changed it first.
{
"data": {
"id": "6731c2a1b3c4d5e6f7a8b9c0",
"name": "June Hale",
"status": "ACTIVE",
"roles": [
"PERFORMER"
],
"countryCode": "GB",
"profiles": {
"spotify": "…",
"appleMusic": "…",
"youtube": "…"
},
"externalId": "6731c2a1b3c4d5e6f7a8b9c0",
"metadata": {
"catalogueId": "1042"
},
"createdAt": "2026-11-01T09:30:00.000Z",
"updatedAt": "2026-11-01T09:30:00.000Z",
"revision": "…"
}
}Errors#
| Code | What it means |
|---|---|
ARTIST_NOT_FOUND | From the workspace rule behind this endpoint; message says what to change. |
REVISION_MISMATCH | The record changed since you read it (If-Match). Read it again and retry. |
PLAN_QUOTA_REACHED | From the workspace rule behind this endpoint; message says what to change. |
Every endpoint can also give the errors every call can give, such as VALIDATION_ERROR, INSUFFICIENT_SCOPE and RATE_LIMITED.