Suite | Team, Growth, Professional, Enterprise, or Enterprise Plus |
Support | Team, Professional, or Enterprise |
You can use OAuth 2 to authenticate all your application's API requests to Zendesk. OAuth provides a secure way for your application to access Zendesk data without having to store and use the passwords of Zendesk users, which is sensitive information.
To use OAuth authentication, you need to register your application with Zendesk. You also need to add some functionality to your application to support the OAuth authorization flow.
Topics covered in this article:
- Registering your application with Zendesk
- OAuth client types
- OAuth client credentials grant type
- Implementing an OAuth authorization flow in your application
Related topics:
- For a tutorial on building a web application that implements an OAuth authorization flow, see Building an OAuth web app.
- To implement an OAuth authorization flow in Zendesk apps, see Adding third-party OAuth to a Support app.
- If you don't need users to grant your application access to their accounts, you can still use OAuth tokens to authenticate API requests. See Creating and using OAuth tokens with the API.
Registering your application with Zendesk
You must register your application to generate OAuth credentials that your application can use to authenticate API calls to Zendesk.
To register your application
- In Admin Center, click
Apps and integrations in the sidebar, then select APIs > Zendesk API.
- Click the OAuth Clients tab on the Zendesk API page, and then click Add OAuth client on the right side of the OAuth client list.
- Complete the following fields to create a client:
- Client Name - Enter a name for your app. This is the name that users will see when asked to grant access to your application, and when they check the list of third-party apps that have access to their Zendesk.
- Description - Optional. This is a short description of your app that users will see when asked to grant access to it.
- Company - Optional. This is the company name that users will see when asked to grant access to your application. The information can help them understand who they're granting access to.
- Logo - Optional. This is the logo that users will see when asked to grant access to your application. The image can be a JPG, GIF, or PNG. For best results, upload a square image. It will be resized for the authorization page.
- Unique Identifier - The field is auto-populated with a reformatted version of the name you entered for your app. You can change it if you want.
- Client kind - Public or Confidential. Public OAuth clients are applications that run in environments where credentials cannot be securely stored, such as mobile and web apps. These clients are required to use PKCE. Confidential OAuth clients run on secure servers where their credentials can be kept secure. These clients can use PKCE, client secret, or both. See OAuth client types.
- Redirect URLs - Enter the URL or URLs that Zendesk should use to send the user's decision to grant access to your application. The URLs must be absolute and not relative, https (unless localhost or 127.0.0.1), and newline-separated.
- Click Save.
After the page refreshes, a new pre-populated Secret field appears on the lower side. This is the "client_secret" value specified in the OAuth2 spec.
- Copy the Secret value to your clipboard and save it somewhere safe. Note: The characters may extend past the width of the text box, so make sure to select everything before copying.
Important: For security reasons, your secret is displayed fully only once. After clicking Save, you'll only have access to the first nine characters.
- Click Save.
Use the unique identifier and the secret value in your application as described in this following topic.
OAuth client types
Zendesk OAuth clients include a kind
property that is passed during OAuth client creation, and can have one of the following values:
- Public: Public OAuth clients are applications that run in environments where credentials cannot be securely stored, such as mobile and web apps. These clients are required to use PKCE.
- Confidential: Confidential OAuth clients run on secure servers where their credentials can be kept secure. These clients can use PKCE, client secret, or both.
For more information, see Client Types.
Zendesk OAuth client type applies only to the Zendesk Support ticketing system. It is not supported in Chat, Conversations, or Sell.
Existing Zendesk OAuth clients currently have the kind
property set to unknown
. These clients remain unaffected until the kind
property is updated to either public
or confidential
. New OAuth clients created in Admin Center must set the kind
property during creation.
kind
property to public
, you must first implement PKCE. Failure to do so will result in the client not working, as PKCE will be immediately required.Setting the kind
property is mandatory for all new OAuth clients created in Admin Center. While the kind
property is not required for OAuth clients created with the api/v2/oauth/clients endpoint
, Zendesk recommends including it.
OAuth client credentials grant type
The OAuth client credentials grant type is only for confidential clients and allows you to create an OAuth token using only a specific client’s secret. To use this flow, pass a valid client_secret
parameter to the /oauth/tokens
endpoint using grant_type: client_credentials
to generate a new OAuth access token. Unlike other authorization flows, this grant type does not return a refresh token and it does not require user authorization. The user associated with the token will be the same as the user linked to the client that was used. You can optionally include an expires_in
value to set the token's expiration time in milliseconds. For security reasons, public clients are not permitted to use this grant type. For more information, see Oauth Clients.
OAuth refresh token grant type
The OAuth refresh token grant type allows for refreshing an access token that has either expired or is about to expire. To generate a new OAuth access token, pass a refresh_token
parameter to the https://{subdomain}.zendesk.com/oauth/tokens
endpoint using grant_type: refresh_token
, which returns a new access token and refresh token while invalidating the previous ones.
Your OAuth client should implement a fallback mechanism to handle expired access tokens and expired refresh tokens. For example, if the access token expired or encounters an error, you can refresh it. However, if the refresh process fails or there is no refresh token linked to the access token, you must redirect the user to https://{subdomain}.zendesk.com/oauth/authorizations/new
to re-authorize your application. For more information, see OAuth Tokens for Grant Type and Creating and using OAuth access tokens with the API.
Implementing an OAuth authorization flow in your application
Zendesk supports the authorization code grant flow to get access tokens. This flow is called the authorization code grant flow because you have to get an authorization code before you can request an access token.
The flow uses refresh tokens, which allows you to generate new access tokens without requiring user re-authorization. The access token may expire if the API provides a valid expires_in
parameter, indicating a specific lifespan for the token. In such cases, implement a mechanism to refresh the access token using the provided refresh token before it expires.
To implement the authorization code grant flow, you need to add the following functionality to your application:
- Step 1 - Send the user to the Zendesk authorization page
- Step 2 - Handle the user's authorization decision
- Step 3 - Get an access token from Zendesk
- Step 4 - Use the access token in API calls
For a tutorial on building a web application that implements an OAuth authorization flow, see Building an OAuth web app.
The authorization code grant method supports Proof Key for Code Exchange (PKCE), which adds an additional layer of security. For more information, see Using PKCE to make Zendesk OAuth access tokens more secure in the developer documentation.
Step 1 - Send the user to the Zendesk authorization page
First, your application has to send the user to the Zendesk authorization page. The page asks the user to authorize your application to access Zendesk on their behalf. After the user makes a choice, Zendesk sends the choice and a few other bits of information back to your application.
To send the user to the Zendesk authorization page
Add a link or button in your application that sends the user to the following URL:
https://{subdomain}.zendesk.com/oauth/authorizations/new
where {subdomain}
is your Zendesk core subdomain, not a host-mapped subdomain.
You can use either a POST or a GET request. Include the following parameters:
-
response_type - Required. Zendesk returns an authorization code in the response, so specify
code
as the response type. Example:response_type=code
. - redirect_uri - Required. The URL that Zendesk should use to send the user's decision to grant access to your application. The URL has to be absolute and not relative. It also has to be secure (https) unless you're using localhost or 127.0.0.1.
- client_id - Required. The unique identifier you obtained when you registered your application with Zendesk. See the section above.
- scope - Required. A space-separated list of scopes that control access to the Zendesk resources. You can request read, write, or impersonate access to all resources or to specific resources. See Setting the scope.
-
state - An arbitrary string included in the response from Zendesk after the user decides whether or not to grant access. You can use the parameter to guard against cross-site request forgery (CSRF) attacks. In a CSRF attack, the end user is tricked into clicking a link that performs an action in a web application where the end user is still authenticated. To guard against this kind of attack, add some value to the
state
parameter and validate it when it comes back. - code_challenge - Required if using PKCE. A string representing a code challenge derived from a code verifier. See Generating the code_challenge value in the developer documentation.
- code_challenge_method - Required if using PKCE. The method used to derive the code challenge. Specify "S256" as the value.
Make sure to URL-encode the parameters.
Example GET request
https://{subdomain}.zendesk.com/oauth/authorizations/new?response_type=code&redirect_uri={your_redirect_url}&client_id={your_unique_identifier}&scope=read%20write
The Zendesk authorization page opens in the end user's browser. After the user makes a decision, Zendesk sends the decision to the redirect URL you specified in the request.
Setting the scope
You must specify a scope to control the app's access to Zendesk resources. The read scope gives an app access to GET endpoints. It includes permission to sideload related resources. The write scope gives an app access to POST, PUT, and DELETE endpoints for creating, updating, and deleting resources.
For more on the scope, see OAuth Tokens for Grant Types.
The impersonate scope allows a Zendesk admin to make requests on behalf of end users. See Making API requests on behalf of end users.
For example, the following parameter gives an app read access to all resources:
"scope": "read"
The following parameter gives read and write access to all resources:
"scope": "read write"
You can fine-tune the scope to the following resources:
- tickets
- users
- auditlogs (read only)
- organizations
- hc
- apps
- triggers
- automations
- targets
- webhooks
- zis
The syntax is as follows:
"scope": "resource:scope"
For example, the following parameter restricts an app to only reading tickets:
"scope": "tickets:read"
To give an app read and write access to a resource, specify both scopes:
"scope": "users:read users:write"
To give an app write access only to one resource, such as organizations, and read access to everything else:
"scope": "organizations:write read"
Step 2 - Handle the user's authorization decision
Your application has to handle the response from Zendesk telling it what the user decided. The information is contained in URL parameters in the redirect URL.
If the user decided to grant access to the application, the redirect URL contains an authorization code. Example:
{redirect_url}?code=7xqwtlf3rrdj8uyeb1yf
The authorization code is only valid for 120 seconds.
If the user decided not to grant access to the application, the redirect URL contains error
and error_description
parameters that inform the app that the user denied access:
{redirect_url}?error=access_denied&error_description=The+end-user+or+authorization+server+denied+the+request
Use these values to control the flow of your application. If the URL contains a code
parameter, get an access token from Zendesk as described in the following section. This is the token to include in API calls to Zendesk.
Step 3 - Get an access token from Zendesk
If your application received an authorization code from Zendesk in response to the user granting access, your application can exchange it for an access token. To get the access token, make a POST request to the following endpoint:
https://{subdomain}.zendesk.com/oauth/tokens
Include the following required parameters in the request:
- grant_type - Specify "authorization_code" as the value.
- code - Use the authorization code you received from Zendesk after the user granted access.
- client_id - Use the unique identifier specified in an OAuth client in the Support admin interface (Admin > Channels > API > OAuth Clients). See Registering your application with Zendesk.
-
client_secret - Use the secret specified in an OAuth client in the Support admin interface (Admin > Channels > API > OAuth Clients). See Registering your application with Zendesk.
If you use the PKCE
code_challenge
andcode_verifier
parameters,client_secret
is not required. You can use this characteristic to migrate from the implicit grant flow, which is no longer recommended because of security concerns. See Using PKCE to migrate from the implicit grant flow in the developer documentation. - redirect_uri - The same redirect URL as in step 1. For ID purposes only.
- scope - See Setting the scope.
-
code_verifier - Required if using PKCE. The string used to generate the
code_challenge
value. See Generating the code_challenge value in the developer documentation. - expires_in - Optional. Number of seconds the access token is valid. See OAuth Tokens for Grant Types.
- refresh_token_expires_in - Optional. Number of seconds the refresh token is valid. See OAuth Tokens for Grant Types.
The request must be over https and the properties must be formatted as JSON. If you use a custom or third-party application to make the API request, see its documentation for the proper format of property values.
Using curl
curl https://{subdomain}.zendesk.com/oauth/tokens \
-H "Content-Type: application/json" \
-d '{"grant_type": "authorization_code", "code": "{your_code}",
"client_id": "{your_client_id}", "client_secret": "{your_client_secret}",
"redirect_uri": "{your_redirect_url}", "scope": "read" }' \
-X POST
Example response
Status: 200 OK
{
"access_token": "gErypPlm4dOVgGRvA1ZzMH5MQ3nLo8bo",
"token_type": "bearer",
"scope":"read"
}
Step 4 - Use the access token in API calls
The app can use the access token to make API calls. Include the token in an HTTP Authorization header with the request, as follows:
Authorization: Bearer {a_valid_access_token}
For example, a curl request to list tickets would look as follows:
curl https://{subdomain}.zendesk.com/api/v2/tickets.json \
-H "Authorization: Bearer gErypPlm4dOVgGRvA1ZzMH5MQ3nLo8bo"
64 comments
Peter Watt
With the new Oauth updates mentioned here, will we be required to set a “refresh_token_expires_in”? If the parameter is not included, will the access token have an expiration?
1
Tushar
I am facing same issue as mentioned in above comment.
I have created a oAuth client with kind as confidential. I am using the /oauth/token API to get token by using client id, client secret, scope and grant as client_credentials. I am get the token, but when i use it with Ticket API, i get 401 "Couldn't authenticate you"
However when i use the other token endpoint /api/v2/oauth/tokens, the access token recieved works fine with Ticket API or rather any other API.
What am i missing ?
1
Ahmed Zaid
I tried using client credentials flow with no luck. My client is confidential, I used client secret, no PKCE and the scope was “read”. The token was generated successfully with user_id null as I expected it. However, I can't do anything with it. No matter what endpoint I use, I always get 401 response. When I inspect the token, I see used_at to be the timestamp when I got the 401 response.
Are there any restrictions on what I can use this token for?
1
Nicholas Hemenway
Are there any plans to add support for expiring access tokens? Having no expiration on access tokens negates a lot of the benefits of OAuth. It sounds like the overall approach to OAuth is being rethought, so wondering if expiration will be added as well.
1
Joel Hellman
Zendesk recently announced support for OAuth2 client credentials flow.
https://support.zendesk.com/hc/en-us/articles/8983332483226-Announcing-support-for-OAuth-2-0-Client-Credentials-grant-type
I am curious what “user” the client credential runs as? An issue we have had is that it has to run as a single user that has to be maintained an in worse case is deactivated etc. Can this new client credentials scheme operate without running as a particular named user in Zendesk?
1
Nicholas Hemenway
Now that all grant flows other than the authorization code grant flow have been deprecated, there is no longer a supported grant flow that is suitable for purely server-to-server communication (no user involved), correct?
Are there any plans to add support for a grant flow more suitable for server-to-server communication such as the client credentials flow?
0
Isabella Ellington
I'm having the same issue with Amit.
“Invalid Authorization Request”
• Error: invalid_request
• Description: “The request is missing a required parameter, includes an unsupported parameter or value, or is otherwise malformed.”
https://{subdomain}.zendesk.com/oauth/authorizations/new?response_type=code&redirect_uri={URI}&client_id={UNIQUE_IDENTIFIER}&scope=read
Anyone has any ideas?
0
Amit Yadav
I’m trying to implement OAuth authentication, but I’m getting a generic error:
“Invalid Authorization Request”
• Error: invalid_request
• Description: “The request is missing a required parameter, includes an unsupported parameter or value, or is otherwise malformed.”
URL I’m using:
https://{subdomain}.zendesk.com/oauth/authorizations/new?response_type=code&redirect_uri={URI}&client_id={UNIQUE_IDENTIFIER}&scope=read
Can you help me debug this?
1
Ben
I can get everything to work except the final step when calling “https://{subdomain}.zendesk.com/oauth/tokens”. This is returning a CORs error, and hence, we cannot move forward. All other endpoints work fine, and if I call the endpoint using CURL and the same parameters, I get a valid response. So this is purely a CORs issue. Can you help?
0
Yevheniy Oliynyk
Hey Zendesk Support Team!
I am trying to implement login thru Zendesk in my UI application and faced issue with losing popup window that is opened for user to log in into Zendesk.
The way how it supposed to work is:
1. User clicks login button
2. It opens new window and redirects to `/oauth/authorizations/new`
3. Once user is successfully logged in, on final redirect, I am preserving code (for this I need a way to communicate back to main window)
And it all works fine if in the same browser session user is already logged into Zendesk so on login thru my application it immediately receives code/token, all is working fine.
But if user is not signed into Zendesk yet, then when I am opening popup, Zendesk closes it and opens new, with it's login form. Not sure why it can't happen in the same window. And the issue here is that I don't have anymore a way to communicate with my main window where the login flow was initiated.
Is it something that was done by intention? Is there any way to prevent this extra window re-creation?
0
Sign in to leave a comment.