Skip to content
Integrations

Discord webhooks

Send messages to a Discord channel from your FlareX app via incoming webhooks — without building a full Discord bot.

Updated

If all you need is "post messages into one specific channel," you don't need a Discord bot. Use an incoming webhook instead. No bot token, no OAuth, no permissions matrix — just a URL you POST JSON to.

If you need a bot that responds to commands, reads messages, or manages roles, that's a full Discord bot instead.

Create the webhook

  1. Open the channel settings in Discord

    Right-click the channel → Edit Channel → Integrations → Webhooks → New Webhook.

  2. Configure

    Name the webhook (this becomes the "from" name on messages — overrideable per-message). Optionally upload an avatar.

  3. Copy the webhook URL

    Click Copy Webhook URL. It looks like:

    https://discord.com/api/webhooks/<id>/<token>
    

    Treat the URL like a password — anyone with it can post to your channel.

Add to Secrets

DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/...

Pattern 1: Plain message

On every new signup, post to Discord with:
🎉 New signup: <email> from <country>
await fetch(process.env.DISCORD_WEBHOOK_URL!, {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    content: `🎉 New signup: ${email} from ${country}`,
  }),
});

Pattern 2: Embed (rich card)

Embeds give you a title, color bar, fields, footer, timestamp:

await fetch(process.env.DISCORD_WEBHOOK_URL!, {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    embeds: [{
      title: 'New paid subscriber',
      color: 0x57F287, // green
      fields: [
        { name: 'Email', value: email, inline: true },
        { name: 'Plan', value: plan, inline: true },
        { name: 'MRR delta', value: `+$${mrrDelta}`, inline: true },
      ],
      footer: { text: 'flarex.app' },
      timestamp: new Date().toISOString(),
    }],
  }),
});

Tell FlareX:

On invoice.paid webhook from Stripe, post a Discord embed to
DISCORD_WEBHOOK_URL with title "Payment received", green color bar,
fields for email + amount + plan, footer "flarex.app", and current timestamp.

Pattern 3: Override the bot name + avatar per message

Same webhook, different "personas":

await fetch(WEBHOOK_URL, {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({
    username: 'Stripe',
    avatar_url: 'https://stripe.com/img/v3/home/twitter.png',
    content: '💳 New payment',
  }),
});

Useful for "a single channel that aggregates events from multiple services" — give each its own avatar so they're visually distinct.

Rate limits

Discord caps webhook posts at 30 messages per minute per channel. Above that, requests get 429.

For high-volume channels:

  • Batch: collect messages in a 5s buffer and post one combined embed.
  • Throttle on your end: post no faster than 1/2s (well under the limit).
  • Use multiple webhooks: separate channels = separate buckets.
On post-signup events, batch up to 10 events per minute into one
Discord embed with each signup as a field. If a single batch would
exceed 25 fields, post immediately.

Error handling

Discord returns { "code": 50027, "message": "Invalid Webhook Token" } when the webhook is deleted or its token rotated. Surface this clearly so you know to update the secret rather than retry forever:

const res = await fetch(WEBHOOK_URL, { ... });
if (res.status === 401 || res.status === 404) {
  console.error('Discord webhook deleted or token rotated — update DISCORD_WEBHOOK_URL');
  // optional: alert yourself via another channel
  return;
}
if (res.status === 429) {
  const retryAfter = Number(res.headers.get('retry-after') ?? 1);
  await new Promise(r => setTimeout(r, retryAfter * 1000));
  // retry once
}

Webhooks vs. bots — when to upgrade

You've outgrown an incoming webhook when you need any of:

  • React to messages or commands → bot with Discord Gateway
  • Read message history → bot
  • Add or remove roles → bot
  • Slash commands → bot (with interaction webhooks)
  • DM users → bot

For one-way notifications, webhooks stay simpler indefinitely.

What's next

Discord webhooks · FlareX