Zendesk Apps framework (ZAF) lets you make API requests from Zendesk apps through the ZAFClient object request() method. This article describes how to make API calls using this method and how to use it to get around Cross Origin Resource Sharing (CORS) issues.

This article describes the various methods for making API requests within the app. It also covers how you can make AJAX requests with other tools such as XMLHttpRequest or jQuery.ajax().

You can install a demo app in your Zendesk account and try out the different kinds of requests discussed.

To get the most out of this article, you should have a basic understanding of the Zendesk Apps framework. If you're new to the framework, please see the following to get the most out of this article:

Understanding ZAF API requests

A ZAF app, once built and deployed, consists simply of HTML, CSS, and JavaScript code. The app is hosted in an iframe embedded in a specific location in the Zendesk Support or Zendesk Chat agent interface.

The embedded app communicates with the Support or Chat product instance through an object called ZAFClient. Behind the scenes, ZAFClient uses the postMessage() method to communicate between the app's iframe and main product window.

Examples that you might see typically initialize ZAFClient as:

var client = ZAFClient.init();

The resulting client variable object has the request() method:

client.request(options)

The options argument is a JavaScript object containing the details of the request.

Note: The client object has other methods, too, such as get(), set(), and invoke(). Learn more in the ZAFClient Object documentation.

The request() method can make three kinds of API requests:

  1. Zendesk REST API requests from your currently authenticated Zendesk session
  2. Third-party API requests
  3. Third-party API requests through a proxy server provided by Zendesk

Here are examples of each:

Method 1: API request to Zendesk API

let options = {  url: '/api/v2/tickets.json',  type: 'GET'};
return client.request(options).then((results) => {  console.log("Example 1 call results:", results);});
  • Makes a direct call to the Zendesk instance that the app is running within.
  • url is a Zendesk REST API endpoint.
  • The call's context is your Zendesk agent session and uses your Zendesk session cookie. This avoids having to pass authentication information.

Calling other Zendesk instances

You can't use this kind of request to call other Zendesk instances. You're only authenticated against the currently running Zendesk instance. If you need to call another Zendesk instance, use AJAX or consider a server-side solution. See also Making an API request to another Zendesk account from an App (error: is not a proxyable URI).

Method 2: API request to third-party API

let options = {  url: 'https://api.github.com',  type: 'GET',  cors: true};
return client.request(options).then((results) => {  console.log("Example 2 call results:", results);});
  • cors:true tells request() to make the API call directly from the browser.

  • If the browser's debug Network tab is open, you'll see a call made to the remote URL.

  • The request's ORIGIN header to the remote API is your Zendesk session. Example:

    origin https://yoursubdomain.zendesk.com

  • The fact that the call is made directly by the browser to the remote end-point makes this a CORS call. CORS stands for Cross-Origin Resource Sharing and is a standard recognized only by browsers. A browser has the context of one origin (the website you're on) and another origin (the website the browser is calling). When the browser requests resources in another origin, it's crossing origins -- thus the name.

Method 3: API request to third-party API through Zendesk proxy service

let options = {  url: 'https://api.github.com',  type: 'GET',  cors: false};
return client.request(options).then((results) => {  console.log("Example 3 call results:", results);});
  • cors:false tells request() to have the Zendesk proxy service make the API call. This is a backend service that Zendesk hosts and maintains.
  • The browser's Network tab will show a call to the Zendesk proxy service with the remote URL appended:

https://yoursubdomain.zendesk.com/proxy/to/**https://api.github.com**

  • The remote location that you're calling may or may not receive an ORIGIN header. ORIGIN headers are added by browsers, not by Zendesk or the Zendesk proxy.
    • If the browser adds an ORIGIN header, the proxy will pass it along to the remote server.
    • Depending upon the browser and HTTP method, an ORIGIN header may be added. See this StackOverflow article for more. There's also additional details in this StackOverflow article on ORIGIN and CORS behaviors.
    • The call to the remote API is made from Zendesk's backend proxy service, not directly from the browser.
  • The fact that the eventual call to the third-party API is not made from a browser but from a backend proxy service essentially makes this a non-CORS call. You can only have a CORS call if it's coming from a browser as explained in Example 2. This is also the reason for the option's false value. You don't want  the browser to make the call directly to the remote endpoint (which would be a CORS call as in Example 2). You instead want to use the proxy service, so cors:false is passed.
  • cors:false is the default if not explicitly set.

Why would you want to use this option?

Some remote web sites are not cross-origin friendly. Calling through a proxy service is sometimes a way to make what would have been a failed CORS call if it came directly from a browser (see CORS Troubleshooting for more details).

cors:false is also needed when using ZAF's secure setting feature. It's the backend proxy that replaces secure setting placeholders with actual values. See Using secure settings for more information.

For a more complete example of an app that uses this kind of request see Zendesk Apps tutorial - Getting data from an external application.

Comparison of the above methods:

AJAX requests

You don't have to use the request() method to make third-party API requests. You can make an AJAX call using tools such as jQuery.ajax() or XMLHttpRequest.

An AJAX request doesn't use ZAFClient. The API call comes directly from your app. Use AJAX requests when ZAFClient request functionality is not needed or not available. For example, ZAFClient doesn't support uploading and downloading binary content but an AJAX call does.

AJAX requests have ORIGIN headers that match the app iframe's origin. Each app runs in its own iframe and has its own origin. When an app makes an AJAX request, its ORIGIN header value looks like:

origin 123456.apps.zdusercontent.com

Method 4: API request to third-party API using AJAX

$.ajax({  url:'https://api.github.com',  type: 'GET'}).then((results) => {  console.log("Example 4, part 1 call results:", results);});
  • This example uses the jQuery $.ajax() method.
  • ZAF hosts "client-side" apps in their own domain. These app domains looks like 123456.apps.zdusercontent.com, where the numeric subdomain value is the Zendesk resource ID of the app. The app's resource ID can be retrieved using GET /api/v2/apps/installations.json.

Note: There are also "server-side" apps, where a remote server hosts the app's assets. See Building a server-side app for more information.

  • As mentioned already, the remote site receives an ORIGIN request header that looks like 123456.apps.zdusercontent.com.
  • Client-side app AJAX calls are cross-origin requests. They go from your app's unique origin to the remote origin. This may or may not work depending on the remote site. In this example, https://api.github.com supports cross-origin CORS requests. Other sites may not and return a CORS error. For example, if the call was instead to https://www.wikipedia.org, which doesn't support CORS, an error would be seen in the browser's Console tab. See CORS Troubleshooting for more information.

Cross-origin requests to the Zendesk REST API need an OAuth access token for authentication. You can't use Basic username/password authentication. See Making cross-origin, browser-side API requests. In this case, you need to pass the access token in an Authorization header with a Bearer token:

$.ajax({  url:'https://yoursubdomain.zendesk.com/api/v2/tickets.json',  type: 'GET',  headers: {"Authorization": "Bearer a276f7baa2a276f7baa2a276f7baa2a276f7baa2"}}).then((results) => {  console.log("Example 4, part 2 call results:", results);});

The following diagram illustrates this kind of request. The AJAX call comes directly from the app, which is running inside an iframe. That iframe is inside the browser that's running Zendesk Support or Chat:

Demo app

See or download the following demo app on Github for examples of the four example requests.

You can install the app in your Zendesk instance and run test requests. You can install it manually by zipping up the directory and uploading it to Admin Center instance using Apps and integrations > Apps > Zendesk Support apps in the admin interface. For details, see Uploading and installing a private app.

The app is a ticket sidebar app that has an action button for each of the above four examples. Open your browser's Console and Network tabs to see app activity when selecting example actions.

Join the discussion about this article in the community.