Skip to main content

Overview

Bluvo webhooks notify your application in real-time when events occur — wallets connecting, balances updating, withdrawals completing, and more. Instead of polling the API, your server receives an HTTP POST with a signed JSON payload the moment something happens. Webhooks are managed through the Bluvo Portal. There is no REST API for webhook management — all configuration (creating endpoints, selecting events, rotating secrets) is done in the dashboard.

Supported events

EventDescription
wallet.createdA wallet was connected via OAuth or API key
wallet.balance.updatedBalances were synced for a wallet
wallet.deletedA wallet was removed
quotation.createdA withdrawal quote was successfully generated
quotation.errorA withdrawal quote failed
transaction.createdA withdrawal was submitted to the exchange
transaction.errorA withdrawal failed
transaction.broadcastedA withdrawal was confirmed on-chain
error.fatalAn unrecoverable error occurred

Creating a webhook endpoint

1

Open the Webhooks page

In the Bluvo Portal, navigate to Settings > Webhooks.
2

Add an endpoint

Click Add Endpoint, enter the URL of your receiver, and select the events you want to subscribe to.
3

Copy your signing secret

After creation, copy the webhook signing secret. You’ll need this to verify signatures. Store it securely — it won’t be shown again.
You can create up to 3 webhook endpoints per project.

Payload structure

Every webhook delivery sends a POST request with a JSON body following this envelope:
{
  "event": "wallet.created",
  "eventId": "wal_abc123",
  "timestamp": "2026-04-21T12:00:00.000Z",
  "data": {
    // Event-specific fields
  }
}
FieldTypeDescription
eventstringThe event type (e.g., wallet.created)
eventIdstringUnique identifier for this event
timestampstringISO 8601 timestamp of when the event occurred
dataobjectEvent-specific payload — see individual event pages

Headers

Each delivery includes two signature headers:
HeaderDescription
X-Webhook-SignatureBase64-encoded HMAC-SHA256 signature
X-Webhook-TimestampUnix timestamp in milliseconds

Building a receiver

Here’s a minimal Express.js receiver that verifies the signature and processes events:
import express from "express";
import crypto from "node:crypto";

const app = express();
const WEBHOOK_SECRET = process.env.BLUVO_WEBHOOK_SECRET!;

app.post("/webhooks/bluvo", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.headers["x-webhook-signature"] as string;
  const timestamp = req.headers["x-webhook-timestamp"] as string;

  // Verify signature
  const expected = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(`${timestamp}\n${req.body}`)
    .digest("base64");

  const isValid = crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );

  if (!isValid) {
    return res.status(401).send("Invalid signature");
  }

  // Return 200 immediately, process async
  res.status(200).send("OK");

  const event = JSON.parse(req.body.toString());
  // Handle event asynchronously...
});

app.listen(3000);
Always use express.raw() or equivalent to access the raw request body for signature verification. Parsing the body as JSON first will alter the string and break the signature check.

Idempotency

Use the eventId field to deduplicate deliveries. The same event may be delivered more than once (e.g., if your server returns a timeout before Bluvo receives the 200 response). Your receiver should be idempotent — processing the same eventId twice should have no side effects.

Next steps

Verify Signatures

Secure your endpoint with HMAC-SHA256 verification.

Retries & Logs

Understand the retry schedule and view delivery logs.

Event Reference

Browse detailed payload schemas for every event.