Webhooks
Receive HTTP POST callbacks from RPC providers when accounts or transactions match your filters - event-driven indexing without maintaining WebSocket or gRPC clients.
Recipe
Quick-reference recipe card - copy-paste ready.
# Provider dashboard: create webhook
# URL: https://api.yourapp.com/webhooks/helius
# Type: enhanced transaction / account / raw
# Account addresses: YOUR_PROGRAM_ID// Next.js route handler (illustrative)
export async function POST(req: Request) {
const body = await req.json();
// verify auth header / signature per provider docs
await enqueueForIndexer(body);
return new Response("ok");
}When to reach for this:
- Serverless or small team without gRPC consumers.
- Reacting to specific program transactions in near real time.
- Triggering workflows (emails, alerts) on on-chain events.
- Complementing batch analytics with live notifications.
Working Example
import { createHmac, timingSafeEqual } from "node:crypto";
function verifyHeliusSignature(
secret: string,
payload: string,
header: string | null
): boolean {
if (!header) return false;
const expected = createHmac("sha256", secret).update(payload).digest("hex");
try {
return timingSafeEqual(Buffer.from(header), Buffer.from(expected));
} catch {
return false;
}
}
export async function POST(req: Request) {
const raw = await req.text();
const sig = req.headers.get("x-helius-signature");
if (!verifyHeliusSignature(process.env.HELIUS_WEBHOOK_SECRET!, raw, sig)) {
return new Response("unauthorized", { status: 401 });
}
const event = JSON.parse(raw);
await persistTransactionEvent(event);
return Response.json({ received: true });
}What this demonstrates:
- Verify webhook authenticity before parsing JSON.
- Respond 200 quickly; heavy indexing async via queue.
- Store raw payload for replay debugging.
Deep Dive
How It Works
- Provider indexer matches chain events to your registered filters.
- HTTP POST delivers JSON payload to your HTTPS endpoint.
- Retries on non-2xx responses - idempotent handlers required.
- Enhanced payloads may include parsed token transfers and NFT metadata.
Webhook Design
| Choice | Recommendation |
|---|---|
| Auth | HMAC header verification |
| Response time | < 1s ACK, async process |
| Idempotency | Key on signature + type |
| Storage | Raw JSON + normalized tables |
TypeScript Notes
// Fast ACK pattern with queue
await queue.add("index-tx", { id: event.signature });
return Response.json({ ok: true });Gotchas
- No signature verification - attackers POST fake events. Fix: HMAC or provider auth token on every request.
- Slow handler causes retry storms - duplicate processing. Fix: queue worker + idempotent upserts.
- Public HTTP without TLS - credentials and data exposed. Fix: HTTPS only.
- Filter too broad - webhook spam and cost. Fix: narrow to program id and instruction types.
- Treating webhooks as sole source of truth - missed events on downtime. Fix: periodic RPC backfill reconciliation job.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Yellowstone gRPC | Massive throughput | Simple alert triggers |
logsSubscribe | You control WS infra | Serverless-only stack |
| Cron GPA scans | Low frequency | Near-real-time needs |
| Internal cron + getSignaturesForAddress | Tiny address sets | High volume programs |
FAQs
Which providers support webhooks?
Helius prominently; others offer similar enhanced callbacks - check dashboards.
Can webhooks replace a full indexer?
Often for alerts; analytics still need database schema and backfill for completeness.
How to test locally?
Use ngrok/cloudflared tunnel to HTTPS endpoint during development.
What if endpoint is down?
Provider retries; reconcile gaps with signature backfill from last known slot.
Raw vs enhanced payload?
Enhanced saves parse work; raw gives full control if program is custom.
Multiple environments?
Separate webhook URLs and secrets for staging vs production.
Rate limits?
Provider plans cap events per month - monitor usage dashboard.
Devnet webhooks?
Provider-dependent - many focus on mainnet production.
Security headers?
Follow vendor doc for exact header names and HMAC algorithm.
Relation to DAS?
Different product surface - webhooks for events, DAS for asset reads.
Related
- Indexing Basics - pipeline context
- Building an Indexer - persistence
- RPC Providers - Helius setup
- Parsing Program Data - decode payloads
Stack versions: This page was written for Agave 4.1.1, Solana CLI 3.0.10, Anchor 0.32.1, anchor-lang 0.32.1, Rust 1.91.1, @solana/kit 7.0.0, Surfpool 0.12.0, and LiteSVM 0.6.x.