Contents

Managing Event Subscriptions

Twitch provides a number of events that you can subscribe to to get near real time notifications. For a list of events, see EventSub Subscription Types.

Before subscribing to events, make sure your event handler is ready to receive notifications; otherwise, your subscription request will fail. For information about writing a webhook event handler, see Getting Events Using Webhooks and for information about writing a WebSocket event handler, see Getting Events Using WebSockets.

Subscribing to events

To subscribe to events, use the Create EventSub Subscription endpoint. The object in the request’s body must include:

The following example shows how to create a subscription using the webhooks transport.

curl -X POST 'https://api.twitch.tv/helix/eventsub/subscriptions' \
-H 'Authorization: Bearer 2gbdx6oar67tqtcmt49t3wpcgycthx' \
-H 'Client-Id: wbmytr93xzw8zbg0p1izqyzzc5mbiz' \
-H 'Content-Type: application/json' \
-d '{"type":"channel.follow","version":"1","condition":{"broadcaster_user_id":"1234"},"transport":{"method":"webhook","callback":"https://example.com/callback","secret":"s3cre77890ab"}}' 

If the request succeeds, it returns HTTP status code 202 and the response’s body contains a JSON object that echoes your request. For webhooks, the status field indicates the state of your subscription. The status is set to webhook_callback_verification_pending while Twitch attempts to verify that you own the event handler specified in the callback field; Twitch won’t send you events until it verifies the callback. After Twitch verifies your callback, the subscription’s status changes to enabled, which indicates that your subscription is active and able to receive events. For WebSockets, the status field is set to enabled.

The following example shows the response for the above webhooks request.

{
  "data": [
    {
      "id": "f1c2a387-161a-49f9-a165-0f21d7a4e1c4",
      "status": "webhook_callback_verification_pending",
      "type": "channel.follow",
      "version": "1",
      "cost": 1,
      "condition": {
        "broadcaster_user_id": "1234"
      },
      "transport": {
        "method": "webhook",
        "callback": "https://example.com/webhooks/callback"
      },
      "created_at": "2019-11-16T10:11:12.634234626Z"
    }
  ],
  "total": 1,
  "total_cost": 1,
  "max_total_cost": 10000
}

Authorization

When subscribing to events using WebSockets, you must use a user access token only. The request fails if you use an app access token. The Subscription Types topic lists the scope requirement for each event. If the event doesn’t specify a scope requirement, you must create a user access token with no scope.

When subscribing to events using webhooks, you must use an app access token. The request fails if you use a user access token. For subscription types that require user authorization, the user must grant your app (client ID) permissions to the required scopes prior to subscribing to the event.

For example, to subscribe to channel.subscribe events, the broadcaster must grant your app permission to get users that subscribe to them. This adds the channel:read:subscriptions scope to your app’s client ID. This means that prior to sending a subscription request, your app must get a user access token with the required scope, and then get an app access token using the same client ID, which you use to subscribe to the events. If your client ID doesn’t include the scope, the subscription request fails.

Getting the list of events you subscribe to

To get the list of events that you subscribe to, use the Get EventSub Subscriptions endpoint.

If you specified the webhook transport when you subscribed to events, use an app access token, but if you used the WebSocket transport, use a user acccess token (no scope requirements).

The following request shows how to get the first page of events that you subscribe to.

curl -X GET 'https://api.twitch.tv/helix/eventsub/subscriptions' \
-H 'Authorization: Bearer 2gbdx6oar67tqtcmt49t3wpcgycthx' \
-H 'Client-Id: wbmytr93xzw8zbg0p1izqyzzc5mbiz'

The response contains a JSON object for each event you subscribe to. The list is paginated and is in ascending order by creation date (oldest subscription first).

{
  "data": [
    {
      "id": "26b1c993-bfcf-44d9-b876-379dacafe75a",
      "status": "enabled",
      "type": "streams.online",
      "version": "1",
      "cost": 1,
      "condition": {
        "broadcaster_user_id": "1234"
      },
      "created_at": "2020-11-10T20:08:634234626Z",
      "transport": {
        "method": "webhook",
        "callback": "https://this-is-a-callback.com"
      }
    },
    {
      "id": "35016908-41ff-33ce-7879-61b8dfc2ee16",
      "status": "webhook_callback_verification_pending",
      "type": "users.update",
      "version": "1",
      "cost": 1,
      "condition": {
        "user_id": "1234"
      },
      "created_at": "2020-11-10T20:31:634234626Z",
      "transport": {
        "method": "webhook",
        "callback": "https://this-is-a-callback.com"
      }
    }
  ],
  "total": 2,
  "total_cost": 2,
  "max_total_cost": 10000,
  "pagination": {}
}

Because it can take a few seconds for the total field to update after subscriptions are added or deleted, you should consider the value an approximation.

For information about the cost, total_cost, and max_total_cost fields, see Subscription limits.

If you’re using WebSockets and the WebSocket is disconnected, the Subscription object includes the disconnected_at field, which lets you know when the connection was lost.

NOTE The GET API includes WebSocket subscriptions that were disabled within the last 1 hour only as compared to webhooks which returns disabled subsriptions for a maximum of up to 10 days.

Filtering the list by type

You can filter the list of subscriptions by the event’s type and status. The filters are mutually exclusive (you cannot specify both type and status in the same request).

To filter the list by type, set the type query parameter to a subscription type. The following example filters the list for all channel.follow subscriptions.

curl -X GET 'https://api.twitch.tv/helix/eventsub/subscriptions?type=channel.follow' \
-H 'Authorization: Bearer 2gbdx6oar67tqtcmt49t3wpcgycthx' \
-H 'Client-Id: wbmytr93xzw8zbg0p1izqyzzc5mbiz'

Filtering the list by status

To filter the list by the subscription’s status, set the status query parameter to one of the following values:

The following example filters the list for all enabled subscriptions.

curl -X GET 'https://api.twitch.tv/helix/eventsub/subscriptions?status=enabled' \
-H 'Authorization: Bearer 2gbdx6oar67tqtcmt49t3wpcgycthx' \
-H 'Client-Id: wbmytr93xzw8zbg0p1izqyzzc5mbiz'

Deleting a subscription

To delete a subscription, use the Delete EventSub Subscription endpoint. Set the id query parameter to the subscription to delete.

If you specified the webhook transport when you subscribed to events, use an app access token, but if you used the WebSocket transport, use a user acccess token (no scope requirements).

curl -X DELETE 'https://api.twitch.tv/helix/eventsub/subscriptions?id=f1c2a387-161a-49f9-a165-0f21d7a4e1c4' \
-H 'Authorization: Bearer 2gbdx6oar67tqtcmt49t3wpcgycthx' \
-H 'Client-Id: wbmytr93xzw8zbg0p1izqyzzc5mbiz'

Subscription limits

EventSub uses a cost-based system for subscription limits. Subscription responses include the following fields to help you keep track of your subscription limits:

The maximum number of subscriptions you can create grows as users authorize your application. Here’s how it works:

Example

Suppose you want to create three subscriptions:

  1. channel.follow (no auth requirements, cost 1)
  2. channel.update (no auth requirements, cost 1)
  3. channel.cheer (bits:read OAuth scope required, cost 0)

User A has granted bits:read authorization to your application. Because the user has authorized your application, the total cost of these three subscriptions is 0.

User B has granted channel:moderate authorization to your application. The cost of subscribing to channel.follow and channel.update subscriptions is 0. Your application cannot create a channel.cheer subscription because User B has not authorized your application with the required OAuth scope.

User C has not granted authorization to your application. The cost of subscribing to channel.follow and channel.update subscriptions is 2. Your application cannot create a channel.cheer subscription because User C has not authorized your application with the required OAuth scope.

WebSocket limits

The following limits apply per user token (client ID and user ID tuple).