JWT With Zoom

The Zoom API uses JSON Web Tokens (JWT) to authenticate account-level access. These tokens offer a method to establish secure server-to-server authentication by transferring a compact JSON object with a signed payload of your account’s API Key and Secret.

When authenticating to the Zoom API, a JWT should be generated uniquely by a server-side application and included as a Bearer Token in the header of each request. Follow this guide to set up the generation and structure of these tokens.

JSON Web Tokens with SDK apps

Some SDK apps use JWT to authenticate account-level SDK Keys and Secrets to initialize the app. These tokens will follow the same structure as with API Keys and Secrets.

Accessing your API Key & Secret

JWT apps provide an API Key and Secret required to authenticate with JWT. To access the API Key and Secret, Create a JWT App on the Marketplace. After providing basic information about your app, locate your API Key and Secret in the App Credentials page.

An account has only one API Key and Secret pair. If a JWT app has already been created, either by yourself or another developer on your account, the API Key and Secret can be viewed.

Note: As account-level apps, JWT apps require Developer Role Permission to create, edit or access.

Generating JWTs

A single JWT consists of three components: Header, Payload, and Signature with a . separating each. For example: aaaaa.bbbbb.ccccc

The Zoom API recommends and supports libraries provided on JWT.io. While other libraries can create JWT, these recommended libraries are the most robust.

Header

The Header includes the specification of the signing algorithm and type of token. alg notes the algorithm being used. Zoom APIs and SDKs use HMAC SHA256 (HS256). typ refers to the token type: JWT.

{
  "alg": "HS256",
  "typ": "JWT"
}

Note: The Zoom API uses HS256 to sign the token. Use of other algorithms is not supported.

Payload

The payload of a token contains the claims or the pieces of information being passed about the user and any metadata required. While there are three types of claims, registered, public, and private, we highly recommend using registered claims for interoperability. A payload will require an issuer (iss) and expiration time (exp).

iss, the issuer of the token, is your API Key.

exp is the expiration timestamp of the token in seconds since Epoch (unix epoch time).

{
  "iss": "API_KEY",
  "exp": 1496091964000
}

Note: The expiration time (exp) can be defined in a numeric date and time format.

It is highly recommended to set the exp timestamp for a short period, i.e. a matter of seconds. This way, if a token is intercepted or shared, the token will only be valid for a short period of time.

Note: Though protected against tampering, the information contained in the Header and Payload is readable by anyone. Do not store confidential information in either of these elements.

Signature

The Signature of the token base64 encodes the header and payload, then includes the API Secret within the HMACSHA256 algorithm to securely sign the entire package.

HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    API_SECRET)

Testing with JWTs

Within the App Credentials page of your JWT app, you will see an option to View JWT Token. Here you can quickly generate a temporary token using the current API Key and Secret for the given expiration time. This single temporary token can then be used to test Zoom APIs, but should never be used in production applications.

View JWT Token

Sample Requests

Sample apps

Reference the following sample apps for a guide to generating and making requests using JWT:

Node JS: Sample Node app using jsonwebtoken

Sample code

The following code snippets can be used to get started making server-side API calls using JWT:

//Make Zoom API call
var options = {
    uri: 'https://api.zoom.us/v2/users',
    qs: {
        status: 'active' // -> uri + '?status=active'
    },
    auth: {
      //Provide your token here
    		'bearer': token
  	},
    headers: {
        'User-Agent': 'Zoom-Jwt-Request',
        'content-type': 'application/json'
    },
    json: true // Automatically parses the JSON string in the response
};

rp(options)
    .then(function (response) {
      //logic for your response
        console.log('User has', response);
    })
    .catch(function (err) {
        // API call failed...
        console.log('API call failed, reason ', err);
    });

Need help?

The first place to look is on our Developer Forum. If you can't find the answer or your request includes sensitive information, contact Developer Support.