Client Authorization

The guide below is specific to client-user authorization. For authentication outside of the user context for chatbots, please see the page on Chatbot Service Authorization.

OAuth with Zoom


At Zoom, we value our customer’s data security above all else. To access Zoom customer data you will need to authenticate those requests.

To make this as easy as possible, we have implemented the OAuth 2.0 spec for authorization. This industry standard protocol will allow you to make requests on behalf of the user securely.

Follow the steps below to enable your application to make secure requests on behalf of our mutual users.

Step 1: Configure Your Zoom Application

If you haven’t already done so, you will need to configure your Zoom application on our marketplace to create your Client ID and Secret to make requests.

First, go to marketplace.zoom.us. Once logged in, click the Develop dropdown in the header and choose Build App.

This will bring you to a page that allows you to describe and register your app with us.

Make sure to select the appropriate application type:

Account Level Application: An app that will manage users across an entire account.

User-Managed Application: An app that will be authenticated by individual users and only has access to that user’s data.

Once you fill out the essential information for your application your credentials will automatically be generated on the next page.

There are two types of credentials here:

Development: These credentials should be used during your development phase and to develop changes after your application is published.

Production: These credentials should be used once your app is ready for publishing.

(In order to “activate” these credentials you will need to create a publishable URL on the submit page).

From here you can input the following information for your app.

  • Description
  • Redirect URI (Required to make access token requests).
  • Scopes
  • Features (such as enabling the chat bot feature).
  • Create local test URLs to test your app against your dev environments.
  • Request publication once your development is complete.
Zoom OAuth Authorization Flow Chart

Step 2: Request an Authorization Code

Once you have your app credentials, you will use your Client ID to request an Authorization Code. This is not the final code that will be used to request user data - it will be used in the next step to authenticate a request for the access token.

Authorization Endpoint

The first step in getting the user token is to call the Zoom authorization endpoint with your Client ID and Secret to get the authorization code.

GET https://zoom.us/oauth/authorize

The following query string needs to be passed as well:

response_type=code
client_id={clientID}
redirect_uri={redirect_uri}

For example:

https://zoom.us/oauth/authorize?response_type=code&client_id={YOUR_CLIENT_ID}&redirect_uri={http://YOUR_REDIRECT_URI}

Available Parameters:

Parameter Description Required
response_type This is the authorization type. In this case, it should be set to code. Yes
client_id The identifier issued to the client during the registration process. Yes
redirect_uri Where to redirect the user after authorization. This must match one of the redirect URIs used during registration. Yes
state An optional string passed with the request to prevent CSRF. The state will be sent back when the redirect occurs to ensure that you initiated the request.

e.g. state=DH73HL9123hfk873g
Optional
scope A URL encoded the string of scopes you’re requesting for your app on behalf of the user. If you do not provide this during the request, we will fallback to the scopes you defined during your application registration.

.e.g. scope=user%3Aread+meeting%3Awrite+webinar%3Awrite
Optional
Example Node Request
const zoomclientid = "enter your client id";
const myappredirect = "https://myapp.io/zoomcallback";
const zoomauth = "https://zoom.us/oauth/authorize"  + "?response_type=code&client_id=" + zoomclientid + "&redirect_uri=" + myappredirect;

res.redirect(zoomurl);

If the user has not previously authorized your app to access their account then they will be directed to the Zoom authorization page. Once the user authorizes and “allows” your app to access their account, then the user will be redirected to the URI provided in the redirect_uri query parameter.

If there is current and valid authorization for your app, the login screen will be immediately bypassed and the user will be redirected to your redirect_uri.

Zoom will return a 200 OK if your Client ID and redirect URI matches with what you have registered when creating the app. If you get a 400 or a 401 error, check your client ID and redirect URI again to make sure they match up with what has been registered in Zoom.

Zoom will trigger a call back to the redirect URL that you have registered. The call back will have the OAuth code that you have requested in the above step.

If the applications are approved, one essential query string will be attached. The code will be sent along with the redirect URI.

The code will be used in the next step to request the access token to allow your app to make requests on behalf of the user.

If you sent a state with the original request, this will also be sent back and can be used to test for CSRF attacks. If the code does not match, you should recieve a 401 error and stop authentication of that application immediately.

Step 3: Exchange the Authorization Code for an Access Token

Once you have the authorization code, you can make the final request for an access token. This is the token that you will use to make subsequent requests on behalf of the authorized user.

You will use the following endpoint along with your code to request the access token:

POST https://zoom.us/oauth/token

With the following query string parameters:

grant_type=authorization_code
code={YOUR_CODE}
redirect_uri={YOUR_REDIRECT_URI}

Additionally, you need to provide the following Authorization Header:

"Authorization" : "Basic base64(<zoom client id>:<zoom client secret>)"

Example Node Request
router.get('/zoomcallback', function(req, res)  {

    const zoomtokenep = "https://zoom.us/oauth/token";
    const myappredirect = "https://myapp.io/zoomcallback";

    if (req.query.code) {
        var auth = "Basic " + new Buffer(zoomclientid + ':' +  
                          zoomclientsec).toString('base64');
        var url = zoomtokenep + '?grant_type=authorization_code&code=' +
                   req.query.code + '&redirect_uri=' + myappredirect;
        request.post( {
                url: url,
                headers : {
                    "Authorization" : auth
                }
            }, function(error, response, body) {
                if (error) {
                    console.log("Error when getting Zoom token = " + error);
                    return;
                }
                body = JSON.parse(body);
                if (body.access_token) {
                     accessToken = body.access_token;
                     refreshToken = body.refresh_token;
                     // Process and securely store these tokens
                } else {
                    console.log("FATAL - could not get zoom token");
                }
                return;
            });

    } else {
        console.log("Missing code from Zoom");
}

Access Token Response

If the request is successful, a JSON response will be returned. This JSON object will have all the information you need to complete requests and to request additional tokens once the initial access token expires.

The following will be returned:

Parameter Description
access_token The token you will use to make requests on behalf of the user.
token_type How this token be sent to make requests.
refresh_token Used when requesting a new access token once the previous one has expired.
expires_in Time in seconds until the access token expires. Once expired you will use the refresh token to request a new access token.
scope A space-delimited string of available scopes for the access token.
Example Response Schema
{
  "access_token": "5kwaMOrdEFWx1jYVK8qg80cImPYBA83Zff",
  "token_type": "bearer",
  "refresh_token": "Ggf2816C5ANa6XVplzO8vwE6IRIXtjvE",
  "expires_in": 3599,
  "scope": "meeting:write user:read recording:write webinar:write"
}
Access Token Expiry

Please note that the access tokens expire in 60 minutes. If you call a Zoom API with an expired access token you will receive a 400 or 401 error. If you receive this error please refresh the token.

Refresh Tokens

Refresh Tokens have a lifespan of 15 years.

When you refresh an access token, you will also get a new refresh token that you need to use in your next refresh. Please make sure that you store the new refresh token as well when refreshing the access tokens.

The “me” Context

When using an OAuth token, you can use me in place of the User ID to restrict the context of the call to the user that token belongs to. This is a shortcut when using user-specific endpoints instead of needing to lookup/store the user ID for each token.

Below is a list of all URLs that support me:

Method URL(v2)
GET /v2/users/me
PATCH /v2/users/me
GET /v2/users/me/settings
PATCH /v2/users/me/settings
GET /v2/users/me/assistants
POST /v2/users/me/assistants
DELETE /v2/users/me/assistants
DELETE /v2/users/me/assistants/{assistantId
GET /v2/users/me/token
DELETE /v2/users/me/token
GET /v2/users/me/meetings
POST /v2/users/me/meetings
GET /v2/users/me/webinars
POST /v2/users/me/webinars
GET /v2/users/me/recordings
Example refresh request
function refresh_token(refreshToken, freshToken, zoomclientid, zoomclientsec, myappredirect)  {

    const zoomtokenep = "https://zoom.us/oauth/token";
 
    var auth = "Basic " + new Buffer(zoomclientid + ':' +
                     zoomclientsec).toString('base64');
    var url = zoomtokenep + '?grant_type=refresh_token&refresh_token=' n&refreshToken &refresh_token=' + refreshToken + 
                    '&redirect_uri=' + myappredirect;
    request.post( {
                url: url,
                headers : {
                    "Authorization" : auth
               }
    }, function(error, response, body) {
        if (error) {
           console.log("Error when getting Zoom token = " + error);
           return;
         }
         body = JSON.parse(body);
         if (body.access_token) {
                     console.log("Got new access and refresh tokens");
                     accessToken = body.access_token;
                     refreshToken = body.refresh_token;
                     // Process and securely store these tokens
          } else {
                    console.log("FATAL - could not refresh access token");
          }
        return;
    });
}

Revoking Tokens

To revoke the access token you need to POST a request to https://zoom.us/oauth/revoke. Please see below for details an how to form your payload.

You will first have to make a POST request to the following endpoint:

POST https://zoom.us/oauth/revoke

The POST must include the following parameters:

Header: Content-Type': 'application/x-www-form-urlencoded

Body: token=<TOKEN>

Authorization is done using the Client ID as the user and the Secret as the password.

var request = require('request');

var headers = {
    'Content-Type': 'application/x-www-form-urlencoded'
};

var dataString = 'token=04WRoU4vb9cK1l8Ne8okytrJSvsZx0J8';

var options = {
    url: 'https://zoom.us/oauth/revoke',
    method: 'POST',
    headers: headers,
    body: dataString,
    auth: {
        'user': 'Odet7ldYQjyagzLKzNomA',
        'pass': 'UeE0e7LZopJRFityw1h3b7dJFz29IeY7'
    }
};

function callback(error, response, body) {
    if (!error && response.statusCode == 200) {
        console.log(body);
    }
}

request(options, callback);

That’s it. You have now successfully authenticated your app with Zoom on behalf of your user!

For more examples, head to Calling Zoom APIs with OAuth.