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

# NGN

> Receive, trade, and withdraw Nigerian naira using bank transfers and cNGN.

The NGN wallet holds Nigerian naira. Customers can receive funds by bank
transfer or, when enabled, cNGN on Base. Both routes credit the same NGN wallet.
Available NGN can fund trades or withdrawals, subject to account limits.

Use `currency: "NGN"` for wallet activity and `settlement_rail: "CNGN"` for
cNGN transfers. Both use the NGN balance. NGN amounts are decimal strings
with two decimal places; use decimal arithmetic rather than floating point.

## Before you start

Set `STABYL_BASE_URL` to your [environment's API URL](/docs/environments.md),
including `/v1`. Authenticated reads require `X-Api-Key` with `wallets:view`.
Withdrawal quotes and submissions require `wallets:withdraw` and
[Ed25519 request signing](/docs/withdrawals.md#request-signing).

In production, approved KYB is required to retrieve deposit instructions and
submit withdrawals. Read route availability before offering a deposit or
withdrawal option:

```bash theme={null}
curl "$STABYL_BASE_URL/partner/wallets/chains?currency=NGN"
```

Check each rail's `deposit_enabled` and `withdrawal_enabled`, and the same
flags on its network routes. Bank rails have no blockchain routes. CNGN uses
`network: "evm"` and `chain.slug: "base"`. Availability can differ by environment;
the presence of a rail in the response does not mean it is enabled.

## Receive NGN by bank transfer

Retrieve your deposit account:

```bash theme={null}
curl "$STABYL_BASE_URL/partner/wallets/fiat/deposit-account?currency=NGN" \
  -H "X-Api-Key: $STABYL_API_KEY"
```

Show the returned bank name, account name, and account number exactly.
Subscribe to `deposit.success` and `deposit.failed`, and reconcile activity
through [wallet transactions](/docs/wallet-transactions.md):

```bash theme={null}
curl "$STABYL_BASE_URL/partner/wallets/transactions?currency=NGN&tx_type=deposit" \
  -H "X-Api-Key: $STABYL_API_KEY"
```

Store the transaction `id` as your reconciliation identifier. Follow
`next_cursor` to retrieve subsequent pages. See
[Fiat deposit accounts](/docs/fiat-deposit-accounts.md) for bank discovery and
account verification.

## Read balances and trade

Call `GET /partner/wallets/balances/overview`. Read the NGN entry in
`data.balances` and the separate `data.withdrawable.ngn` value:

| Field | How to use it |
| - | - |
| `total` | Total NGN balance, including available and locked funds. |
| `available` | NGN available to spend or trade. Use this for your trading balance display. |
| `locked` | Funds unavailable for spending, including pending activity and CNGN awaiting conversion capacity. |
| `withdrawable.ngn` | NGN eligible for withdrawal after credit restrictions; may be `null` when temporarily unavailable. Use withdrawal quotes for rail-specific limits and fees. |

Use the returned `available` amount directly; it already excludes locked funds.
A balance read does not reserve funds; the trade or withdrawal request checks
availability when submitted. Use
[Exchange](/docs/exchange-overview.md) to discover markets and place trades.

## Withdraw NGN to a bank

Quote with `POST /partner/wallets/withdrawal/quotes`, using `currency: "NGN"`
and bank-account `items`. Submit the same intent to
`POST /partner/wallets/withdrawals` with a stable `idempotency_key`.
See [Single withdrawals](/docs/withdrawals.md) for request bodies and signing, or
[Bulk withdrawals](/docs/bulk-withdrawals.md) for multiple beneficiaries.

Read the `bank_transfer` quote's `status`, `max_withdrawable_amount`, `fee`,
and `debit_amount`. The maximum is recipient principal after allowing for
fees and applicable limits. Funds awaiting CNGN conversion are excluded.
A valid request above the maximum returns an unavailable quote with the
current maximum, so your application can offer a smaller amount.

Store the submitted transaction ID. A `processing` response is not payment
completion: follow wallet transactions and
[withdrawal events](/docs/webhook-withdrawal-events.md) for the final outcome.

## cNGN

cNGN is a naira-denominated digital currency. On Stabyl, customers can receive
and send cNGN on **Base** through their NGN wallet. Amounts convert at
**1 cNGN = ₦1**, before fees. Use `NGN` as the wallet currency and `CNGN` as
the settlement rail in API requests.

A cNGN deposit may be credited before its full value is available for trading
or bank withdrawal. Your integration should check conversion availability
before showing deposit instructions, then use balances and withdrawal quotes
to show what the customer can do with credited funds.

### Check conversion capacity

Check the cNGN route's enabled flags using
`GET /partner/wallets/chains?currency=NGN`. Then check how much cNGN can
currently convert to spendable NGN:

```bash theme={null}
curl "$STABYL_BASE_URL/partner/wallets/rails/CNGN/pool" \
  -H "X-Api-Key: $STABYL_API_KEY"
```

```json theme={null}
{
  "status": "success",
  "data": {
    "rail": "CNGN",
    "currency": "NGN",
    "cap": "500000000.00",
    "utilized": "450000000.00",
    "available": "50000000.00",
    "status": "available",
    "as_of": "2026-10-20T12:00:00Z"
  }
}
```

Amounts are NGN decimal strings. `cap` is the total conversion limit,
`utilized` is the amount in use, and `available` is the remaining capacity
at `as_of`.

| `status` | How to use it |
| - | - |
| `available` | Show the current `available` amount. |
| `exhausted` | Explain that new deposits may need to wait before trading or bank withdrawal. |
| `paused` | Explain that conversion to spendable NGN is temporarily paused. |

> [!NOTE]
>
> Availability is shared across customers and can change before a deposit
> arrives. This response does not reserve capacity. A deposit route must also
> be enabled before you offer it.

For a `503` response, show availability as temporarily unknown and retry
with backoff. The rail path accepts either `CNGN` or `cngn`; responses use `CNGN`.

### Receive cNGN

Retrieve the Base deposit address:

```bash theme={null}
curl "$STABYL_BASE_URL/partner/wallets/crypto/address?chain=evm&slug=base" \
  -H "X-Api-Key: $STABYL_API_KEY"
```

Show **cNGN on Base**, the returned address, any memo, and the route's
`minimum_deposit_amount`. Customers must send the supported token on the
correct network.

Subscribe to [deposit events](/docs/webhook-deposit-events.md) and read
[wallet transactions](/docs/wallet-transactions.md) to track the deposit. cNGN
activity uses `currency: "NGN"` and `settlement_rail: "CNGN"`. Store the wallet
transaction `id`. If `required_action.type` is `travel_rule`, complete the
[Travel Rule flow](/docs/travel-rule-deposit-info.md).

The standard deposit fee is **0.02% (2 basis points)**. Account pricing may
differ; discovery shows standard pricing, while the transaction records the
applied fee and net NGN credit.

### Show the customer's usable balance

`deposit.success` confirms that the deposit was credited. It does not guarantee
that the full amount is available for trading or bank withdrawal. Refresh
`GET /partner/wallets/balances/overview` after the deposit:

| Customer action | Value to use |
| - | - |
| Trade or spend NGN | The NGN balance's `available` amount. |
| View funds not yet available to spend | The NGN balance's `locked` amount, which also includes other holds. |
| Withdraw to a bank or as cNGN | That rail's withdrawal quote and `max_withdrawable_amount`. |

### When capacity returns

Funds awaiting conversion become available automatically when conversion
completes. This can happen in parts; no conversion request is needed and no
completion time is guaranteed. Customers can also request a cNGN withdrawal
of funds awaiting conversion, subject to the withdrawal quote.

### Track conversion progress

Use the **incoming wallet transaction ID** to read progress:

```bash theme={null}
curl "$STABYL_BASE_URL/partner/wallets/transactions/$TRANSACTION_ID/conversion" \
  -H "X-Api-Key: $STABYL_API_KEY"
```

```json theme={null}
{
  "status": "success",
  "data": {
    "transaction_id": "019a0430-0000-7000-8000-000000000001",
    "revision": 3,
    "currency": "NGN",
    "settlement_rail": "CNGN",
    "initially_restricted_amount": "10000000.00",
    "released_amount": "4000000.00",
    "returned_amount": "1000000.00",
    "remaining_amount": "5000000.00",
    "status": "pending"
  }
}
```

| Field | Meaning |
| - | - |
| `revision` | Increasing version of this transaction's progress. Keep the highest version received. |
| `initially_restricted_amount` | Net deposit amount that initially awaited conversion. |
| `released_amount` | Cumulative amount that has become available through conversion. |
| `returned_amount` | Cumulative amount withdrawn as cNGN or sent to another Stabyl account while awaiting conversion. |
| `remaining_amount` | Amount still awaiting conversion or return. This can include a pending withdrawal; it is not a withdrawable balance. |
| `status` | `pending` while an amount remains; `completed` when none remains. |

All amounts are NGN strings, net of the deposit fee. `completed` can mean
funds were converted, returned, or both. A deposit available in full from the
start has zero amounts and is already completed.

Treat this response as progress for the original deposit, not a new credit.
Refresh balances and quotes for current spending and withdrawal amounts.
If the endpoint returns `404`, progress is not available: check the transaction
ID and deposit status rather than marking it completed.

### Subscribe to conversion updates

You can poll the progress endpoint or subscribe to the optional
`conversion.updated` webhook. Add it to your endpoint's `event_types` alongside
`deposit.action_required`, `deposit.success`, and `deposit.failed`. Use
`POST /partner/webhooks` to create an endpoint or
`PUT /partner/webhooks/{webhook_id}` to replace its configuration, retaining
all topics you need. These events require `wallets:view`; managing the endpoint
also requires `webhooks:manage`.

The event's `data` matches the conversion progress response:

```json theme={null}
{
  "id": "30f0c0a3-99e0-56b4-89cf-5398b856da06",
  "type": "conversion.updated",
  "version": 1,
  "occurred_at": "2026-10-20T12:05:00Z",
  "data": {
    "transaction_id": "019a0430-0000-7000-8000-000000000001",
    "revision": 3,
    "currency": "NGN",
    "settlement_rail": "CNGN",
    "initially_restricted_amount": "10000000.00",
    "released_amount": "4000000.00",
    "returned_amount": "1000000.00",
    "remaining_amount": "5000000.00",
    "status": "pending"
  }
}
```

Follow the [webhook delivery contract](/docs/webhooks.md#delivery-contract) to
verify signatures and acknowledge deliveries. Deduplicate by event `id`, and
only replace stored progress with a higher `revision` for the same transaction.
Events can repeat or arrive out of order, including before `deposit.success`.
`version` identifies the event format; `revision` identifies transaction progress.
Use the progress endpoint to recover missed updates. A conversion event is not
another deposit and does not incur another deposit fee.

### Withdraw as cNGN

Request a quote with `currency: "NGN"`, `settlement_rail: "CNGN"`, and a Base
recipient address. Send this body to the signed
`POST /partner/wallets/withdrawal/quotes` endpoint:

```json theme={null}
{
  "currency": "NGN",
  "settlement_rail": "CNGN",
  "items": [
    {
      "client_item_id": "cngn-withdrawal-1",
      "amount": "10000000.00",
      "destination": {
        "type": "crypto_address",
        "chain": "evm",
        "slug": "base",
        "address": "0x1111111111111111111111111111111111111111"
      }
    }
  ]
}
```

Replace the example address with the recipient's address. Read `status`,
`max_withdrawable_amount`, `fee`, `debit_amount`, and `estimated_receive` before
submitting. If unavailable, use `reason_code` and the current maximum to help
the customer choose another amount or route. To compare with a bank withdrawal,
request a separate quote using a bank destination.

**Returning funds that are still awaiting conversion as cNGN has no withdrawal
fee.** The original deposit fee still applies. Other cNGN withdrawals normally
cost **0.02% (2 basis points)**, subject to account pricing. A withdrawal that
includes both types of funds is charged only on the amount already available
as NGN. Always display the fee returned by the quote.

For example, a customer with ₦1 million available and ₦10 million awaiting
conversion can request the latter as cNGN without a withdrawal fee. A bank
withdrawal can use only the available ₦1 million, allowing for fees and limits.
Use fresh quotes to determine the amounts currently permitted on each rail.

Submit the same withdrawal details to `POST /partner/wallets/withdrawals`,
adding a stable `idempotency_key`. Follow [Single withdrawals](/docs/withdrawals.md)
for signing and retry handling. A quote does not reserve funds or require a
quote ID on submission. Track the returned withdrawal transaction ID and
[withdrawal events](/docs/webhook-withdrawal-events.md) for completion; conversion
progress alone does not confirm that the recipient was paid.


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