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

# Transfer API Reference

> Reference for the GoPay B2C transfer initiation API

# Transfer API Reference

This reference documents the B2C (business-to-customer) transfer initiation API.

## Base URL

The B2C API is a separate deployment from the C2B payment API — use the transfers base URL provided during onboarding. Because the host is part of the signed canonical string, signatures are bound to the exact host and environment you call.

## Authentication

Requests are authenticated with a detached Ed25519 signature over the [v1 canonical string](/getting-started/authentication#the-canonical-string-v1), sent via the `X-Public-Key`, `X-Signature`, `X-Timestamp`, and `X-Request-ID` headers. Your API key must carry the **`b2c` permission**.

See [Authentication](/getting-started/authentication) for the full scheme, signing helpers, and the replay/rate-limit rules that apply to every request.

## Initiate Transfer

Creates a payout transaction and debits your merchant wallet. The payout itself settles asynchronously; the final result is delivered by webhook.

**Endpoint**

```
POST /api/v1/initiate-transfer
```

### Request Body

| Parameter               | Type   | Required | Description                                                  |
| ----------------------- | ------ | -------- | ------------------------------------------------------------ |
| `mer_id`                | string | Yes      | Your merchant ID                                             |
| `amount`                | number | Yes      | Transfer amount; must be > 0 and at most 10,000,000          |
| `currency`              | string | Yes      | One of: `ETB`, `KES`, `USD`, `EUR`, `GBP`                    |
| `reason`                | string | Yes      | Purpose of the transfer (included in the settlement webhook) |
| `receiver_phone_number` | string | Yes      | Ethiopian mobile number: `09XXXXXXXX` or `+2519XXXXXXXX`     |
| `client_reference`      | string | Yes      | Your unique reference for reconciliation                     |
| `notify_url`            | string | Yes      | Absolute HTTPS URL that receives the settlement webhook      |
| `bank_id`               | string | Yes      | Payout rail: `"1"`–`"5"` (see table below)                   |

Validation failures are accumulated — the error message lists every failing field.

### Payout Rails

| `bank_id` | Rail              |
| --------- | ----------------- |
| `1`       | Telebirr          |
| `2`       | CBE Birr          |
| `3`       | Awash Bank        |
| `4`       | Dashen Bank       |
| `5`       | Bank of Abyssinia |

### Response

<Tabs>
  <Tab title="Success (200 OK)">
    ```json theme={null}
    {
        "message": "B2C transaction initiated successfully",
        "txn_id": "b2c_tx_6fcb15a983c54a7e97b1",
        "status": "pending"
    }
    ```

    A 200 means the transaction was recorded and your wallet debited. Track `txn_id` — the settlement webhook references it.
  </Tab>

  <Tab title="Error (non-2xx)">
    All errors share the standard shape — see [Errors](/getting-started/errors) for the full code taxonomy:

    ```json theme={null}
    {
        "error": {
            "code": "INSUFFICIENT_FUNDS",
            "message": "insufficient funds",
            "requestId": "req_..."
        }
    }
    ```

    `INSUFFICIENT_FUNDS` (HTTP 402) is specific to transfers: your merchant wallet balance cannot cover the payout.
  </Tab>
</Tabs>

<Warning>
  Retrying transfers moves money — be careful. On `UPSTREAM_TIMEOUT` or `UPSTREAM_UNAVAILABLE`, check for a settlement webhook or contact support with the `requestId` before resubmitting, and always use a stable `client_reference` so duplicates can be detected during reconciliation. The wallet debit itself is idempotent per transaction, so a single accepted transfer can never double-charge.
</Warning>

### Transfer Statuses

Delivered via webhook (see [B2C Callbacks](/webhooks/b2c-callbacks)):

| Status      | Description                                      |
| ----------- | ------------------------------------------------ |
| `completed` | Payout settled to the recipient                  |
| `failed`    | Payout failed; funds are returned to your wallet |
| `expired`   | Payout expired before settlement                 |
| `cancelled` | Payout was cancelled                             |
