# Having troubles authenticating Zoom API with OAuth 2.0 Authentication (Python)

**URL:** <https://devforum.zoom.us/t/having-troubles-authenticating-zoom-api-with-oauth-2-0-authentication-python/27114>\
**Category:** API and Webhooks\
**Created:** [August 13, 2020, 8:30pm UTC](https://devforum.zoom.us/t/having-troubles-authenticating-zoom-api-with-oauth-2-0-authentication-python/27114 "2020-08-13T20:30:27Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![chrispotvin4](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/chrispotvin4/32/13491_2.png) [@chrispotvin4](https://devforum.zoom.us/u/chrispotvin4)\
**Post date:** [August 13, 2020, 8:30pm UTC](https://devforum.zoom.us/t/having-troubles-authenticating-zoom-api-with-oauth-2-0-authentication-python/27114/1 "2020-08-13T20:30:27Z")

</div>

**Description**  
Having troubles understanding how to save access\_tokens and refresh\_tokens to environmental variables so we can use these tokens in subsequent post calls. Authorization code keeps expiring whenever a session is exited out.

**Error**  
{‘reason’: ‘Invalid authorization code xxxxxxxxxxxxxxxxxxxxxxxxxx’, ‘error’: ‘invalid\_request’}

**Which App Type (OAuth / Chatbot / JWT / Webhook)?**  
OAuth

**Which Endpoint/s?**  
'[https://zoom.us/oauth/token?’](https://zoom.us/oauth/token?'), ‘[https://api.zoom.us/v2/meetings/](https://api.zoom.us/v2/meetings/)’

**How To Reproduce (If applicable)**

Steps to reproduce the behavior:

1. Initialize API URLS (token\_url and meeting\_url)

2. Initialize client secret, client id and auth code received from OAuth app.

3. Run functions with authorization

**def get\_token(client\_id, client\_secret, token\_url):**  
headers = {‘Authorization’: ‘Basic {}’.format(base64.b64encode(bytes(’{}:{}’.format(client\_id,client\_secret).encode(‘utf-8’))).decode(‘utf-8’))}  
response = requests.post(token\_url+‘grant\_type=authorization\_code&code=’ + authorization\_code + ‘&redirect\_uri=https://manual.connect-care.ca/’, headers=headers)  
return json.loads(response.text)\*\*

**def token\_refresh(client\_id, client\_secret, token\_url, refresh\_token):**  
refresh\_data = ‘grant\_type=refresh\_token&refresh\_token=’+ refresh\_token  
headers = {‘Authorization’: ‘Basic {}’.format(base64.b64encode(bytes(’{}:{}’.format(client\_id,client\_secret).encode(‘utf-8’))).decode(‘utf-8’))}  
response = requests.post(token\_url + refresh\_data, headers=headers)  
return json.loads(response.text)

1. Save response.text into Access\_Token and Refresh\_Token variables.

refresh\_token = json\_token[‘refresh\_token’]  
access\_token = json\_token[‘access\_token’]

1. Use Access\_token to post to meeting url

headers = {‘content-type’: ‘application/json’,‘Authorization’: "Bearer " + access\_token}  
for i in range(len(input\_values)):  
if input\_values.ZoomInvite[i] == ‘Blank’:  
payload = {‘email’:input\_values.Email\_Address[i],‘first\_name’:input\_values.Learner\_Name[i], ‘last\_name’:‘Test’}  
SessionDetail = str(input\_values.SessionDetail[i])  
r = requests.post(meetingurl + SessionDetail + “/registrants”, data=json.dumps(payload), headers=headers)  
RegistrationData = json.loads(r.text)  
input\_values.ZoomInvite[i] = RegistrationData[‘join\_url’]  
if r.ok:  
print(“download complete”)  
else:  
print(“error”)  
if “token” in r.text:  
print(“refresh token”)  
else:  
print(“Invite is not Blank”)

**Additional context**

Once we get the tokens, we want to automate the post request (daily) without having to reproduce the authorization code on a daily basis (human interaction). Right now I am trying to save the access\_token and refresh\_token from the JSON response to an environmental variable. IE.

```
os.environ['refresh_token'] = refresh_token
os.environ['access_token'] = access_token

```

And use these saved values in subsequent Post requests to the Zoom API.

---

<div class="post-metadata">

**Author:** ![michael.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/michael.zoom/32/37213_2.png) [@michael.zoom](https://devforum.zoom.us/u/michael.zoom)\
**Post date:** [August 17, 2020, 3:13pm UTC](https://devforum.zoom.us/t/having-troubles-authenticating-zoom-api-with-oauth-2-0-authentication-python/27114/2 "2020-08-17T15:13:25Z")

</div>

Hi @chrispotvin4, when an access token is provided, the response includes a single refresh token used to request the next valid access token. Access tokens are valid for one hour, with only one valid at one time per user. Refresh tokens have an expiration time of 15 years, but as with the access token - only one is valid at one time.

So when implementing OAuth token exchanges, you should store the currently valid access token (to make API requests) and currently valid refresh token. When the access token expires, the current refresh token (stored) should then be used to request a new access token.

This exchange should be built into the request process. If the access token is found to not be valid, you should use the stored refresh token to receive a new one.

Hope this helps

---

<div class="post-metadata">

**Author:** ![chrispotvin4](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/chrispotvin4/32/13491_2.png) [@chrispotvin4](https://devforum.zoom.us/u/chrispotvin4)\
**Post date:** [August 20, 2020, 6:51pm UTC](https://devforum.zoom.us/t/having-troubles-authenticating-zoom-api-with-oauth-2-0-authentication-python/27114/3 "2020-08-20T18:51:57Z")

</div>

Hey Michael,

Yes using the database to store the tokens have made it much easier to handle. I have been able to run my script now without a hitch. I do have another question if that is okay.

---

<div class="post-metadata">

**Author:** ![chrispotvin4](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/chrispotvin4/32/13491_2.png) [@chrispotvin4](https://devforum.zoom.us/u/chrispotvin4)\
**Post date:** [August 20, 2020, 6:53pm UTC](https://devforum.zoom.us/t/having-troubles-authenticating-zoom-api-with-oauth-2-0-authentication-python/27114/4 "2020-08-20T18:53:43Z")

</div>

[https://zoom.us/meeting/attendee/{meeting}/calendar/google/add?user\_id={user\_id}&type=google](https://zoom.us/meeting/attendee/%7Bmeeting%7D/calendar/google/add?user_id=%7Buser_id%7D&type=google)

How does this Endpoint work? What does the JSON response look like? We’re trying to embed the Calendar invitation but haven’t figured it out quite yet.

---

<div class="post-metadata">

**Author:** ![tommy](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/tommy/32/72769_2.png) [@tommy](https://devforum.zoom.us/u/tommy)\
**Post date:** [August 24, 2020, 5:08pm UTC](https://devforum.zoom.us/t/having-troubles-authenticating-zoom-api-with-oauth-2-0-authentication-python/27114/5 "2020-08-24T17:08:01Z")

</div>

Hey @chrispotvin4,

That endpoint is not available in our [Developer Platform](https://marketplace.zoom.us/docs/guides). What are you trying to accomplish?

Thanks,  
Tommy

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/6/1/614bdd549b610bbaa46ff934617683a02bdaa03c.png) [@system](https://devforum.zoom.us/u/system)\
**Post date:** [September 24, 2020, 3:08am UTC](https://devforum.zoom.us/t/having-troubles-authenticating-zoom-api-with-oauth-2-0-authentication-python/27114/6 "2020-09-24T03:08:02Z")

</div>

Closed on September 24, 2020, 3:08am UTC

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
