US Lottery API Logo
US Lottery API
LoginGet Free API Key
Webhooks / Push Alerts12 Min Read · Advanced LevelUpdated August 2026

How to Build Real-Time Lottery Draw Notifications & Webhooks

Polling an API continuously wastes server resources. With US Lottery API Webhooks, your server receives an instant HTTP POST push notification within seconds of official draw validation. In this guide, you will learn how to verify HMAC-SHA256 signatures, handle idempotent events, and broadcast live draw alerts to Discord, Telegram, and Email subscribers.

EVENT DRIVEN PUSH ARCHITECTURE

🎰Official DrawNumbers Audited
US Lottery EngineHMAC-SHA256 Sign
🛡️Your Webhook ReceiverSignature Verify
📢Discord & TelegramInstant Push Alert
1

Webhook Payload Schema

When a drawing completes, US Lottery API delivers an HTTP POST request to your registered webhook URL with an event payload:

Webhook Event Payload (POST /api/webhooks/lottery)json
{
  "event": "draw.results.published",
  "event_id": "evt_powerball_20260801_9911",
  "timestamp": "2026-08-01T23:05:12Z",
  "data": {
    "game_id": "powerball",
    "game_name": "Powerball",
    "draw_date": "2026-08-01",
    "winning_numbers": [12, 34, 45, 56, 67],
    "powerball": 10,
    "multiplier": "2x",
    "estimated_jackpot": "$1,200,000,000",
    "next_draw_date": "2026-08-03",
    "next_jackpot_estimate": "$1,350,000,000"
  }
}
2

HMAC-SHA256 Signature Verification

To prevent spoofing attacks, every webhook contains an X-Lottery-Signature header. Calculate the HMAC-SHA256 digest using your secret signing key and verify equality before processing:

webhook_listener.jsNode.js / Express
const express = require("express");
const crypto = require("crypto");
const fetch = require("node-fetch");

const app = express();
// Note: Use raw body buffer for signature calculation
app.use(express.json({
  verify: (req, res, buf) => {
    req.rawBody = buf;
  }
}));

const WEBHOOK_SECRET = process.env.LOTTERY_WEBHOOK_SECRET;
const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
const TELEGRAM_CHAT_ID = process.env.TELEGRAM_CHAT_ID;
const DISCORD_WEBHOOK_URL = process.env.DISCORD_WEBHOOK_URL;

// Helper: Verify HMAC-SHA256 signature
function verifySignature(req) {
  const signature = req.headers["x-lottery-signature"];
  if (!signature || !WEBHOOK_SECRET) return false;

  const expectedSignature = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(req.rawBody)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// Push to Telegram Channel
async function sendTelegramAlert(data) {
  if (!TELEGRAM_BOT_TOKEN || !TELEGRAM_CHAT_ID) return;

  const message = `🚨 *NEW ${data.game_name.toUpperCase()} DRAW RESULT* 🚨\n\n` +
    `📅 *Draw Date:* ${data.draw_date}\n` +
    `🎱 *Numbers:* ${data.winning_numbers.join(", ")}\n` +
    `🔴 *Powerball:* ${data.powerball}\n` +
    `⚡ *Multiplier:* ${data.multiplier}\n` +
    `💰 *Jackpot:* ${data.estimated_jackpot}\n\n` +
    `➡️ *Next Jackpot:* ${data.next_jackpot_estimate} (${data.next_draw_date})`;

  await fetch(`https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      chat_id: TELEGRAM_CHAT_ID,
      text: message,
      parse_mode: "Markdown",
    }),
  });
}

// Push to Discord Channel
async function sendDiscordAlert(data) {
  if (!DISCORD_WEBHOOK_URL) return;

  const payload = {
    embeds: [
      {
        title: `🎉 ${data.game_name} Winning Numbers Released!`,
        color: 65535, // Neon Cyan
        fields: [
          { name: "Draw Date", value: data.draw_date, inline: true },
          { name: "Winning Numbers", value: data.winning_numbers.join(" - "), inline: false },
          { name: "Bonus Ball", value: String(data.powerball), inline: true },
          { name: "Multiplier", value: data.multiplier, inline: true },
          { name: "Current Jackpot", value: data.estimated_jackpot, inline: true },
        ],
        footer: { text: "Powered by US Lottery API" },
        timestamp: new Date().toISOString(),
      },
    ],
  };

  await fetch(DISCORD_WEBHOOK_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(payload),
  });
}

// Webhook HTTP Receiver Route
app.post("/api/webhooks/lottery", async (req, res) => {
  if (!verifySignature(req)) {
    console.warn("Unauthorized webhook attempt - HMAC signature mismatch!");
    return res.status(401).json({ status: "error", message: "Invalid signature" });
  }

  const { event, data } = req.body;
  console.log(`Received Webhook Event: ${event} for ${data.game_name}`);

  if (event === "draw.results.published") {
    // Send alerts concurrently
    await Promise.allSettled([
      sendTelegramAlert(data),
      sendDiscordAlert(data)
    ]);
  }

  // Always respond 200 OK within 5 seconds to acknowledge receipt
  return res.status(200).json({ status: "success", message: "Event processed" });
});

app.listen(3000, () => console.log("Webhook receiver listening on port 3000"));
3

Idempotency & Delivery Guarantees

To guarantee zero missing events during transient network failures, US Lottery API enforces an exponential retry strategy. Webhook receivers should maintain idempotency using event_id:

  • Retry Policy: If your server returns HTTP 5xx or times out (5s limit), the engine retries delivery 5 times (10s, 30s, 2m, 10m, 1h).
  • Idempotency Check: Store processed event_id values in Redis or your database for 24 hours to prevent sending duplicate Telegram/Discord push messages.

Activate Webhooks on Business & Enterprise Plans

Upgrade to Business or Enterprise tier to unlock real-time HTTP Webhook subscriptions and custom push alerts.