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

# Transfers

> Initiate and retrieve bank transfers, mobile money payouts, and stablecoin sends.

A transfer is a debit instruction from an entity's account to a counterparty's payment details. All transfers are asynchronous — the response reflects the initial queued state, and status updates are delivered via webhooks.

***

## The Transfer object

<ResponseField name="id" type="string">
  Unique transfer identifier.
</ResponseField>

<ResponseField name="account_id" type="string">
  The ID of the source account being debited.
</ResponseField>

<ResponseField name="entity_id" type="string">
  The ID of the entity that initiated the transfer.
</ResponseField>

<ResponseField name="counterparty_id" type="string">
  The ID of the recipient counterparty.
</ResponseField>

<ResponseField name="payment_detail_id" type="string">
  The ID of the payment detail record used to route this transfer.
</ResponseField>

<ResponseField name="type" type="string">
  Always `outflow` for transfers initiated via the API.
</ResponseField>

<ResponseField name="currency" type="string">
  ISO 4217 currency code (e.g. `USD`, `GBP`, `EUR`). Use `USC` for USDC and `UST` for USDT.
</ResponseField>

<ResponseField name="amount" type="number">
  Transfer amount in the smallest currency unit. `10000` = \$100.00 USD or £100.00 GBP.
</ResponseField>

<ResponseField name="applicable_fee" type="number">
  Fee charged for this transfer in the smallest currency unit.
</ResponseField>

<ResponseField name="status" type="string">
  Transfer status. One of `pending`, `processing`, `successful`, `failed`, or `reversed`.
</ResponseField>

<ResponseField name="status_reason" type="string">
  Human-readable description of the current status. For failures, indicates the cause — e.g. `insufficient_funds`, `invalid_account_details`, `compliance_hold`.
</ResponseField>

<ParamField body="payment_type" type="string" required>
  The payment type of the transfer. It can be bank-transfer, momo-transfer, stablecoin-transfer, and book-transfer.
</ParamField>

<ResponseField name="narration" type="string">
  Transfer description passed to the recipient's bank statement where supported.
</ResponseField>

<ResponseField name="unique_reference" type="string">
  The idempotency key provided at creation. Used to identify and deduplicate transfers.
</ResponseField>

<ResponseField name="meta" type="object">
  Arbitrary key-value metadata attached at creation.
</ResponseField>

<ResponseField name="created" type="number">
  Unix timestamp in milliseconds when the transfer was created.
</ResponseField>

<ResponseField name="updated" type="number">
  Unix timestamp in milliseconds when the transfer was last updated.
</ResponseField>

```json Example transfer object theme={null}
{
  "id": "01K7H0QM421E9CB5M24W5AK3Q3",
  "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
  "entity_id": "01K3HJAK85YJP13WJ41P3CWAVM",
  "counterparty_id": "01KM37EZ0AYCVDXJ3WDHXPPSZ9",
  "payment_detail_id": "pd_01KM37FAABC123DEF456GHI789",
  "type": "outflow",
  "currency": "GBP",
  "amount": 10000,
  "applicable_fee": 50,
  "status": "pending",
  "status_reason": "awaiting_processing",
  "payment_type": "bank-transfer",
  "narration": "Invoice payment INV-2025-001",
  "unique_reference": "PAY-2025-001",
  "meta": {},
  "created": 1760434049154,
  "updated": 1760434050159
}
```

### Transfer statuses

| Status       | Description                                                  |
| ------------ | ------------------------------------------------------------ |
| `pending`    | Transfer created and queued for processing.                  |
| `processing` | Being executed by the payment network.                       |
| `successful` | Delivered to the recipient.                                  |
| `failed`     | Could not be completed. Check `status_reason` for the cause. |
| `reversed`   | Completed transfer was subsequently reversed.                |

### Payment Types

| Type                  | Description                                                                                                                           |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `bank-transfer `      | Initiates a payout to a counterparty via a bank transfer rail (FPS, SEPA, ACH, Wire, SWIFT, and others)                               |
| `momo-transfer`       | Initiates a payout to a mobile money wallet. Supports M-Pesa, MTN, Airtel, Orange, Wave, and Tigo                                     |
| `stablecoin-trabsfer` | Initiates a stablecoin send to an on-chain wallet address. Supports USDC (USC) and USDT (UST) on Ethereum, Solana, Base, and Polygon. |
| `book-transfer`       | Book a transfer                                                                                                                       |

<Note>
  Subscribe to `outflows.created`, `outflows.completed`, `outflows.failed`, and `outflows.cancelled` webhooks to track transfers in real time. See [Event types](/webhooks/event-types).
</Note>

***

## Create a bank transfer

`POST /transfers`

Initiates a payout to a counterparty via a bank transfer rail (FPS, SEPA, ACH, Wire, SWIFT, and others). The payment method and routing scheme are derived from the payment detail record.

### Request parameters

<ParamField body="account_id" type="string" required>
  The ID of the source account to debit. The account must have sufficient available balance.
</ParamField>

<ParamField body="payment_detail_id" type="string" required>
  The ID of the payment detail record. Returned by `POST /payment-details`.
</ParamField>

<ParamField body="amount" type="number" required>
  Amount to send in the smallest currency unit. `10000` = \$100.00 USD or £100.00 GBP.
</ParamField>

<ParamField body="payment_type" type="string" required>
  The payment type of the transfer. It can be bank-transfer, momo-transfer, stablecoin-transfer, and book-transfer.
</ParamField>

<ParamField body="narration" type="string" required>
  Transfer description. Passed to the recipient's bank statement where the rail supports it. Maximum 100 characters.
</ParamField>

<ParamField body="unique_reference" type="string" required>
  Idempotency key. If a transfer with this reference already exists for the account, the original transfer is returned rather than creating a duplicate. Maximum 64 characters.
</ParamField>

<ParamField body="meta" type="object">
  Arbitrary key-value metadata. Values must be strings.
</ParamField>

### Request

<CodeGroup>
  ```bash FPS — GBP theme={null}
  curl -X POST https://api.nuvion.dev/transfers \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
      "payment_detail_id": "pd_01KM37FAABC123DEF456GHI789",
      "amount": 10000,
      "narration": "Invoice payment INV-2025-001",
      "payment_type": "bank-transfer",
      "unique_reference": "PAY-2025-001"
    }'
  ```

  ```bash ACH — USD theme={null}
  curl -X POST https://api.nuvion.dev/transfers \
    -H "Authorization: Bearer $NUVION_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
      "payment_detail_id": "pd_01KM37FABCD123EFG456HIJ789",
      "amount": 50000,
      "narration": "Contractor payment May 2025",
      "payment_type": "book-transfer",
      "unique_reference": "PAY-2025-002"
    }'
  ```
</CodeGroup>

### Response

Returns the created transfer object with `status: "pending"`.

```json theme={null}
{
  "id": "01K7H0QM421E9CB5M24W5AK3Q3",
  "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
  "entity_id": "01K3HJAK85YJP13WJ41P3CWAVM",
  "counterparty_id": "01KM37EZ0AYCVDXJ3WDHXPPSZ9",
  "payment_detail_id": "pd_01KM37FAABC123DEF456GHI789",
  "type": "outflow",
  "currency": "GBP",
  "amount": 10000,
  "applicable_fee": 50,
  "status": "pending",
  "status_reason": "awaiting_processing",
  "narration": "Invoice payment INV-2025-001",
  "unique_reference": "PAY-2025-001",
  "meta": {},
  "created": 1760434049154,
  "updated": 1760434050159
}
```

### Errors

| Code  | Description                                                                            |
| ----- | -------------------------------------------------------------------------------------- |
| `422` | Validation error — a required field is missing or invalid.                             |
| `422` | Insufficient funds in the source account.                                              |
| `404` | The `account_id` or `payment_detail_id` was not found.                                 |
| `409` | A transfer with this `unique_reference` already exists. Returns the original transfer. |

***

## Create a mobile money transfer

`POST /transfers`

Initiates a payout to a mobile money wallet. Supports M-Pesa, MTN, Airtel, Orange, Wave, and Tigo.

### Request parameters

<ParamField body="account_id" type="string" required>
  The ID of the source account to debit.
</ParamField>

<ParamField body="payment_detail_id" type="string" required>
  The ID of the payment detail record with `payment_method: "momo-transfer"`.
</ParamField>

<ParamField body="amount" type="number" required>
  Amount in the smallest currency unit.
</ParamField>

<ParamField body="payment_type" type="string" required>
  The payment type of the transfer. It can be bank-transfer, momo-transfer, stablecoin-transfer, and book-transfer.
</ParamField>

<ParamField body="narration" type="string" required>
  Transfer description. Maximum 100 characters.
</ParamField>

<ParamField body="unique_reference" type="string" required>
  Idempotency key. Maximum 64 characters.
</ParamField>

<ParamField body="meta" type="object">
  Arbitrary key-value metadata. Values must be strings.
</ParamField>

### Request

```bash theme={null}
curl -X POST https://api.nuvion.dev/transfers \
  -H "Authorization: Bearer $NUVION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
    "payment_detail_id": "pd_01KM37FABCD456EFG789HIJ012",
    "amount": 150000,
    "narration": "Freelancer payout April 2025",
    "payment_type": "momo-transfer",
    "unique_reference": "MOMO-2025-001"
  }'
```

### Response

Returns the created transfer object with `status: "pending"`.

```json theme={null}
{
  "id": "01K7H2PNABC123DEF456GHI789",
  "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
  "entity_id": "01K3HJAK85YJP13WJ41P3CWAVM",
  "counterparty_id": "01KM37EZ0AYCVDXJ3WDHXPPSZ9",
  "payment_detail_id": "pd_01KM37FABCD456EFG789HIJ012",
  "type": "outflow",
  "currency": "KES",
  "amount": 150000,
  "applicable_fee": 0,
  "status": "pending",
  "status_reason": "awaiting_processing",
  "narration": "Freelancer payout April 2025",
  "unique_reference": "MOMO-2025-001",
  "meta": {},
  "created": 1760434049154,
  "updated": 1760434050159
}
```

***

## Create a stablecoin transfer

`POST /transfers`

Initiates a stablecoin send to an on-chain wallet address. Supports USDC (`USC`) and USDT (`UST`) on Ethereum, Solana, Base, and Polygon.

### Request parameters

<ParamField body="account_id" type="string" required>
  The ID of the source account to debit. Must hold a stablecoin balance (`USC` or `UST`).
</ParamField>

<ParamField body="payment_detail_id" type="string" required>
  The ID of the payment detail record with `payment_method: "stablecoin-transfer"`.
</ParamField>

<ParamField body="amount" type="number" required>
  Amount in the smallest stablecoin unit. `100000000` = 100.00 USDC.
</ParamField>

<ParamField body="narration" type="string" required>
  Transfer description. Maximum 100 characters.
</ParamField>

<ParamField body="payment_type" type="string" required>
  The payment type of the transfer. It can be bank-transfer, momo-transfer, stablecoin-transfer, and book-transfer.
</ParamField>

<ParamField body="unique_reference" type="string" required>
  Idempotency key. Maximum 64 characters.
</ParamField>

<ParamField body="meta" type="object">
  Arbitrary key-value metadata. Values must be strings.
</ParamField>

### Request

```bash theme={null}
curl -X POST https://api.nuvion.dev/transfers \
  -H "Authorization: Bearer $NUVION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
    "payment_detail_id": "pd_01KM37FABCD789EFG012HIJ345",
    "amount": 100000000,
    "narration": "Token distribution batch 3",
    "payment_type": "stablecoin-transfer",
    "unique_reference": "STABLE-2025-001"
  }'
```

### Response

Returns the created transfer object with `status: "pending"`.

```json theme={null}
{
  "id": "01K7H3QABC456DEF789GHI012",
  "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
  "entity_id": "01K3HJAK85YJP13WJ41P3CWAVM",
  "counterparty_id": "01KM37EZ0AYCVDXJ3WDHXPPSZ9",
  "payment_detail_id": "pd_01KM37FABCD789EFG012HIJ345",
  "type": "outflow",
  "currency": "USC",
  "amount": 100000000,
  "applicable_fee": 0,
  "status": "pending",
  "status_reason": "awaiting_processing",
  "narration": "Token distribution batch 3",
  "unique_reference": "STABLE-2025-001",
  "meta": {},
  "created": 1760434049154,
  "updated": 1760434050159
}
```

***

## Get a transfer

`GET /transfers/{transfer_id}`

Retrieves a single transfer by ID.

### Path parameters

<ParamField path="transfer_id" type="string" required>
  The transfer ID.
</ParamField>

### Query parameters

<ParamField query="entity_id" type="string">
  Required when authenticating with an API key.
</ParamField>

### Request

```bash theme={null}
curl "https://api.nuvion.dev/transfers/01K7H0QM421E9CB5M24W5AK3Q3" \
  -H "Authorization: Bearer $NUVION_API_KEY"
```

### Response

Returns the [Transfer object](#the-transfer-object).

***

## List transfers

`GET /transfers`

Returns a paginated list of transfers for an entity or account.

### Query parameters

<ParamField query="entity_id" type="string">
  Filter by entity ID. Required when authenticating with an API key.
</ParamField>

<ParamField query="account_id" type="string">
  Filter by source account.
</ParamField>

<ParamField query="status" type="string">
  Filter by status. One of `pending`, `processing`, `successful`, `failed`, or `reversed`.
</ParamField>

<ParamField query="limit" type="integer">
  Number of results to return. Between 1 and 100. Defaults to `20`.
</ParamField>

<ParamField query="cursor" type="string">
  Pagination cursor from a previous response. Omit for the first page.
</ParamField>

### Request

```bash theme={null}
curl "https://api.nuvion.dev/transfers?entity_id=01K3HJAK85YJP13WJ41P3CWAVM&status=successful&limit=20" \
  -H "Authorization: Bearer $NUVION_API_KEY"
```

### Response

```json theme={null}
{
  "data": [
    {
      "id": "01K7H0QM421E9CB5M24W5AK3Q3",
      "account_id": "01K747KD7QW8KQS2GRD8MQBT55",
      "entity_id": "01K3HJAK85YJP13WJ41P3CWAVM",
      "counterparty_id": "01KM37EZ0AYCVDXJ3WDHXPPSZ9",
      "payment_detail_id": "pd_01KM37FAABC123DEF456GHI789",
      "type": "outflow",
      "currency": "GBP",
      "amount": 10000,
      "applicable_fee": 50,
      "status": "successful",
      "status_reason": "processing_complete",
      "narration": "Invoice payment INV-2025-001",
      "unique_reference": "PAY-2025-001",
      "meta": {},
      "created": 1760434049154,
      "updated": 1760434050159
    }
  ],
  "meta": {
    "pagination": {
      "has_next": false,
      "has_previous": false,
      "next_cursor": null,
      "previous_cursor": null,
      "total_count": 1
    }
  }
}
```
