Skip to main content
Scrip’s reporting endpoints cover ledger activity, balances, liabilities, and gift-card fulfillment. Ledger reports use the double-entry ledger; fulfillment-cost reports use the gift card’s face value and order status. Ledger reports show amounts separately for each asset. Each row carries asset_id, asset_symbol, and scale, and Scrip never sums values across assets.

Liability

Outstanding liability is the value participants and groups currently hold. This is the number that belongs on a balance sheet.
Because the ledger is immutable, as_of queries are stable: ask for June 30 in July, or in December, and get the same answer. Close your books against this number and every other report reconciles back to it.

Liability rollforward

The rollforward explains a period: opening balance, every movement decomposed into named categories, closing balance.
For each asset and program, the response itemizes issued, issuance returns, redeemed, redemption receipts, redemption reversals, reversal clawbacks, forfeited, expired, debited, transfers, and bucket movements. The lines sum exactly to closing - opening. There is no residual bucket, and unclassifiable activity fails the request rather than misstating the report. A typical close: run liability at from and to, run the rollforward for the window, and verify that opening plus the itemized lines equals closing for each asset. This is the artifact to hand an auditor.

Participant rollforward

The same report for one participant. For each asset the participant has used by to, it returns the opening balance, the closing balance, and how the balance changed, split into named amounts.
Use it to print the rewards summary on a cardholder’s statement for a billing cycle: earned, redeemed, reversed, expired. You do not need to classify statement rows yourself. from and to are required. Both bounds are inclusive and select entries by posting time, the same way statements do. The response repeats from and to exactly as you sent them, including fractional seconds, so a request made with the returned values gives the same figures. Pass asset_id to return one asset. There is no program_id filter. Balances are per asset, not per program, and include AVAILABLE, HELD, and DEFERRED together. Each amount is called a line. The table shows what each line counts and which action_type creates it: For every row:
Every change is counted in one of the lines, so they always add up to the difference. If the ledger contains activity the lines cannot cover, the request fails instead of returning a wrong figure. Each journal entry counts once, by its total effect on the participant. A settlement for less than the pending amount shows the difference in issuance_returns. It does not count as issued and then returned. A settlement for the full pending amount changes nothing and appears in no line. To see the rows behind a figure, run the statement for the same window and use its action_type, rule_id, and reference_id fields to classify them.

Redemption attribution

For shared LOT-mode assets, break gross redemptions down by the program that issued the consumed value and the program used as the redemption channel:
Each row is one asset, channel program, and issuer program cell. Diagonal cells are same-program redemptions. Off-diagonal cells are cross-program flows you can use for partner settlement. The response preserves rows with unknown issuer lineage under a null issuer so the matrix still reconciles to gross channel redemption totals. Use program_id to filter by redemption channel or asset_id to select one LOT-mode asset. The report is gross and does not net reversals. It does not allocate reversals back to issuer/channel cells. Use liability rollforward, ledger summary, redemption records, or journal entries for reversal-aware financial reporting. SIMPLE-mode assets do not carry the lot lineage required for issuer attribution. See Multi-Program Balances for how this report differs from ordinary per-program liability and activity views.

Expiration schedule

For LOT-mode assets, project when outstanding value expires:
Each asset’s response buckets outstanding lot value by expiry period, with separate never_expiring, expiring_before_window (past expires_at but not yet removed by expiration processing, so still liability), and expiring_after_window figures. Together they sum exactly to total_outstanding. Held and deferred lots are included, since they still expire. Use this for breakage estimation and forecasting how much value expires in the next 30, 60, or 90 days. See Lots & Expiration for the underlying lifecycle.

Ledger integrity

Verify the ledger is internally consistent and tamper-free:
Four checks run in one snapshot: postings balance to zero, value conservation, hash-chain validity, and unsealed-entry count. The response includes the current chain_head hash. Pin that hash externally at each close; because every entry’s hash depends on all prior entries, any later alteration of history becomes detectable against your pinned value. See the Ledger guide for how the hash chain works.

Statements

Statements give a bank-statement view with running balances, for support tooling, end-user receipts, or per-account audits:
Each row is one posting with the balance after it. asset_id is required, since a running balance only makes sense within one asset. Pass bucket to limit rows and balances to one or more buckets, such as bucket=AVAILABLE,DEFERRED. The balances cover the selected buckets together. A card program can report spendable value and value that is still maturing (AVAILABLE plus DEFERRED) as of a billing cycle close in one call. Set to to the close time. GET /v1/participants/{id}/balances returns only the current balance, so it cannot give that figure for a past moment.

Classifying rows

Three fields on every row tell you what it is. You do not need to fetch the journal entry. Start with action_type. Then use rule_id and event_id to separate rule-driven movement from manual and system activity. Then group related rows by reference_id. For a rewards summary over a period (earned, redeemed, reversed, expired), use the participant rollforward instead. It returns those figures directly.

Window boundaries

from and to select rows by created_at. Both bounds are inclusive. opening_balance adds up every posting before from, and closing_balance adds up every posting through to. For any window:
The running balance counts the account’s full history, so closing_balance equals the account’s balance as of to. Paging does not change the running balance. from and to accept fractional seconds. to=2026-03-31T23:59:59.999Z closes a month without catching the first posting of the next one. Timestamps in the response are whole seconds, and several postings can share one second. Do not reuse a row’s created_at as the next window’s boundary. To continue a long statement, use the cursor from pagination.

When a statement is final

A row can appear up to a few seconds after its created_at. Wait at least a minute after to before treating a statement as final. A statement you fetch sooner can gain a row when you fetch it again.

Posting time, not event time

Statements use posting time: the posting’s created_at, which is when the ledger recorded it. For a row created by an event, that is when the event was processed. It is later than the event’s own created_at and is never the event’s event_timestamp. There is no way to select statement rows by event_timestamp. You set event_timestamp on each event, and events can arrive out of order. Lot spending, holds, settlements, and expirations happen in posting order, so a balance built from event times would not match the ledger. For a customer-facing statement, show event_timestamp as the transaction date next to the posting date. See Timestamps for how the two timestamps relate.

Reading a HELD statement

A statement with bucket=HELD shows value entering and leaving HELD. Each row’s action_type tells you why: A settlement is a CREDIT entry with a negative HELD posting, so it appears as a negative CREDIT row with the same reference_id as the authorization credit. See Settlement journal entry and Ledger entries. For raw movement lists without running balances, the activity endpoints remain available: GET /v1/participants/{id}/activity/history and GET /v1/programs/{id}/history, including dual time filters (from/to on record time, event_from/event_to on event time).

Ledger summary

Per-asset totals and flows for dashboards:
Both filters are optional and combinable. Add from/to for a per-asset period rollforward (opening, flows, closing). Period redemption figures are gross, so a reversal after the window closes doesn’t rewrite history; all-time figures are net of reversals.
The ledger summary’s period view includes an other_adjustments_net residual. For audit work, prefer the liability rollforward, which decomposes every movement with no residual.

Program activity

Compare programs, or fetch one program’s scorecard:
Use since to exclude dormant programs. Prefer the by_asset rows over the top-level totals for any program with more than one asset, since the top-level figures sum across assets.

Fulfillment cost

Use the fulfillment-cost report to track gift-card orders and their costs. Results are grouped by program, order status, and currency. Amounts are in currency minor units, such as cents for USD. Use ledger reports to track the asset balances spent on those cards.
The date range selects orders by their authorization time. The report shows each order’s current status, so running the same report later can give a different breakdown. For example, an order still processing at month-end can appear as succeeded the next day. Add program_id to report on one program. See Get fulfillment cost report for the returned fields.

Journal entries

The journal is the full audit trail. Every aggregate above traces down to these rows. Each entry is an atomic set of postings (debits and credits) that balance to zero.
List entries with GET /v1/journal-entries, and fetch one entry with all its postings and its entry_hash with GET /v1/journal-entries/{id}. For the full filter reference (program, entity, asset, bucket, action_type, reference_id, time and amount ranges) and entry detail semantics, see the Ledger guide.

Common queries