Authentication

This is a guide to help developers use Twitch Authentication, which enables your application to take actions on behalf of a Twitch account or access certain data about a user’s account. There are multiple ways for you to obtain access to a Twitch account on behalf of a user. We use parts of the OAuth 2.0 protocol.

Authentication involves:

  1. Registering your app to obtain a client ID and client secret.
  2. Getting an access token. This includes specifying scopes, or the permissions your app requires.
  3. Sending the access token in your API request, to authenticate API requests.

As we describe the steps, we provide sample requests that your application would make, for one of your users to grant you access to her viewing activity.

Note: For readability, some of the parameterized example code is shown on multiple lines; the real examples are on one line.

Registration

To make an application that uses the Twitch API, you will first need to “Register your application” from the connections tab of your Twitch settings page. When creating this app, enter your redirect URI, which is where your users are redirected after being authorized.

Once you create a developer application, you are assigned a client ID. Some authentication flows also require a client secret, which you can generate on the same page as the client ID.

  • Client IDs are public and can be shared (for example, embedded in the source of a Web page).
  • Client secrets are equivalent to a password for your application and must be kept confidential. Never expose it to users, even in an obscured form.

Because your client secret is confidential, we cannot show it to you once you leave the page, so make sure to record it somewhere safe. Also, generating a new client secret immediately invalidates the current one, which might make your API requests fail until your app is updated.

Getting Access Tokens

There are two ways to get an OAuth access token:

  • Use the Implicit Grant Flow if your app does not use a server, such as a client-side JavaScript app or mobile app. This approach does not require a server that must make requests to the API.
  • Use the Authorization Code Flow if you are making a Web app that uses a server.

Within both of the above, there is an option to use OIDC (OpenID Connect) to get more information about your user (such as email address).

Implicit Grant Flow

1) Send the user you want to authenticate to your registered redirect URI. Then, an authorization page will ask the user to sign up or log in with her Twitch account and allow the user to choose whether to authorize your application/identity system.

Use this request:

1
2
3
4
5
GET https://api.twitch.tv/kraken/oauth2/authorize
    ?client_id=<your client ID>
    &redirect_uri=<your registered redirect URI>
    &response_type=<type>
    &scope=<space-separated list of scopes>

There are several required and optional query-string parameters:

Required Parameter Type Description
client_id string Your client ID.
redirect_uri URI Your registered redirect URI. This must exactly match the redirect URI registered in the prior, Registration step.
response_type string Specifies what information to return. For non-OIDC requests, this must be:

* token – Return an access token. The user may be prompted to confirm authorization once or repeatedly; this is controlled by the optional force_verify parameter, below.

For OIDC requests, there are two valid values:

* token id_token – Return an access token and an ID token (JWT). A given user is prompted to confirm authorization only on the first request.
* id_token – Return only an ID token. For example, a client with a valid access token, who only needs added information about the user authorizing it, might specify this option. The user is prompted to confirm authorization on every request.
scope string Space-separated list of scopes. For OIDC requests, this must include the openid scope.
Optional Parameter Type Applies to these Requests Description
force_verify boolean Non-OIDC Specifies whether the user should be re-prompted for authorization. If this is true, the user always is prompted to confirm authorization. This is useful to allow your users to switch Twitch accounts, since there is no way to log users out of the API. Default: false (a given user sees the authorization page for a given set of scopes only the first time through the sequence).
nonce string OIDC OIDC opaque value to avoid CSRF attacks. (Specifically, this is used to associate the client’s authorization session with an ID token, to avoid replay attacks.) This value is echoed back in the response.

We strongly recommend you use this for OIDC requests.
state string All Your unique token, generated by your application. This is an OAuth 2.0 opaque value, used to avoid CSRF attacks. This value is echoed back in the response.

We strongly recommend you use this for all requests.

In our example, you request access to a user’s viewing activity (by specifying the viewing_activity_read scope) and send the user to http://localhost:

1
2
3
curl -H 'Accept: application/vnd.twitchtv.v5+json' \
-H 'Authorization: OAuth cfabdegwdoklmawdzdo98xt2fo512y' \
-X GET 'https://api.twitch.tv/kraken/oauth2/authorize?response_type=token&client_id=uo6dggojyb8d6soh92zknwmi5ej1q2&redirect_uri=http://localhost&scope=viewing_activity_read&state=c3ab8aa609ea11e793ae92361f002671'

2) If the user authorizes your application, she is redirected to your redirect URL:

1
https://<your registered redirect URI>#access_token=<an access token>

The access token is in the URL fragment, not the query string, so it will not show up in HTTP requests to your server. URI fragments can be accessed from JavaScript with document.location.hash.

The response includes the nonce and state parameters, if they were in your request.

OIDC responses include an ID token, if that was requested. The following claims about the ID token are included in the payload of the JWT that is returned:

  • iss – Token issuer (Twitch)
  • sub – Subject or end user for whom the token is presenting claims/identity
  • aud – Audience or OAuth 2.0 client that is the intended recipient of the token
  • exp – Expiration time
  • iat – Issuance time

For more information on the claims presented in the ID token, see the OpenID Connect spec.

In our example, your user gets redirected to:

1
2
3
https://localhost#access_token=pk2bh6y1vi8mrn7l67bp9i6dpg2wnk
	&scope=viewing_activity_read
	&state=c3ab8aa609ea11e793ae92361f002671

Here is a sample response with an ID token:

1
2
3
4
5
https://localhost#access_token=pk2bh6y1vi8mrn7l67bp9i6dpg2wnk
 &token_type=bearer
 &id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjRvaXU4In0.eyJzdWIiOiJuZnlmZSIsImF1ZCI6ImltX29pY19jbGllbnQiLCJqdGkiOiJUOU4xUklkRkVzUE45enU3ZWw2eng2IiwiaXNzIjoiaHR0cHM6XC9cL3Nzby5tZXljbG91ZC5uZXQ6OTAzMSIsImlhdCI6MTM5MzczNzA3MSwiZXhwIjoxMzkzNzM3MzcxLCJub25jZSI6ImNiYTU2NjY2LTRiMTItNDU2YS04NDA3LTNkMzAyM2ZhMTAwMiIsImF0X2hhc2giOiJrdHFvZVBhc2praVY5b2Z0X3o5NnJBIn0.g1Jc9DohWFfFG3ppWfvW16ib6YBaONC5VMs8J61i5j5QLieY-mBEeVi1D3vr5IFWCfivY4hZcHtoJHgZk1qCumkAMDymsLGX-IGA7yFU8LOjUdR4IlCPlZxZ_vhqr_0gQ9pCFKDkiOv1LVv5x3YgAdhHhpZhxK6rWxojg2RddzvZ9Xi5u2V1UZ0jukwyG2d4PRzDn7WoRNDGwYOEt4qY7lv_NO2TY2eAklP-xYBWu0b9FBElapnstqbZgAXdndNs-Wqp4gyQG5D0owLzxPErR9MnpQfgNcai-PlWI_UrvoopKNbX0ai2zfkuQ-qh6Xn8zgkiaYDHzq4gzwRfwazaqA
 &state=c3ab8aa609ea11e793ae92361f002671
 &scope=viewing_activity_read

3) OIDC only: Validate the ID token. We leverage asymmetric signing of the token (RSA256), to ensure no tampering occurs. See the OpenID Connect Core 1.0 specification for instructions on how to validate the ID token. Use our PEM-encoded RSA public key to verify the ID token’s signature:

1
2
3
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6lq9MQ+q6hcxr7kOUp+tHlHtdcDsVLwVIw13iXUCvuDOeCi0VSuxCCUY6UmMjy53dX00ih2E4Y4UvlrmmurK0eG26b+HMNNAvCGsVXHU3RcRhVoHDaOwHwU72j7bpHn9XbP3Q3jebX6KIfNbei2MiR0Wyb8RZHE+aZhRYO8/+k9G2GycTpvc+2GBsP8VHLUKKfAs2B6sW3q3ymU6M0L+cFXkZ9fHkn9ejs+sqZPhMJxtBPBxoUIUQFTgv4VXTSv914f/YkNw+EjuwbgwXMvpyr06EyfImxHoxsZkFYB+qBYHtaMxTnFsZBr6fn8Ha2JqT1hoP7Z5r5wxDu3GQhKkHwIDAQAB
-----END PUBLIC KEY-----

Example: How to validate an OpenID Connect ID token.

Authorization Code Flow

1) Send the user you want to authenticate to your registered redirect URI. Then, an authorization page will ask the user to sign up or log in with her Twitch account and allow the user to choose whether to authorize your application/identity system. Use this request:

1
2
3
4
5
GET https://api.twitch.tv/kraken/oauth2/authorize
    ?client_id=<your client ID>
    &redirect_uri=<your registered redirect URI>
    &response_type=code
    &scope=<space-separated list of scopes>

Specifying response_type=code causes an authorization code to be returned, which is used later in this procedure. A given user is prompted to confirm authorization only on the first request.

There are several required and optional query-string parameters:

Required Parameter Type Description
client_id string Your client ID.
redirect_uri URI Your registered redirect URI. This must exactly match the redirect URI registered in the prior, Registration step.
scope string Space-separated list of scopes. For OIDC requests, this must include the openid scope.
Optional Parameter Type Applies to these Requests Description
force_verify boolean Non-OIDC Specifies whether the user should be re-prompted for authorization. If this is true, the user always is prompted to confirm authorization. This is useful to allow your users to switch Twitch accounts, since there is no way to log users out of the API. Default: false (a given user sees the authorization page for a given set of scopes only the first time through the sequence).
nonce string OIDC OIDC opaque value to avoid CSRF attacks. (Specifically, this is used to associate the client’s authorization session with an ID token, to avoid replay attacks.) This value is echoed back in the response.

We strongly recommend you use this for OIDC requests.
state string All Your unique token, generated by your application. This is an OAuth 2.0 opaque value, used to avoid CSRF attacks. This value is echoed back in the response.

We strongly recommend you use this for all requests.

In our example, you request access to a user’s viewing activity (by specifying the viewing_activity_read scope) and send the user to http://localhost:

1
2
3
curl -H 'Accept: application/vnd.twitchtv.v5+json' \
-H 'Authorization: OAuth cfabdegwdoklmawdzdo98xt2fo512y' \
-X GET 'https://api.twitch.tv/kraken/oauth2/authorize?response_type=code&client_id=uo6dggojyb8d6soh92zknwmi5ej1q2&redirect_uri=http://localhost&scope=viewing_activity_read&state=c3ab8aa609ea11e793ae92361f002671'

2) If the user authorizes your application, she is redirected to your redirect URI, with an authorization code:

1
https://<your registered redirect URI>/?code=<authorization code>

The OAuth 2.0 authorization code is a 30-character, randomly generated string. It is used in the next step subsequent request made to the token endpoint in exchange for access and ID tokens. ID tokens are a set of claims about the end user, for a given authorization.

The response includes the nonce and state parameters, if they were in your request.

In our example, your user gets redirected to:

1
2
3
http://localhost/?code=394a8bc98028f39660e53025de824134fb46313
	&scope=viewing_activity_read
	&state=c3ab8aa609ea11e793ae92361f002671

3) On your server, get an access token (and ID token, for OIDC requests) by making this request:

1
2
3
4
5
6
7
POST https://api.twitch.tv/kraken/oauth2/token
    ?client_id=<your client ID>
    &client_secret=<your client secret>
    &code=<authorization code received above>
    &grant_type=authorization_code
    &redirect_uri=<your registered redirect URI>
    &state=<your unique token generated by your application>

Here is a sample request:

1
POST https://api.twitch.tv/kraken/oauth2/token?client_id=uo6dggojyb8d6soh92zknwmi5ej1q2&client_secret=nyo51xcdrerl8z9m56w9w6wg&grant_type=authorization_code&redirect_uri=http://localhost&code=394a8bc98028f39660e53025de824134fb46313&state=c3ab8aa609ea11e793ae92361f002671

4) We respond with a JSON-encoded access token. For non-OIDC requests, the response looks like this:

1
2
3
4
{
   "access_token": "<user access token>",
   "scope": <your previously listed scope(s)>
}

In our example:

1
2
3
4
{
   "access_token": "pk2bh6y1vi8mrn7l67bp9i6dpg2wnk",
   "scope": viewing_activity_read
}

OIDC responses include an additional OAuth 2.0 token, an ID token, with the following claims about the token included in the JWT payload:

  • iss – Token issuer (Twitch)
  • sub – Subject or end user for whom the token is presenting claims/identity
  • aud – Audience or OAuth 2.0 client that is the intended recipient of the token
  • exp – Expiration time
  • iat – Issuance time
  • nonce – Value optionally specified in the request

For more information on the claims presented in the ID token, see the OpenID Connect spec.

Here is an OIDC response:

1
2
3
4
5
{
   "access_token": "pk2bh6y1vi8mrn7l67bp9i6dpg2wnk",
   "scope": "viewing_activity_read",
   "id_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxNDk0MzkxNDQiLCJ1cGRhdGVkX2F0IjoiMDAwMS0wMS0wMVQwMDowMDowMFoiLCJpc3MiOiJodHRwczovL3Bhc3Nwb3J0LnR3aXRjaC50diIsImF1ZCI6IjJrOGl6MnE0eG1scDM2MmQyaWR5YzBoNnA0MmQxZSIsImV4cCI6IjIwMTctMDUtMDVUMjI6MzI6MjcuNzk1MzQxNjI1WiIsImlhdCI6MTQ5NDAyMjY0N30=.6HkHCuwUufojZn3ogeyl8Bi0J8IyVjIzrTLLR-v-MpmP2-EYExjVT_aPjoIfuOmfK2cCDCsGSRL-p7rtFamuv3e4v--S_TkhekLioAdL-9Nm-ZnX8kdys9XYLEf8acFkQOmQ2W5DLfm68u3zAmpRMXsq_LPcsWVbPe5AGZK4Tt5mS5JIK1S8VCPTQLc7__rMI_3Hzpij09fILlbaicAKPqybLnqfMowyemcWmrecseNc_Jig_ZpGm7RqNkbxctBIBDouB_rGtH1R1CwlDs_PE5pSq4I67G6aoL0P4aUIOpFCXxLU45975ZdQDRRq3o2Lqce6cmRLOemO5JSCyTGZhQ=="
}

5) OIDC only: Validate the ID token. We leverage asymmetric signing of the token (RSA256), to ensure no tampering occurs. See the OpenID Connect Core 1.0 specification for instructions on how to validate the ID token. Use our PEM-encoded RSA public key to verify the ID token’s signature:

1
2
3
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6lq9MQ+q6hcxr7kOUp+tHlHtdcDsVLwVIw13iXUCvuDOeCi0VSuxCCUY6UmMjy53dX00ih2E4Y4UvlrmmurK0eG26b+HMNNAvCGsVXHU3RcRhVoHDaOwHwU72j7bpHn9XbP3Q3jebX6KIfNbei2MiR0Wyb8RZHE+aZhRYO8/+k9G2GycTpvc+2GBsP8VHLUKKfAs2B6sW3q3ymU6M0L+cFXkZ9fHkn9ejs+sqZPhMJxtBPBxoUIUQFTgv4VXTSv914f/YkNw+EjuwbgwXMvpyr06EyfImxHoxsZkFYB+qBYHtaMxTnFsZBr6fn8Ha2JqT1hoP7Z5r5wxDu3GQhKkHwIDAQAB
-----END PUBLIC KEY-----

Example: How to validate an OpenID Connect ID token.

Sending Access Tokens

When an API request requires authentication, send the access token as a header:

curl -H "Authorization: OAuth <access token>" https://api.twitch.tv/kraken/

Revoking Access Tokens

To clean up previously obtained access tokens, use the Twitch OAuth token-revocation endpoint. Its implementation follows the OAuth standard.

On your server, revoke an access token by making this request:

1
2
3
POST https://api.twitch.tv/kraken/oauth2/revoke
    ?client_id=<your client ID>
    &token=<your OAuth token>

For example, using our previously authenticated user, the request is:

1
POST https://api.twitch.tv/kraken/oauth2/revoke?client_id=uo6dggojyb8d6soh92zknwmi5ej1q2&token=pk2bh6y1vi8mrn7l67bp9i6dpg2wnk

Both successful requests and requests with bad tokens return 200 OK with no body. Requests with bad tokens return the same response, as there is no meaningful action a client can take after sending a bad token.

Malformed requests return 400 Bad Request, along with information about how to fix the request, typically reminding the requester to include the client_id and client_secret.

Scopes

As mentioned above, when you request authorization from users, the URL scope parameter allows you to specify which permissions your app requires. These scopes are tied to the access token you receive on successful authorization. Without specifying scopes, your app can access only basic information about the authenticated user.

You can specify any or all of these scopes:

Scope Name Type of Access
channel_check_subscription Read whether a user is subscribed to your channel.
channel_commercial Trigger commercials on channel.
channel_editor Write channel metadata (game, status, etc).
channel_feed_edit Add posts and reactions to a channel feed.
channel_feed_read View a channel feed.
channel_read Read nonpublic channel information, including email address and stream key.
channel_stream Reset a channel’s stream key.
channel_subscriptions Read all subscribers to your channel.
chat_login Log into chat and send messages.
collections_edit Manage a user’s collections (of videos).
communities_edit Manage a user’s communities.
communities_moderate Manage community moderators.
openid Use OpenID Connect authentication.
user_blocks_edit Turn on/off ignoring a user. Ignoring a user means you cannot see him type, receive messages from him, etc.
user_blocks_read Read a user’s list of ignored users.
user_follows_edit Manage a user’s followed channels.
user_read Read nonpublic user information, like email address.
user_subscriptions Read a user’s subscriptions.
viewing_activity_read Turn on Viewer Heartbeat Service ability to record user data.

Scopes are specified as a space-separated list in the URL scope parameter, when requesting authorization:

&scope=user_read+channel_read

Ask for only the permissions you need, as users can view each requested permission when authorizing your app.