Skip to content

API reference

Cover licences

Licences for cover songs: asking for one, documents and cancelling.

On this page

Base address https://api.stillmoregroup.com/api/v1. Every answer is JSON; errors have one shape.

EndpointWhat it does
GET /cover-licensesCover licence requests
GET /cover-licenses/{licenseId}One request
POST /cover-licensesAsk for a cover licence
POST /cover-licenses/{licenseId}/documentStart uploading the licence file
POST /cover-licenses/{licenseId}/document/completeFinish uploading the licence file
POST /cover-licenses/{licenseId}/cancelCancel a request not sent in yet

Cover licence requests#

GET /cover-licenses · scope releases:read

Query parameters#

limitinteger
From 1 to 100. Default 25.
cursorstring
Up to 200 characters.
trackIdstring
An id.
releaseIdstring
An id.
statusstring
One of AWAITING_PAYMENT, AWAITING_DOCUMENT, PENDING, IN_PROGRESS, APPROVED, REJECTED, CANCELLED.

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/cover-licenses?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.

idstring
numberstring
Our reference, e.g. CVL-2026-0042.
releaseIdstring
trackIdstring
modestring
OWN: you send in a licence you have; PURCHASE: Stillmore Group gets one for you. One of PURCHASE, OWN.
statusstring
One of AWAITING_PAYMENT, AWAITING_DOCUMENT, PENDING, IN_PROGRESS, APPROVED, REJECTED, CANCELLED.
originalobject
The song being covered.
original.titlestring
Show 17 more fields
original.artiststring
original.writersstring[]
original.publisherstring or null
original.isrcstring or null
original.linkstring or null
notesstring or null
pricestring
USD; 0.00 for OWN.
payWithstring or null
One of CARD, WALLET.
documentobject or null
The licence file on the request.
document.fileNamestring
document.uploadedAtstring or null
licenseRefstring or null
reasonstring or null
Why it was refused.
paidAtstring or null
dueAtstring or null
decidedAtstring or null
createdAtstring
Example response
{
  "data": [
    {
      "id": "6731c2a1b3c4d5e6f7a8b9c0",
      "number": "…",
      "releaseId": "6731c2a1b3c4d5e6f7a8b9c0",
      "trackId": "6731c2a1b3c4d5e6f7a8b9c0",
      "mode": "PURCHASE",
      "status": "AWAITING_PAYMENT",
      "original": {
        "title": "Night Signals",
        "artist": "…",
        "writers": [
          "…"
        ],
        "publisher": "…",
        "isrc": "GBXYZ2600001",
        "link": "https://example.com/webhooks/stillmore"
      },
      "notes": "Sent from our catalogue system",
      "price": "250.00",
      "payWith": "CARD",
      "document": {
        "fileName": "cover.jpg",
        "uploadedAt": "2026-11-01T09:30:00.000Z"
      },
      "licenseRef": "…",
      "reason": "Sent from our catalogue system",
      "paidAt": "2026-11-01T09:30:00.000Z",
      "dueAt": "2026-11-01T09:30:00.000Z",
      "decidedAt": "2026-11-01T09:30:00.000Z",
      "createdAt": "2026-11-01T09:30:00.000Z"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}

One request#

GET /cover-licenses/{licenseId} · scope releases:read

Path parameters#

licenseIdstring
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/cover-licenses/{licenseId}" \
  -H "Authorization: Bearer $STILLMORE_API_KEY"

Response 200#

data holds the object below.

idstring
numberstring
Our reference, e.g. CVL-2026-0042.
releaseIdstring
trackIdstring
modestring
OWN: you send in a licence you have; PURCHASE: Stillmore Group gets one for you. One of PURCHASE, OWN.
statusstring
One of AWAITING_PAYMENT, AWAITING_DOCUMENT, PENDING, IN_PROGRESS, APPROVED, REJECTED, CANCELLED.
originalobject
The song being covered.
original.titlestring
Show 17 more fields
original.artiststring
original.writersstring[]
original.publisherstring or null
original.isrcstring or null
original.linkstring or null
notesstring or null
pricestring
USD; 0.00 for OWN.
payWithstring or null
One of CARD, WALLET.
documentobject or null
The licence file on the request.
document.fileNamestring
document.uploadedAtstring or null
licenseRefstring or null
reasonstring or null
Why it was refused.
paidAtstring or null
dueAtstring or null
decidedAtstring or null
createdAtstring
Example response
{
  "data": {
    "id": "6731c2a1b3c4d5e6f7a8b9c0",
    "number": "…",
    "releaseId": "6731c2a1b3c4d5e6f7a8b9c0",
    "trackId": "6731c2a1b3c4d5e6f7a8b9c0",
    "mode": "PURCHASE",
    "status": "AWAITING_PAYMENT",
    "original": {
      "title": "Night Signals",
      "artist": "…",
      "writers": [
        "…"
      ],
      "publisher": "…",
      "isrc": "GBXYZ2600001",
      "link": "https://example.com/webhooks/stillmore"
    },
    "notes": "Sent from our catalogue system",
    "price": "250.00",
    "payWith": "CARD",
    "document": {
      "fileName": "cover.jpg",
      "uploadedAt": "2026-11-01T09:30:00.000Z"
    },
    "licenseRef": "…",
    "reason": "Sent from our catalogue system",
    "paidAt": "2026-11-01T09:30:00.000Z",
    "dueAt": "2026-11-01T09:30:00.000Z",
    "decidedAt": "2026-11-01T09:30:00.000Z",
    "createdAt": "2026-11-01T09:30:00.000Z"
  }
}

Errors#

CodeWhat it means
COVER_LICENSE_NOT_FOUNDFrom 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.

Ask for a cover licence#

POST /cover-licenses · scope releases:write

A track marked as a cover needs a mechanical licence before it goes to the stores. OWN: upload the licence you hold with …/document, Stillmore Group checks it for free. PURCHASE: Stillmore Group gets it for a fixed price, from the balance (WALLET, at once) or by card (a person pays at checkoutUrl). One open request per track.

Body#

trackIdstringRequired
A track marked as a cover (isCover: true). An id.
modestringRequired
One of PURCHASE, OWN.
originalobjectRequired
The song being covered, as its rights holders know it.
original.titlestringRequired
1 to 160 characters.
original.artiststringRequired
1 to 160 characters.
original.writersstring[]Required
1 to 20 items.
original.publisherstring
Up to 160 characters.
original.isrcstring
Up to 20 characters.
original.linkstring
Up to 500 characters.
payWithstring
PURCHASE only: WALLET takes the price from the balance at once; CARD answers with a checkout link a person pays. One of CARD, WALLET.
notesstring
Up to 2000 characters.

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/cover-licenses" \
  -H "Authorization: Bearer $STILLMORE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "trackId": "6731c2a1b3c4d5e6f7a8b9c0",
    "mode": "PURCHASE",
    "payWith": "WALLET",
    "original": {
      "title": "Paper Moons",
      "artist": "The Lanterns",
      "writers": [
        "Ada Quinn"
      ]
    }
  }'

Response 201#

data holds the object below.

licenseobject
license.idstring
license.numberstring
Our reference, e.g. CVL-2026-0042.
license.releaseIdstring
license.trackIdstring
license.modestring
OWN: you send in a licence you have; PURCHASE: Stillmore Group gets one for you. One of PURCHASE, OWN.
license.statusstring
One of AWAITING_PAYMENT, AWAITING_DOCUMENT, PENDING, IN_PROGRESS, APPROVED, REJECTED, CANCELLED.
license.originalobject
The song being covered.
Show 11 more fields
license.notesstring or null
license.pricestring
USD; 0.00 for OWN.
license.payWithstring or null
One of CARD, WALLET.
license.documentobject or null
The licence file on the request.
license.licenseRefstring or null
license.reasonstring or null
Why it was refused.
license.paidAtstring or null
license.dueAtstring or null
license.decidedAtstring or null
license.createdAtstring
checkoutUrlstring or null
CARD purchases: where a person pays; the request starts once paid.
Example response
{
  "data": {
    "license": {
      "id": "6731c2a1b3c4d5e6f7a8b9c0",
      "number": "…",
      "releaseId": "6731c2a1b3c4d5e6f7a8b9c0",
      "trackId": "6731c2a1b3c4d5e6f7a8b9c0",
      "mode": "PURCHASE",
      "status": "AWAITING_PAYMENT",
      "original": {
        "title": "Night Signals",
        "artist": "…",
        "writers": [
          "…"
        ],
        "publisher": "…",
        "isrc": "GBXYZ2600001",
        "link": "https://example.com/webhooks/stillmore"
      },
      "notes": "Sent from our catalogue system",
      "price": "250.00",
      "payWith": "CARD",
      "document": {
        "fileName": "cover.jpg",
        "uploadedAt": "2026-11-01T09:30:00.000Z"
      },
      "licenseRef": "…",
      "reason": "Sent from our catalogue system",
      "paidAt": "2026-11-01T09:30:00.000Z",
      "dueAt": "2026-11-01T09:30:00.000Z",
      "decidedAt": "2026-11-01T09:30:00.000Z",
      "createdAt": "2026-11-01T09:30:00.000Z"
    },
    "checkoutUrl": "https://example.com/webhooks/stillmore"
  }
}

Errors#

CodeWhat it means
TRACK_NOT_A_COVERFrom the workspace rule behind this endpoint; message says what to change.
COVER_LICENSE_EXISTSFrom the workspace rule behind this endpoint; message says what to change.
COVER_LICENSING_CLOSEDFrom the workspace rule behind this endpoint; message says what to change.
INSUFFICIENT_BALANCEFrom 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.

Start uploading the licence file#

POST /cover-licenses/{licenseId}/document · scope releases:write

OWN requests: PDF, Word, JPEG or PNG up to 20 MB, also to answer a refusal.

Path parameters#

licenseIdstring
An id.

Body#

fileNamestringRequired
The file's name, with its extension. 1 to 255 characters.
contentTypestringRequired
image/jpeg or image/png for covers; audio/wav or audio/flac for masters. 3 to 120 characters.
sizeBytesintegerRequired
Exact size in bytes; the PUT must send the same Content-Length.

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/cover-licenses/{licenseId}/document" \
  -H "Authorization: Bearer $STILLMORE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "cover.jpg",
    "contentType": "image/jpeg",
    "sizeBytes": 2483117
  }'

Response 201#

data holds the object below.

uploadIdstring
uploadUrlstring
PUT the file's bytes here.
method"PUT"
headersmap of string
Send these headers with the PUT, and Content-Length equal to sizeBytes.
expiresAtstring
Upload and complete before this time.
Example response
{
  "data": {
    "uploadId": "6731c2a1b3c4d5e6f7a8b9c0",
    "uploadUrl": "https://storage.example.com/upload/cover.jpg?signature=…",
    "method": "PUT",
    "headers": {
      "key": "…"
    },
    "expiresAt": "2026-11-01T09:30:00.000Z"
  }
}

Errors#

CodeWhat it means
COVER_LICENSE_NOT_FOUNDFrom the workspace rule behind this endpoint; message says what to change.
COVER_LICENSE_STATEFrom 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.

Finish uploading the licence file#

POST /cover-licenses/{licenseId}/document/complete · scope releases:write

The request goes to Stillmore Group (PENDING).

Path parameters#

licenseIdstring
An id.

Body#

uploadIdstringRequired
An id.
durationSecondsnumber
From 0 to 21600.

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/cover-licenses/{licenseId}/document/complete" \
  -H "Authorization: Bearer $STILLMORE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "uploadId": "6731c2a1b3c4d5e6f7a8b9c0"
  }'

Response 200#

data holds the object below.

idstring
numberstring
Our reference, e.g. CVL-2026-0042.
releaseIdstring
trackIdstring
modestring
OWN: you send in a licence you have; PURCHASE: Stillmore Group gets one for you. One of PURCHASE, OWN.
statusstring
One of AWAITING_PAYMENT, AWAITING_DOCUMENT, PENDING, IN_PROGRESS, APPROVED, REJECTED, CANCELLED.
originalobject
The song being covered.
original.titlestring
Show 17 more fields
original.artiststring
original.writersstring[]
original.publisherstring or null
original.isrcstring or null
original.linkstring or null
notesstring or null
pricestring
USD; 0.00 for OWN.
payWithstring or null
One of CARD, WALLET.
documentobject or null
The licence file on the request.
document.fileNamestring
document.uploadedAtstring or null
licenseRefstring or null
reasonstring or null
Why it was refused.
paidAtstring or null
dueAtstring or null
decidedAtstring or null
createdAtstring
Example response
{
  "data": {
    "id": "6731c2a1b3c4d5e6f7a8b9c0",
    "number": "…",
    "releaseId": "6731c2a1b3c4d5e6f7a8b9c0",
    "trackId": "6731c2a1b3c4d5e6f7a8b9c0",
    "mode": "PURCHASE",
    "status": "AWAITING_PAYMENT",
    "original": {
      "title": "Night Signals",
      "artist": "…",
      "writers": [
        "…"
      ],
      "publisher": "…",
      "isrc": "GBXYZ2600001",
      "link": "https://example.com/webhooks/stillmore"
    },
    "notes": "Sent from our catalogue system",
    "price": "250.00",
    "payWith": "CARD",
    "document": {
      "fileName": "cover.jpg",
      "uploadedAt": "2026-11-01T09:30:00.000Z"
    },
    "licenseRef": "…",
    "reason": "Sent from our catalogue system",
    "paidAt": "2026-11-01T09:30:00.000Z",
    "dueAt": "2026-11-01T09:30:00.000Z",
    "decidedAt": "2026-11-01T09:30:00.000Z",
    "createdAt": "2026-11-01T09:30:00.000Z"
  }
}

Errors#

CodeWhat it means
COVER_LICENSE_NOT_FOUNDFrom the workspace rule behind this endpoint; message says what to change.
COVER_LICENSE_STATEFrom the workspace rule behind this endpoint; message says what to change.
UPLOAD_NOT_RECEIVEDComplete was called before the file arrived at the upload address. Finish the PUT first.

Every endpoint can also give the errors every call can give, such as VALIDATION_ERROR, INSUFFICIENT_SCOPE and RATE_LIMITED.

Cancel a request not sent in yet#

POST /cover-licenses/{licenseId}/cancel · scope releases:write

Before payment (CARD) or before the file (OWN).

Path parameters#

licenseIdstring
An id.

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/cover-licenses/{licenseId}/cancel" \
  -H "Authorization: Bearer $STILLMORE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

Response 200#

data holds the object below.

idstring
numberstring
Our reference, e.g. CVL-2026-0042.
releaseIdstring
trackIdstring
modestring
OWN: you send in a licence you have; PURCHASE: Stillmore Group gets one for you. One of PURCHASE, OWN.
statusstring
One of AWAITING_PAYMENT, AWAITING_DOCUMENT, PENDING, IN_PROGRESS, APPROVED, REJECTED, CANCELLED.
originalobject
The song being covered.
original.titlestring
Show 17 more fields
original.artiststring
original.writersstring[]
original.publisherstring or null
original.isrcstring or null
original.linkstring or null
notesstring or null
pricestring
USD; 0.00 for OWN.
payWithstring or null
One of CARD, WALLET.
documentobject or null
The licence file on the request.
document.fileNamestring
document.uploadedAtstring or null
licenseRefstring or null
reasonstring or null
Why it was refused.
paidAtstring or null
dueAtstring or null
decidedAtstring or null
createdAtstring
Example response
{
  "data": {
    "id": "6731c2a1b3c4d5e6f7a8b9c0",
    "number": "…",
    "releaseId": "6731c2a1b3c4d5e6f7a8b9c0",
    "trackId": "6731c2a1b3c4d5e6f7a8b9c0",
    "mode": "PURCHASE",
    "status": "AWAITING_PAYMENT",
    "original": {
      "title": "Night Signals",
      "artist": "…",
      "writers": [
        "…"
      ],
      "publisher": "…",
      "isrc": "GBXYZ2600001",
      "link": "https://example.com/webhooks/stillmore"
    },
    "notes": "Sent from our catalogue system",
    "price": "250.00",
    "payWith": "CARD",
    "document": {
      "fileName": "cover.jpg",
      "uploadedAt": "2026-11-01T09:30:00.000Z"
    },
    "licenseRef": "…",
    "reason": "Sent from our catalogue system",
    "paidAt": "2026-11-01T09:30:00.000Z",
    "dueAt": "2026-11-01T09:30:00.000Z",
    "decidedAt": "2026-11-01T09:30:00.000Z",
    "createdAt": "2026-11-01T09:30:00.000Z"
  }
}

Errors#

CodeWhat it means
COVER_LICENSE_NOT_FOUNDFrom the workspace rule behind this endpoint; message says what to change.
COVER_LICENSE_STATEFrom 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.