> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scrip.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-Program Balances

> Pooled vs. partitioned balance modeling when one asset spans multiple programs

When one asset is linked to multiple programs, there are two ways to model member balances: pooled, where each member has one ledger entity and one combined balance, or partitioned, where each membership or account has its own ledger entity and its own balance. You choose a shape through your entity model. There is no configuration flag.

The shapes differ in member experience and in how ordinary per-program reports attribute activity. For `LOT`-mode assets, the redemption attribution report can also separate the original issuer from the redemption channel. Pick the shape before you issue value.

This guide builds on [lots and expiration](/guides/lots-and-expiration), [transfers](/guides/transfers), and [reporting](/guides/reporting).

## Pooled: One Entity Per Member

Link the asset to every program, and create one participant per member. Balances and lots belong to the participant and asset, not to any one program, so the member sees a single combined balance no matter which program issued the value.

```bash theme={null}
# Link the shared asset to a second program
POST /v1/programs/{programId}/assets
{"asset_id": "{asset_id}"}
```

A redemption through any linked `ACTIVE` program draws on the pooled balance. For `LOT`-mode assets, the oldest eligible lots are spent first across everything the member holds, regardless of which program issued each lot. Rule conditions read the same pooled number through `participant.balance.<symbol>`. See [CEL Expressions](/guides/cel-expressions#balances).

This is the right shape for a one-brand currency earned through multiple channels: a retailer with store and app programs, or an airline whose miles accrue through both flights and a status program. Members expect one number, and they get one number.

> Ordinary per-program reports attribute each redemption to the program it was redeemed through. For `LOT`-mode assets, use the [redemption attribution report](/api-reference/reporting/get-redemption-attribution) to break that value down by original issuer. See [How reporting attributes redemptions](#how-reporting-attributes-redemptions) before choosing this shape.

## Partitioned: One Entity Per Account

Create a separate participant entity for each membership or account, even when they belong to the same person. Each entity accrues into its own balance, and combining value is an explicit transfer.

This is how Chase models Ultimate Rewards: Sapphire Reserve and Freedom each accrue points into separate card-account balances, and moving points between cards is a deliberate action the member takes. In Scrip, each card account is its own participant, and the merge is a [transfer](/guides/transfers):

```bash theme={null}
POST /v1/transfers
{
  "program_id": "program-uuid",
  "source_external_id": "member-123-freedom",
  "asset_id": "asset-uuid",
  "description": "Combine Freedom points into Sapphire account",
  "recipients": [
    {"external_id": "member-123-sapphire", "amount": "25000"}
  ]
}
```

The transfer requires an `ACTIVE` program and both participants in `ACTIVE` status, and it produces a journal entry like any other balance movement. This makes cross-account movement auditable, but it does not bind a participant to one program. Callers still supply the intended linked `program_id` for transfers and redemptions because ordinary reporting follows that journal-entry channel.

## How Reporting Attributes Redemptions

Journal entries for program operations, such as earning, redemptions, and transfers, carry the `program_id` of the program the operation ran through. System entries such as expiration carry no `program_id` and report under a separate no-program row. Liability, rollforward, and activity reports therefore reflect the redemption channel, not the issuing program.

In the pooled shape, a member can earn through program A and redeem through program B. Program B's ordinary redemption line then includes value program A issued, so per-program cells diverge from per-program issuance, and a program's individual liability cell can go negative. Asset-level totals remain exact: the itemized lines of the [liability rollforward](/guides/reporting#liability-rollforward) always sum to the change in outstanding liability for the asset as a whole.

For `LOT`-mode assets, `GET /v1/reports/redemption-attribution` adds the missing settlement view. It groups consumed lot value by both original issuer and redemption channel. In the example above, value issued by program A and redeemed through program B appears as its own issued-by-A, redeemed-through-B line. Value whose issuer is unknown remains visible under a no-issuer line, and values are gross of reversals.

In the partitioned shape, your application keeps each account's operations in its intended program. Cross-program movement is visible as a transfer before any cross-program redemption attribution appears.

## Choosing a Shape

| If...                                                             | Choose                              |
| ----------------------------------------------------------------- | ----------------------------------- |
| Members expect one balance with no merge step                     | Pooled                              |
| Balances must remain operationally separate by account or partner | Partitioned                         |
| A pooled `LOT` balance needs issuer-vs-channel settlement         | Pooled, with redemption attribution |

A useful test: if members would be confused by holding two balances of the same currency, use pooled. For `LOT`-mode assets, finance can still answer "how much of program A's issuance was redeemed through program A or B" with redemption attribution. Use partitioned when the balances themselves must remain distinct, or when a `SIMPLE`-mode asset cannot provide lot-level issuer lineage.

For the mechanics of linking assets across programs, see [Programs](/guides/programs#linking-assets). For oldest-first spending and lot lifecycle, see [Lots and Expiration](/guides/lots-and-expiration).
