Request method is a secure mechanism to send HTTP requests from an app to a third-party or Freshworks domain, without exposing any sensitive information that is part of the request. Through browsers, app users may intercept sensitive information such as API keys or user credentials. Request method safeguards against such exposure. Typically, HTTP requests are routed through proxy servers. In such cases, sending the HTTP requests through the request method helps identify the origin in scenarios where the third-party domain has enabled Cross Origin Resource Sharing (CORS) support.
To use the request method,
- As part of the app configuration, configure request templates.
- In manifest.json, declare the template(s) that the app code uses.
- From the app logic, invoke the configured template(s), and make HTTP requests.
- The default request timeout is 15 seconds. If the request timeout is increased to 20, 25, or 30 seconds, the app execution timeout is extended to 40 seconds. For the local testing of apps that use the request method, you can specify an appropriate timeout. For information on local testing with REQUEST_TIMEOUT, see Test apps that use request method.
- The rate limit for requests is 50 requests per minute per app per account.
- The payload passed to the severless component should not exceed 100 KB.
- The payload retrieved in the response should not exceed 6 MB.
- In the requests.json file, you can configure a maximum of 100 templates.
- To know all the platform restrictions and constraints, see Rate limits and constraints.
Allow-list IPs
At times, API/resource providers do not want apps to connect to their APIs/resources, unless the app is trying to connect from a known and approved system/org. To get the origin (from where the requests originate) approved, the app devs will have to provide the list of IPs from which the requests can originate. The resource providers will allow-list these IPs in their system and allow any request that comes from these IPs to access their resources. If you want to access such a resource, you will have to provide the following IPs to the resource providers, for allow-listing.
For custom app devsIf you are building an app and if IP whitelisting is enabled for the parent application (the Freshworks' product on which the app is deployed after installation) account, allow-list the following IPs to enable your app to access the parent application resources.
| Region | IPs |
|---|---|
| United States | 18.233.117.211 and 35.168.222.30 |
| Germany/Europe-Central | 18.197.138.225 and 52.57.69.21 |
| Sweden/Europe-North | 13.63.205.168 and 13.50.203.236 |
| India | 13.232.159.149 and 13.233.170.242 |
| Australia | 13.211.182.225 and 52.63.187.64 |
| United Arab Emirates | 3.29.180.34 and 51.112.23.180 |
Configure request templates
Request templates are snapshots of all the HTTP requests that an app is expected to make.
- From the app’s root directory, navigate to the config folder and create a requests.json file (if requests.json does not exist).
- In requests.json, use the following syntax to configure all request templates that the app is expected to use, as JSON objects.
Attributes of the request.json file
- <requestTemplateName>object
<requestTemplateName> is the name used at runtime to invoke the request template. This object contains the attributes that are required to build the request.
- schemaobjectRequired
Properties of HTTP requests and the corresponding values specified as key-value pairs of <property-name>:<property-value>. The property values are used to build the HTTP request.
Note:The HTTP request body is not part of the template configuration/schema. It is passed as part of the template invocation.
Example"schema": { "method": "GET", "host": "northstar.freshchat.com", "path": "/api/v2/conversations/{conversation_id}/messages", "headers": { "Authorization": "Bearer <%=iparam.apikey %>", "Content-Type": "application/json" } }Note:Some of these attribute values can contain variables that can be filled at runtime. For more information, see template substitutions.
- methodstringRequired
HTTP method.
Valid values: GET, POST, PUT, DELETE, PATCH
- protocolstring
If specified, the value must be HTTPS. You can use HTTP during local testing of the app. Ensure that the app submitted for review does not contain a protocol value of HTTP.
Default value: HTTPS (if no protocol value is specified)
Valid values: GET, POST, PUT, DELETE, PATCH
- hoststringRequired
Absolute domain name of the domain to which the app sends the HTTP request. Must not be an IP address; must be a Fully Qualified Domain Name. Ensure not to specify the protocol nor to append a trailing slash as part of the host value.
- pathstring
Path to the resource on the host domain. Ensure to construct the path with a leading slash.
Default value: / (if no path value is specified)
- queryobject
Query parameters and the corresponding values, specified as key-value pairs of <queryParameter-name>:<queryParameter-value>. The query parameters are used in conjunction with the path parameters when constructing the HTTP request.
Example"query": { "page": "<%= context.page %>", "per_page": "20" } - headersobject
Valid HTTP headers (such as Authorization, Content-Type, and so on) and the corresponding values, specified as key-value pairs of <header-name>:<header-value>.
Supported Content-Type headers for a response:- application/json
- application/xml
- text/html
- text/xml
- application/jsonp
- text/plain
- text/javascript
- application/vnd.api+json
If the response Content-Type doesn't match any of the above, it would result in 415-Unsupported Media Type error. If the app you are building requires support for other Content-Type headers, reach out to the Freshworks Community.
- optionsobject
Optional parameters and the corresponding values that help to make a successful HTTP request call. The options are specified as key-value pairs of <optional-parameter-name>:<optional-parameter-value>.
Example"options": { "retryDelay": 1000 }- maxAttemptsnumber
Maximum number of times that a request can be resent if a network or 429/5xx HTTP error occurs.
Valid values: 1, 2, 3, 4, 5
Default value: 1
- retryDelaynumber
Time in milliseconds after which a request can be resent.
Valid values: 1 through 1500
Default value: 1000
- oauthstring
<oauth_configuration_name> defined in the config/oauth_config.json file.
If you’ve configured an OAuth object in your app, the access token for OAuth authorization must be specified as a variable in schema.headers.Authorization.Example of access_token usage:"headers": { "Authorization": "Authtoken=<%= access_token %>" }As part of our OAuth offering, when app users Authorize an app to place an OAuth request, the access token is stored in .fdk/ localstore (for account level authorization) or the browser's localStorage (for agent level authorization). When the request call is placed, the access_token variable used in the Authorization value is populated with the stored access token.
For more information, see OAuth. - securityobject
Contains the configuration settings used to establish an encrypted and authenticated connection between the client and the server.
Important: As a best practice, we recommend that you don't hard-code values for these attributes. Instead, provide these values by using app settings.
- castring
The PEM-encoded content of the Certificate Authority (CA) certificate.
- certstring
The PEM-encoded content of the client certificate.
- keystring
The PEM-encoded content of the private key for the client certificate.
- pfxstring
The Base64-encoded string that contains both the certificate and the key.
- passphrasestring
The plain-text password required to decrypt the key or PFX file.
Template substitutions
Template substitutions enable the usage of variables in the <requestTemplateName>.schema attributes. During runtime, depending on where the variables are used, they can be populated by:
- Installation parameter (iparam) values
- Contextual data
- currentHost - endpoint_urls
- Stored access tokens
- App settings
Variable limitations
Variables can be used only in the following <requestTemplateName>.schema attributes. Also, the type of data that can populate the variables varies depending on the attribute in which the variables are used.
| <requestTemplateName>.schema attributes | Type of data that can populate the variables |
|---|---|
| Note:For a detailed description of these schema attributes, see the <requestTemplateName>. | |
| host |
|
| path |
|
| headers (can be used only in <header-value>) |
|
| query |
|
Substitute template variables with iparam values
Use the following syntax to declare a template variable that is populated with iparam values at runtime.
<%= iparam.validIparamName %>variableName must match the context variable name used in the runtime API when invoking the request template. If there is a mismatch in the names, the runtime API call fails.
encode() This function enables encoding secure iparams that are passed as part of the request.
| Syntax | Example |
|---|---|
| <%= encode(iparam.validIparamName) %> | "Authorization": "Bearer <%= encode(iparam.api_key) +':x'>" |
Substitute template variables with contextual data
Use the following syntax to declare a template variable that is populated with contextual data, passed through the runtime API that invokes the request template.
<%= context.variableName %>Important:To construct a dynamic host value that is populated during runtime, though it is possible to retrieve the endpoint_urls through the currentHost data method or from the serverless payload attributes and pass it as contextual data, you should use the currentHost - enpoint_urls template substitution method. For more information on currentHost and endpoint_urls, see Global app concepts.
Substitute template variables with currentHost - endpoint_urls
Use the following syntax to declare a template variable that is populated, at runtime, with the appropriate url of the account (product) on which the app is deployed.
<%= current_host.endpoint_urls.<product_name> %>Note:During local testing, you can navigate to the System settings page and enter the account URLs that are necessary to test your app.
Substitute template variables with access tokens
Use the following syntax to declare a template variable that is populated with an access token value.
<%= access_token %>Note:This variable is used only in <requestTemplateName>.schema.headers.<header_value> to facilitate the app to place an OAuth request call. This variable should be used when <requestTemplateName>.options.oauth is set to the name of the OAuth configuration object defined in the config/oauth_config.json file.
Substitute template variables with app settings values
Use the following syntax to declare a template variable that is populated with the app settings values at runtime.
<%= app_settings.{key} %>File upload using request template New feature
Using request templates, you can upload a file to third-party APIs by simply referencing the files stored in the Object Store. You can configure templates to upload files using multipart/form-data or application/octet-stream.
The uploaded file is referenced by its object store reference identifier in the ref attribute. These files can be directly sent to external endpoints using the invokeTemplate() method.
Notes:All files referenced in the request template must be uploaded to object storage before invoking the request template.
By default, when uploading multiple files, you can upload up to 5 files per request template. You can increase this limit based on your requirements using the following command:
FDK_MAX_PER_REQUEST = 6
You can increase this limit up to 40 files per request template.
FDK_MAX_PER_REQUEST = 40
Retrieve the file reference identifier of the files uploaded to object storage by listing all files. For more information, see the list all files.
Pass the obtained reference identifier in the API request using
- multipart/form-data
- application/octet-stream
multipart/form-data
You can upload a single or multiple files (up to 5) simultaneously to the third-party API. Files are transmitted as multipart/form-data. Under the formData, add the reference identifier as the value of the ref attribute inside the files object as follows:
application/octet-stream
Use this mode to upload one file per request to the third-party API. The file is transmitted as application/octet-stream. Add the reference identifier as the value of the ref attribute inside the file object as follows:
Declare templates
From templates configured in the config/requests.json, in manifest.json, declare the ones that the app code uses, for a specific product.
- From the app’s root directory, navigate to the manifest.json file.
- Under modules.common, use the sample shown in the right pane and create a requests attribute.
Invoke templates
To send an HTTP request to a third-party or Freshworks domain, in the app code, include the invokeTemplate() method. This method serves as a runtime API call. As part of the call, the app can pass a dynamic context and any other data that the template requires.
Navigate to the server.js file and use the syntax in the right pane to include the invokeTemplate() method.
Arguments of invokeTemplate()
requestTemplateName string Mandatory
Identifier of the request template in config/requests.json and the request in manifest.json. The requestTemplateName must be the same in the app code, configuration (config/requests.json), and declaration (manifest.json).An object with the following optional attributes:
- contextobject
All contextual data that the template requires, specified as key-value pairs of <variableName>:<variableValue>. <variableName> must be the same as that used in config/requests.json to receive contextual data.
- bodyobject
Request body.
Response caching: Requests made through the request method are governed by rate limits. To prevent repetitive calls from breaching the rate limits, the request method comes with an opt-in response caching feature, for front-end apps. The cache and ttl options available as part of the invokeTemplate() method, enable browsers to cache the responses that are retrieved from HTTP calls. The responses are cached in the Browser’s local storage. For requests that haven’t changed since the last call, the response is retrieved from the cache. This conserves the app’s rate limits as the number of HTTP requests made are conserved.- cacheboolean
This option is valid only for front-end apps and can be used only with client.request.invokeTemplate(). cache specifies whether a successful response to the HTTP request is cached in the browser’s local storage. The cached response persists in the local storage for a time specified by the ttl value. If no ttl is specified, the response is cached for the default ttl value of 60000 milliseconds.
Possible values: true, false - ttlnumber
This option is valid only for front-end apps, when cache is true, and can be used only with client.request.invokeTemplate(). If cache is true, ttl (time to live) is the duration (specified in milliseconds) for which the response is stored in the cache.
Default value: 60000
- optionsobject
Valid for apps built using platform v3.1 and later.
Information pertaining to the account name of an OAuth-secured resource. The multi-account support for an OAuth-secured resource lets you authorize a particular account when a specific event occurs. To learn more, see OAuth.
- accountobject
Name of the account of an OAuth-secured resource.
Notes:- You can either hard-code the account name or add logic to dynamically retrieve it during runtime.
- If you choose to hard-code the account name, ensure that it matches the account name entered during app installation.
- If you want to dynamically retrieve the account name, one approach is to configure a drop-down in the app UI, which allows users to select an account from a list. To learn more, refer to the code of the OAuth sample app.
Sample code$request.invokeTemplate('clientOauth', { options: { account: 'onedrive_1' } }).then( function (data) { console.log("Onedrive oauth call", data.status); }, function (err) { console.log(err); } );
Response
If the runtime API call results in placing a successful HTTP request, a data object similar to the following sample is returned.
{
"status" : 200,
"headers":
{
"Content-Length": 20,
"Content-Type": "application/json;charset=utf-8"
},
"response": '{ "Name": "Rachel"}'
}- status number
HTTP status code.
- headers object
Additional context about the response, received as an object of valid <headerParameterName>:<headerParameterValue> pairs.
- response string
Data retrieved successfully, through the request method, specified as a string.
The circuit breaker prevents platform-wide impact when certain apps repeatedly fail due to an external API issue.
If an app's API requests repeatedly fail, the platform cuts off further requests after a set threshold and returns a 400 error with the message: Circuit breaker opened due to client error threshold breach. After a pre-defined cool-off period, the platform allows a limited number of test requests to check if the API is functional.
If these test requests succeed, normal traffic resumes.
If these test requests fail, the circuit breaker activates again, and the cycle continues until successful requests restore normal traffic.
This functionality is always enabled for all live Marketplace apps and applies for proxy and request template calls.
Test apps that use request method
In the local testing of apps that use the Request Method to make HTTP requests, you can specify a value for the request timeout.
To configure the request timeout to a suitable value, use the fdk config command to set the request timeout as follows.
| Syntax | Example |
|---|---|
| fdk config set request.timeout <timeout in milliseconds> | fdk config set request.timeout 20000 |
This command adds or updates the request.timeout attribute with the given value in the .fdk/configs.json file of your app.
Important:- The valid values for the timeout are 15000, 20000, 25000, and 30000, with 15000 being the default value.
- If you specify any value for timeout other than these, it defaults to 15 seconds, and a warning message is displayed.
- If you don’t specify a timeout value, it defaults to 15 seconds.
For information on how to test an app that uses the Request method feature, see Test your App.
List of error codes
The following table describes common request method errors, associated status codes, and their details.
| Status | Body (message) | Description |
| 400 | Invalid URL - Must be HTTPS | The request URL must use https; plain HTTP requests are rejected. |
| 400 | Invalid URL - IP is disallowed | The host must be a hostname; connecting using a raw IP address is not allowed. |
| 400 | Invalid URL - Must be FQDN | The host must be a fully qualified domain name (not a bare hostname like api). |
| 400 | Invalid URL - host must not contain protocol | The URL's host segment includes a scheme (for example, https://); separate the scheme and host correctly. |
| 400 | Invalid URL - host must not have path | Path segments were included in the host; use the separate path field (starting with /). |
| 400 | Invalid URL - path must start with / | The path is malformed; paths must begin with /. |
| 400 | This domain has not been whitelisted | IP allowlisting is enabled for the account, but this domain is not on the approved list (or allowlisting is blocking the request). |
| 400 | Error while substituting the templates | A requests.json template variable could not be resolved (missing key, typo, or invalid iparam / context / etc.). |
| 400 | Invalid URL - Redirect to localhost not allowed | The upstream response redirected to localhost or a loopback address; this is blocked for security reasons. |
| 403 | URL not allowed | The domain or URL matches a platform blocklist or policy (disallowed target). |
| 415 | Unsupported content type | The third-party response's Content-Type (media type only, before ;) is not on the platform allowlist. |
| 502 | Error in establishing connection | The proxy could not complete a network connection to the remote host due to DNS, TLS, or connection refusal issues. |
| 504 | Timeout error while processing the request | The outbound request exceeded the configured timeout before a complete response was received. |
| 400 | Response size exceeded maximum limit | The endpoint returned a response larger than the platform allows (response size limit exceeded). |