Guides
Earnings and payouts
Statements and their lines, earnings by store or country, the balance, and payouts to your saved methods.
On this page
Royalties reach you as statements, and statements fill the balance that payouts come from. This guide reads each of them from your own systems, then asks for a payout.
How the money moves#
- The stores report what each release earned. Stillmore Group matches every line to your catalogue.
- A statement is published for a period and a currency: what the stores reported (
gross), Stillmore Group's share (fees), and what you keep (net).statement.publishedtells you. - The
netis credited to your balance, in the statement's currency. While an advance is still to recoup, it is held back from what can be paid out. - You ask for a payout of what is available, to a payout method saved in the workspace. Stillmore Group reviews it and pays it;
payout.*events follow it.
Statements#
GET /statements lists the statements published to your organization, newest first; period=2026-10 keeps those covering one month. Each one's lines (GET /statements/{id}/lines, up to 500 a page) are the store lines behind it: release, track, UPC and ISRC, store, territory, units and gross. GET /statements/{id}/export gives the same lines as CSV, for a spreadsheet or your own royalty system.
import { StillmoreApi } from "./stillmore-api";
const api = new StillmoreApi({ apiKey: process.env.STILLMORE_API_KEY! });
for await (const statement of api.list<{ id: string; periodStart: string; currency: string; net: string }>("/statements", { period: "2026-10" })) {
console.log(statement.periodStart, statement.currency, statement.net);
for await (const line of api.list<{ isrc: string | null; store: string; units: number; gross: string }>(`/statements/${statement.id}/lines`, { limit: 500 })) {
// Your royalty system takes it from here.
}
}Earnings, any way you slice them#
GET /earnings sums what the stores reported by month, release, track, store or territory (groupBy), biggest first (months in order). Filter by reporting months (from, to), currency, release, track, store or country. These are gross amounts, before Stillmore Group's share; statements carry the net.
curl "https://api.stillmoregroup.com/api/v1/earnings?groupBy=store&from=2026-07&to=2026-09¤cy=USD" \
-H "Authorization: Bearer $STILLMORE_API_KEY"The balance and its ledger#
GET /balance gives each currency's balance:
| Field | What it is |
|---|---|
earnings | Royalties and adjustments credited, minus fees, payouts and recoupments |
advanceOutstanding | Advance granted and not recouped yet |
pendingPayouts | Payouts asked for and not paid or refused yet |
available | What can be paid out now |
minimumPayout | The smallest payout, when there is one |
GET /transactions lists every credit and debit behind it, newest first: royalties, fees, payouts, adjustments, recoupments and transfers. Each amount is signed: credits positive, debits negative.
Asking for a payout#
Payout requests through the API are off until an owner or admin turns them on in Workspace › API › Settings, with a code from their authenticator app; each request is then told to them. Payouts go only to methods saved in the workspace (bank accounts, PayPal, Payoneer): GET /payout-methods lists them, masked.
const [method] = await api.get<Array<{ id: string; isDefault: boolean }>>("/payout-methods");
const payout = await api.post<{ id: string; status: string }>("/payouts", {
amount: "250.00",
currency: "USD",
payoutMethodId: method!.id,
note: "October royalties"
});
console.log(payout.status); // "PENDING"Send an Idempotency-Key, so a retry never asks twice. The amount must be at least minimumPayout and at most available: otherwise the answer is 400 BELOW_MINIMUM_PAYOUT or 400 INSUFFICIENT_BALANCE.
The request stays PENDING until Stillmore Group approves it (APPROVED, and PROCESSING while a batch of payments is being made) and becomes PAID once the money is sent. It can also be REJECTED, or FAILED if the payment doesn't go through. payout.approved, payout.paid, payout.rejected and payout.failed tell you. While it is PENDING, POST /payouts/{id}/cancel withdraws it.
Collaborators' shares#
Splits record how a release's or a track's money is shared with collaborators: PUT /releases/{id}/split and PUT /tracks/{id}/split, with shares adding up to exactly 100. Once a published statement has used a split, it is locked and can no longer change.
Try it in the sandbox#
With a sandbox key, POST /sandbox/royalties plays a month of royalties (month, gross) over your sandbox's live releases: it publishes a statement and credits the balance, with statement.published. POST /sandbox/payouts/{id}/pay pays a payout request. See Sandbox.