Skip to main content

Webhook

Twitch can POST notifications to your server via EventSub.

Your server must accept public traffic on port 443, and have a valid SSL certificate (consider using ZeroSSL or Let's Encrypt to obtain a free SSL certificate).

tip

For development purposes, you can utilize ngrok or a Cloudflare Tunnel (among other options) to generate a HTTPS URL that serves as a reverse proxy to your localhost webhook server.

If your server's firewall prevents incoming webhook requests, consider using a Conduit backed by websockets instead.

EventSub Subscription Management

With webhooks, you utilize an app access token to create and delete EventSub subscriptions.

Since certain subscription types require user authorization, these users must authenticate with your Client ID to generate a user access token (but you do not need to maintain this user token to utilize webhooks).

If the subscription does not have a scope requirement, you do not need user authorization, but the subscription will have a cost of 1. When your Client ID has user authorization, the subscription has a cost of 0. By default, every Client ID has a max_total_cost of 10,000 for webhooks.

When your webhooks server start, you should call TwitchHelix#getEventSubSubscriptions to check whether your EventSub subscriptions are already healthy (so you don't create duplicate subscriptions). Twitch imposes a limit of three (3) subscriptions with the same type and condition values.

To create EventSub subscriptions, you would call TwitchHelix#createEventSubSubscription. The first argument must be an app access token (or null if withDefaultAuthToken is an app access token OR withClientId/withClientSecret is specified while withDefaultAuthToken is not specified). The second argument is an EventSubSubscription that includes type, version, condition, and transport (with callback and secret specified, while method is set to "webhook").

It is easiest to create EventSubSubscription instances through our SubscriptionTypes utility class:

EventSubSubscription sub = SubscriptionTypes.STREAM_ONLINE.prepareSubscription(
builder -> builder.broadcasterUserId("channel-id-goes-here").build(),
EventSubTransport.builder()
.callback("your-webhook-url")
.secret("your-eventsub-secret")
.method(EventSubTransportMethod.WEBHOOK)
.build()
);
helix.createEventSubSubscription(null, sub).execute();
info

EventSub Webhook subscriptions require a shared secret to generate the Twitch-Eventsub-Message-Signature header. This secret must be between 10 and 100 ASCII characters. Avoid reusing your client secret for the EventSub secret. It is best practice to utilize a cryptographically-secure random generator to create this secret. It is acceptable to utilize the same secret across multiple EventSub subscriptions.

While Twitch does not officially document their specific retry policy, it has been observed that they employ exponential backoff to retry failed notifications up to 5 times over a couple minutes. If all retries are exhausted without the webserver responding with a 2xx code, the EventSub subscription would be disabled.

Web Server Logic

You can use any framework you desire to implement the webhook server.

For example, this gist utilizes Javalin to handle incoming webhooks.

This example highlights a few important notes:

tip

For debugging, you can utilize the Twitch CLI to verify subscriptions and trigger notifications.

For any further clarification, please refer to Twitch's official documentation on handling webhook events.