Read your catalogue, create and submit releases, pull royalties, and receive events — for labels and distributors working on top of Distovia.
Ask your account manager. Keys are issued per account with either read or read+write scope, and the secret is shown once at creation — we store only its hash and cannot recover it.
curl https://app.bemusix.com/api/partner/v1/me \ -H "Authorization: Bearer bk_live_your_key_here"
A revoked key stops working immediately, with 401.
https://app.bemusix.com/api/partner/v1
| Path | Scope | What it does | |
|---|---|---|---|
| GET | /me |
read | The account this key belongs to. → { user } |
| GET | /releases |
read | Every release on the account, newest first. → { releases } |
| GET | /releases/:id |
read | One release with its tracks and per-store delivery state. → { release } |
| POST | /releases{ "title": "Nodir Kule", "primaryArtist": "Hasan", "genre": "Folk", "releaseDate": "2026-09-01" } |
write | Create a release as a draft. → { release } |
| POST | /releases/:id/submit |
write | Send a completed draft for review. Fails with the missing fields named. → { release } |
| GET | /earnings |
read | Royalty lines, filterable by month. → { earnings, totals } |
| GET | /webhooks |
read | The webhooks registered for this account. → { webhooks } |
| POST | /webhooks{ "url": "https://you.example/hooks/backstage", "events": ["release.status"] } |
write | Register a URL to receive events. → { webhook, secret } |
| DELETE | /webhooks/:id |
write | Stop sending to a webhook. → { ok } |
Register a URL and we POST a JSON body to it when something happens. Every request carries an x-backstage-signature header: the hex HMAC-SHA256 of the raw body, keyed with the secret you were given when the webhook was created.
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
if (expected !== req.headers["x-backstage-signature"]) return res.sendStatus(401);
We retry once on failure. Reply 2xx quickly and do your work afterwards.
| Event | Sent when |
|---|---|
release.status | A release moves between states — submitted, approved, delivered, live, taken down. |
release.delivered | A store has accepted a delivery. |
payout.paid | A payout has been sent. |
Errors are JSON and shaped the same everywhere. fields is present when something specific was wrong with the payload.
{
"error": {
"code": "BAD_REQUEST",
"message": "Release is incomplete",
"fields": { "artwork": "Artwork is required" }
}
}
Requests are limited per key. A 429 means slow down — retry after a short pause rather than immediately.
400 with each missing field named, so you can surface it in your own UI.