OAuth with Zoom

The Zoom API uses OAuth2 to authenticate and authorize users to make requests. To setup access credentials and request scopes for your app, create an OAuth app on the Marketplace. Follow the Create an OAuth App guide for a full walkthrough.

OAuth2 endpoints are located at https://zoom.us/oauth/.

All Zoom OAuth and API endpoints must be called from the server side of your application. If called from the client side, CORS errors will be thrown.

Getting an Access Token

Obtaining an access token requires a user to authorize the app for the requested scopes. Then the user’s access token can be requested.

Step 1: Request User Authorization

Direct the user to https://zoom.us/oauth/authorize with the following query parameters:

Query Parameter Description
response_type Access response type being requested. The supported authorization workflow requires the value `code`.
redirect_uri URI to handle successful user authorization. Must match with Development or Production Redirect URI in your OAuth app settings.
client_id OAuth application’s Development or Production Client ID.

Example:

https://zoom.us/oauth/authorize?response_type=code&client_id=7lstjK9NTyett_oeXtFiEQ&redirect_uri=https://yourapp.com

This URL is the same as the Install Button link on the Zoom App Marketplace.

If this is the first time that you are requesting authorization from a user, the user will be prompted by Zoom to authorize access for your app.

If authorized, the user will be redirected to the redirect_uri with the authorization code in the code query parameter.

https://yourapp.com/?code=obBEe8ewaL_KdyNjniT4KPd8ffDWt9fGB

Step 2: Request Access Token

Make a POST request to https://zoom.us/oauth/token with the following query parameters and authorization header:

Query Parameter Description
grant_type Value authorization_code.
code The authorization code supplied to the callback by Zoom.
redirect_uri Your application’s redirect URI.
Authorization Header Description
Authorization The string "Basic" with your Client ID and Client Secret with a colon : in between, Base64 Encoded. For example, Client_ID:Client_Secret Base64 Encoded is Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ=.

Example Request:

POST

https://zoom.us/oauth/token?grant_type=authorization_code&code=obBEe8ewaL_KdYKjnimT4KPd8KKdQt9FQ&redirect_uri=https://yourapp.com

Request Headers:

{
  "Authorization": "Basic Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ="
}

If successful, the response body will be a JSON representation of the user’s access token:

{
  "access_token": "eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJ2ZXIiOiI2IiwiY2xpZW50SWQiOiI8Q2xpZW50X0lEPiIsImNvZGUiOiI8Q29kZT4iLCJpc3MiOiJ1cm46em9vbTpjb25uZWN0OmNsaWVudGlkOjxDbGllbnRfSUQ-IiwiYXV0aGVudGljYXRpb25JZCI6IjxBdXRoZW50aWNhdGlvbl9JRD4iLCJ1c2VySWQiOiI8VXNlcl9JRD4iLCJncm91cE51bWJlciI6MCwiYXVkIjoiaHR0cHM6Ly9vYXV0aC56b29tLnVzIiwiYWNjb3VudElkIjoiPEFjY291bnRfSUQ-IiwibmJmIjoxNTgwMTQ2OTkzLCJleHAiOjE1ODAxNTA1OTMsInRva2VuVHlwZSI6ImFjY2Vzc190b2tlbiIsImlhdCI6MTU4MDE0Njk5MywianRpIjoiPEpUST4iLCJ0b2xlcmFuY2VJZCI6MjV9.F9o_w7_lde4Jlmk_yspIlDc-6QGmVrCbe_6El-xrZehnMx7qyoZPUzyuNAKUKcHfbdZa6Q4QBSvpd6eIFXvjHw",
  "token_type": "bearer",
  "refresh_token": "eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJ2ZXIiOiI2IiwiY2xpZW50SWQiOiI8Q2xpZW50X0lEPiIsImNvZGUiOiI8Q29kZT4iLCJpc3MiOiJ1cm46em9vbTpjb25uZWN0OmNsaWVudGlkOjxDbGllbnRfSUQ-IiwiYXV0aGVudGljYXRpb25JZCI6IjxBdXRoZW50aWNhdGlvbl9JRD4iLCJ1c2VySWQiOiI8VXNlcl9JRD4iLCJncm91cE51bWJlciI6MCwiYXVkIjoiaHR0cHM6Ly9vYXV0aC56b29tLnVzIiwiYWNjb3VudElkIjoiPEFjY291bnRfSUQ-IiwibmJmIjoxNTgwMTQ2OTkzLCJleHAiOjIwNTMxODY5OTMsInRva2VuVHlwZSI6InJlZnJlc2hfdG9rZW4iLCJpYXQiOjE1ODAxNDY5OTMsImp0aSI6IjxKVEk-IiwidG9sZXJhbmNlSWQiOjI1fQ.Xcn_1i_tE6n-wy6_-3JZArIEbiP4AS3paSD0hzb0OZwvYSf-iebQBr0Nucupe57HUDB5NfR9VuyvQ3b74qZAfA",
  "expires_in": 3599,
  "scope": "user:read:admin"
}

Pro Tip: You can JWT Decode your Access token and Refresh Token to get a JSON object that includes data like the userId and more.

This access token can now be used to make requests to the Zoom API. Access tokens expire after 1 hour.

Using an Access Token

Make requests to the Zoom API by sending the access_token as the Authorization Bearer header.

"Authorization": "Bearer <ACCESS_TOKEN>"

Example Request:

GET

https://api.zoom.us/v2/users/me

Note: This endpoint uses the /me context.

Request Headers:

{
  "Authorization": "Bearer eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJ2ZXIiOiI2IiwiY2xpZW50SWQiOiI8Q2xpZW50X0lEPiIsImNvZGUiOiI8Q29kZT4iLCJpc3MiOiJ1cm46em9vbTpjb25uZWN0OmNsaWVudGlkOjxDbGllbnRfSUQ-IiwiYXV0aGVudGljYXRpb25JZCI6IjxBdXRoZW50aWNhdGlvbl9JRD4iLCJ1c2VySWQiOiI8VXNlcl9JRD4iLCJncm91cE51bWJlciI6MCwiYXVkIjoiaHR0cHM6Ly9vYXV0aC56b29tLnVzIiwiYWNjb3VudElkIjoiPEFjY291bnRfSUQ-IiwibmJmIjoxNTgwMTQ2OTkzLCJleHAiOjE1ODAxNTA1OTMsInRva2VuVHlwZSI6ImFjY2Vzc190b2tlbiIsImlhdCI6MTU4MDE0Njk5MywianRpIjoiPEpUST4iLCJ0b2xlcmFuY2VJZCI6MjV9.F9o_w7_lde4Jlmk_yspIlDc-6QGmVrCbe_6El-xrZehnMx7qyoZPUzyuNAKUKcHfbdZa6Q4QBSvpd6eIFXvjHw"
}

If successful, the response body will be a JSON representation of your user:

{
  "id": "KdYKjnimT4KPd8FFgQt9FQ",
  "first_name": "Jane",
  "last_name": "Dev",
  "email": "jane.dev@email.com",
  "type": 2,
  "role_name": "Owner",
  "pmi": 1234567890,
  "use_pmi": false,
  "vanity_url": "https://janedevinc.zoom.us/my/janedev",
  "personal_meeting_url": "https://janedevinc.zoom.us/j/1234567890",
  "timezone": "America/Denver",
  "verified": 1,
  "dept": "",
  "created_at": "2019-04-05T15:24:32Z",
  "last_login_time": "2019-12-16T18:02:48Z",
  "last_client_version": "4.6.12611.1124(mac)",
  "pic_url": "https://janedev.zoom.us/p/KdYKjnimFR5Td8KKdQt9FQ/19f6430f-ca72-4154-8998-ede6be4542c7-837",
  "host_key": "533895",
  "jid": "kdykjnimt4kpd8kkdqt9fq@xmpp.zoom.us",
  "group_ids": [],
  "im_group_ids": [
    "3NXCD9VFTCOUH8LD-QciGw"
  ],
  "account_id": "gVcjZnYYRLDbb_MfgHuaxg",
  "language": "en-US",
  "phone_country": "US",
  "phone_number": "+1 1234567891",
  "status": "active"
}

Refreshing an Access Token

Access tokens expire after one hour. Once expired, you will have to refresh a user’s access token.

Make a POST request to https://zoom.us/oauth/token with the following query params and authorization header:

Query Param Description
grant_type Value `refresh_token`.
refresh_token Your refresh token.
Authorization Header Description
Authorization The string "Basic" with your Client ID and Client Secret with a colon : in between, Base64 Encoded. For example, Client_ID:Client_Secret Base64 Encoded is Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ=.

Example Request:

POST

https://zoom.us/oauth/token?grant_type=refresh_token&refresh_token=eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJ2ZXIiOiI2IiwiY2xpZW50SWQiOiI8Q2xpZW50X0lEPiIsImNvZGUiOiI8Q29kZT4iLCJpc3MiOiJ1cm46em9vbTpjb25uZWN0OmNsaWVudGlkOjxDbGllbnRfSUQ-IiwiYXV0aGVudGljYXRpb25JZCI6IjxBdXRoZW50aWNhdGlvbl9JRD4iLCJ1c2VySWQiOiI8VXNlcl9JRD4iLCJncm91cE51bWJlciI6MCwiYXVkIjoiaHR0cHM6Ly9vYXV0aC56b29tLnVzIiwiYWNjb3VudElkIjoiPEFjY291bnRfSUQ-IiwibmJmIjoxNTgwMTQ2OTkzLCJleHAiOjIwNTMxODY5OTMsInRva2VuVHlwZSI6InJlZnJlc2hfdG9rZW4iLCJpYXQiOjE1ODAxNDY5OTMsImp0aSI6IjxKVEk-IiwidG9sZXJhbmNlSWQiOjI1fQ.Xcn_1i_tE6n-wy6_-3JZArIEbiP4AS3paSD0hzb0OZwvYSf-iebQBr0Nucupe57HUDB5NfR9VuyvQ3b74qZAfA

Request Headers:

{
  "Authorization": "Basic Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ="
}

If successful, the response body will be a JSON representation of your user’s refreshed access token:

{
    "access_token": "eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJ2ZXIiOiI2IiwiY2xpZW50SWQiOiI8Q2xpZW50X0lEPiIsImNvZGUiOiI8Q29kZT4iLCJpc3MiOiJ1cm46em9vbTpjb25uZWN0OmNsaWVudGlkOjxDbGllbnRfSUQ-IiwiYXV0aGVudGljYXRpb25JZCI6IjxBdXRoZW50aWNhdGlvbl9JRD4iLCJ1c2VySWQiOiI8VXNlcl9JRD4iLCJncm91cE51bWJlciI6MCwiYXVkIjoiaHR0cHM6Ly9vYXV0aC56b29tLnVzIiwiYWNjb3VudElkIjoiPEFjY291bnRfSUQ-IiwibmJmIjoxNTgwMTQ3Mzk0LCJleHAiOjE1ODAxNTA5OTQsInRva2VuVHlwZSI6ImFjY2Vzc190b2tlbiIsImlhdCI6MTU4MDE0NzM5NCwianRpIjoiPEpUST4iLCJ0b2xlcmFuY2VJZCI6MjZ9.5c58p0PflZJdlz4Y7PgMIVCrQpHDnbM565iCKlrtajZ5HHmy00P5FCcoMwHb9LxjsUgbJ7653EfdeX5NEm6RoA",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJ2ZXIiOiI2IiwiY2xpZW50SWQiOiI8Q2xpZW50X0lEPiIsImNvZGUiOiI8Q29kZT4iLCJpc3MiOiJ1cm46em9vbTpjb25uZWN0OmNsaWVudGlkOjxDbGllbnRfSUQ-IiwiYXV0aGVudGljYXRpb25JZCI6IjxBdXRoZW50aWNhdGlvbl9JRD4iLCJ1c2VySWQiOiI8VXNlcl9JRD4iLCJncm91cE51bWJlciI6MCwiYXVkIjoiaHR0cHM6Ly9vYXV0aC56b29tLnVzIiwiYWNjb3VudElkIjoiPEFjY291bnRfSUQ-IiwibmJmIjoxNTgwMTQ3Mzk0LCJleHAiOjIwNTMxODczOTQsInRva2VuVHlwZSI6InJlZnJlc2hfdG9rZW4iLCJpYXQiOjE1ODAxNDczOTQsImp0aSI6IjxKVEk-IiwidG9sZXJhbmNlSWQiOjI2fQ.DwuqOzywRrQO2a6yp0K_6V-hR_i_mOB62flkr0_NfFdYsSqahIRRGk1GlUTQnFzHd896XDKf_FnSSvoJg_tzuQ",
    "expires_in": 3599,
    "scope": "user:read"
}

Refresh tokens expire after 15 years. The latest refresh token must always be used for the next refresh request.

Revoking an Access Token

To revoke a users access token, make a POST request to https://zoom.us/oauth/revoke with the following query parameters and authorization header:

Query Parameter Description
token The current access token to revoke that is valid and not expired.
Authorization Header Description
Authorization The string "Basic" with your Client ID and Client Secret with a colon : in between, Base64 Encoded. For example, Client_ID:Client_Secret Base64 Encoded is Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ=.

Example Request:

POST

https://zoom.us/oauth/revoke?token=eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJ2ZXIiOiI2IiwiY2xpZW50SWQiOiI8Q2xpZW50X0lEPiIsImNvZGUiOiI8Q29kZT4iLCJpc3MiOiJ1cm46em9vbTpjb25uZWN0OmNsaWVudGlkOjxDbGllbnRfSUQ-IiwiYXV0aGVudGljYXRpb25JZCI6IjxBdXRoZW50aWNhdGlvbl9JRD4iLCJ1c2VySWQiOiI8VXNlcl9JRD4iLCJncm91cE51bWJlciI6MCwiYXVkIjoiaHR0cHM6Ly9vYXV0aC56b29tLnVzIiwiYWNjb3VudElkIjoiPEFjY291bnRfSUQ-IiwibmJmIjoxNTgwMTQ3Mzk0LCJleHAiOjE1ODAxNTA5OTQsInRva2VuVHlwZSI6ImFjY2Vzc190b2tlbiIsImlhdCI6MTU4MDE0NzM5NCwianRpIjoiPEpUST4iLCJ0b2xlcmFuY2VJZCI6MjZ9.5c58p0PflZJdlz4Y7PgMIVCrQpHDnbM565iCKlrtajZ5HHmy00P5FCcoMwHb9LxjsUgbJ7653EfdeX5NEm6RoA

Request Headers:

{
  "Authorization": "Basic Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ="
}

If successful, the response body will be a JSON success object:

{
  "status": "success"
}

The /me Context

For APIs where OAuth is available, you can replace the {userID} path param with me to restrict the context of the call to the user the token belongs to. This is a quick way to use user-specific endpoints instead of needing to lookup or store the user ID for each token.

Below is a list of requests which support the /me context:

URL Methods
/v2/users/me GET, PATCH
/v2/users/me/token GET, DELETE
/v2/users/me/settings GET, PATCH
/v2/users/me/meetings GET, POST
/v2/users/me/webinars GET, POST
/v2/users/me/recordings GET
/v2/users/me/assistants GET, POST, DELETE
/v2/users/me/assistants/{assistantId} DELETE

OAuth with Chatbots

Account-level OAuth apps can also be Chatbot apps, just as Chatbot apps can be account-level OAuth apps; however, OAuth apps and Chatbots have a different authentication flows.

Combining OAuth and Chatbot functionality into one app will require you to implement two authorization flows for both OAuth and Chatbot tokens.

Requesting an OAuth and Chatbot Token

Direct the user to https://zoom.us/oauth/authorize with the following query parameters:

Query Parameter Description
response_type Access response type being requested. The supported authorization workflow requires the value `code`.
redirect_uri URI to handle successful user authorization. Must match with Development or Production Redirect URI in your OAuth app settings.
client_id OAuth application’s Development or Production Client ID.

Example:

https://zoom.us/oauth/authorize?response_type=code&client_id=U1RqQ9UsQo6hd6fJQWFLQ&redirect_uri=https://yourapp.com

This URL is the same as the Install Button link on the Zoom App Marketplace.

If this is the first time that you are requesting authorization from a user, the user will be prompted by Zoom to authorize access for your app.

If authorized, the user will be redirected to the redirect_uri with the authorization code in the code query parameter.

https://yourapp.com/?code=obBEe8ewaL_KdyNjniT4KPd8ffDWt9fGB

Notice the code returned in the redirect URL. Follow Step 2 in Requesting an Access Token to obtain an OAuth Access Token.

To get a Chatbot token, make a POST request to https://zoom.us/oauth/token with the following query parameters and authorization header:

Query Parameter Description
grant_type Value client_credentials.
Authorization Header Description
Authorization The string "Basic" with your Client ID and Client Secret with a colon : in between, Base64 Encoded. For example, Client_ID:Client_Secret Base64 Encoded is Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ=.

Example Request:

POST

https://api.zoom.us/oauth/token?grant_type=client_credentials

Request Headers:

{
  "Authorization": "Basic Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ="
}

If successful, the response body will be a JSON representation of the Chatbot token:

{
  "access_token": "eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJhdWQiOiJodHRwczovL29hdXRoLnpvb20udXMiLCJ2ZXIiOiI2IiwibmJmIjoxNTgwMTQ2NjkzLCJjbGllbnRJZCI6IjxDbGllbnRfSUQ-IiwiaXNzIjoidXJuOnpvb206Y29ubmVjdDpjbGllbnRpZDo8Q2xpZW50X0lEPiIsImF1dGhlbnRpY2F0aW9uSWQiOiI8QXV0aGVudGljYXRpb25fSUQ-IiwiZXhwIjoxNTgwMTUwMjkzLCJ0b2tlblR5cGUiOiJjbGllbnRfdG9rZW4iLCJpYXQiOjE1ODAxNDY2OTMsInVzZXJJZCI6IjxVc2VyX0lEPiIsImdyb3VwTnVtYmVyIjowLCJqdGkiOiI8SlRJPiJ9.chgzEaGxeYl3alAaLsFSRvQFVRqoabM5BINVELOYPO1FqveoEk02i8AIGrtg0FiX779pMWpMObkxFnPQy7euNA",
  "token_type": "bearer",
  "expires_in": 3599,
  "scope": "imchat:bot"
}

Pro Tip: You can JWT Decode your Chatbot token to get a JSON object that includes data like the userId and more.

Chatbot tokens expire after one hour.

Using a Chatbot Token

Make requests to the Chatbot API by sending the Chatbot token as the Authorization Bearer header:

"Authorization": "Bearer <CHATBOT_TOKEN>"

Example Request:

POST

https://api.zoom.us/v2/im/chat/messages

Request Headers

{
  "Authorization": "Bearer eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJhdWQiOiJodHRwczovL29hdXRoLnpvb20udXMiLCJ2ZXIiOiI2IiwibmJmIjoxNTgwMTQ2NjkzLCJjbGllbnRJZCI6IjxDbGllbnRfSUQ-IiwiaXNzIjoidXJuOnpvb206Y29ubmVjdDpjbGllbnRpZDo8Q2xpZW50X0lEPiIsImF1dGhlbnRpY2F0aW9uSWQiOiI8QXV0aGVudGljYXRpb25fSUQ-IiwiZXhwIjoxNTgwMTUwMjkzLCJ0b2tlblR5cGUiOiJjbGllbnRfdG9rZW4iLCJpYXQiOjE1ODAxNDY2OTMsInVzZXJJZCI6IjxVc2VyX0lEPiIsImdyb3VwTnVtYmVyIjowLCJqdGkiOiI8SlRJPiJ9.chgzEaGxeYl3alAaLsFSRvQFVRqoabM5BINVELOYPO1FqveoEk02i8AIGrtg0FiX779pMWpMObkxFnPQy7euNA"
}

Request Body:

{
  "robot_jid": "v1zx6cy00psoylshypvg-iuq@xmpp.zoom.us",
  "to_jid": "kdykjnimt4kpd8kkdqt9fq@xmpp.zoom.us",
  "account_id": "gVcjZnWWRLWvv_GtyGuaxg",
  "content": {
    "head": {
      "text": "Hello World"
    }
  }
}

If successful, the response body will be a JSON representation of the sent Chatbot message:

{
	"message_id": "20191218175454248_UvRlxOz_aw1",
	"robot_jid": "v1zx6cy00psoylshypvg-iuq@xmpp.zoom.us",
	"sent_time": "2019-12-18 17:54:54",
	"to_jid": "kdykjnimt4kpd8kkdqt9fq@xmpp.zoom.us"
}
Chatbot Message
Chatbot Message

Refreshing a Chatbot Token

Refreshing a Chatbot token is the same process as requesting a Chatbot token. Make a POST request to https://zoom.us/oauth/token with the following query parameters and authorization header:

Query Parameter Description
grant_type Value client_credentials.
Authorization Header Description
Authorization The string "Basic" with your Client ID and Client Secret with a colon : in between, Base64 Encoded. For example, Client_ID:Client_Secret Base64 Encoded is Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ=.

Example Request:

POST

https://zoom.us/oauth/token?grant_type=client_credentials

Request Headers:

{
  "Authorization": "Basic Q2xpZW50X0lEOkNsaWVudF9TZWNyZXQ="
}

If successful, the response body will be a JSON representation of your refreshed Chatbot token:

{
  "access_token": "eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiI8S0lEPiJ9.eyJhdWQiOiJodHRwczovL29hdXRoLnpvb20udXMiLCJ2ZXIiOiI2IiwibmJmIjoxNTgwMTQ2NjkzLCJjbGllbnRJZCI6IjxDbGllbnRfSUQ-IiwiaXNzIjoidXJuOnpvb206Y29ubmVjdDpjbGllbnRpZDo8Q2xpZW50X0lEPiIsImF1dGhlbnRpY2F0aW9uSWQiOiI8QXV0aGVudGljYXRpb25fSUQ-IiwiZXhwIjoxNTgwMTUwMjkzLCJ0b2tlblR5cGUiOiJjbGllbnRfdG9rZW4iLCJpYXQiOjE1ODAxNDY2OTMsInVzZXJJZCI6IjxVc2VyX0lEPiIsImdyb3VwTnVtYmVyIjowLCJqdGkiOiI8SlRJPiJ9.chgzEaGxeYl3alAaLsFSRvQFVRqoabM5BINVELOYPO1FqveoEk02i8AIGrtg0FiX779pMWpMObkxFnPQy7euNA",
  "token_type": "bearer",
  "expires_in": 3599,
  "scope": "imchat:bot"
}

Chatbot tokens expire after one hour.

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.