Yara Webhooks Documentation
Webhooks allow you to receive real-time notifications about events happening in your Yara account. Your application can listen for webhook events and take action when they occur.
Table of Contents
Getting Started
Prerequisites
- A Yara account with API access
- An active API key with a configured webhook URL
- A publicly accessible endpoint to receive webhook events
Configuring Webhooks
To receive webhooks, you need to:
- Generate or activate an API key in your Yara account
- Set the
WebhookUrlin your API key configuration - Store your
EncryptionKey(also calledSecret) securely—this is used to verify webhook signatures
Your webhook endpoint should:
- Be publicly accessible over HTTPS
- Accept POST requests
- Return a 2xx status code to acknowledge receipt
- Process requests quickly (ideally within a few seconds)
Webhook Signature Verification
Every webhook sent by Yara includes an x-yara-signature header that you should verify to ensure the request is authentic.
Algorithm
- Hash Function: HMAC-SHA512
- Key: Your API key's
EncryptionKey(Secret) - Message: The raw JSON body of the webhook request
Verification Steps
- Extract the
x-yara-signatureheader from the request - Read the raw request body (before any JSON parsing)
- Compute the HMAC-SHA512 signature using:
- Key: Your
EncryptionKey(as a string) - Message: The raw JSON body
- Key: Your
- Compare the computed signature with the header value (case-insensitive hex comparison)
Example Implementation (Go)
import (
"crypto/hmac"
"crypto/sha512"
"encoding/hex"
"fmt"
"io"
"net/http"
)
func verifyWebhookSignature(req *http.Request, secret string) (bool, error) {
// Get the signature from headers
providedSignature := req.Header.Get("x-yara-signature")
if providedSignature == "" {
return false, fmt.Errorf("missing x-yara-signature header")
}
// Read the raw body
body, err := io.ReadAll(req.Body)
if err != nil {
return false, err
}
// Compute HMAC-SHA512
h := hmac.New(sha512.New, []byte(secret))
h.Write(body)
expectedSignature := hex.EncodeToString(h.Sum(nil))
// Compare signatures (case-insensitive)
valid := hmac.Equal(
[]byte(providedSignature),
[]byte(expectedSignature),
)
return valid, nil
}Example Implementation (Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(req, secret) {
const providedSignature = req.headers['x-yara-signature'];
if (!providedSignature) {
throw new Error('Missing x-yara-signature header');
}
const body = req.rawBody; // Make sure this is the raw body as a Buffer
const hmac = crypto.createHmac('sha512', secret);
hmac.update(body);
const expectedSignature = hmac.digest('hex');
// Case-insensitive comparison
return providedSignature.toLowerCase() === expectedSignature.toLowerCase();
}Example Implementation (Python)
import hmac
import hashlib
def verify_webhook_signature(headers, body, secret):
"""
Verify webhook signature.
Args:
headers: Request headers dict
body: Raw request body as bytes
secret: Your API key's EncryptionKey
Returns:
bool: True if signature is valid
"""
provided_signature = headers.get('x-yara-signature')
if not provided_signature:
raise ValueError('Missing x-yara-signature header')
# Compute HMAC-SHA512
expected_signature = hmac.new(
secret.encode('utf-8'),
body,
hashlib.sha512
).hexdigest()
# Case-insensitive comparison
return hmac.compare_digest(
provided_signature.lower(),
expected_signature.lower()
)Webhook Events
Yara sends webhooks for the following events:
Event Types
| Event Value | Description |
|---|---|
ONCHAIN_DEPOSIT | A cryptocurrency deposit has been confirmed on-chain |
ONCHAIN_PAYOUT | A cryptocurrency payout has been confirmed on-chain |
TRANSFER_SUCCESS | A fund transfer has completed successfully |
TRANSFER_FAILED | A fund transfer has failed |
WIDGET_DEPOSIT | A deposit via the Yara widget has been received |
ONRAMP_CREATED | An onramp has been created and a funding account has been issued |
ONRAMP_FUNDING_RECEIVED | An onramp funding payment has been received |
ONRAMP_COMPLETED | An onramp has been funded and settled successfully |
ONRAMP_FAILED | An onramp has failed during funding or settlement |
SPLIT_PAYMENT_COMPLETED | A split payment virtual account has been fully funded and processed |
PAYOUT_SUCCESS | A payout request has completed successfully |
PAYOUT_FAILED | A payout request has failed |
PAYOUT_INITIATED | A payout request has been initiated and is pending |
Event Payload Structure
All webhook events follow this structure:
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "PAYOUT_SUCCESS",
"data": {
// Event-specific data (see below for each event type)
}
}Field Descriptions
createdAt(string, ISO 8601): The timestamp when the event was createdevent(string): The type of event (see Event Types table above)data(object): Event-specific payload data
Event-Specific Payloads
ONCHAIN_DEPOSIT
Fired when a cryptocurrency deposit is confirmed on-chain.
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "ONCHAIN_DEPOSIT",
"data": {
"eventId": "evt_1234567890",
"address": "0x742d35Cc6634C0532925a3b844Bc112e0303d9e0",
"amount": 1.5,
"token": "USDC",
"chain": "ethereum",
"txHash": "0xabc123def456...",
"addressId": "addr_1234567890",
"amountUsd": "1500.00"
}
}eventId: Unique identifier for this eventaddress: Deposit destination addressamount: Amount received (in token units)token: Token symbol (e.g., "USDC", "ETH", "BTC")chain: Blockchain network (e.g., "ethereum", "polygon", "solana")txHash: Transaction hash on the blockchainaddressId: Unique identifier for the deposit addressamountUsd: Equivalent amount in USD
ONCHAIN_PAYOUT
Fired when a cryptocurrency payout is confirmed on-chain.
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "ONCHAIN_PAYOUT",
"data": {
"eventId": "evt_9876543210",
"address": "0x742d35Cc6634C0532925a3b844Bc112e0303d9e0",
"amount": 2.5,
"token": "USDC",
"chain": "ethereum",
"txHash": "0xdef456abc789...",
"amountUsd": "2500.00"
}
}Fields: Same as ONCHAIN_DEPOSIT
WIDGET_DEPOSIT
Fired when a deposit is received via the Yara widget.
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "WIDGET_DEPOSIT",
"data": {
"eventId": "evt_5555555555",
"amount": 3.0,
"token": "USDT",
"chain": "polygon",
"address": "0x742d35Cc6634C0532925a3b844Bc112e0303d9e0",
"txHash": "0xaaa111bbb222...",
"amountUsd": 3000.0,
"fiatPayoutAmount": 0.0
}
}eventId: Unique event identifieramount: Deposit amounttoken: Token symbolchain: Blockchain networkaddress: Deposit address (optional)txHash: Transaction hashamountUsd: USD equivalentfiatPayoutAmount: Associated fiat payout amount (if applicable)
ONRAMP_CREATED
Fired when an onramp is created and Yara provisions the single-use funding account.
{
"createdAt": "2026-07-09T03:29:59Z",
"event": "ONRAMP_CREATED",
"data": {
"eventId": "460b5fc1-3b52-4aa2-a1b5-eb359bf20f7d:ONRAMP_CREATED",
"onrampId": "460b5fc1-3b52-4aa2-a1b5-eb359bf20f7d",
"reference": "test-mags-002",
"status": "created",
"fundingStatus": "ACTIVE",
"provider": "palmpay",
"providerReference": "24260709033042163487",
"sourceAmount": 3000,
"sourceCurrency": "NGN",
"receivedAmount": 0,
"receivedAmountUsd": 0,
"netSourceAmount": 2950,
"payoutAmount": 2.1135045057050292,
"payoutCurrency": "USD",
"recipientType": "YARA_TAG",
"recipientName": "OLUWASEYI OLADELE",
"recipientYaraTag": "ayo",
"recipientAddress": "",
"recipientBankName": "",
"recipientAccountLast4": "",
"fundingAccountNumber": "8776644943",
"fundingBankName": "PalmPay",
"fundingBankCode": "100033",
"fundingBeneficiaryName": "OLUWASEYI OLADELE",
"destinationSettlementTxHash": "",
"failureReason": ""
}
}eventId: Unique event identifieronrampId: Yara onramp IDreference: Caller-supplied or generated referencestatus: Onramp lifecycle state such ascreated,funding_received,completed, orfailedfundingStatus: Funding leg statusprovider: Funding provider, currentlypalmpayproviderReference: Provider-side order or funding referencesourceAmount: Expected NGN amountsourceCurrency: Source currency, currentlyNGNreceivedAmount: Actual NGN amount receivedreceivedAmountUsd: Received amount converted to USDnetSourceAmount: Net NGN amount after deposit-side feespayoutAmount: Final payout amountpayoutCurrency: Destination payout currencyrecipientType:YARA_TAG,CRYPTO_WALLET, orUSD_BANK_ACCOUNTrecipientName: Recipient display namerecipientYaraTag: YaraTag when the destination is a Yara walletrecipientAddress: Crypto address when the destination is a crypto walletrecipientBankName: USD bank name when the destination is a USD bank accountrecipientAccountLast4: Last 4 digits of the recipient account number for USD bank destinationsfundingAccountNumber: The PalmPay funding account numberfundingBankName: The funding bank namefundingBankCode: The funding bank codefundingBeneficiaryName: Funding account beneficiary namedestinationSettlementTxHash: Settlement transaction hash for crypto settlements when availablefailureReason: Failure reason for failed or review-required outcomes
ONRAMP_FUNDING_RECEIVED
Fired when the expected funding payment is received for an onramp.
{
"createdAt": "2026-07-09T03:33:29Z",
"event": "ONRAMP_FUNDING_RECEIVED",
"data": {
"eventId": "460b5fc1-3b52-4aa2-a1b5-eb359bf20f7d:ONRAMP_FUNDING_RECEIVED",
"onrampId": "460b5fc1-3b52-4aa2-a1b5-eb359bf20f7d",
"reference": "test-mags-002",
"status": "funding_received",
"fundingStatus": "PAID",
"provider": "palmpay",
"providerReference": "24260709033042163487",
"sourceAmount": 3000,
"sourceCurrency": "NGN",
"receivedAmount": 3000,
"receivedAmountUsd": 2.1135045057050292,
"netSourceAmount": 2950,
"payoutAmount": 2.1135045057050292,
"payoutCurrency": "USD",
"recipientType": "YARA_TAG",
"recipientName": "OLUWASEYI OLADELE",
"recipientYaraTag": "ayo",
"recipientAddress": "",
"recipientBankName": "",
"recipientAccountLast4": "",
"fundingAccountNumber": "8776644943",
"fundingBankName": "PalmPay",
"fundingBankCode": "100033",
"fundingBeneficiaryName": "OLUWASEYI OLADELE",
"destinationSettlementTxHash": "",
"failureReason": ""
}
}Fields: Same as ONRAMP_CREATED
ONRAMP_COMPLETED
Fired when an onramp has been funded and settled successfully.
{
"createdAt": "2026-07-09T03:33:30Z",
"event": "ONRAMP_COMPLETED",
"data": {
"eventId": "460b5fc1-3b52-4aa2-a1b5-eb359bf20f7d:ONRAMP_COMPLETED",
"onrampId": "460b5fc1-3b52-4aa2-a1b5-eb359bf20f7d",
"reference": "test-mags-002",
"status": "completed",
"fundingStatus": "PAID",
"provider": "palmpay",
"providerReference": "24260709033042163487",
"sourceAmount": 3000,
"sourceCurrency": "NGN",
"receivedAmount": 3000,
"receivedAmountUsd": 2.1135045057050292,
"netSourceAmount": 2950,
"payoutAmount": 2.1135045057050292,
"payoutCurrency": "USD",
"recipientType": "YARA_TAG",
"recipientName": "OLUWASEYI OLADELE",
"recipientYaraTag": "ayo",
"recipientAddress": "",
"recipientBankName": "",
"recipientAccountLast4": "",
"fundingAccountNumber": "8776644943",
"fundingBankName": "PalmPay",
"fundingBankCode": "100033",
"fundingBeneficiaryName": "OLUWASEYI OLADELE",
"destinationSettlementTxHash": "",
"failureReason": ""
}
}Fields: Same as ONRAMP_CREATED
ONRAMP_FAILED
Fired when an onramp fails during funding or settlement.
{
"createdAt": "2026-07-09T03:33:30Z",
"event": "ONRAMP_FAILED",
"data": {
"eventId": "460b5fc1-3b52-4aa2-a1b5-eb359bf20f7d:ONRAMP_FAILED",
"onrampId": "460b5fc1-3b52-4aa2-a1b5-eb359bf20f7d",
"reference": "test-mags-002",
"status": "failed",
"fundingStatus": "FAILED",
"provider": "palmpay",
"providerReference": "24260709033042163487",
"sourceAmount": 3000,
"sourceCurrency": "NGN",
"receivedAmount": 3000,
"receivedAmountUsd": 2.1135045057050292,
"netSourceAmount": 2950,
"payoutAmount": 2.1135045057050292,
"payoutCurrency": "USD",
"recipientType": "YARA_TAG",
"recipientName": "OLUWASEYI OLADELE",
"recipientYaraTag": "ayo",
"recipientAddress": "",
"recipientBankName": "",
"recipientAccountLast4": "",
"fundingAccountNumber": "8776644943",
"fundingBankName": "PalmPay",
"fundingBankCode": "100033",
"fundingBeneficiaryName": "OLUWASEYI OLADELE",
"destinationSettlementTxHash": "",
"failureReason": "destination settlement failed"
}
}Fields: Same as ONRAMP_CREATED
SPLIT_PAYMENT_COMPLETED
Fired when a split payment virtual account receives the exact expected amount and Yara completes processing for both the recipient payout and developer fee.
{
"createdAt": "2026-07-09T11:10:20Z",
"event": "SPLIT_PAYMENT_COMPLETED",
"data": {
"eventId": "b62e5a0a-87f0-4c54-ac63-4f88a8f6e30d:SPLIT_PAYMENT_COMPLETED",
"splitPaymentId": "b62e5a0a-87f0-4c54-ac63-4f88a8f6e30d",
"reference": "split-test-integration-002",
"status": "completed",
"baseAmount": 5000,
"providerFee": 100,
"developerFee": 125,
"developerFeePercentage": 2.5,
"totalExpectedAmount": 5225,
"netPayoutAmount": 5000,
"currency": "NGN",
"recipientBankCode": "100004",
"recipientAccountNumber": "8030959098",
"recipientName": "OLUWASEYI TAMUNOMIEBI OLADELE"
}
}eventId: Unique event identifier for this webhook deliverysplitPaymentId: Unique split payment identifierreference: Client or system reference associated with the split paymentstatus: Final split payment status. For this event, the value iscompletedbaseAmount: Original recipient payout amount in the smallest NGN unitproviderFee: Provider fee charged for the split payment in the smallest NGN unitdeveloperFee: Developer fee credited to the API caller in the smallest NGN unitdeveloperFeePercentage: Developer fee percentage applied to the base amounttotalExpectedAmount: Exact amount the virtual account needed to receive before processingnetPayoutAmount: Amount paid out to the recipient bank account in the smallest NGN unitcurrency: Settlement currency for the split paymentrecipientBankCode: Destination bank code for the recipient payoutrecipientAccountNumber: Destination bank account number for the recipient payoutrecipientName: Resolved account name for the recipient payout
PAYOUT_SUCCESS
Fired when a payout request completes successfully.
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "PAYOUT_SUCCESS",
"data": {
"eventId": "evt_3333333333",
"payoutId": "payout_9876543210",
"amount": 1.75,
"amountUsd": 1750.0,
"payoutCurrency": "USDC",
"fiatAmount": 1750.0,
"reference": "ref_payout_123456",
"status": "completed",
"bankCode": "GTCO",
"bankAccountNumber": "0123456789"
}
}eventId: Unique event identifierpayoutId: Unique payout identifieramount: Crypto amountamountUsd: USD equivalentpayoutCurrency: Currency sent (e.g., "USDC")fiatAmount: Equivalent fiat amountreference: Payout reference numberstatus: Payout statusbankCode: Bank code (for fiat payouts)bankAccountNumber: Bank account number (for fiat payouts)
PAYOUT_FAILED
Fired when a payout request fails.
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "PAYOUT_FAILED",
"data": {
"eventId": "evt_4444444444",
"payoutId": "payout_1234567890",
"amount": 0.5,
"amountUsd": 500.0,
"payoutCurrency": "USDC",
"fiatAmount": 500.0,
"reference": "ref_payout_789012",
"status": "failed",
"bankCode": "GTCO",
"bankAccountNumber": "9876543210"
}
}Fields: Same as PAYOUT_SUCCESS
PAYOUT_INITIATED
Fired when a payout request is initiated and pending processing.
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "PAYOUT_INITIATED",
"data": {
"eventId": "evt_2222222222",
"payoutId": "payout_5555555555",
"amount": 0.75,
"amountUsd": 750.0,
"payoutCurrency": "USDC",
"fiatAmount": 750.0,
"reference": "ref_payout_345678",
"status": "pending",
"bankCode": "GTCO",
"bankAccountNumber": "1111111111"
}
}Fields: Same as PAYOUT_SUCCESS
TRANSFER_SUCCESS
Fired when a fund transfer completes successfully.
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "TRANSFER_SUCCESS",
"data": {
// Payload structure varies based on transfer type
// May include deposit or payout information
}
}TRANSFER_FAILED
Fired when a fund transfer fails.
{
"createdAt": "2024-01-15T10:30:45.123Z",
"event": "TRANSFER_FAILED",
"data": {
// Payload structure varies based on transfer type
// May include deposit or payout information
}
}Retry Policy
Yara implements automatic retry logic for webhook deliveries:
Retry Mechanism
- Initial Delivery: Webhooks are sent immediately upon event occurrence
- Failed Delivery: If your endpoint returns a non-2xx status code or times out, Yara will retry
- Maximum Retries: Up to 5 automatic retries
- Backoff Strategy: Exponential backoff between retries
- Idempotency: Each webhook event includes a unique
eventIdin the data payload to help you identify duplicate deliveries
Best Practices for Webhook Handling
- Verify Signatures: Always verify the
x-yara-signatureheader - Idempotent Processing: Use the
eventIdto track and deduplicate events - Quick Response: Return a 2xx status code quickly; process event data asynchronously
- Store Events: Log all received webhooks for audit trails and debugging
- Handle Retries: Be prepared to receive the same event multiple times
- Error Handling: Return appropriate HTTP status codes:
- 2xx: Event acknowledged and will be processed
- 5xx: Temporary error; Yara will retry
- Other 4xx: Permanent error; Yara will not retry
Exponential Backoff Example
If a webhook fails, retries occur with exponential backoff:
| Attempt | Delay (approx) |
|---|---|
| 1st Retry | ~15 seconds |
| 2nd Retry | ~30 seconds |
| 3rd Retry | ~1 minute |
| 4th Retry | ~2 minutes |
| 5th Retry | ~4 minutes |
Common Questions
How do I test webhooks locally?
Use a tunnel service like ngrok to expose a local endpoint:
ngrok http 3000Then configure your webhook URL to point to your ngrok URL (e.g., https://abc123.ngrok.io/webhook).
Can I modify my webhook URL after creating an API key?
Yes, you can update the WebhookUrl in your API key settings at any time.
Should I trust all x-yara-signature headers?
Always verify signatures, even if the request appears to come from Yara. This protects against spoofed requests.