Recall-Managed OAuth

OAuth your customers' Zoom Account using Recall-managed OAuth.

The last step in the setup process is to OAuth your customers' Zoom accounts. This should be done programmatically in your app, for example by requesting Zoom OAuth permission as part of your onboarding flow.

In this guide, we'll go through the process manually and OAuth your own Zoom account, as a demonstration.

Recall-managed OAuth flow works

  • You send the OAuth code to Recall directly after a customer completes the OAuth flow.
  • Recall manages access and refresh tokens for you.

Registering A Redirect URL

Click the "App Credentials" tab, and input a URL into the "Redirect URL for OAuth" box, and the "OAuth Allow List". For our testing purposes, this can be any URL, I've used https://localhost:8000


WARNING: The trailing backslash MUST match

Carefully take note of if your Redirect URL for OAuth contains a trailing backslash or not. The presence or absence of this backslash MUST be the same when you construct your Zoom OAuth URL, as well as when you make the request to the Recall API.

Constructing a Zoom OAuth URL

A Zoom OAuth URL is the URL that you'll be navigating your users to, for them to grant the permissions. For example, you might have a button that says "Connect Zoom", that redirects your user to the OAuth URL.

You can generate the URL using the following Python code

from urllib.parse import urlencode
def generate_auth_url(redirect_uri, client_id):
    base_url = ""
    query_params = {
        "response_type": "code",
        "redirect_uri": redirect_uri,
        "client_id": client_id,
    return base_url + "?" + urlencode(query_params)

Client ID should be your Client ID from Step 2. The redirect URI should be the URL you set in step 4a.1. In my example, that's "https://localhost:8000".

After calling this function, you should get a URL that looks like the following:

Paste this URL into your web browser, and grant the permission when prompted by Zoom.

Obtaining the OAuth Code

After clicking "Allow", you will be redirected to "https://localhost:8000" and will likely see a page that looks like the following:

This is expected behavior. You now want to look at the URL in your web browser, which should look something like the following: https://localhost:8000/?code=JFiSLNVIEejhfiJLmU6AuTnKZQ

The value in the query parameter code is your OAuth code, and you want to take note of it for the next step.


If you're getting "Invalid redirect", check your Redirect URI

The redirect URI specified in the query parameter must match EXACTLY the redirect URI registered in the Zoom OAuth App console, including any trailing slashes.

Calling the Recall API

You'll now use the OAuth code to register your account with the Recall API. You'll want to call the Create Zoom OAuth Credential endpoint, using the code you just obtained.

$ curl -X POST
	-H 'Authorization: Token YOUR-RECALL-API-KEY'
 	-H 'Content-Type: application/json'
  -d '{
    "oauth_app": "YOUR-RECALL-ZOOM-OAUTH-APP-ID",
    "authorization_code": {
      "code": "YOUR-CODE-HERE",
      "redirect_uri": "YOUR-REDIRECT-URI-HERE",


If you're getting "Invalid Grant", check your Redirect URI

The redirect URI sent in this request must match EXACTLY the redirect URI registered in the Zoom OAuth App console, including any trailing slashes.

Handling Deauthorization


A disconnected Zoom user will not be reflected immediately

When a Zoom user revokes their OAuth permissions for your app, Recall doesn't know this immediately.

Since Recall doesn't get notified when a user revokes their OAuth permissions, the user's credentials will still exist in Recall unless you explicitly delete them.

This can cause issues when a user tries to re-authenticate to your app, since their credentials will already exist.

Currently, you must handle this case by recreating the credentials if they already exist.

In this case, your logic directing a user through the OAuth flow should add a code path for handling a 400 response from Create Zoom OAuth Credential with a conflicting_zoom_account_id in the body:

  "detail": "A Zoom OAuth Credential already exists for this OAuth App and Zoom account(account_id: ...). A Zoom OAuth App can have at most one Zoom OAuth Credential registered per authorized Zoom account. Please delete the existing Zoom OAuth Credential for Zoom account(account_id: ...) and try again.",
  "conflicting_zoom_account_id": "..."

You can then:

  1. Delete the credentials using the conflicting_zoom_account_id
  2. Recreate the credentials