GET /transactions
Get all transactions
Retrieve a paginated list of accounting transactions for the authenticated user's account, ordered by created_at descending (most recent first).
Opt-in per-label filtering: pass any of filter[label_id], filter[release_id], filter[isrc] or filter[upc] to switch to server-recomputed per-label REVENUE rows sourced from the royalty line-item layer (one row per payment period). Filtered rows carry a scope of label, transaction_type of REVENUE, a single monetary gross_usd, and a meta.gross_definition discriminator; ledger balance_before/balance_after are null. gross_usd matches the customer-facing UI + CSV column of the same name: gross revenue AFTER the statement-provider fee (e.g. Merlin/Orchard) and BEFORE LabelGrid platform/UGC fees; net revenue (after LabelGrid fees) and the final payout are on the statements endpoint. filter[start_date]/filter[end_date] (Y-m-d) narrow by payment period and require an entity filter. Only labels you directly own are visible; an unowned label_id/release_id returns 404 and an unowned upc/isrc returns an empty data array. With no filter the response is unchanged.
This endpoint returns one of two shapes depending on whether an entity filter is present. The @response schema below is the union of both — filtered-only keys (scope, period, gross_usd) and the filtered meta fields (scope, filter, gross_definition, note) are present only in filtered mode, and every ledger field is nullable so a filtered row (where those fields are null) validates against the same schema.
- Unfiltered (no
filter[*]entity): paginated account-level ledger rows.idis an int;transaction_date,transaction_type,created_atare strings;net_usd,balance_before,balance_afterare floats;links/metaare the standard pagination envelope. - Filtered (any
filter[*]entity present): server-recomputed per-labelREVENUErows, one per payment period, returned in the same paginated envelope (which degrades to a single page). Each row carriesscope: "label",transaction_type: "REVENUE",period,currency, and a single monetarygross_usd(gross revenue after the statement-provider fee, before LabelGrid platform/UGC fees — matching the customer-facing UI + CSVgross_usdcolumn). All account-level-only fields (id,transaction_date,reference_number,vendor,vendor_statement_id,category,net_usd,balance_before,balance_after,description,created_at) arenull, andlinksare allnull.metaadditionally carriesscope, the echoedfilter,gross_definition: "post_provider_fee_pre_labelgrid_fee", and anote(net revenue after LabelGrid fees and the final payout are on the statements endpoint). Consumers branch onscope; the filtered shape is not a strict superset of the unfiltered one.
Per-release rollup: add group_by=release (which requires filter[label_id]) to get one REVENUE row per release under that label, grouped by payment period, instead of one per-label total. Amounts not attributable to a specific release (and any per-release rounding residue) surface as an explicit remainder row with release_id: null per period — never silently apportioned or dropped — so the per-release rows plus the remainder always sum exactly to the per-label total the non-grouped path returns for the same filters. Grouped rows carry scope: "release" and a release_id (null on the remainder row); meta adds group_by: "release". Any other group_by value, or group_by=release without filter[label_id], returns 422.
Parameters
- group_by (query)
- page (query)
- per_page (query)
- sort (query)
- filter[label_id] (query)
- filter[release_id] (query)
- filter[isrc] (query)
- filter[upc] (query)
- filter[start_date] (query)
- filter[end_date] (query)
Responses
- 200
- 401
- 422