Skip to main content
Use wallet transaction reads to reconcile account activity across fiat deposits, stablecoin deposits, fees, adjustments, refunds, and withdrawals initiated through the API or Stabyl Pro. The timeline can include deposits, fees, adjustments, refunds, and withdrawals. Use transaction id as the stable public identifier. Use rail, currency, and settlement_rail to distinguish NGN bank, NGN CNGN, USD cash, USDT, and USDC activity. settlement_rail is present only on stablecoin activity. settlement_details appears only on the detail route, not in list items. CNGN deposits can be successfully credited while some funds await conversion capacity in locked. Use conversion progress to track releases and returns, and balances and withdrawal quotes to check current spendability.

Conversion Liquidity Reason

Both list items and transaction details optionally include processing_reason: "liquidity_pending" for a cNGN deposit with funds still awaiting conversion-pool capacity. This is a reason field, not a new status; the existing status values and filters are unchanged.
A deposit can already be successfully credited while its restricted portion awaits conversion. Use the conversion progress endpoint for amounts. The reason is omitted when that portion is fully released or returned, and on failed, cancelled, or compliance-held transactions. Ordinary processing, payout delays, screening, and Travel Rule holds do not produce this reason. SDKs should add optional processing_reason to both summary and detail models and tolerate absent or future values. Web clients currently checking status === "liquidity_pending" must check processing_reason === "liquidity_pending" instead, independently of the transaction’s status. Replace stored reasons on every refresh so an omitted field clears an earlier explanation.

Required Actions

Some crypto deposits may be confirmed on-chain but unavailable until additional Travel Rule information is submitted through the partner API. These rows keep status: "hold" and include required_action:
Call GET on submission_url to retrieve the required fields and POST to the same path to submit sender information. The GET needs wallets:view; the POST needs wallets:transfer. required_action.status changes to submitted after a successful submission and before the deposit is credited. Once credited, required_action is omitted.

Listing Transactions

Results are newest first. limit defaults to 20 and is capped at 100. Each page returns items and next_cursor; pass next_cursor back as cursor until it is null. An unparseable cursor returns 400. Filters are rail (fiat or crypto), currency, status, tx_type (deposit, withdrawal, refund, fee, adjustment), date_from and date_to (RFC 3339, or YYYY-MM-DD interpreted as a UTC day; date_to is inclusive), and reference (case-insensitive partial match). Unknown query parameters return 400. Do not assume a page boundary is stable while new activity is happening; store the highest processed transaction timestamp and transaction ID in your own reconciliation job.

Reading One Transaction

Use the detail route when an operator opens a record, when a reconciliation job finds a gap, or when your system needs to refresh the status of a known transaction.

Withdrawal Detail and Bulk Transfers

A withdrawal is always one transaction, even when it pays several beneficiaries or was split into several bank transfers. The list route shows the parent with a transfer_count. The detail route adds settlement_details.transfers, one entry per bank transfer with its own status, so you can tell exactly which beneficiaries were paid.
The parent recipient is the first beneficiary in the request. The parent amount is the full requested amount, not the amount that was paid. When a transfer fails, its principal comes back as a separate refund transaction in this timeline and the fee for that transfer is released back to your balance. A single-beneficiary withdrawal above the per-transfer limit also appears here with several transfers, all sharing item_index 0. See Bulk withdrawals for the submission side.

Status Handling

Treat success, partial, failed, and cancelled as terminal. A transaction can move from pending, processing, or hold to a terminal status. partial only appears on NGN withdrawals with more than one bank transfer. The principal and fee for each failed transfer are returned to the NGN wallet, and settlement_details.transfers shows which transfers were paid, as shown above. It is announced by the withdrawal.partial webhook.

Reconciliation Pattern

  1. Process deposit and withdrawal webhooks as the primary source of timely changes.
  2. Upsert transactions by public id; a later status updates the existing record.
  3. Run a cursor-based reconciliation job periodically and after webhook downtime.
  4. Use the detail endpoint for operator lookups and targeted gap recovery, not continuous polling.
  5. Keep transaction IDs, webhook event IDs, and timestamps in your support logs.

Required Headers

Transaction reads require X-Api-Key with wallets:view. Common failures are 400 for an invalid filter, cursor, date, or a non-UUID transaction id, and 404 for a transaction outside your account or one that has not yet appeared in the timeline.