Contents

PubSub Guide

Introduction

PubSub enables you to subscribe to a topic, for updates (e.g. when a user cheers in a channel).

The Twitch PubSub system allows back-end services to broadcast realtime messages to clients. Example applications include:

These example applications share a common pattern: on application load, the application fetches a complete snapshot of its state and uses a persistent connection through PubSub to receive updates to this state. The updates act as “diffs” to the initial state.

Clients establish a WebSocket connection to our server, listen on topics they care about, and get messages on those topics in real time. Each command or message sent between the client and server is a JSON string encapsulated in one WebSocket frame.

WebSocket is a communications protocol, providing full-duplex communication channels over a single TCP connection. For more information, see the WebSocket Wikipedia entry.

The JSON messages differ, depending on the type of message or command, but typically they have this form:

{
   "type": "<type string>",
   "data": "<JSON blob>"
}

A code sample is available for JavaScript.

Terminology

Term Definition
Client An end-user session of the Twitch application or a third-party application’s integration point.
Command An action that a client issues to the server, which modifies the state of the client connection.
Message A piece of data which back-end services broadcast to interested clients via PubSub. PubSub never inspects or mutates messages.
Server A Twitch machine that clients connect to for PubSub service.
Topic Aka event. A logical partition of messages that clients may subscribe to, to get messages.

Connection Management

Clients establish a secure WebSocket connection to:

wss://pubsub-edge.twitch.tv

To keep the server from closing the connection, clients must send a PING command at least once every 5 minutes. If a client does not receive a PONG message within 10 seconds of issuing a PING command, it should reconnect to the server. See details in Handling Connection Failures.

Clients must LISTEN on at least one topic within 15 seconds of establishing the connection, or they will be disconnected by the server.

Clients may receive a RECONNECT message at any time. This indicates that the server is about to restart (typically for maintenance) and will disconnect the client within 30 seconds. During this time, we recommend that clients reconnect to the server; otherwise, the client will be forcibly disconnected.

Example: PING Connection Message

// Sent from client to server
{
  "type": "PING"
}

Example: PONG Connection Message

// Sent from server to client in response to a PING
{
  "type": "PONG"
}

Example: RECONNECT Connection Message

// Sent from server to client
{
  "type": "RECONNECT"
}

Handling Connection Failures

When a client encounters a situation where it must reconnect to the server, it should first establish a new successful WebSocket connection and then issue a LISTEN command that contains the set of topics that the application expects to receive messages on.

If a client fails to connect to the server or is disconnected from the server, it should reconnect to the server using an exponential backoff. Our official client implementation initially waits one second (plus a small random jitter: see the next paragraph) to retry a failed connection and doubles the backoff period on subsequent failures, up to a maximum backoff threshold of 2 minutes. This prevents some “stampeding herd” situations where many clients simultaneously connect to the server.

If a client uses timers to issue PING commands, it should add a small random jitter to the timer. This prevents some situations where many clients issue PING commands simultaneously.

After a client reconnects to the server, some applications should fetch fresh state, to compensate for any missed messages while the connection was broken. For instance, our Chat application fetches the Bits leaderboard on reconnect (as it does on initial page load), in case the leaderboard received an update while the connection was down.

Authorization Revoked

An authorization can be revoked at any time for a number of reasons, such a user disconnecting from an app through https://www.twitch.tv/settings/connections. Topics associated with the authorization will be unlistened to, and clients will receive an AUTH_REVOKED message.

Example: AUTH_REVOKED Connection Message

// Sent from server to client
{
  "type": "AUTH_REVOKED",
    "data": {
      "topics": ["channel-bits-events-v1.44322889"]
  }
}

API Limits

The two limits above are likely to be relaxed for approved third-party applications, as we start to better understand third-party requirements.

Topics

Once a client establishes a connection, it can LISTEN on topics it cares about. Clients can LISTEN on many topics at once and add new topics at any time by issuing new LISTEN commands.

Once a client no longer cares about a particular set of topics, it should issue UNLISTEN commands to stop receiving messages on those topics.

Authentication

All topics require an OAuth token, but only some topics have a specific required scope (noted in the table below).

Available Topics

All topics require an OAuth token, but only some topics have a specific required scope (noted in the table).

Feature Topic and Example Required Scope You are notified when…
Bits channel-bits-events-v1.<channel_id>

Example:
channel-bits-events-v1.44322889
bits:read Anyone cheers in a specified channel.
Bits channel-bits-events-v2.<channel_id>

Example:
channel-bits-events-v2.4602499
bits:read Anyone cheers in a specified channel.
Bits Badge Notification channel-bits-badge-unlocks.<channel_id>

Example:
channel-bits-badge-unlocks.44322889
bits:read Message sent when a user earns a new Bits badge in a particular channel, and chooses to share the notification with chat.
Channel Points channel-points-channel-v1.<channel_id>

Example:
channel-points-channel-v1.44322889
channel:read:redemptions A custom reward is redeemed in a channel.
Channel Subscriptions channel-subscribe-events-v1.<channel_id>

Example:
channel-subscribe-events-v1.44322889
channel:read:subscriptions Anyone subscribes (first month), resubscribes (subsequent months), or gifts a subscription to a channel. 

Subgift subscription messages contain recipient information.
Chat automod-queue.<moderator_id>.<channel_id>

Example: automod-queue.46024993.44322889
channel:moderate AutoMod flags a message as potentially inappropriate, and when a moderator takes action on a message.
Chat chat_moderator_actions.<user_id>.<channel_id>

Example: chat_moderator_actions.46024993.44322889
channel:moderate Supports moderators listening to the topic, as well as users listening to the topic to receive their own events. 

Examples of moderator actions are bans, unbans, timeouts, deleting messages, changing chat mode (followers-only, subs-only), changing AutoMod levels, and adding a mod.
Chat low-trust-users.<channel_id>.<suspicious_user_id>

Example:
low-trust-users.12826.141981764
channel:moderate The broadcaster or a moderator updates the low trust status of a user, or a new message has been sent in chat by a potential ban evader or a bans shared user.
Chat user-moderation-notifications.<current_user_id>.<channel_id>

Example: user-moderation-notifications.46024993.44322889
chat:read A user’s message held by AutoMod has been approved or denied.
Whispers whispers.<user_id>

Example:
whispers.44322889
whispers:read Anyone whispers the specified user.

Where:

Note: channel-bitsevents is deprecated. For Bits events, use channel-bits-events-v2 instead.

Note: channel-commerce-events-v1.<channel id> is deprecated.

Requests

This is an example request for Bits events. It listens to Bits events on channel 44322889. The authorization scope is specified when you generate the OAuth token using our authorization flow; see the Apps & Authentication Guide.

// Request from client to server
{
  "type": "LISTEN",
  "nonce": "44h1k13746815ab1r2",
  "data": {
    "topics": ["channel-bits-events-v1.44322889"],
    "auth_token": "cfabdegwdoklmawdzdo98xt2fo512y"
  }
}
Request Parameter Type Description
type string Valid values: LISTEN, UNLISTEN.
nonce string (Optional) Random string to identify the response associated with this request.
data JSON Wraps the topics and auth_token fields.
topics array of strings List of topics to listen on. Valid values are any of the topics listed in Available Topics.
auth_token string OAuth token required to listen on some topics. The token is linked to either the specified <channel user ID> (for Bits events) or the specified <user ID> (for whispers events).

Responses

Here is a sample response:

// Response from server to client
{
  "type": "RESPONSE",
  "nonce": "44h1k13746815ab1r2",
  "error": ""
}
Field Type Description
type string Valid value: RESPONSE.
nonce string The nonce that was passed in the request, if one was provided there.
error string The error message associated with the request, or an empty string if there is no error.

For Bits and whispers events requests, error responses can be: ERR_BADMESSAGE, ERR_BADAUTH, ERR_SERVER, ERR_BADTOPIC.

Receiving Messages

When a message for your subscription is published, you will receive a message containing the applicable data.

Message Parameters: All Messages

Parameter Type Description
type string Valid value: MESSAGE
data JSON Wraps the topics and message fields.
topic string The topic that the message pertains to.
message string The body of the message. Depending on the type of message, the message body contains different fields; see below.

Example: Bits Event v2 Message

{
  "type": "MESSAGE",
  "data": {
     "topic": "channel-bits-events-v2.46024993",
     "message": "{\"data\":{\"user_name\":\"jwp\",\"channel_name\":\"bontakun\",\"user_id\":\"95546976\",\"channel_id\":\"46024993\",\"time\":\"2017-02-09T13:23:58.168Z\",\"chat_message\":\"cheer10000 New badge hype!\",\"bits_used\":10000,\"total_bits_used\":25000,\"context\":\"cheer\",\"badge_entitlement\":{\"new_version\":25000,\"previous_version\":10000}},\"version\":\"1.0\",\"message_type\":\"bits_event\",\"message_id\":\"8145728a4-35f0-4cf7-9dc0-f2ef24de1eb6\",\"is_anonymous\":true}"
  }
}
Field Type Description
badge_entitlement
(optional)
object  Information about a user’s new badge level, if the cheer was not anonymous and the user reached a new badge level with this cheer. Otherwise, null.
bits_used integer Number of bits used.
channel_id string ID of the channel in which Bits were used.
chat_message string Chat message sent with the cheer.
context string Event type associated with this use of Bits.
is_anonymous Boolean Whether or not the event was anonymous.
message_id string Message ID.
message_type string The type of object contained in the data field.
time string Time when the Bits were used.
RFC 3339 format.
total_bits_used integer All time total number of Bits used in the channel by a specified user.
user_id 
(optional)
string User ID of the person who used the Bits - if the cheer was not anonymous.
Null if anonymous.
user_name
(optional)
string Login name of the person who used the Bits - if the cheer was not anonymous. 
Null if anonymous
version string Message version

Example: Bits Event v1 Message

{
   "type": "MESSAGE",
   "data": {
      "topic": "channel-bits-events-v1.44322889",
      "message": "{\"data\":{\"user_name\":\"dallasnchains\",\"channel_name\":\"dallas\",\"user_id\":\"129454141\",\"channel_id\":\"44322889\",\"time\":\"2017-02-09T13:23:58.168Z\",\"chat_message\":\"cheer10000 New badge hype!\",\"bits_used\":10000,\"total_bits_used\":25000,\"context\":\"cheer\",\"badge_entitlement\":{\"new_version\":25000,\"previous_version\":10000}},\"version\":\"1.0\",\"message_type\":\"bits_event\",\"message_id\":\"8145728a4-35f0-4cf7-9dc0-f2ef24de1eb6\"}"
   }
}
Field Type Description
badge_entitlement object Information about the user’s new badge level, if the user reached a new badge level with this cheer; otherwise. null.
bits_used integer Number of Bits used.
channel_id string User ID of the channel on which Bits were used.
channel_name string Name of the channel on which Bits were used.
chat_message string Chat message sent with the cheer.
context string Event type associated with this use of Bits (for example, cheer).
message_id string Message ID
message_type string Message type (that is, the type of object contained in the data field)
time string Time when the Bits were used. RFC 3339 format.
total_bits_used integer All-time total number of Bits used on this channel by the specified user.
user_id string User ID of the person who used the Bits.
user_name string Login name of the person who used the Bits.
version string Message version

Example: Bits Badge Notification Message

{
     "type":"MESSAGE","data":{"topic":"channel-bits-badge-unlocks.401394874","message":"
     {
          \"user_id\":\"232889822\",\"user_name\":\"willowolf\",\"channel_id\":\"401394874\",\"channel_name\":\"fun_test12345\",\"badge_tier\":1000,\"chat_message\":\"this should be received by the public pubsub listener\",\"time\":\"2020-12-06T00:01:43.71253159Z\"}"
     }
}
Field Type Description
user_id string ID of user who earned the new Bits badge
user_name string Login of user who earned the new Bits badge
channel_id string ID of channel where user earned the new Bits badge
channel_name string Login of channel where user earned the new Bits badge
badge_tier integer Value of Bits badge tier that was earned (1000, 10000, etc.)
chat_message string [Optional] Custom message included with share
time string Time when the new Bits badge was earned.
RFC 3339 format.

Example: Channel Points Event Message

{
"type": "reward-redeemed",
"data": {
  "timestamp": "2019-11-12T01:29:34.98329743Z",
  "redemption": {
    "id": "9203c6f0-51b6-4d1d-a9ae-8eafdb0d6d47",
    "user": {
      "id": "30515034",
      "login": "davethecust",
      "display_name": "davethecust"
    },
    "channel_id": "30515034",
    "redeemed_at": "2019-12-11T18:52:53.128421623Z",
    "reward": {
      "id": "6ef17bb2-e5ae-432e-8b3f-5ac4dd774668",
      "channel_id": "30515034",
      "title": "hit a gleesh walk on stream",
      "prompt": "cleanside's finest \n",
      "cost": 10,
      "is_user_input_required": true,
      "is_sub_only": false,
      "image": {
        "url_1x": "https://static-cdn.jtvnw.net/custom-reward-images/30515034/6ef17bb2-e5ae-432e-8b3f-5ac4dd774668/7bcd9ca8-da17-42c9-800a-2f08832e5d4b/custom-1.png",
        "url_2x": "https://static-cdn.jtvnw.net/custom-reward-images/30515034/6ef17bb2-e5ae-432e-8b3f-5ac4dd774668/7bcd9ca8-da17-42c9-800a-2f08832e5d4b/custom-2.png",
        "url_4x": "https://static-cdn.jtvnw.net/custom-reward-images/30515034/6ef17bb2-e5ae-432e-8b3f-5ac4dd774668/7bcd9ca8-da17-42c9-800a-2f08832e5d4b/custom-4.png"
      },
      "default_image": {
        "url_1x": "https://static-cdn.jtvnw.net/custom-reward-images/default-1.png",
        "url_2x": "https://static-cdn.jtvnw.net/custom-reward-images/default-2.png",
        "url_4x": "https://static-cdn.jtvnw.net/custom-reward-images/default-4.png"
      },
      "background_color": "#00C7AC",
      "is_enabled": true,
      "is_paused": false,
      "is_in_stock": true,
      "max_per_stream": { "is_enabled": false, "max_per_stream": 0 },
      "should_redemptions_skip_request_queue": true
    },
    "user_input": "yeooo",
    "status": "FULFILLED"
    }
  }
}
Field Type Description
timestamp string Time the pubsub message was sent
redemption object Data about the redemption, includes unique id and user that redeemed it
channel_id string ID of the channel in which the reward was redeemed.
redeemed_at string Timestamp in which a reward was redeemed
reward object Data about the reward that was redeemed
user_input
(optional)
string A string that the user entered if the reward requires input
status string reward redemption status, will be FULFULLED if a user skips the reward queue, UNFULFILLED otherwise

Example: Channel Subscriptions Event Message

The data field is a JSON object that contains topic and message fields. Typically, message is a JSON object that has been escaped (see “Example: Bits Event Message”) and cast into a string.

Note: The months field is deprecated. We now have fields for cumulative-months and streak-months.

Following is an example of a sub/resub message:

{
  "type": "MESSAGE",
  "data": {
    "topic": "channel-subscribe-events-v1.44322889",
    "message": {
      "user_name": "tww2",
      "display_name": "TWW2",
      "channel_name": "mr_woodchuck",
      "user_id": "13405587",
      "channel_id": "89614178",
      "time": "2015-12-19T16:39:57-08:00",
      "sub_plan": "1000",
      "sub_plan_name": "Channel Subscription (mr_woodchuck)",
      "cumulative_months": 9,
      "streak_months": 3,
      "context": "resub",
      "is_gift": false,
      "sub_message": {
        "message": "A Twitch baby is born! KappaHD",
        "emotes": [
          {
            "start": 23,
            "end": 7,
            "id": 2867
          }
        ]
      }
    }
  }
}

Here is an example of a subgift message, which contains recipient information.

{
  "type": "MESSAGE",
  "data": {
    "topic": "channel-subscribe-events-v1.44322889",
    "message": {
      "user_name": "tww2",
      "display_name": "TWW2",
      "channel_name": "mr_woodchuck",
      "user_id": "13405587",
      "channel_id": "89614178",
      "time": "2015-12-19T16:39:57-08:00",
      "sub_plan": "1000",
      "sub_plan_name": "Channel Subscription (mr_woodchuck)",
      "months": 9,
      "context": "subgift",
      "is_gift": true,
      "sub_message": {
        "message": "",
        "emotes": null
      },
      "recipient_id": "19571752",
      "recipient_user_name": "forstycup",
      "recipient_display_name": "forstycup"
    }
  }
}

Here is an example of a multi-month subgift message, which contains recipient information as well as the number of months gifted.

{
  "type": "MESSAGE",
  "data": {
    "topic": "channel-subscribe-events-v1.44322889",
    "message": {
      "user_name": "tww2",
      "display_name": "TWW2",
      "channel_name": "mr_woodchuck",
      "user_id": "13405587",
      "channel_id": "89614178",
      "time": "2015-12-19T16:39:57-08:00",
      "sub_plan": "1000",
      "sub_plan_name": "Channel Subscription (mr_woodchuck)",
      "months": 9,
      "context": "subgift",
      "is_gift": true,
      "sub_message": {
        "message": "",
        "emotes": null
      },
      "recipient_id": "19571752",
      "recipient_user_name": "forstycup",
      "recipient_display_name": "forstycup",
      "multi_month_duration": 6
    }
  }
}

Here is an example of an anonsubgift message. This is like subgift but contains no sender information, since the gifter is anonymous.

{
  "type": "MESSAGE",
  "data": {
    "topic": "channel-subscribe-events-v1.44322889",
    "message": {
      "channel_name": "mr_woodchuck",
      "channel_id": "89614178",
      "time": "2015-12-19T16:39:57-08:00",
      "sub_plan": "1000",
      "sub_plan_name": "Channel Subscription (mr_woodchuck)",
      "months": 9,
      "context": "anonsubgift",
      "is_gift": true,
      "sub_message": {
        "message": "",
        "emotes": null
      },
      "recipient_id": "13405587",
      "recipient_user_name": "tww2",
      "recipient_display_name": "TWW2"
    }
  }
}
Field Type Description
channel_id string ID of the channel that has been subscribed or subgifted
channel_name string Name of the channel that has been subscribed or subgifted
context string Event type associated with the subscription product, values: sub, resub, subgift, anonsubgift, resubgift, anonresubgift
data JSON Wraps the topics and message fields
user_id string User ID of the person who subscribed or sent a gift subscription
user_name string Login name of the person who subscribed or sent a gift subscription
display_name string Display name of the person who subscribed or sent a gift subscription
message string The body of the user-entered resub message. Depending on the type of message, the message body contains different fields
months int Cumulative number of months the gifter has giften in the channel (Deprecated)
recipient_id string User ID of the subscription gift recipient
recipient_user_name string Login name of the subscription gift recipient
recipient_display_name string Display name of the person who received the subscription gift
sub_plan string Subscription Plan ID, values: Prime, 1000, 2000, 3000
sub_plan_name string Channel Specific Subscription Plan Name
time string Time when the subscription or gift was completed. RFC 3339 format
topic string The topic that the message pertains to
type string Valid value: MESSAGE
cumulative_months string Cumulative number of tenure months of the subscription
streak_months string Denotes the user’s most recent (and contiguous) subscription tenure streak in the channel
is_gift bool If this sub message was caused by a gift subscription
multi_month_duration int Number of months gifted as part of a single, multi-month gift OR number of months purchased as part of a multi-month subscription

Example: Multi-month Subscription Message

Here is an example of a multi-month subscription message. This message is published upon purchase, auto-renewal, or re-subscription for a multi-month, recurring subscription

 {
   "type": "MESSAGE",
   "data": {
     "topic": "channel-subscribe-events-v1.44322889",
     "message": {
       "user_name": "tww2",
       "display_name": "TWW2",
       "channel_name": "mr_woodchuck",
       "user_id": "13405587",
       "channel_id": "89614178",
       "time": "2015-12-19T16:39:57-08:00",
       "sub_plan": "1000",
       "sub_plan_name": "Channel Subscription (mr_woodchuck)",
       "months": 4,
       "context": "sub",
       "is_gift": false,
       "sub_message": {
         "message": "",
         "emotes": null
       },
       "recipient_id": "19571752",
       "recipient_user_name": "forstycup",
       "recipient_display_name": "forstycup",
       "multi_month_duration": 6
     }
   }
 }

Example: AutoMod Queue Message

{
  "type": "MESSAGE",
  "data": {
    "topic": "automod-queue.46024993.44322889",
    "message": {
      "type": "automod_caught_message",
      "data": {
        "message": {
          "id": "some-automod-caught-message-id",
          "content": {
            "text": "a bad word",
            "fragments": [
              {
                "text": "a bad word",
                "automod": {
                  "topics": {
                    "swearing": 6
                  }
                }
              }
            ]
          },
          "sender": {
            "user_id": "559969259",
            "login": "msongvo222",
            "display_name": "msongvo222",
            "chat_color": "#8A2BE2"
          },
          "sent_at": "2021-05-24T18:46:20.964Z"
        },
        "content_classification": {
          "category": "swearing",
          "level": 2
        },
        "status": "PENDING",
        "reason_code": "",
        "resolver_id": "",
        "resolver_login": ""
      }
    }
  }
}
Field Type Description
id string Identifier of the message
content object Object containing details about the message
text string The text of the message
fragments object Object defining the potentially inappropriate content of the message
sender object Object representing the sender of the message
user_id integer User ID of the sender
login string User login on the sender
display_name string User display name of the sender
chat_color string Chat color of the sender
sent_at string Timestamp the message was sent in RFC3339 format.
content_classification object Object defining the category and level that the content was classified as
category string Category that the message was classified as
level number The level that the message was classified as.
status string Current status of the message, can be “PENDING”, “ALLOWED”, “DENIED”, or “EXPIRED”.
reason_code string Reserved for internal use
resolver_id string User ID of the moderator that resolved this message
resolver_login string User login of the moderator that resolved this message

Example: Low Trust User Treatment Message

{
  "low_trust_id": "12826.141981764",
  "channel_id": "12826",
  "updated_by": {
    "id": "12826",
    "login": "twitch",
    "display_name": "Twitch"
  },
  "updated_at": "2023-02-03T21:36:12Z",
  "target_user_id": "141981764",
  "target_user": "twitchdev",
  "treatment": "RESTRICTED",
  "types": [
    "MANUALLY_ADDED"
  ],
  "ban_evasion_evaluation": "",
  "evaluated_at": "2023-01-26T20:56:24Z"
}
Field Type Description
low_trust_id string An ID for the suspicious user entry, which is a combination of the channel ID where the treatment was updated and the user ID of the suspicious user.
channel_id string ID of the channel where the suspicious user was present.
updated_by object Information about the moderator who made any update for the suspicious user.
  id string User ID of the moderator.
  login string Login of the moderator.
  display_name string Display name of the moderator.
updated_at string RFC3339 timestamp of when the treatment was updated for the suspicious user.
target_user_id string User ID of the suspicious user.
target_user string Login of the suspicious user.
treatment string The treatment set for the suspicious user, can be “NO_TREATMENT”, “ACTIVE_MONITORING”, or “RESTRICTED”
types array of strings User types (if any) that apply to the suspicious user, can be “UNKNOWN_TYPE”, “MANUALLY_ADDED”, “DETECTED_BAN_EVADER”, or “BANNED_IN_SHARED_CHANNEL”
ban_evasion_evaluation string A ban evasion likelihood value (if any) that as been applied to the user automatically by Twitch, can be “UNKNOWN_EVADER”, “UNLIKELY_EVADER”, “LIKELY_EVADER”, or “POSSIBLE_EVADER”
evaluated_at string If applicable, an RFC3339 timestamp for the first time the suspicious user was automatically evaluated by Twitch.

Example: Low Trust User Chat Message

{
  "low_trust_user": {
    "id": "141981764",
    "low_trust_id": "NDU3NTcxMjM0LjgyNjA2NzQyNg",
    "channel_id": "12826",
    "sender": {
      "user_id": "141981764",
      "login": "twitchdev",
      "display_name": "TwitchDev"
    },
    "evaluated_at": "2023-01-26T20:56:24Z",
    "updated_at": "2023-02-03T21:36:12Z", 
    "ban_evasion_evaluation": "UNKNOWN_EVADER",
    "treatment": "RESTRICTED",
    "updated_by": {
      "id": "12826",
      "login": "twitch",
      "display_name": "Twitch"
    },
    "shared_ban_channel_ids": null,
    "types": [
      "MANUALLY_ADDED"
    ]
  },
  "message_content": {
    "text": "hola HeyGuys",
    "fragments": [
      {
        "text": "hola " 
      },
      {
        "text": "HeyGuys",
        "emoticon": {
          "emoticonID": "30259",
          "emoticonSetID": "0"
        }
      }
    ]
  },
  "message_id": "853093ce-17c5-4daa-b500-d1ce03115812",
  "sent_at": "2023-02-03T21:36:06Z"
}
Field Type Description
low_trust_user object Information about the low trust message and suspicious user.
  id string The user ID of the suspicious user.
  low_trust_id string Unique ID for this low trust chat message.
  channel_id string ID of the channel where the suspicious user was present.
  sender object Information about the suspicious user.
    user_id string The user ID of the suspicious user.
    login string The login of the suspicious user.
    display_name string The display name of the suspicious user.
  evaluated_at string If applicable, an RFC3339 timestamp for the first time the suspicious user was automatically evaluated by Twitch.
  updated_at string RFC3339 timestamp of when the treatment was updated for the suspicious user.
  ban_evasion_evaluation string A ban evasion likelihood value (if any) that as been applied to the user automatically by Twitch, can be “UNKNOWN_EVADER”, “UNLIKELY_EVADER”, “LIKELY_EVADER”, or “POSSIBLE_EVADER”
  treatment string The treatment set for the suspicious user, can be “NO_TREATMENT”, “ACTIVE_MONITORING”, or “RESTRICTED”
  updated_by object Information about the moderator who made any update for the suspicious user.
    id string The user ID of the moderator who made any update for the suspicious user.
    login string The login of the moderator who made any update for the suspicious user.
    display_name string The display name of the moderator who made any update for the suspicious user.
  shared_ban_channel_ids array of strings A list of channel IDs where the suspicious user is also banned.
  types array of strings User types (if any) that apply to the suspicious user, can be “UNKNOWN_TYPE”, “MANUALLY_ADDED”, “DETECTED_BAN_EVADER”, or “BANNED_IN_SHARED_CHANNEL”
message_content object The chat message text and fragments sent by the suspicious user.
  text string Plain text of the message sent.
  fragments array Fragments contained in the message, including emotes.
    text string Plain text fragment of the message sent.
    emoticon object Information about an emote if present in the message.
    emoticonID string An ID that identifies this emote.
    emoticonSetID string An ID that identifies the emote set that the emote belongs to.
message_id string ID of the chat message.
sent_at string RFC3339 timestamp of when the chat message was sent.

Example: User Moderation Notification Message

{
  "type": "MESSAGE",
  "data": {
    "topic": "user-moderation-notifications.46024993.44322889",
    "message": {
      "type": "automod_caught_message",
      "data": {
        "message_id": "some-automod-caught-message-id",
        "status": "DENIED"
      }
    }
  }
}
Field Type Description
id string Identifier of the message
status string Current status of the message, can be “PENDING”, “ALLOWED”, “DENIED”, or “EXPIRED”.

Example: Whispers Event Message

The data field is a JSON object that contains topic and message fields. Typically, message is a JSON object that has been escaped (see “Example: Bits Event Message” above) and cast into a string.

{
  "type":"MESSAGE",
  "data":{
     "topic":"whispers.44322889",
     "message":{
        "type":"whisper_received",
        "data":{
           "id":41
        },
        "thread_id":"129454141_44322889",
        "body":"hello",
        "sent_ts":1479160009,
        "from_id":39141793,
        "tags":{
           "login":"dallas",
           "display_name":"dallas",
           "color":"#8A2BE2",
           "emotes":[

           ],
           "badges":[
              {
                 "id":"staff",
                 "version":"1"
              }
           ]
        },
        "recipient":{
           "id":129454141,
           "username":"dallasnchains",
           "display_name":"dallasnchains",
           "color":"",
           "badges":[]
        },
        "nonce":"6GVBTfBXNj7d71BULYKjpiKapegDI1"
     },
     "data_object":{
        "id":41,
        "thread_id":"129454141_44322889",
        "body":"hello",
        "sent_ts":1479160009,
        "from_id":44322889,
        "tags":{
           "login":"dallas",
           "display_name":"dallas",
           "color":"#8A2BE2",
           "emotes":[],
           "badges":[
              {
                 "id":"staff",
                 "version":"1"
              }
           ]
        },
        "recipient":{
           "id":129454141,
           "username":"dallasnchains",
           "display_name":"dallasnchains",
           "color":"",
           "badges":[]
        },
        "nonce":"6GVBTfBXNj7d71BULYKjpiKapegDI1"
     }
  }
}

The fields in this message are similar to IRC fields. See the Chatbots and IRC documentation.