Solana Webhooks: The Complete Guide to Real-Time On-Chain Alerts (2026)

Tools Mentioned in This Article
Compare features, read reviews, and check live health scores on MadeOnSol.

Compare features, read reviews, and check live health scores on MadeOnSol.

Learn how to build a Solana token analytics dashboard that combines real-time price feeds, holder data, trading volume, and liquidity metrics into a single view using TypeScript and the MadeOnSol API.

Solana validators prune old data aggressively, making historical analysis difficult. Learn how to access Solana historical data using BigQuery, Flipside, Dune, Helius DAS API, and archival services — with practical query examples.

Learn how to track Solana program activity by monitoring program IDs, decoding instructions with Anchor IDLs, parsing custom events, and following CPI chains. Covers real use cases like DEX monitoring and pool creation detection.
Build with MadeOnSol API
KOL tracking, deployer intelligence, DEX streaming, and webhooks. Free API key — 200 requests/day.
import { MadeOnSol } from "madeonsol";
// Get a free API key at madeonsol.com/developer
const client = new MadeOnSol({ apiKey: "msk_your_key" });
const { trades } = await client.kol.feed({ limit: 10 });
const { alerts } = await client.deployer.alerts({ limit: 5 });
const { tools } = await client.tools.search({ q: "trading" });Get weekly Solana ecosystem insights delivered to your inbox.
Every meaningful event on Solana — a token transfer, an NFT sale, a program invocation — is a transaction. If your application needs to react to those events in real-time, you have four main options: polling, WebSockets, gRPC streams, and webhooks.
Webhooks are the simplest. Instead of your application maintaining a persistent connection or repeatedly querying the chain, the provider watches for events matching your criteria and sends an HTTP POST to your server when they occur. No connection management, no parsing raw transactions, no infrastructure overhead.
This guide covers everything you need to set up Solana webhooks in production: how they work, which providers to use, and how to build reliable webhook handlers with TypeScript.
A webhook is a server-to-server HTTP callback. You register a URL with a provider, specify which on-chain events you care about, and the provider sends a POST request to your URL whenever a matching event occurs.
For Solana, this means you can get notified about:
The provider handles the hard parts: running Solana validators or RPC nodes, parsing transaction data, matching events to your filters, and retrying failed deliveries.
Choosing the right real-time data method depends on your use case. Here is how each approach compares:
| Feature | Webhooks | WebSockets | gRPC (Yellowstone) | Polling |
|---|---|---|---|---|
| Connection model | Push (HTTP POST) | Persistent bidirectional | Persistent stream | Pull (repeated requests) |
| Latency | 200-500ms | 50-200ms | 10-50ms | Depends on interval |
| Infrastructure needed | HTTP endpoint | WebSocket client | gRPC client + plugin | HTTP client |
| Complexity | Low | Medium | High | Low |
| Reliability | Provider handles retries | Must handle reconnects | Must handle reconnects | Simple but wasteful |
| Cost | Usually included in plan | Varies | Node cost or provider fee | RPC credits per request |
| Best for | Alerts, notifications, async processing | Live dashboards, trading UIs | High-frequency trading, indexing | Low-frequency checks |
If you need sub-100ms latency for trading or indexing, gRPC streaming is the better choice. If you want a live UI with flexible subscriptions, WebSockets work well. But for alerts, notifications, and async event processing, webhooks are the most practical option.
Four major providers offer Solana webhook functionality, each with different strengths.
Helius is the most popular choice for Solana webhooks. It offers enhanced webhooks that deliver parsed, human-readable transaction data rather than raw bytes. You can filter by transaction type (NFT sale, token transfer, etc.), specific accounts, or programs.
QuickNode provides webhook functionality through its QuickAlerts product. It supports Solana along with 30+ other chains, making it a good choice for multi-chain projects.
Shyft offers callback-style webhooks with strong NFT and token parsing. Its GraphQL API pairs well with webhooks for enriching event data.
Triton (by Triton One) focuses on high-performance Solana infrastructure. Its webhook and streaming offerings target teams that need low-latency, high-throughput event delivery.
Here is a complete TypeScript example for registering a webhook with Helius and handling incoming events.
const HELIUS_API_KEY = process.env.HELIUS_API_KEY!;
async function createWebhook(walletAddress: string, webhookUrl: string) {
const response = await fetch(
`https://api.helius.xyz/v0/webhooks?api-key=${HELIUS_API_KEY}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
webhookURL: webhookUrl,
transactionTypes: ["TRANSFER", "SWAP", "NFT_SALE"],
accountAddresses: [walletAddress],
webhookType: "enhanced",
}),
}
);
const webhook = await response.json();
console.log("Webhook created:", webhook.webhookID);
return webhook;
}
import express from "express";
import crypto from "crypto";
const app = express();
app.use(express.json());
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET!;
function verifySignature(payload: string, signature: string): boolean {
const expected = crypto
.createHmac("sha256", WEBHOOK_SECRET)
.update(payload)
.digest("base64");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
app.post("/webhook/solana", (req, res) => {
const signature = req.headers["x-webhook-signature"] as string;
const rawBody = JSON.stringify(req.body);
if (signature && !verifySignature(rawBody, signature)) {
return res.status(401).json({ error: "Invalid signature" });
}
const events = Array.isArray(req.body) ? req.body : [req.body];
for (const event of events) {
processEvent(event);
}
// Respond quickly — process async
res.status(200).json({ received: true });
});
function processEvent(event: any) {
switch (event.type) {
case "TRANSFER":
console.log(
`Transfer: ${event.nativeTransfers?.[0]?.amount / 1e9} SOL`
);
break;
case "SWAP":
console.log(`Swap on ${event.source}: ${event.description}`);
break;
case "NFT_SALE":
console.log(`NFT sold: ${event.description}`);
break;
default:
console.log(`Event: ${event.type}`);
}
}
app.listen(3100, () => console.log("Webhook server running on port 3100"));
Webhook deliveries can fail due to network issues or temporary server downtime. Most providers retry automatically, but your handler should be idempotent:
const processedSignatures = new Set<string>();
function processEventIdempotent(event: any) {
const txSignature = event.signature;
if (processedSignatures.has(txSignature)) {
console.log(`Skipping duplicate: ${txSignature}`);
return;
}
processedSignatures.add(txSignature);
// Prevent unbounded memory growth
if (processedSignatures.size > 10_000) {
const oldest = processedSignatures.values().next().value;
processedSignatures.delete(oldest);
}
processEvent(event);
}
For production, replace the in-memory Set with Redis or a database table to persist deduplication state across restarts.
Track all activity on a wallet — useful for treasury monitoring, whale watching, or personal alerts:
await createWebhook(
"YourWalletAddressHere",
"https://yourserver.com/webhook/wallet"
);
// In your handler:
function handleWalletEvent(event: any) {
const solChange = event.nativeTransfers?.reduce(
(sum: number, t: any) =>
t.toUserAccount === "YourWalletAddressHere"
? sum + t.amount
: sum - t.amount,
0
);
if (solChange && Math.abs(solChange) > 1e9) {
// Alert on transfers > 1 SOL
sendAlert(`Wallet activity: ${solChange / 1e9} SOL`);
}
}
Monitor a collection for sales across marketplaces:
await createWebhook(
"CollectionMintAuthority",
"https://yourserver.com/webhook/nft-sales"
);
// Filter for NFT_SALE events in your handler
function handleNftSale(event: any) {
if (event.type !== "NFT_SALE") return;
const { amount, buyer, seller, nfts } = event.events?.nft || {};
const solPrice = (amount || 0) / 1e9;
console.log(`Sale: ${nfts?.[0]?.mint} for ${solPrice} SOL`);
console.log(`Buyer: ${buyer}, Seller: ${seller}`);
}
Monitor a specific program for all interactions — useful for protocol analytics or security monitoring:
const PROGRAM_ID = "YourProgramIdHere";
const response = await fetch(
`https://api.helius.xyz/v0/webhooks?api-key=${HELIUS_API_KEY}`,
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
webhookURL: "https://yourserver.com/webhook/program",
accountAddresses: [PROGRAM_ID],
webhookType: "raw",
txnStatus: "confirmed",
}),
}
);
Confirm incoming payments without polling the chain. For more on building alert systems, see our Solana alerts and notifications guide.
function handlePayment(event: any) {
const transfers = event.nativeTransfers || [];
const incoming = transfers.find(
(t: any) =>
t.toUserAccount === MERCHANT_WALLET &&
t.amount >= EXPECTED_AMOUNT_LAMPORTS
);
if (incoming) {
confirmOrder(event.signature, incoming.amount);
}
}
Running webhooks in production requires more than just a handler. Keep these points in mind:
Always verify signatures. Without verification, anyone can send fake events to your endpoint. Use HMAC verification as shown above.
Respond with 200 quickly. Process events asynchronously after acknowledging receipt. Providers will retry if your endpoint takes too long to respond (typically 5-10 seconds timeout).
Make handlers idempotent. Providers retry on failure, so you may receive the same event multiple times. Deduplicate by transaction signature.
Use a queue for heavy processing. If your event processing involves database writes, external API calls, or complex logic, push events to a queue (Redis, SQS, BullMQ) and process them in a worker.
Monitor your endpoint. Track response times, error rates, and missed events. Set up alerts if your webhook endpoint goes down.
Secure your endpoint. Use HTTPS, restrict access by IP if your provider publishes their IP ranges, and validate all incoming data.
A Solana webhook is an HTTP callback that notifies your server when specific on-chain events occur. You register a URL with a provider like Helius or QuickNode, specify your filters (wallet addresses, programs, transaction types), and the provider sends a POST request to your endpoint whenever a matching transaction is confirmed. This eliminates the need to poll the blockchain or maintain persistent connections.
Webhooks and gRPC serve different needs. Webhooks deliver events via HTTP POST with 200-500ms latency and require no persistent connection, making them ideal for alerts, notifications, and async workflows. gRPC streams deliver events with 10-50ms latency over a persistent connection, suited for trading bots and real-time indexing. For a deep dive into gRPC, see our gRPC streaming guide.
For most developers, Helius is the best starting point. Its enhanced webhooks deliver parsed transaction data, it includes a free tier with one webhook, and it has the largest Solana-specific feature set. If you need multi-chain support, QuickNode covers 30+ chains. For NFT-heavy projects, Shyft offers strong NFT parsing. For high-performance infrastructure needs, Triton provides dedicated Yellowstone-backed delivery.
Webhooks are reliable for payment notifications but should not be your only verification method. Use webhooks as the trigger, then independently verify the transaction on-chain using the signature before crediting a user. Providers like Helius retry failed deliveries for up to 24 hours, but network partitions or endpoint downtime can still cause delays. Combine webhooks with periodic polling as a fallback for critical payment flows.
Solana webhooks give you the simplest path to real-time on-chain alerts. Register an endpoint, define your filters, and let the provider handle the infrastructure. For most notification and monitoring use cases, webhooks hit the right balance of simplicity, reliability, and cost.
If your use case demands lower latency, explore gRPC streaming or WebSocket-based DEX trade streams for real-time data feeds.