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

# Transfers overview

> The object that moves money, the seven states it can be in, and where FX quotes fit.

A **transfer** moves value out of one of your accounts to a destination. It is the only object in the API that debits a balance, and it is deliberately the last step in a sequence — by the time you create one, the destination has been resolved and verified, the rate has been locked if the currencies differ, and the amounts have been previewed.

## The sequence

```mermaid theme={null}
flowchart LR
    D["Destination<br/>24h · single use"] --> Q["FX quote<br/>only if converting"]
    Q --> P["Preview<br/>fee · totalDebit"]
    P --> T["Transfer<br/>externalReference"]
    D --> P
    T --> W["Webhook<br/>fiat.withdrawal.*"]
```

Only the transfer is required. Preview is optional but cheap, and a quote is mandatory whenever the source and destination currencies differ.

## Statuses

Seven, and only some of them are ones you will see in a response.

| Status | Meaning | Terminal |
| - | - | - |
| `awaiting_approval` | Your business requires a human approval | No |
| `submitting` | Transient, internal. Never published to a webhook | No |
| `pending` | Accepted and submitted; settlement is in flight | No |
| `completed` | Settled | Yes |
| `failed` | Terminal failure. `failureCode` and `failureReason` say why | Yes |
| `reversed` | A completed movement was reversed | Yes |
| `rejected` | An approver refused it | Yes |

```mermaid theme={null}
stateDiagram-v2
    [*] --> awaiting_approval: policy requires approval
    [*] --> submitting: no approval needed
    awaiting_approval --> submitting: approved (dashboard only)
    awaiting_approval --> rejected: rejected (dashboard only)
    submitting --> pending
    submitting --> failed
    pending --> completed
    pending --> failed
    completed --> reversed
```

<Warning>
  **A transfer awaiting approval cannot be approved through this API.** Approval and rejection are dashboard actions. If your business has an approval policy switched on, API-initiated transfers stop at `awaiting_approval` until a person acts.
</Warning>

## Amounts change form

This catches nearly everyone. The request and the response are not in the same units.

| | Form | Example for ₦25,000 |
| - | - | - |
| Request (`sourceAmount`) | Integer of minor units, as a string | `"2500000"` |
| Response (`sourceAmount`) | Decimal display string | `"25000.00"` |
| Account `balance` | Integer of minor units, as a string | `"2500000"` |

Never feed a response amount back into a request. `totalDebit` — `sourceAmount` plus `fee` — is what actually leaves the account, and is the figure to put in front of whoever approves the payment.

## `externalReference` is the idempotency key

You choose it, it is unique within your business, and reusing it returns the existing transfer without looking at the rest of your payload.

Two consequences worth internalising now:

* **A different payment under a used reference returns the old transfer** and moves nothing.
* **A failed transfer keeps its reference.** Retrying with it returns the failure, not a new attempt.

## FX quotes

A quote locks a rate for exactly one transfer. It is bound to five things — source account, destination, both currencies, and the side with its amount — and spending it on anything that differs is refused.

Its expiry comes from the FX provider rather than a fixed Sakawave window, so read `expiresAt` instead of assuming a duration. Like a destination, it is single use.

## Events

Transfers reach your endpoint as **`fiat.withdrawal.*`** events. There are no `transfer.*` events.

| Event | When |
| - | - |
| `fiat.withdrawal.created` | The transfer was accepted |
| `fiat.withdrawal.completed` | It settled |
| `fiat.withdrawal.failed` | It failed terminally |

The payload is the posted ledger transaction, with the transfer described inside `relatedOperation`. See [webhook events](/webhooks/events).

## Next

<CardGroup cols={2}>
  <Card title="Introduction" icon="book-open" href="/services/transfers/introduction">
    Why a transfer needs four prior calls.
  </Card>

  <Card title="Get started" icon="play" href="/services/transfers/get-started">
    A same-currency transfer end to end.
  </Card>

  <Card title="Setup and configuration" icon="sliders" href="/services/transfers/setup-and-configuration">
    Limits, approval policy, and pacing a batch.
  </Card>

  <Card title="Cross-currency transfers" icon="arrow-right-left" href="/services/transfers/cross-currency-transfers">
    Quotes, corridors, and what binds to what.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.