Contents

Building Extensions

Reviews for organizations and chatbot verification continue to be temporarily paused while we revise our processes. Reviews for Extensions and game ownership have resumed. Thank you for your patience and understanding.

As of July 9th 2024, there is no longer a requirement to have an Apple Developer account, or fill out the "iOS Allowlist Request" form, to allow an Extension to work on the iOS version of the Twitch app. All mobile Extensions, existing and new, are available on iOS and Android without additional requirements in the submission process.

Creating An Extension Front End

As previously defined, extensions are front-end iframes. Now that you have created your extension and defined its settings, you are ready to create the assets that will live within the iframe.

Mobile Support

If your extension is intended for mobile devices, you can provide a second front end for those devices. You can use an identical front end for mobile and web, if it is responsive enough to render and perform well on both platforms; otherwise, submit different front ends.

On the Twitch developer site, you are prompted to submit separate front ends for web and mobile. If you use the same viewer HTML for both web and mobile, we enable you to customize your behavior based on the native platform by providing your viewer with the query strings ?platform=mobile and ?platform=web.

Proper layout, rendering, performance, and interaction on mobile devices are not the same as they are on the web, so if you provide mobile support, test your extension thoroughly on the Twitch mobile app.

Note: As of July 9th 2024, there is no longer a requirement to have an Apple Developer account, or fill out the “iOS Allowlist Request” form, to allow an Extension to work on the iOS version of the Twitch app. All mobile Extensions, existing and new, are available on iOS and Android without additional requirements in the submission process.

Extension Helper Library

An extension’s iframe must import the Extension Helper JavaScript file, created and hosted by Twitch. It provides methods for dealing with authentication, receiving notifications of stream properties, and listening to PubSub events. All HTML files included in your Extension must load the Extension Helper. To do so, include this line:

<script src="https://extension-files.twitch.tv/helper/v1/twitch-ext.min.js"></script>

For details on the Extension Helper, including the callbacks and functions it provides, see the Extensions Reference.

Creating Your Extension Backend Service (EBS)

The EBS is your optional backend service that supports the extension. Your EBS can be written in whatever language you prefer. Depending on the nature of your extension, it generally should be capable of the operations described below.

Note: An extension without an EBS usually acts as a display panel for 3rd party API calls (like a Twitch recent follower list). An EBS is unnecessary in such cases because an existing service can perform all the work necessary to generate content. Many popular utility extensions are “display only”.

Verifying the JWT

Your EBS needs to verify the communication it receives via any AJAX call from your extension. For example, it may need to enforce a policy that certain configuration tasks can be performed only by broadcasters. It also may want to ensure that a confirmed Twitch viewer, as opposed to an unidentified agent, is connecting to the EBS. As described above, the front-end iframe can obtain a signed JWT via the Extension Helper, using the onAuthorized() callback. The extension developer may then include this token as a header when making AJAX calls to the EBS.

JWT signing and validation libraries are available for many languages at JWT. They usually follow a calling interface similar to this:

verify(<jwt>, <secret>)

Where:

The JWTs used by Twitch Extensions expire, and verification of them fails after the expiration date. The Extension Helper automatically refreshes the token and then re-calls the onAuthorized() callback. Always use the latest JWT supplied by the Extension Helper.

For the full JWT schema and detailed notes on each field, see the “JWT Schema” section of the Extensions Reference.

Signing the JWT

In addition to verifying tokens signed by the Extension Helper, your EBS needs to be able to sign new JWTs for calls to various Extensions endpoints that use JWT as the authentication mechanism. Use the following format for the payload object in a JWT signed by your EBS:

{
  "exp": 1502646259,
  "user_id": "27419011",
  "role": "external"
}

Where:

For more information about these fields, see the “JWT Schema” section of the the Extensions Reference.

Sign the payload using your JWT library of choice, which usually has a calling interface similar to this:

sign(<payload>, <secret>)

Where:

Note: If the call fails, consult the documentation for your software library for the details on formatting the call.

The shared secret is located in the Key field under Extension Client Configuration on your extension’s Extension Settings page. The secret is base64 encoded, but some JWT libraries might expect the secret to be a byte array instead. For example, to sign the JWT using the jsonwebtoken Node.js package, you need to convert the base64 secret to a byte array.

const jwt = require('jsonwebtoken')

const sharedSecret = 's7sK6iKws1KS+ihSERL7fgoT8rx90iFkJ/hUdcAEGSs='
const broadcasterId = '12345678'
const tokenPayload = {
    user_id: broadcasterId,
    role: 'external'
}

const token = jwt.sign(tokenPayload, Buffer.from(sharedSecret, 'base64'), { expiresIn: '1d' })
console.log("token: " + token)

Finally, send your signed JWT in the request header, following this format:

Authorization: Bearer <signed JWT>

Broadcasting via PubSub

When the EBS wants to transmit real-time messages or state via PubSub, it will use the Send Extension PubSub Message endpoint. Using this endpoint, your EBS can broadcast to all viewers of a given channel or to specific users via a whisper.

Adhere to these limits for Twitch PubSub traffic:

These rules ensure the stability and scalability of our systems.

Required Configurations

If you specify configuration information in your EBS, you can optionally require that a broadcaster successfully configures your extension before activation is allowed. This can be useful if, for example, an active extension would show a confusing error message to all viewers if misconfigured. You enforce required broadcaster configuration with a string in the Required Configurations field. The contents of this string can be whatever you want. By using the string you provide in this field, you can easily require different configurations from version to version, so that if a new version requires reconfiguration, the broadcaster will need to complete configuration before activating the new version.

Once your EBS determines that the extension is correctly configured on a channel, call the Set Extension Required Configuration endpoint.

Using the Configuration Service

The configuration service enables you to store persistent per-channel and per-extension data and have it provided to your front end on extension startup. This is a common need for most extensions. With the configuration service, you can quickly support scenarios like:

More importantly, with the configuration service, you do not need to expose your EBS to the extension front end on initial load, eliminating the need for your EBS to scale to support that scenario. In some cases, you can build an extension without an EBS, just by using the configuration service. (You can still build this functionality in your EBS, if you choose.)

You choose whether to use the configuration service in the capabilities section of extension management on the developer site. To make your choice, select one of the options (“No configuration”, “Custom/My Own Service”, or “Extension Configuration Service”) on the radio control on that page. Note that the page also controls whether the extension opts into other features such as identity linking and chat injection.

After making your choice, data that is set via either Set Extension Configuration Segment or the set helper function (see Helper: Configuration) will be provided to the extension during bootstrap.

An extension configuration has three types of configuration segments:

Segment TypeIs delivered to ...Can be set by ...
DeveloperViews of your extension on the associated channel.Developers 
BroadcasterViews of your extension on the associated channel.Developers and broadcasters
GlobalEvery view of your extension, regardless of the channel.Developers 

For Extension examples that leverage the configuration service see the Twitch API Reference. Also, see these repositories:

Setting Required Configuration with the Configuration Service (Optional)

Extensions can choose to use the configuration service and then make a second choice to display without configuration:

Managing Extension Secrets

Each extension maintains a shared secret that is used to sign and verify JSON Web Tokens (JWT) that provide the identity of users. Use this authentication method when making Extensions API calls from your EBS (for endpoints that support it).

Twitch extension technology relies on a secret shared between the Twitch API and the EBS, to validate JWTs. This secret has an extremely long life (100 years); however, we strongly recommend that extension developers rotate the shared secret often, to better ensure its security.

JWT Roles

Both the EBS and Twitch create JWTs.

The EBS should create and sign JWTs with the external role to perform API actions. Twitch creates JWTs with other roles, so the EBS can perform user authentication. Both use cases (the external role and other roles) use the same secret. (For a discussion of roles, see the “JWT Schema” section of the Extensions Reference.)

Creating Secrets

To create a new secret:

  1. Go to the Settings page of your extension in the Extensions console.
  2. On the left panel, click Secret Keys.
  3. Click Create New Secret to generate a new secret key. You will see the following:
    • Key — The secret, base64 encoded.
    • Active — UTC timestamp when the secret becomes active. This allows the secret to propagate through both Twitch servers and the EBS, before you use it.
    • Expires — Timestamp when the secret expires. This is the latest time to use this secret to verify a JWT; the JWT should be discarded after this time.

Optionally, you can create new secrets with the Create Extension Secret endpoint.

Note: Each time a new secret is requested, the old one is updated to expire after one hour (enough time for Twitch clients to rotate over to the new secret smoothly).

Rotating Secrets

To keep your secrets from becoming useless, you must rotate them before they expire. To do so, create a new secret on the extension’s Settings page under Secret Keys. The table will update, showing when the previous key will expire and the new key will be active.

Because of the activation delay, you can have multiple secrets active for some (configurable) period of time. For signing, use the active secret with the latest expiration time.

Note: This option is for emergency situations where a secret has been compromised and breaking the extension is preferable to waiting for the secret to cycle.

For a higher level of security, you can rotate secrets programmatically on a scheduled basis. For more information, see the Extensions Reference

Revoking Secrets

At any time, if your secrets are compromised, you can use the Revoke All Secrets option on the extension’s Settings page under Secret Keys. View this as a kill switch: it immediately deletes all secrets associated with a specified extension.

Optionally, you can revoke all secrets by using the Create Extension Secret endpoint, which rotates any current secrets out of service.