Request API

You should use the Request API to avoid exposing sensitive information, such as your API keys or user credentials, when you make HTTP requests to third-party domains as users will be able to inspect these values in a browser and access them. The other benefit is Cross-Origin Resource Sharing (CORS) support as requests are routed through a proxy.

Note:
1. All apps that make requests to third-party domains must use the Request API or they will not be published in Freshworks Marketplace.
2. Requests made using the Request API should return String, JSON, or XML data type.
3. The timeout for request is six seconds.
4. There is a rate limit of 50 requests per minute per app per account.

Configure

To use the Request API, the list of domains should be specified in the manifest.json file.

  • You must use only HTTPS.
  • Do not use IP addresses.

Example 1
If your app makes an API call to https://example.com/api/1.json, include the following in the manifest.json file.

Copied Copy
1
2
3
"whitelisted-domains": [ "https://www.google.com" ]

Example 2
Sometimes, you will have to make calls to a URL whose name is not static. Then, part of the domain value will come from Installation Parameters (iparams).

  1. All users who sign up for a Freshsales account have a unique Freshsales domain. Therefore, if your app makes calls to the Freshsales domain, part of the domain value will come from iparams. To whitelist such domains, include the following code in the manifest.json file. Copied Copy
    1
    2
    3
    4
    "whitelisted-domains": [ "https://<%= iparam.subdomain %>.freshsales.io", "https://<%= oauth_iparams.subdomain %>.freshsales.io" ]
    In the above sample code, subdomain is the display name of the iparam and oauth_iparams.
  2. In some cases, the entire domain value comes from iparams. To whitelist such domains, include the following code in the manifest.json file. Copied Copy
    1
    2
    3
    4
    "whitelisted-domains": [ "https://<%= iparam.domain %>", "https://<%= oauth_iparams.domain %>" ]
    In the above sample code, domain is the display name of the iparam and oauth_iparams.

Example 3
Wildcards are supported to enable you to whitelist all subdomains of a parent. For example, an app wants to make requests to multiple Freshsales accounts like menswear.freshsales.io, kidstoys.freshsales.io, accesories.freshsales.io, and so on.

To whitelist such domains, include the following code in the manifest.json file.

Copied Copy
1
2
3
"whitelisted-domains": [ "https://*.freshsales.io" ]
Usage

The Request API should be defined in the app.js file by using the following syntax.

Copied Copy
1
2
3
4
5
6
7
8
9
10
client.request.get("URL", options) .then( function(data) { //handle "data" //"data" is a json string with status, headers, and response. }, function(error) { //handle failure } );

The Request API should be defined in the server.js file by using the following syntax.

Copied Copy
1
2
3
4
5
6
7
8
9
10
$request.get("URL", options) .then( function(data) { //handle "data" //"data" is a json string with status, headers, and response. }, function(error) { //handle failure } );

The following table lists the parameters and their description.

PARAMETER DESCRIPTION
URL Is mandatory to make the Request API call.
options Is a JSON object and can include the following properties:
  • headers: HTTP Headers
  • body: Entity body, applicable for PATCH, POST, and PUT requests. Should be a string.
  • staticIP: A boolean value used to make requests with a static outgoing IP.
data Data received from the Request API if the request is successful.
error Data received from the request if an error is encountered.

Using Iparams

Iparams can be used in requests as part of the following:

  • Header
  • URL Copied Copy
    1
    https://passport-office.com/user?id=<%= iparam.passport %>
  • Body Copied Copy
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    client.request.post("https://helloworld.freshsales.io/api/leads", { headers: { Authorization: "Basic <%= encode(iparam.username + ':' + iparam.password) %>" }, body: JSON.stringify({ status: 2, priority: 1, description: "Test", subject: "<%= iparam.subjectPrefix %> Hello there", email: "tom@outerspace.com" }) });
    EXPAND ↓
Sample Requests

Request API should be defined in the app.js file, you can use the following sample requests for reference.

1. GET request with authentication Copied Copy
1
2
3
4
5
6
7
8
9
10
11
var headers = {"Authorization": "Token token=<%= (iparam.api_key) %>"}; var options = { headers: headers }; var url = "https://sample.freshsales.io/itil/requesters/5.json"; client.request.get(url, options) .then ( function(data) { console.log(data); }, function(error) { console.log(error); });
EXPAND ↓

If the request is successful, data is returned in the following format.

Copied Copy
1
2
3
4
5
6
7
8
9
{ status : 200, headers: { "Content-Length": 20, "Content-Type": "application/json;charset=utf-8" }, response: `{ "Name": "Rachel"}` }

If the request fails, an error response is returned in the following format.

Copied Copy
1
2
3
4
5
6
7
8
{ status : 401, headers: { "Content-Type": "application/json;charset=utf-8" }, response: [{"message": "Session expired or invalid", "errorCode": "INVALID_SESSION_ID"}] }

If the request fails due to an error from the app, the error response is returned in the following format.

Copied Copy
1
2
3
4
5
6
7
8
9
{ "status" : 400, "headers": { "Content-Type": "application/json;charset=utf-8" }, "response": "This domain has not been whitelisted.", "errorSource": "APP" }

2. GET request without authentication Copied Copy
1
2
3
4
5
6
7
8
9
10
var options = {}; var url = "https://httpbin.org/get?arg1=hello_world"; client.request.get(url, options) .then ( function(data) { console.log(data); }, function(error) { console.log(error); });

3. POST request with authentication Copied Copy
1
2
3
4
5
6
7
8
9
10
11
var headers = {"Authorization": "Token token=<%= (iparam.api_key) %>"}; var options = { headers: headers, body: "Hello world"}; var url = "https://sample.freshsales.io/api/leads"; client.request.post(url, options) .then ( function(data) { console.log(data); }, function(error) { console.log(error); });
EXPAND ↓
OAuth Request

For information on how to make an OAuth request, see Usage in the OAuth section.

Testing

Note: For testing, we recommend that you use the latest version of Chrome browser.

Open your console, navigate to your project folder, and execute the following command. $ fdk run

During testing, you may see a shield icon in the browser address bar. Clicking the icon displays a warning message as the support portal runs on HTTPS while the server that is used for testing runs on HTTP. Click Load Unsafe Scripts to continue testing.

IP Ranges

Here is the list of IPs you must whitelist when using Request APIs if IP whitelisting is enabled on the Freshdesk support portal or you wish to whitelist requests from your app.

Region IPs
United States 18.233.117.211 and 35.168.222.30
Europe-Central 18.197.138.225 and 52.57.69.21
India 13.232.159.149 and 13.233.170.242
Australia 13.211.182.225 and 52.63.187.64

Errors

In case of request failure, a status code is displayed along with a message to help troubleshoot the issue.

An example of a status code and message is as follows.

Copied Copy
1
2
3
4
5
6
7
8
9
10
11
{ "status": 401, "headers": { "Content-Type": "text/plain" }, "response": [{ "message": "Session expired or invalid", "errorCode": "INVALID_SESSION_ID" }] }

The following table lists all the supported status code.

STATUS DESCRIPTION
400 Is returned due to invalid input. For example, if you are making a request to a domain that has not been whitelisted, you will receive this status.
401 Is returned if you performed an unauthorized request.
429 Is returned when the number of requests exceeds the threshold.
500 Is returned if the server encountered an unexpected error. If this error persists, contact us at support@freshsales.io.
502 Is returned when there is a network error. If this error persists, contact us at support@freshsales.io.
503 Is returned when the service is temporarily unavailable.
504 Is returned when there is a timeout error while processing the request.