# How to create JWT token using REST api in c#

**URL:** <https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620>\
**Category:** API and Webhooks\
**Created:** [November 12, 2019, 11:50am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620 "2019-11-12T11:50:01Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![vaibhav.bhosale](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/vaibhav.bhosale/32/1779_2.png) [@vaibhav.bhosale](https://devforum.zoom.us/u/vaibhav.bhosale)\
**Post date:** [November 12, 2019, 11:50am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/1 "2019-11-12T11:50:01Z")

</div>

Hi,

how to create JWT token using REST api in c#

---

<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:** [November 12, 2019, 5:03pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/2 "2019-11-12T17:03:28Z")

</div>

Hey @vaibhav.bhosale, thanks for posting and using Zoom!

You can reference our JWT with Zoom guide:

[https://marketplace.zoom.us/docs/guides/authorization/jwt/jwt-with-zoom](https://marketplace.zoom.us/docs/guides/authorization/jwt/jwt-with-zoom)

I would suggest using one of the C# libraries here:

> **[JWT.IO](https://jwt.io)**
>
> JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

Possible duplicate post with more info:

> [@C# JWT token invalid](https://devforum.zoom.us/t/c-jwt-token-invalid/5968):
>
> I am having an issue with token, the error is invalid token. Please help. string key = "MY\_Key"; var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(key)); var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256); var header = new JwtHeader(credentials); var payload = new JwtPayload { …

Thanks,  
Tommy

---

<div class="post-metadata">

**Author:** ![nvanderson](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/nvanderson/32/20082_2.png) [@nvanderson](https://devforum.zoom.us/u/nvanderson)\
**Post date:** [November 12, 2019, 5:19pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/3 "2019-11-12T17:19:56Z")

</div>

As I recall, you need to create the token on Zoom web-page first. Put some future expiration date, then use that date in the code. You should see the same token during debugging.

---

<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:** [November 12, 2019, 6:00pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/4 "2019-11-12T18:00:21Z")

</div>

Thanks @nvanderson, yes you can do that!

@vaibhav.bhosale, go here: [https://marketplace.zoom.us/develop/create](https://marketplace.zoom.us/develop/create), create a JWT app, then on the “App Credentials” page you will see an already generated JWT token:

 ![08%20AM](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/2X/0/09e5bb7fcb39d3a0a53d2aa127751a3d2076287f.png)

Thanks,  
Tommy

---

<div class="post-metadata">

**Author:** ![lgelman](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/lgelman/32/2391_2.png) [@lgelman](https://devforum.zoom.us/u/lgelman)\
**Post date:** [November 18, 2019, 11:13am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/5 "2019-11-18T11:13:21Z")

</div>

Hi ! I used Microsoft.IdentityModel.Tokens and System.IdentityModel.Tokens.Jwt to create C# command line tool that can generate JWT token for Zoom. In payload you have to use “iss” end “exp”. Sorry, I can’t share my code exactly…

---

<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:** [November 18, 2019, 5:37pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/6 "2019-11-18T17:37:08Z")

</div>

Thanks for posting @lgelman! 🙂

Is the tool you made internal, or do you plan on sharing it?

-Tommy

---

<div class="post-metadata">

**Author:** ![k.krylov](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/k.krylov/32/316_2.png) [@k.krylov](https://devforum.zoom.us/u/k.krylov)\
**Post date:** [November 21, 2019, 5:01pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/7 "2019-11-21T17:01:05Z")

</div>

```
using System;
using System.Text;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
namespace Zoom 
{
    public static class ZoomToken
    {
        public static string ZoomToken(){
		// Token will be good for 20 minutes
        DateTime Expiry = DateTime.UtcNow.AddMinutes(20);

		string ApiKey = "YOUR_API_KEY_HERE");
		string ApiSecret = "YOUR_API_SECRET_HERE";

		int ts = (int)(Expiry - new DateTime(1970, 1, 1)).TotalSeconds;

		// Create Security key using private key above:
		var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(ApiSecret));

		// length should be >256b
		var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

		//Finally create a Token
		var header = new JwtHeader(credentials);

		//Zoom Required Payload
		var payload = new JwtPayload
		{
			{ "iss", ApiKey},
			{ "exp", ts },
		};

		var secToken = new JwtSecurityToken(header, payload);
		var handler = new JwtSecurityTokenHandler();

		// Token to String so you can use it in your client
		var tokenString = handler.WriteToken(secToken);
		
        return tokenString;
        }
    }
}
```

---

<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:** [November 21, 2019, 5:46pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/8 "2019-11-21T17:46:12Z")

</div>

Thanks @k.krylov! 🙂

-Tommy

---

<div class="post-metadata">

**Author:** ![marklackey](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/marklackey/32/7238_2.png) [@marklackey](https://devforum.zoom.us/u/marklackey)\
**Post date:** [April 29, 2020, 1:21am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/9 "2020-04-29T01:21:19Z")

</div>

@k.krylov, Thank you!

I created a one-liner to set the expiration date that works for .NET Core 3.1:

`var ts = (int)DateTimeOffset.UtcNow.AddMinutes(MINUTES).ToUnixTimeSeconds();`

You could replace `AddMinutes` with a method of your choosing to set the expiration.

---

<div class="post-metadata">

**Author:** ![jason3](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/jason3/32/6979_2.png) [@jason3](https://devforum.zoom.us/u/jason3)\
**Post date:** [April 30, 2020, 10:32pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/10 "2020-04-30T22:32:01Z")

</div>

I think the problem is in the c# example code on zooms site… I took all parameters and compared the output between between the builtin signature function and the output do not match. I am going to need to pull the embeded javascript function apart and replicate in c# unless someone has an uptodate function example.

---

<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:** [May 5, 2020, 6:32pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/11 "2020-05-05T18:32:57Z")

</div>

Thanks for sharing @marklackey! 🙂

-Tommy

---

<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:** [May 5, 2020, 6:33pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/12 "2020-05-05T18:33:31Z")

</div>

Hey @jason3,

Have you tried any of the C# libraries here:

> **[JWT.IO](https://jwt.io/)**
>
> JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

Thanks,  
Tommy

---

<div class="post-metadata">

**Author:** ![sakosile](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/sakosile/32/7512_2.png) [@sakosile](https://devforum.zoom.us/u/sakosile)\
**Post date:** [June 2, 2020, 1:34am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/13 "2020-06-02T01:34:49Z")

</div>

This is what works for me on .Net Core 3.1.4  
var setting = GetZoomSetting(); //This is where I picked the API Key and API Secret From

```
        var zone = TimeZoneInfo.FindSystemTimeZoneById("W. Central Africa Standard Time");
        var utcNow = DateTime.UtcNow;
        var westNow = TimeZoneInfo.ConvertTimeFromUtc(utcNow, zone);
        string s = null;
        TimeSpan t = westNow.AddMinutes(Convert.ToInt32(5)) - new DateTime(1970, 1, 1);
        int secondsSinceEpoch = (int)t.TotalSeconds;

        TimeSpan secpacific = TimeZoneInfo.ConvertTimeFromUtc(utcNow, zone) - new DateTime(1970, 1, 1);
        int NowsecondsSinceEpoch = (int)secpacific.TotalSeconds;
        var tokenHandler = new JwtSecurityTokenHandler();
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.API.APISecret));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
        //Finally create a Token
        var header = new JwtHeader(creds);

        //Zoom Required Payload
        var payload = new JwtPayload
        {
            {"aud",s },
            { "iss", setting.API.APIKey},
            { "exp", secondsSinceEpoch },
            {"iat",NowsecondsSinceEpoch }
        };
        var token = new JwtSecurityToken(header, payload);
        var authtoken = tokenHandler.WriteToken(token);
        return authtoken;
```

---

<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:** [June 4, 2020, 8:13pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/14 "2020-06-04T20:13:16Z")

</div>

Thanks for sharing your this code snippet @sakosile! 🙂

We appreciate you contributing to the Zoom Developer Community!

-Tommy

---

<div class="post-metadata">

**Author:** ![biss.hakanzor](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/biss.hakanzor/32/9731_2.png) [@biss.hakanzor](https://devforum.zoom.us/u/biss.hakanzor)\
**Post date:** [July 6, 2020, 11:44am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/15 "2020-07-06T11:44:42Z")

</div>

Hi, with this code I taking token. But, zoom api return it’s invalid token.  
zoom link : [https://api.zoom.us/v2/users](https://api.zoom.us/v2/users)

---

<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:** [July 8, 2020, 10:16pm UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/16 "2020-07-08T22:16:32Z")

</div>

Hey @biss.hakanzor,

Are you passing in a [JWT token](https://marketplace.zoom.us/docs/guides/auth/jwt) or an [OAuth access token](https://marketplace.zoom.us/docs/guides/auth/oauth) as the authorization bearer header?

Thanks,  
Tommy

---

<div class="post-metadata">

**Author:** ![kshitij.gugale](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/kshitij.gugale/32/4654_2.png) [@kshitij.gugale](https://devforum.zoom.us/u/kshitij.gugale)\
**Post date:** [July 9, 2020, 3:08am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/17 "2020-07-09T03:08:58Z")

</div>

Hi @biss.hakanzor, you’re right. I am also getting the Invalid token when I use @k.krylov 's code.  
tommy, I’ve passed the JWT token as authorization bearer header but still no luck. I’ve sent an email to [developersupport@zoom.us](mailto:developersupport@zoom.us) yesterday regarding the issue and looking for the quicker response because its been a couple days I am stuck in it.

---

<div class="post-metadata">

**Author:** ![k.krylov](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/k.krylov/32/316_2.png) [@k.krylov](https://devforum.zoom.us/u/k.krylov)\
**Post date:** [July 9, 2020, 5:30am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/18 "2020-07-09T05:30:37Z")

</div>

My code has been in production for well over a year, and never experienced any problems. Can you show us the whole thing please

---

<div class="post-metadata">

**Author:** ![kshitij.gugale](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/kshitij.gugale/32/4654_2.png) [@kshitij.gugale](https://devforum.zoom.us/u/kshitij.gugale)\
**Post date:** [July 9, 2020, 6:11am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/19 "2020-07-09T06:11:49Z")

</div>

Hi @k.krylov,

Here is the sample code(with reference to your code):

private const string apiKey = “MyKey”;  
private const string apiSecret = “MyKey”;

public static string ZoomToken()  
{  
// Token will be good for 20 minutes  
DateTime Expiry = DateTime.UtcNow.AddMinutes(20);

int ts = (int)(Expiry - new DateTime(1970, 1, 1)).TotalSeconds;

// Create Security key using private key above:  
var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(apiSecret));

// I did changes in below line because DLL needed HmacSha256Signature instead of HmacSha256  
var credentials = new Microsoft.IdentityModel.Tokens.SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);

//Finally create a Token  
var header = new JwtHeader(credentials);

//Zoom Required Payload  
var payload = new JwtPayload  
{  
{ “iss”, apiKey},  
{ “exp”, ts },  
};

var secToken = new JwtSecurityToken(header, payload);  
var handler = new JwtSecurityTokenHandler();

// Token to String so you can use it in your client  
var tokenString = handler.WriteToken(secToken);

return tokenString;  
}

And following is the code to call the API:

var jwtToken = ZoomToken();  
var client = new RestClient(“[https://api.zoom.us/v2/users?page\_size=300&status=active](https://api.zoom.us/v2/users?page_size=300&status=active)”);  
var request = new RestRequest(Method.GET);  
request.AddHeader(“authorization”, String.Format(“Bearer {0}”, jwtToken));  
IRestResponse resp = client.Execute(request);

I think the issue is because of latest DLL version, but I am not sure.  
Microsoft.IdentityModel.Tokens -\> v6.7.1.0  
System.IdentityModel.Tokens.Jwt -\> v6.7.1.0

What are the DLLs versions you have?

---

<div class="post-metadata">

**Author:** ![k.krylov](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/k.krylov/32/316_2.png) [@k.krylov](https://devforum.zoom.us/u/k.krylov)\
**Post date:** [July 9, 2020, 6:56am UTC](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620/20 "2020-07-09T06:56:49Z")

</div>

Make sure you are using correct API secret and Key, and your account supports API calls (i.e. not a free one, it may’ve changed lately though)  
LogIn Here ([https://marketplace.zoom.us/user/build](https://marketplace.zoom.us/user/build))  
Make sure your app is **JWT** and its active

 ![ZoomKeys](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/2X/2/2205df913fa83f26da32f0bed8880945691d81e2.png)  
 ![ZoomActive](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/2X/3/364eeaab3168a901f2b631b66aef4fe11bb02a7f.png)

**Here is the class that generates my token**

```auto
using System;
using System.Text;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;

namespace ZoomIntegration.Configuration {
    
    public class ZoomToken
    {
        public ZoomToken(string ZoomApiKey, string ZoomApiSecret )
        {   
            DateTime Expiry = DateTime.UtcNow.AddMinutes(5);
            string ApiKey = ZoomApiKey;
            string ApiSecret = ZoomApiSecret;

            int ts = (int)(Expiry - new DateTime(1970, 1, 1)).TotalSeconds;

            // Create Security key using private key above:
            // note that latest version of JWT using Microsoft namespace instead of System
            var securityKey = new Microsoft.IdentityModel.Tokens.SymmetricSecurityKey(Encoding.UTF8.GetBytes(ApiSecret));

            // Also note that securityKey length should be >256b
            // so you have to make sure that your private key has a proper length
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

            //Finally create a Token
            var header = new JwtHeader(credentials);

            //Zoom Required Payload
            var payload = new JwtPayload
            {
                { "iss", ApiKey},
                { "exp", ts },
            };

            var secToken = new JwtSecurityToken(header, payload);
            var handler = new JwtSecurityTokenHandler();

            // Token to String so you can use it in your client
            var tokenString = handler.WriteToken(secToken);
            //string Token = tokenString;
            this.Token = tokenString;
        }
        
        public string Token { get; set; }
    }
    
}

```

```auto
//Here is the method to get Zoom users
private void GetAccountUsers(string ZoomApiKey, string ZoomApiSecret) {
            try
            {
                
                ZoomToken zt = new ZoomToken(ZoomApiKey, ZoomApiSecret);
                string Token = zt.Token;
                
                //Create new Request
                string BaseUrl = "https://api.zoom.us/v2/users?status=active&page_size=300&page_number=1";
                HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(BaseUrl);
                myHttpWebRequest.Method = "GET";
                myHttpWebRequest.ContentType = "application/json;";
                myHttpWebRequest.Accept = "application/json;";
                myHttpWebRequest.Headers.Add("Authorization", String.Format("Bearer {0}", Token));

                //Get the associated response for the above request
                HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
                using (StreamReader MyStreamReader = new StreamReader(myHttpWebResponse.GetResponseStream(), true))
                {
                    this.AccountUsers = JsonConvert.DeserializeObject<AccountUsers>(MyStreamReader.ReadToEnd());
                }
                
                myHttpWebResponse.Close();
                myHttpWebResponse.Dispose();
        
            }
            catch (WebException ex)
            {
                int errorCode = (int)((HttpWebResponse)ex.Response).StatusCode;
                if (errorCode != 0)
                {
                    ErrorCode = errorCode;
                    Stream MyStream = ex.Response.GetResponseStream();
                    StreamReader MyStreamReader = new StreamReader(MyStream, true);
                    this.ZoomException = JsonConvert.DeserializeObject<ZoomErrorResponse>(MyStreamReader.ReadToEnd());                  

                    //would be nice to check ZoomException for Null before throwing
                    throw new Exception(this.ZoomException.Message);
                }
            }
        }

```

```auto
//Here are 3 models for the response
[JsonObject]
    public class AccountUsers{
        
        [JsonProperty("page_count")]
        public Int32 PageCount { get; set; }

        [JsonProperty("page_number")]
        public Int32 PageNumber { get; set; }
        
        [JsonProperty("page_size")]
        public Int32 PageSize { get; set; }
        
        [JsonProperty("total_records")]
        public Int32 TotalRecords { get; set; }
        
        [JsonProperty("users")]
        public List<User> Users { get; set;}
        
        
    }
    
    [JsonObject]
    public class User{
        [JsonProperty("id")]
        public string Id { get; set; }

        [JsonProperty("first_name")]
        public string FirstName { get; set; }

        [JsonProperty("last_name")]
        public string LastName { get; set; }
        
        [JsonProperty("email")]
        public string Email { get; set; }

        [JsonProperty("type")]
        public Int32 Type { get; set; }

        [JsonProperty("pmi")]
        public string Pmi { get; set; }

        [JsonProperty("timezone")]
        public string TimeZone { get; set; }

        [JsonProperty("verified")]
        public Int32 Verified { get; set; }
        
        [JsonProperty("dept")]
        public string Department { get; set; }
        
        [JsonProperty("created_at")]
        public DateTime CreatedAt { get; set; }
        
        [JsonProperty("last_login_time")]
        public DateTime LastLoginTime { get; set; }
        
        [JsonProperty("last_client_version")]
        public string LastClientVersion { get; set; }
        
    }
    
    [JsonObject]
    public class ZoomErrorResponse {
    
        [JsonProperty("code")]
        public String Code { get; set; }
        
        [JsonProperty("message")]
        public String Message { get; set; }
    }

```

[Next page](https://devforum.zoom.us/t/how-to-create-jwt-token-using-rest-api-in-c/6620.md?page=2)
