Skip to main content

Products / API

Azza API documentation

Integrate cNGN to NGN bank offramps, verify recipients, and track transfers through payout with a server-side API key.

API partner sign-in →

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.

FormatJSON over HTTPS
AuthenticationBearer API key
NetworksBase · Bep20

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.

HTTP request
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.

SituationAction
Response lost or timed outRead the quote or operation, then retry only the identical request with the same key.
New quote or new actionCreate a new key; never recycle a key with changed details.
Transfer outcome uncertainCheck 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.

  1. Fetch /offramps/banks and /offramps/limits; the limit applies to the NGN payout after fees.
  2. Create a quote with the connected wallet as expectedSenderAddress.
  3. Review the verified bank name, fee, token contract, exact amount, address, and deadline. Send one transfer.
  4. After a successful receipt, submit the hash and poll the operation. Azza independently verifies deposit and sweep webhooks before payout.
POST /api/v1/offramps/quotes
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.

Quote response · selected fields
{
  "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>"
}
POST /api/v1/offramps/:operationId/confirm
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.

  1. Provision or read your funding address with /offramps/funding-addresses/:network. Confirm available balance.
  2. Create a partner_balance quote and review the verified bank account and fee. These quotes expire after two minutes.
  3. Call POST /offramps once with your payment attestation and stable key.
  4. Store the operation ID and poll GET /offramps/:operationId.
POST /api/v1/offramps/quotes
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>"
    }
  }'
POST /api/v1/offramps
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.

MethodPathScopePurpose
GET/offramps/banksofframps:quoteSupported bank codes and names
GET/offramps/limitsofframps:quoteCurrent NGN payout limits
POST/offramps/quotesofframps:quoteCreate a verified bank quote
GET/offramps/quotes/:quoteIdofframps:readRetrieve an owned quote
POST/offramps/funding-addresses/:networkofframps:fundingProvision a partner funding address
GET/offramps/funding-addresses/:networkofframps:fundingRead address and available balance
POST/offrampsofframps:executeExecute a partner-balance quote
POST/offramps/:operationId/confirmofframps:executeSubmit an external transfer hash
GET/offramps/:operationIdofframps:readRead operation and payout state
POST/quotesquotes:createCreate an onramp quote only
GET/quotes/:quoteIdquotes:readRetrieve 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.

GET /api/v1/offramps/:operationId · selected fields
{
  "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>"
}
StateWhat to do
awaiting_depositWait for the exact external-wallet transfer and provider verification.
reserved / funding_pendingKeep polling; the partner-balance funding leg is pending.
payout_pending / payout_submittedKeep polling; do not submit a second payout.
completedBank payout completed; retain the operation and payout references.
reconciliation_requiredPause 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 response
{
  "error": {
    "code": "amount_out_of_range",
    "message": "Payout amount is outside the selected channel limits",
    "requestId": "<request-id>"
  }
}
HTTPMeaningNext step
400Invalid fields or keyCorrect the request; check invalidFields when supplied.
401 / 403Authentication or scope deniedCheck key validity and admin-approved scopes.
404Owned resource not foundCheck the ID and calling API partner.
409Idempotency conflictInspect the existing action; do not bypass an uncertain payment.
422Unsupported bank, asset, or amountFetch current banks and limits, then request a new quote.
429Rate limitBack off; do not generate new keys for the same action.
503Dependency unavailableRead existing quote/operation first; preserve keys and evidence.
Azza API documentation · cNGN offramps on Base and BNB Smart Chain · API access requires approval