GET STARTED
Overview
Azza exposes a JSON REST API for cNGN to NGN bank offramps on Base and BNB Smart Chain. Create a quote, review the verified recipient and fees, then track the resulting operation through deposit verification and bank payout.
GET STARTED
Authentication
An Azza administrator invites your company and approves scopes. The invited owner signs in to the API partner dashboard, creates a live key with a fresh emailed code, and copies its secret once. Keep that secret in your backend or secret manager.
curl 'https://<your-azza-api-host>/api/v1/offramps/banks' \
-H 'Authorization: Bearer <your-live-api-key>'Dashboard sessions authenticate a person to manage keys. They cannot authenticate payment API calls. API keys cannot sign in to the dashboard. Never place either credential in a browser bundle or mobile app.
GET STARTED
Idempotency & retries
Send an Idempotency-Key on quote creation, partner-balance execution, and external-transfer confirmation. It must be 1–128 letters, numbers, periods, underscores, colons, or hyphens. Persist one stable key per attempted action.
| Situation | Action |
|---|---|
| Response lost or timed out | Read the quote or operation, then retry only the identical request with the same key. |
| New quote or new action | Create a new key; never recycle a key with changed details. |
| Transfer outcome uncertain | Check chain and wallet activity first. Never automatically send another transfer. |
OFFRAMP GUIDE
External customer wallet
Use this mode when your customer sends cNGN directly from a connected wallet. Each quote supplies one dedicated deposit address and an operationId. The customer does not need an Azza user ID.
- Fetch
/offramps/banksand/offramps/limits; the limit applies to the NGN payout after fees. - Create a quote with the connected wallet as
expectedSenderAddress. - Review the verified bank name, fee, token contract, exact amount, address, and deadline. Send one transfer.
- After a successful receipt, submit the hash and poll the operation. Azza independently verifies deposit and sweep webhooks before payout.
curl -X POST 'https://<your-azza-api-host>/api/v1/offramps/quotes' \
-H 'Authorization: Bearer <your-live-api-key>' \
-H 'Idempotency-Key: quote-<your-stable-id>' \
-H 'Content-Type: application/json' \
--data '{
"fundingMode": "external_deposit",
"assetId": "cngn-base",
"network": "Base",
"sourceAmount": "3000.00",
"expectedSenderAddress": "0x<customer-wallet-address>",
"bankAccount": {
"bankCode": "<code-from-banks>",
"accountNumber": "<10-digit-account-number>"
}
}'For BNB Smart Chain, use assetId: cngn-bep20 and network: Bep20.
{
"data": {
"id": "<quote-id>",
"status": "open",
"sourceAmount": "3000.000000",
"payoutAmount": "<ngn-after-fees>",
"feeAmount": "<cngn-fee>",
"bankAccount": { "accountName": "<verified-name>" },
"expiresAt": "<ISO-8601-time>",
"deposit": {
"operationId": "<operation-id>",
"address": "0x<dedicated-deposit-address>",
"tokenAddress": "0x<approved-cngn-contract>",
"amount": "3000.000000",
"deadline": "<ISO-8601-time>"
}
},
"requestId": "<request-id>"
}curl -X POST 'https://<your-azza-api-host>/api/v1/offramps/<operation-id>/confirm' \
+ -H 'Authorization: Bearer <your-live-api-key>' \
+ -H 'Idempotency-Key: confirm-<your-stable-id>' \
+ -H 'Content-Type: application/json' \
+ --data '{
"transactionHash": "0x<64-hex-character-hash>",
"network": "Base"
}'Confirm requires offramps:execute and a stable idempotency key. A submitted hash is only a hint; it cannot authorize payout without verified provider and chain evidence. A deposit after expiry, wrong amount, wrong token, or sweep failure can enter reconciliation.
OFFRAMP GUIDE
API partner balance
Use this mode when you have already received the customer’s payment on your side and have confirmed cNGN in your dedicated Azza funding address. Do not use the external-wallet confirm endpoint for this mode.
- Provision or read your funding address with
/offramps/funding-addresses/:network. Confirm available balance. - Create a
partner_balancequote and review the verified bank account and fee. These quotes expire after two minutes. - Call
POST /offrampsonce with your payment attestation and stable key. - Store the operation ID and poll
GET /offramps/:operationId.
curl -X POST 'https://<your-azza-api-host>/api/v1/offramps/quotes' \
+ -H 'Authorization: Bearer <your-live-api-key>' \
+ -H 'Idempotency-Key: quote-<your-stable-id>' \
+ -H 'Content-Type: application/json' \
+ --data '{
"fundingMode": "partner_balance",
"assetId": "cngn-base",
"network": "Base",
"sourceAmount": "3000.00",
"bankAccount": {
"bankCode": "<code-from-banks>",
"accountNumber": "<10-digit-account-number>"
}
}'curl -X POST 'https://<your-azza-api-host>/api/v1/offramps' \
-H 'Authorization: Bearer <your-live-api-key>' \
-H 'Idempotency-Key: payout-<your-stable-id>' \
-H 'Content-Type: application/json' \
--data '{
"quoteId": "<quote-id>",
"fundsReceivedByPartner": true,
"partnerPaymentReference": "<your-reference>"
}'REFERENCE
Endpoints & scopes
Paths below are relative to /api/v1. Use only scopes approved for your company. The :network path value is Base or Bep20.
| Method | Path | Scope | Purpose |
|---|---|---|---|
| GET | /offramps/banks | offramps:quote | Supported bank codes and names |
| GET | /offramps/limits | offramps:quote | Current NGN payout limits |
| POST | /offramps/quotes | offramps:quote | Create a verified bank quote |
| GET | /offramps/quotes/:quoteId | offramps:read | Retrieve an owned quote |
| POST | /offramps/funding-addresses/:network | offramps:funding | Provision a partner funding address |
| GET | /offramps/funding-addresses/:network | offramps:funding | Read address and available balance |
| POST | /offramps | offramps:execute | Execute a partner-balance quote |
| POST | /offramps/:operationId/confirm | offramps:execute | Submit an external transfer hash |
| GET | /offramps/:operationId | offramps:read | Read operation and payout state |
| POST | /quotes | quotes:create | Create an onramp quote only |
| GET | /quotes/:quoteId | quotes:read | Retrieve an onramp quote |
GET /offramps/banks returns bank codes and names used by quote validation. GET /offramps/limits returns minPayoutAmount and maxPayoutAmount for the NGN amount after cNGN fees.
REFERENCE
Responses & operation states
Successful responses wrap the result in data and include requestId. The X-Request-Id header carries the same support reference. Responses are not cached.
{
"data": {
"id": "<operation-id>",
"quoteId": "<quote-id>",
"state": "awaiting_deposit",
"sourceAmount": "3000.000000",
"payoutTransactionId": null,
"deposit": {
"confirmed": false,
"swept": false,
"verifiedTransactionHash": null,
"holdReason": null
}
},
"requestId": "<request-id>"
}| State | What to do |
|---|---|
| awaiting_deposit | Wait for the exact external-wallet transfer and provider verification. |
| reserved / funding_pending | Keep polling; the partner-balance funding leg is pending. |
| payout_pending / payout_submitted | Keep polling; do not submit a second payout. |
| completed | Bank payout completed; retain the operation and payout references. |
| reconciliation_required | Pause retries and contact Azza with the operation ID and chain/provider evidence. |
Other intermediate states can appear. Treat every non-terminal state as pending and read the operation again. A confirmation response is not proof that the bank payout completed.
REFERENCE
Errors & recovery
Errors return a stable code and a request ID. Include both when contacting Azza support. Never log API keys, bank details, or raw customer payloads.
{
"error": {
"code": "amount_out_of_range",
"message": "Payout amount is outside the selected channel limits",
"requestId": "<request-id>"
}
}| HTTP | Meaning | Next step |
|---|---|---|
| 400 | Invalid fields or key | Correct the request; check invalidFields when supplied. |
| 401 / 403 | Authentication or scope denied | Check key validity and admin-approved scopes. |
| 404 | Owned resource not found | Check the ID and calling API partner. |
| 409 | Idempotency conflict | Inspect the existing action; do not bypass an uncertain payment. |
| 422 | Unsupported bank, asset, or amount | Fetch current banks and limits, then request a new quote. |
| 429 | Rate limit | Back off; do not generate new keys for the same action. |
| 503 | Dependency unavailable | Read existing quote/operation first; preserve keys and evidence. |