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
- 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 OAuth to apps.
- 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 Zendesk Support, click Manage (
) and then select API in the Channels category.
- Click the OAuth Clients tab on the Channels/API page, and then click the plus icon (+) on the right side of the 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.
- 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.
Implementing an OAuth authorization flow in your application
Zendesk supports several OAuth grant types. This article describes the authorization code grant type in detail. Another flow, the implicit grant type, is similar to the first except it doesn't use an authorization code. The third option, the password grant type, is a server-side grant type that doesn't require interacting with end users.
Authorization code grant flow
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 doesn't use refresh tokens. The access token doesn't expire.
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.
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 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 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.
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
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 valid only for a short time.
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.
- redirect_uri - The same redirect URL as in step 3. For ID purposes only.
- scope - See Setting the scope..
The request must be over https and the parameters must be formatted as JSON.
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"
Implicit grant flow
The implicit grant flow is similar to the authorization code grant flow except there's no step 3. You request a token instead of an authorization code. In other words, you set the value of the response_type
parameter to "token" instead of "code". If the end user authorizes access, the token is sent immediately in the redirect URL. No endpoint exists to create the token or set its scope. The token grants read and write access to all resources.
Example request
https://{subdomain}.zendesk.com/oauth/authorizations/new?response_type=token&client_id={your_unique_identifier}&scope=read%20write
Example responses
If the user grants access to the application, the token is included in the redirect URL.
{redirect_url}#access_token=gErypPlm4dOVgGRvA1ZzMH5MQ3nLo8bo&token_type=bearer
If the user decides not to grant access to the application, the URL contains error
and error_description
parameters.
{redirect_url}#error=access_denied&error_description=The+end-user+or+authorization+server+denied+the+request
Password grant type
Use the password grant type to exchange a Zendesk username and password for an access token directly. This grant type should only be used if your application can get Zendesk usernames and passwords. This is usually a highly privileged application with Zendesk. The application should never store the usernames and passwords. It should also be highly secure about how it gets them.
Example request
curl https://{subdomain}.zendesk.com/oauth/tokens \
-H "Content-Type: application/json" \
-d '{"grant_type": "password", "client_id": "{your_client_id}",
"client_secret": "{your_client_secret}", "scope": "read",
"username": "{zendesk_username}", "password": "{zendesk_password}"}' \
-X POST
A Zendesk username is usually an email address such as agent@zendesk.com.
Example response
Status: 200 OK
{
"access_token": "gErypPlm4dOVgGRvA1ZzMH5MQ3nLo8bo",
"token_type": "bearer",
"scope":"read"
}
58 Comments
Thank you very much.
My application supports only Oauth 1.0, will I be able to use Oauth authentication with Zendesk?
Regards,
Aditya
Hi Aditya -- The OAuth 2.0 flows mentioned above are the ones Zendesk supports.
Along with this article, here's some more background info on the supported OAuth 2.0 options: https://support.zendesk.com/hc/en-us/articles/203663426-Having-the-talk-Am-I-ready-for-a-more-advanced-authentication-option
Hope this helps!
Hi There,
First of all its a pretty good guide. Making OAuth flow work with the example from Implicit Grant Flow, was very easy :)
However id like to be using the Authorization code grant flow instead. So i followed your steps and I am getting Authorization Code from query parameter code just fine. But when i run the provided Curl snippet or xhr to the token endpoint I get error invalid_client with error description "The client identifier provided is invalid, the client failed to authenticate, the client did not include its credentials, provided multiple client credentials, or used unsupported credentials type".
I've been checking my provided credentials over and over, since that would be the obvious place for my issue. I've Also tried to regenerate the client_secret and then granting new code to try with but i am having no luck.
Just in case my body is:
{
"grant_type": "authorization_code",
"code": "8d535c<....>",
"client_id": "50789",
"client_secret": "c4497<...>",
"redirect_uri": "http://localhost:8080",
"scope": "read"
}
Any help will be highly appreciate :)
Hi Jens -- try setting client_id to the "Unique Identifier" value in your Zendesk's Admin > API > OAuth Clients dialog -- should look something like this (although 'test_oauth_client' will be a different value in your case):
For this particular API call, the numeric ID of your client_id is not the value you want to pass -- you want to pass the alpha-numeric OAuth client value. Let me know how this works.
It works !! Great Thanks alot. I believe I had tested that before. Might've been using wrong redirect along with it since one had changed it cause we didnt notice that it was possible to add more with newlines :).
Have nice day.
Glad to hear you got things working, Jens!
Also, I see that this is your first post - Welcome to the Zendesk Community! I encourage you to head over to the Introductions thread in The Lounge to introduce yourself to everyone and familiarize yourself with our Community Guidelines.
We look forward to seeing you around the Community. Happy Zendesking!
Thanks Nicole,
I've actually worked 5+ years now with Zendesk - Jens is just a "incognito"-profile. It offers a great API.
What I am\was trying to do is to make customers authorize without having there access_token exposed. and that works now :)
I am still grubbling over 2 things though. I cant seem to find any information about what the authenticity_token is for ? And I cant seem to find a way to be able to retrieve an refresh_token ?
Hi Jens -- the authenticity_token is useful if, say, you're in the Help Center and want to do AJAX calls back into Zendesk. It basically is a CSRF token that you can use on subsequent calls. If you don't have it, even though you're authenticated, you'll get a 403. You should be able to do something like this (get the token, then use it in a subsequent call):
The oauth flow is working in my application, but there is one small issue that I've run into with our flow sometimes.
The /oauth/authorizations/new page seems to cache credentials, so that if I redirect to it after a user has already authenticated, it immediately redirects to my callback rather than displaying the login form. This is not desired for my scenario because I do want to give my users the opportunity to log in to a different Zendesk account. (Though this scenario is relatively rare)
Is there any parameter I can pass to /oauth/authorizations/new to not use the cached session? Essentially I just want it to load the login prompt every time instead of letting users "stay signed in". If the user clears their cookies then they'll see the login prompt again, but I'm wondering if there is anything that our application can control.
Hi Andrew.
The /oauth/authorizations/new endpoint is just for 'authorization' not 'authentication', so there are no explicit options to manage logins.
However, doing an explicit logout before you call the /oauth/authorizations/new endpoint should do it. Something like:
Im currently experiencing issues with this Curl query.
curl https://domain.zendesk.com/oauth/tokens \
-H "Content-Type: application/json" \
-d '{"grant_type": "authorization_code", "code": "0f9c9c141a8cd5fcbb1483e05cbaa7d35d1f7a44a45477954bd38e1330df6909",
"client_id": "zendesk_auth", "client_secret": "secretklæfdflæhkdfklæhlædfkhlæsecret",
"redirect_uri": "https://localhost:9000/tokens/exchange-token", "scope": "read" }' \
-X POST
response:
{"error":"Couldn't authenticate you"}
Ive trippled checked the secret, code, client id, redirect_uri and permissions.
I can't find any reason in this :)
I can access the the correct json response with following URL, but only from browser with shared_sessions cookie.
https://domain.zendesk.com/api/v2/oauth/tokens?grant_type=authorization_code&code=258fb8a8743928ae0eff68cd54c9a2e24c032139cf49f15980dca792673e844c&client_id=zendesk_auth&client_secret=secretklæfdflæhkdfklæhlædfkhlæsecret&redirect_uri=https://localhost:9000/tokens/exchange-token&scope=read
Does anyone know this issue or am i doing something wrong ?
Thanks in advance!
Hi Jonathan,
My guess is that your authorization code is invalid in some way -- i.e. it's already been used (so expired), or was created and has gone stale (authorization codes should not last forever).
I would go back, generate a new authorization code value, and use it right away. Let us know how that goes. If you're still having problems, I would submit a ticket to support@zendesk.com, so we can dive deeper into the issue with your particular environment.
Hi Bryan,
Thank you for your response!
It doesn't seem that the code is the issue here, Its my authServiceApp thats handles the request/repsonses, and it retrieves a new authorization code every time, but still receives the Unauthorized response.
So far i can read from the API documentation, it should not be handling cookies in the requests aswell ? The reason i am asking is my browser with my current session cookie, can easily access the correct json from the same type of request.
Hi Jonathan. In that case, please open a ticket with support@zendesk.com and we can diagnose your particular account and workflow more closely. This is a general-use how-to article, so is not going to be the best place to figure this particular situation out. Thanks!
Hey Bryan.
Thank your for your help !
I'll continue the investigation :)
When going to production, how can my server capture the subdomain of the incoming request for a Global oAuth Token?
Hi Lucas,
The process of capturing the subdomain is something that you'll need to develop and implement yourself as part of your user authentication workflow. It can be a simple form/field to prompt and capture this information so that it can be used to construct the URL of the request.
You can also find some additional documentation and user discussions of this in our article here - https://develop.zendesk.com/hc/en-us/articles/360001074388-Requesting-a-global-OAuth-client-for-a-Zendesk-Support-integration
Hope this helps!
Is it possible to be a little more generic with the redirect URIs? I'd like to do something like a wildcard with `https://developers.hp.com/*` so I can allow any page that starts with that domain. We have lots and lots of individual pages, and rather than redirecting users to some generic home page, or listing every single possible page out in the OAuth settings, it would be great to just say "hey, this domain is cool," and have it work as long as I redirect users to that domain, regardless of the actual page/path.
Hi, I can't follow the steps 2 and 3 in my java application.
After the 1st step, I give the grant how the second step describes.
The code in the URL in the browser close the redirect URL I saw but for 1 second. How can I retrieve that value in java?
The third step, where do I find the response with those parameters?
After the second step from the browser, I don't return in my java application.
How do I do?
I'm struggling to implement this authentication, but I need more specific tips to implement that.
Can someone give me more details?
Many thanks.
Hi guys. I just saw these posts. Hopefully you find these answers still helpful...
@Dru -- Because of the security design around OAuth, the redirect URL(s) defined in the OAuth client can't be wildcards. By maintaining very strict, known redirects, redirects to unexpected, possibly malicious web sites are avoided. You can, however, enter more than one redirect URL in your client and indicate the one you want to use in your grant flow.
@Raffaele -- Implementing OAuth grant flows is not trivial. Your technology stack (what kind of backend server you're running, the primary language, and other factors) can add to the learning curve. Because of all that, helping debug and write an authorization grant flow is beyond the scope here. There are resources out there that might help, however. I would look at this or similar resources (keyword search on Java, OAuth, authorization code grant flow, ...) to familiarize yourself more with all the steps and details to consider: OAuth 2.0 clients in Java programming.
Hope these points help at least to some degree. Regards.
So, if the bearer token never expires, then why did I start getting this in production at 8:45 AM EST? It should go without saying that we changed nothing on our side to cause this.
Hi Ryan,
Another possible cause might be that the person who initially created the token was downgraded in role (from admin to agent or user, for example). See https://support.zendesk.com/hc/en-us/articles/360002008127-OAuth-Token-Revoked-Upon-User-Downgrade.
Alas, I have no permission to view that article:
oops
You're not authorized to access this page
Regardless, the API also implemented a breaking change at the same time, that the per_page param of the guide search API must be non-zero. That these two changes happened simultaneously would indicate that someone published new API code. The act of publishing probably invalidated all the bearer tokens.
In any case, we gathered a new token and scrambled to push a hotfix to send a 1 instead of 0 when all we want is the count of matching articles. The service is back up in production. Zendesk might consider better documenting breaking changes.
Apologies, first day back from holidays. The link was to an internal KB article for our customer service team. Here's the gist of what is says:
When a user creates an OAuth token with the API, the user must be an admin to make the request. The token is associated with the user and inherits the user's API permissions (in other words, admin permission to endpoints). However, if the admin user is downgraded to agent or end user (such as when the user leaves the company, for example), the token's permission changes accordingly. The token only works with endpoints requiring agent or end-user permissions, depending on the new role.
I am trying to use Chat Conversation API so I need to put chat in scope. Is there any endpoint where this is possible to receive token?
Retrieving OAuth tokens for Zendesk Support is different than for Zendesk Chat.
For Zendesk Chat, please check out this article for how to generate an OAuth token manually:
Generating a REST API token for integrated Chat accounts
For other Chat Conversation API resource, also check out these links:
Chat Conversations API Community
Getting started with the Chat Conversations API
Chat Conversations API
I want to host a web server for my customers to download software, and have them log in with their Zendesk accounts. If they are an active customer, they could then access the site and download sofware. Is there a tutorial somewhere for how to use Zendesk authentication on an external web server? Is that possible?
Hello. Zendesk cannot be used as an Identity Provider (IdP). While Zendesk can use other IdPs (such as Google), it cannot be used as an IdP itself.
Coming from SForce we used verifysession.php to allow access to hosted files from SF. How can I can I go about setting this up using OAuth2 from this article, or is there a better way?
Please sign in to leave a comment.