Webhooks
Receive real-time notifications for wallet and usage events.
How Webhooks Work
Webhooks allow your application to receive real-time HTTP POST callbacks whenever significant events occur in your Valta account. Instead of polling the API, you register an endpoint URL and Valta pushes event data to it as events happen.
When an event is triggered, Valta sends a JSON payload to your configured endpoint. Your server should respond with a 2xx status code within 30 seconds to acknowledge receipt. If we don't receive a successful response, we'll retry the delivery using an exponential backoff schedule.
Available Events
Subscribe to any combination of the following event types when configuring your webhook endpoint:
Payload Format
All webhook payloads follow a consistent JSON structure. The type field identifies the event, and the data object contains the event-specific details.
{
"id": "evt_8k2nV3xQ9m",
"type": "payment.deducted",
"createdAt": "2026-02-27T14:32:10Z",
"data": {
"walletId": "wal_7f3k...",
"transactionId": "txn_9x2m...",
"amount": 0.03,
"currency": "USDC",
"description": "GPT-4o inference — 1,200 tokens",
"newBalance": 142.47
}
}Signature Verification
Every webhook request includes an X-Valta-Signature header containing an HMAC-SHA256 signature. You should always verify this signature to ensure the payload was sent by Valta and has not been tampered with.
The signature is computed over the raw request body using your webhook signing secret, which you can find in the Valta dashboard under Settings → Webhooks.
import crypto from "crypto";
function verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const expected = crypto
.createHmac("sha256", secret)
.update(payload, "utf8")
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
app.post("/webhooks/valta", (req, res) => {
const signature = req.headers["x-valta-signature"] as string;
const isValid = verifyWebhookSignature(
req.body,
signature,
process.env.VALTA_WEBHOOK_SECRET!
);
if (!isValid) {
return res.status(401).json({ error: "Invalid signature" });
}
const event = JSON.parse(req.body);
// Process event...
res.status(200).json({ received: true });
});Retry Policy
If your endpoint does not return a 2xx response within 30 seconds, Valta will retry the delivery with exponential backoff:
- 1st retry: 1 minute after initial attempt
- 2nd retry: 5 minutes after 1st retry
- 3rd retry: 30 minutes after 2nd retry
- 4th retry: 2 hours after 3rd retry
- 5th retry: 12 hours after 4th retry (final attempt)
After 5 failed attempts, the event is marked as failed and will not be retried automatically. You can manually replay failed events from the Valta dashboard.
Best Practices
- Always verify signatures. Never process a webhook payload without validating the HMAC signature first.
- Return 200 quickly. Acknowledge receipt immediately, then process the event asynchronously using a message queue.
- Handle duplicates. Use the event id field to deduplicate, as retries may deliver the same event more than once.
- Use HTTPS endpoints. Valta only delivers webhooks to HTTPS URLs. HTTP endpoints will be rejected.
- Monitor delivery health. Check the webhook logs in your dashboard regularly to ensure your endpoint is healthy.