> ## 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.

# Transfers

> Move funds between participants and groups within a program

Transfers move existing funds from one participant or group to one or more recipients. No new value is created: the source balance decreases by the exact total credited to all recipients. You might use them for peer-to-peer gifting, marketplace payouts with platform fees, or distributing a pool across multiple participants.

## Creating a Transfer

```bash theme={null}
POST /v1/transfers
{
  "program_id": "program-uuid",
  "source_external_id": "alice",
  "asset_id": "asset-uuid",
  "description": "Gift to Bob",
  "recipients": [
    {"external_id": "bob", "amount": "50"}
  ]
}
```

| Field                   | Required | Description                                                                                                             |
| ----------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| `program_id`            | Yes      | Program context                                                                                                         |
| `asset_id`              | Yes      | Which asset to transfer                                                                                                 |
| `source_external_id`    | One of   | Participant sending funds (by your external ID). Mutually exclusive with `source_group_id` and `source_participant_id`. |
| `source_participant_id` | One of   | Participant sending funds (by Scrip UUID). Mutually exclusive with `source_external_id` and `source_group_id`.          |
| `source_group_id`       | One of   | Group sending funds. Mutually exclusive with `source_external_id` and `source_participant_id`.                          |
| `recipients`            | Yes      | Array of 1-100 recipients, each with `external_id`, `participant_id`, or `group_id` and an `amount`                     |
| `description`           | Yes      | Reason for the transfer (1-500 characters)                                                                              |
| `idempotency_key`       | No       | Prevents duplicate transfers on retry. Same key + different payload returns `409`.                                      |

The source's `available` balance is debited for the total amount, and each recipient's `available` balance is credited. The entire transfer is atomic: if any part fails, nothing moves.

## Multi-Recipient Transfers

Split funds across multiple recipients in a single request:

```bash theme={null}
POST /v1/transfers
{
  "program_id": "program-uuid",
  "source_external_id": "alice",
  "asset_id": "asset-uuid",
  "description": "Marketplace payout with platform fee",
  "recipients": [
    {"external_id": "bob", "amount": "95"},
    {"external_id": "platform_account", "amount": "5"}
  ]
}
```

Up to 100 recipients per transfer. This covers marketplace payouts with platform fees, prize splits, revenue sharing, and similar distributions.

## Identifying Participants and Groups

The source and recipients can be identified by external ID, Scrip UUID, or group ID. Each identifier is mutually exclusive. Provide exactly one per source or recipient.

For the source, use `source_external_id`, `source_participant_id`, or `source_group_id`. For recipients, use `external_id`, `participant_id`, or `group_id` on each entry.

```bash theme={null}
POST /v1/transfers
{
  "program_id": "program-uuid",
  "source_group_id": "team-pool-uuid",
  "asset_id": "asset-uuid",
  "description": "Team bonus distribution",
  "recipients": [
    {"external_id": "alice", "amount": "200"},
    {"external_id": "bob", "amount": "200"},
    {"group_id": "reserve-fund-uuid", "amount": "100"}
  ]
}
```

## LOT-Mode Assets

For `LOT`-mode assets, transfers spend the source's oldest eligible lots first and create new lots for each recipient. The new lots get fresh `created_at` timestamps, so their age resets to zero. Source lot expiration dates do not carry over to the recipient. Destination lots do preserve the source lots' issuer lineage, so [redemption attribution](/guides/multi-program-balances#how-reporting-attributes-redemptions) still reports the original issuer.

## Response

The response includes a `journal_entry_id` for tracing the transfer in the ledger, along with computed totals.

```json theme={null}
{
  "journal_entry_id": "uuid",
  "asset_id": "asset-uuid",
  "source_id": "uuid",
  "total_amount": "300.50",
  "recipient_count": 3
}
```

## Transfer vs. Credit vs. Adjust

| Operation              | What it does                                     | Use case                         |
| ---------------------- | ------------------------------------------------ | -------------------------------- |
| Transfer               | Moves existing funds from source to recipients   | P2P gifting, marketplace payouts |
| `CREDIT` (rule action) | Creates new funds (or draws from program wallet) | Rewards, bonuses, earning points |
| Adjust (API)           | Manual credit or debit on a single participant   | Customer service, corrections    |

## Requirements

* Source and all recipients must be `ACTIVE`. To recover funds from a closed account, use [forfeit](/guides/balance-operations#forfeit), which is allowed on `CLOSED` participants.
* Program must be `ACTIVE` (not `SUSPENDED` or `ARCHIVED`)
* Source must have sufficient `available` balance for the total transfer amount. If insufficient, the entire transfer rolls back.
* Source and recipient cannot be the same entity
* Idempotency keys are scoped per program. Replaying a request with the same key and parameters returns the original result. Replaying with the same key but different parameters returns a 409 conflict.
