Breet sends webhook notifications to your server whenever important events occur, such as incoming crypto deposits or withdrawal status changes. Your application can listen for these events and respond accordingly.
Crypto wallet deposit webhooks
These webhooks fire whenever a wallet address receives crypto assets. You will receive events for the following transaction states:
| Event | Description |
|---|
trade.pending | An incoming crypto transaction has been detected on the blockchain but has not yet been fully confirmed or processed. |
trade.completed | The transaction is fully confirmed, has passed all checks, and your account has been credited. |
trade.flagged | The transaction is confirmed on-chain but failed a check: below the asset minimum, failed AML screening, or flagged as a possible duplicate. Funds are held and not credited. |
Payload example
{
"id": "692f91aa729255932afe9078",
"asset": "SOL_TEST",
"feePercentage": 1.5,
"feeAmountInUsd": 0.32,
"cryptoAmount": 0.00025406,
"amountInUSD": 21.379427842514175,
"flagFeeUSD": 0,
"vaultId": "121",
"destinationAddress": "6DKYpZfd86BUDTjPe4E3JEGwnYW99KU3NDazk7BjpN8V",
"destinationDescription": "Partner_testingizzy",
"txHash": "aa801188ukdjfhdbf3771dfdf86388b8b694a2ac0226748346y34kbc3",
"status": "completed",
"confirmations": 3,
"note": "",
"event": "trade.completed",
"createdAt": 1764614655493,
"updatedAt": 1764616198265,
"index": 19,
"blockInfo": {
"blockHeight": "926040",
"blockHash": "0000000000000000000158f293cda641e08a144673dc03814b187e8db758c929"
}
}
Payload fields
| Field | Type | Description |
|---|
id | string | Unique identifier for the transaction. |
asset | string | The crypto asset involved (e.g., ETH, BTC). |
feePercentage | number | Breet’s platform fee rate applied to the trade, expressed as a percentage (e.g., 0.5 means 0.5%). |
feeAmountInUsd | number | The platform fee amount in USD, calculated as (feePercentage / 100) x amountInUSD. |
cryptoAmount | number | Amount of crypto transferred. |
amountInUSD | number | Value of the transaction in USD. |
flagFeeUSD | number | Fee applied for trades below minimum asset requirement. Initially 0, may be updated later. |
vaultId | string | ID of the vault handling the transaction. |
destinationAddress | string | Wallet address receiving the funds. |
destinationDescription | string | Optional description for the recipient. |
txHash | string | Blockchain transaction hash. |
status | string | Transaction status (pending, completed, failed). |
confirmations | number | Number of blockchain confirmations. |
note | string | Optional note associated with the transaction. |
event | string | Webhook event type (trade.completed, trade.pending, trade.flagged). |
createdAt | timestamp | Transaction creation timestamp (milliseconds). |
updatedAt | timestamp | Last update timestamp (milliseconds). |
index | number | Internal index for ordering transactions. |
blockInfo.blockHeight | string | Block height in the blockchain. |
blockInfo.blockHash | string | Hash of the block containing this transaction. |
Auto-settlement fields
When a bank account is linked to a wallet address and auto-settlement is enabled, the webhook payload includes additional fields. For a full explanation of how auto-settlement works, see the Auto-settlement guide.
| Field | Type | Description |
|---|
markupPercent | number | The percentage markup configured on your integration (e.g. 2.5, optionally set by you). |
markupAmount | number | The absolute amount deducted as markup from the converted local currency amount. |
amountSettled | number | The final amount paid out to the linked bank account, after markup deduction. |
settlementRate | number | The exchange rate used to convert USD to the base local currency (NGN). |
settlementConversionRate | number | The conversion rate applied when settling in a secondary currency (e.g. NGN to GHS). For Nigerian accounts this is 1. |
If a markup percentage is set, it is deducted from the transaction amount before the final payout is calculated. For example, if a trade amount is 1,000 USD and a 5% markup is applied, 50 USD is deducted and the settlement is calculated based on 950 USD.
Behavior notes
- The webhook may send multiple events for the same transaction as its status changes. For example, a transaction may first trigger
trade.pending, then later trade.completed.
- The
confirmations field indicates how many blockchain confirmations the transaction has received. This is especially important for trade.completed events.
- For auto-settlement trades, withdrawal events are also sent and the related trade ID is included in the notification response.
Fiat/Crypto withdrawal webhooks
These webhooks fire whenever a withdrawal is created or when its status changes.
| Event | Description |
|---|
withdrawal.pending | The withdrawal request has been received and is being processed. |
withdrawal.completed | The withdrawal has been successfully processed and paid out. |
withdrawal.reversed | The withdrawal was sent to the payment provider but the provider returned a failure. Funds are refunded to your wallet. |
withdrawal.rejected | The withdrawal was rejected during internal review before being sent to a payment provider. Funds are refunded to your wallet. |
Payload example
{
"id": "6968ed1398fea49e805363bb",
"event": "withdrawal.pending",
"amount": 1000,
"originalAmount": 1000,
"currency": "usd",
"status": "pending",
"txHash": "0x123abcdef",
"reference": "6968ed1398fea49e805363bb",
"fee": 10,
"meta": {
"walletAddress": "14grJpemFaf88c8tiVb77W7TYg2W3ir6pfkKz3YjhhZ5",
"network": "SOL",
"token": "USDT",
"symbol": "USDT",
"avatar": "https://assets.breet.io/token-network-assets/USDT_SOL.png",
"label": "",
"txLink": "https://solscan.io/tx/"
},
"reason": "",
"createdAt": "2026-01-15T13:35:15.967Z",
"updatedAt": "2026-01-15T13:35:15.967Z"
}
Payload fields
| Field | Type | Description |
|---|
id | string | Unique identifier for the withdrawal request. |
event | string | Webhook event type (withdrawal.pending, withdrawal.completed, withdrawal.reversed, withdrawal.rejected). |
txHash | string | Blockchain transaction hash (only present on completed transactions). |
amount | number | Net amount to be withdrawn after fees. |
originalAmount | number | Original withdrawal amount before fees were applied. |
currency | string | Currency of the withdrawal (e.g., usd). |
status | string | Current withdrawal status (pending, completed, reversed, rejected). |
reference | string | Unique reference for the withdrawal. Always the same value as id. We recommend using id instead. |
trade | string | Trade ID (if withdrawal was initiated from a trade). |
fee | number | Fee charged for processing the withdrawal. |
meta | object | Additional metadata related to the withdrawal destination. |
meta.type | string | Withdrawal destination type (e.g., nuban, crypto). |
meta.bankId | string | Bank identifier for NUBAN withdrawals. |
meta.bankName | string | Name of the destination bank. |
meta.accountName | string | Verified bank account holder name. |
meta.account | string | Internal account reference ID. |
meta.accountNumber | string | Bank account number (NUBAN). |
meta.autoSettlement | boolean | Whether the withdrawal is processed automatically. |
meta.narration | string | Transfer narration or description shown on bank statement. |
meta.fee | number | Withdrawal fee charged for the transaction. |
meta.walletAddress | string | Destination wallet address for crypto withdrawals. |
meta.network | string | Blockchain network used for the withdrawal (e.g., SOL). |
meta.token | string | Token being withdrawn (e.g., USDT). |
meta.symbol | string | Token symbol. |
meta.avatar | string | URL to the token or network asset icon. |
meta.label | string | Optional label or description for the withdrawal destination. |
meta.txLink | string | Base URL for viewing the transaction on a blockchain explorer. |
reason | string | Reason for rejection or reversal (empty if not applicable). |
createdAt | string (ISO 8601) | Timestamp when the withdrawal was created. |
updatedAt | string (ISO 8601) | Timestamp of the most recent status update. |
Behavior notes
- A single withdrawal may trigger multiple webhook events as its status progresses.
withdrawal.pending is always sent first.
txHash will not be present until the withdrawal is completed.
- Always rely on the
event and status fields to determine the current state of a withdrawal.
Webhook verification
To ensure the security and authenticity of incoming webhook notifications, Breet provides multiple layers of verification.
IP whitelisting
All webhook requests originate from Breet’s secure servers. Verify that incoming requests come from one of the following IP addresses:
46.101.201.155
46.101.225.109
46.101.225.97
46.101.225.251
159.89.20.62
Requests from any other IP addresses should be considered untrusted and ignored.
Webhook secret
Each webhook endpoint is configured with a webhook secret, visible in your dashboard (Go to Settings → For Developer) under the Webhook Verification Secret Key. The secret is included in every webhook request as a header:
x-webhook-secret: <your-webhook-secret>
To verify a webhook request:
- Retrieve the
x-webhook-secret header from the incoming request.
- Compare it against the secret configured in your dashboard.
- Only process the request if the secrets match.
Keep your webhook secret secure. Do not expose it in public repositories, client-side code, or logs.
Recommended verification flow
- Check the request IP against the allowed Breet IPs.
- Validate the
x-webhook-secret header against the configured secret.
- Only process the payload if both checks pass.
- As an extra check, call Fetch Transaction by ID or Fetch Withdrawal by ID to confirm the transaction exists on Breet before taking any action.
Webhook retries
If your server does not respond with a successful 2xx status code, Breet automatically retries delivering the webhook using an exponential backoff schedule:
| Attempt | Delay |
|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 1 hour |
| 4th retry | 4 hours |
| 5th retry | 8 hours |
| 6th retry | 12 hours |
| 7th retry | 24 hours |
After the final retry (24 hours), the webhook attempt is marked as permanently failed.
Retry conditions
Retries occur when:
- Your webhook endpoint returns any non-2xx HTTP status code (including 3xx, 4xx, or 5xx).
- Your webhook endpoint times out.
- Your server is unreachable.
Breet does not retry events where your server returns 2xx, even if the response body contains an error.
Best practices
- Return a 2xx status code as soon as your server receives and accepts the webhook.
- Handle duplicate deliveries. Breet may deliver the same event more than once during retries. Use the
id and event fields together to detect duplicates and ensure your processing logic is idempotent.
- Log all received events and failures to aid debugging.