Skip to main content
Strails sends real-time event notifications to your configured webhook URL for all 22 critical operations across the platform. Every delivery is HMAC-signed so you can verify its authenticity, and any delivery that does not receive a 200 response is automatically retried with exponential backoff.

Common payload fields

Every event delivered by Strails shares the following top-level fields regardless of event type.

HTTP headers

Strails includes the following headers on every webhook POST request. For signature verification implementation details, see the HMAC Signatures page.

Events by category

user.onboarded

Fired when a user completes onboarding and is successfully registered under your fintech account.Key payload fields: firstName, lastName, onboardedAt

virtual.account.created

Fired when a reserved or checkout virtual account is created for a user.Key payload fields: vaId, accountNumber, bankName, accountName, createdAt

payments.confirmed

Fired when an inbound payment to a virtual account is confirmed by the payment gateway.Key payload fields: txRef, reference, amount, currency, status, confirmedAt, metadata.vaId, metadata.provider, metadata.walletAddress

fintech.virtual_account.deposit.received

Fired when a deposit is received on your fintech’s permanent reserved virtual account (as opposed to a user-level virtual account).Key payload fields: depositId, virtualAccount.accountNumber, deposit.amount, deposit.reference, depositor.name, depositor.bankName, metadata.provider

fintech.user.deposit.received

Fired when a deposit is received on a user’s permanent virtual account, before cNGN minting has begun. This is the first event in the user deposit funding flow.Key payload fields: depositId, virtualAccount.accountNumber, deposit.amount, deposit.reference, depositor.name, depositor.bankCode, metadata.provider

fintech.user.deposit.funding.completed

Fired after a user’s fiat deposit is fully processed and cNGN has been sent to their destination wallet. This is the final success event in the user deposit flow.Key payload fields: depositId, amount, currency, transactionReference, smartWalletAddress, transactionHash, depositor, bvnVerified, completedAt
If the user has an external default wallet registered, the cNGN is delivered there and smartWalletAddress carries that address. The event fires either way.

fintech.user.deposit.refunded

Fired when a deposit to a user’s permanent virtual account is automatically refunded because the depositor’s name did not match the BVN on file for that account.Key payload fields: depositId, amount, refundReference, refundReason, depositor, bvnVerification.isMatch, bvnVerification.confidenceScore, bvnVerification.rejectionReasons, refundedAt

wallet.funding.completed

Fired when cNGN minting is complete and tokens have been credited to the user’s smart wallet following a confirmed payment to a checkout or reserved virtual account.Key payload fields: walletAddress, amount, transactionHash, completedAt

swap.completed

Fired when a token swap initiated from a user’s smart wallet completes successfully.Key payload fields: walletAddress, sellToken, buyToken, amountIn, amountOut, swapTxHash, transferTxHash, completedAt, swapMetrics.executionTime, swapMetrics.gasUsed, swapMetrics.slippage

swap.failed

Fired when a token swap fails. The payload includes an error code and a retryable flag to help you decide whether to attempt the swap again.Key payload fields: walletAddress, sellToken, buyToken, amountIn, failedAt, error.code, error.message, retryable, metadata.attemptNumber

fintech.asset.transfer.completed

Fired when your fintech account successfully transfers assets from its smart wallet to a registered external wallet address.Key payload fields: smartWalletAddress, destinationAddress, destinationLabel, amount, ticker, transactionHash, blockNumber, gasUsed, commitmentsSafeguarded, completedAt

fintech.asset.transfer.failed

Fired when a fintech-initiated asset transfer fails, for example due to insufficient balance after accounting for FX orderbook commitments.Key payload fields: error, failedAt

fintech.user.asset.transfer.completed

Fired when a user successfully transfers assets from their smart wallet to an external wallet address.Key payload fields: smartWalletAddress, destinationAddress, amount, ticker, network, transactionHash, blockNumber, gasUsed, completedAt

fintech.user.asset.transfer.failed

Fired when a user-initiated asset transfer fails.Key payload fields: smartWalletAddress, destinationAddress, amount, ticker, network, error, failedAt

vault.return.transfer.confirmed

Fired when cNGN has been sent from a user’s smart wallet to the Strails vault as the first step of a user-initiated offramp.Key payload fields: transferId, vaultReturnId, amount, tokenAddress, transactionHash, confirmedAt, blockNumber

vault.return.payout.completed

Fired when the fiat payout to the user’s bank account is confirmed, completing the vault-return offramp flow.Key payload fields: payoutId, vaultReturnId, amount, recipientAccountNumber, recipientBankCode, transactionReference, completedAt

vault.return.payout.failed

Fired when the fiat payout to the user’s bank account fails during the vault-return offramp flow. Check retryable to determine if the payout can be reattempted.Key payload fields: payoutId, vaultReturnId, amount, recipientAccountNumber, recipientBankCode, failedAt, error.message, error.code, retryable

fintech.offramp.initiated

Fired immediately when your fintech account initiates an offramp (cNGN-to-NGN) payout request.Key payload fields: amount, currency, status, bankAccount.accountNumber, bankAccount.bankName, wallet.source, wallet.address, wallet.network

fintech.offramp.transfer.completed

Fired when the on-chain cNGN transfer to the Strails settlement wallet is confirmed. The bank payout has not yet been initiated at this point.Key payload fields: amount, currency, status, burnDetails.txHash, burnDetails.cNgnAmount, burnDetails.blockNumber, burnDetails.confirmations, metadata.gasUsed, metadata.transferredAt

fintech.offramp.payout.initiated

Fired when the bank payout is submitted to the payment provider after the on-chain token transfer is confirmed.Key payload fields: amount, currency, status, bankAccount, payoutDetails.reference, payoutDetails.provider, payoutDetails.status, metadata.payoutInitiatedAt

fintech.offramp.completed

Fired when the entire offramp flow is complete - the on-chain token burn is confirmed and the fiat payout has settled to the destination bank account.Key payload fields: amount, currency, status, bankAccount, wallet, burnDetails.txHash, payoutDetails.reference, payoutDetails.status, completedAt, metadata.processingTime

fintech.offramp.failed

Fired when an offramp fails at any stage in the pipeline - whether during the on-chain transfer or the bank payout. The error object indicates where the failure occurred and its cause.Key payload fields: amount, currency, status, bankAccount, burnDetails, error.message, error.code, metadata.retryable, metadata.attemptNumber

FX trades do not emit webhook events. None of the 22 events above cover the orderbook or trading flow, so track trade settlement by polling GET /fx/trades/status until the trade reaches completed, expired, or failed.

Retry behaviour

Strails retries failed webhook deliveries using exponential backoff. A delivery is considered failed if your endpoint returns any HTTP status other than 2xx, or if it does not respond within the timeout window.To avoid timeouts causing spurious retries, acknowledge receipt immediately by returning HTTP 200 as soon as you receive the request, then process the payload asynchronously. Use the X-Webhook-ID header to deduplicate any events your system may receive more than once due to retries.
For full details on verifying the HMAC signature on each delivery, see the HMAC Signatures page.