API Request Block

The API Request Block allows you to make API calls within a dataflow. You can configure it by specifying the HTTP method, API endpoint, headers, query, body, and path parameters. The methods supported are GET, POST, PUT, DELETE, and PATCH.

You can use the API Request Block to invoke the private APIs. When you use this block, ensure that you use the endpoints https://{host_name}/das/getUserDetails.

Example Scenario

Requirement
Consider a scenario where, during the creation of a dataflow, you need to retrieve customer details using the Get Customer Details API.

Solution
You can add an API Request Block with the following details.

  • Method: GET
  • URL: https://{host}/v2/customers/lookup/customerDetails
  • Query Parameters:
    • Key: embed
    • Value: points, mlp

Configuring the API Request Block

To configure the API Request block, perform the following:

  1. From the dataflow canvas, click on the connector.
  2. Select the API Request block from the pop-up window.
  3. In the Block name section, enter the block name.
    Note: Block names cannot contain spaces or special characters, except for underscores (_). Use camelCase or snake_case formatting.
  4. In the Method section, select a method from the drop-down menu. The available methods are GET, POST, PUT, DELETE, and PATCH.
  5. In the URL section, enter the API URL.
    Syntax: https://{host}/{URL} Example: https://{host}/v2/customers/lookup/customerDetails
  6. In the Query Parameters section, enter the key and its corresponding value. The entries into the Key and the Value fields depend on the API parameters.
    Example: For the API endpoint https://{host}/v2/customers/lookup/customerDetails, some of the query parameters are source, embed, and identifierName. The query parameters are set as Key, and their corresponding values are provided as Value. Consider the parameter embed. Some possible values for embed are points, subscriptions, and mlp. So, if the Key is embed, the Value can be points, subscriptions, or mlp.
  7. If applicable, in the Path Parameters section, enter the Key and its corresponding Value . The entries into the Key and the Value fields depend on the API parameters.
    Example: For the API endpoint, https://{host}/api_gateway/loyalty/v1/programs/{programs}/promotions/{promotions}/get, the path parameters are program and promotion. Here, program and promotion are set as Key, and their respective values should be provided in the Value section.
  8. If applicable, in the Headers section, enter the Key and its corresponding Value. For more information on headers, see Header Management in Neo.
  9. Configure the input execution logic, cachable feature, and define the execution path as per the requirement.
  10. Click Done.
Configuring API Request block

Configuring API Request block

Header Management in Neo

Request headers are key-value pairs in an HTTP request that provide essential information about the request context. They help the server understand how to process the request and respond appropriately.

Below is a list of headers available in Neo. Additionally, you can create custom headers according to your requirements.

KeyDescriptionPossible Values & Default ValueModifiable in the dataflow
Content-TypeThe Content-Type header specifies the format of the request or response body. It tells the server or client how to process the transmitted data.Default: application/jsonYes
Accept-EncodingThe Accept-Encoding header informs the server about the compression methods supported by the client. This helps reduce the response size and speeds up data transfer.Default: gzip, deflate, brNo
User-AgentThe User-Agent header identifies the API client for the server. It helps the server customize responses based on the client’s software, operating system, or device type.Default: neoNo
ReferrerA header that indicates the source of a request. It helps Neo identify where the request originates.URL of the Neo dataflow that is triggered.No
AuthorizationApplicable for API requests that come directly from POS terminal to the Capillary Server. The Authorization header value is constructed using the below format: Basic <Base64 encoded (username:md5(password))>If the incoming request to the dataflow includes a value, Neo sets the header with that value. If no value is provided, the header is excluded.Modifiable in a hierarchical organization using the OrgContextSwitch block to switch the dataflow execution context from the parent organization to the child organization.
x-cap-api-oauth-tokenA custom authentication header for Capillary internal APIs. Applicable for POS server-to-server integration, FTP server-to-server integration, Server-to-server custom integration and Prebuilt server-to-server integrations. OAuth token generated using the API key and secret.If the incoming request to the dataflow includes a value, Neo sets the header with that value. If no value is provided, the header is excluded.Modifiable in a hierarchical organization using the OrgContextSwitch block to switch the dataflow execution context from the parent organization to the child organization.
x-cap-api-auth-keyA custom authentication header for Capillary internal APIs. It adds an extra security layer to verify API requests and ensures that only authorized clients can access Capillary’s services.If the incoming request to the dataflow includes a value, Neo sets the header with that value. If no value is provided, the header is excluded.Modifiable in a hierarchical organization using the OrgContextSwitch block to switch the dataflow execution context from the parent organization to the child organization.
x-cap-api-auth-org-idA custom authentication header for Capillary internal APIs. It identifies the organization making the API request.If the incoming request to the dataflow includes a value, Neo sets the header with that value. If no value is provided, the header is excluded.Modifiable in a hierarchical organization using the OrgContextSwitch block to switch the dataflow execution context from the parent organization to the child organization.
x-cap-neo-block-log-levelA custom header for Capillary internal APIs that defines the log level for the Neo platform, similar to the logger in the Script block. Logs are generated according to the specified level.debug, info, warn, error <br>Default: DebugYes
x-cap-neo-debug-enabledA custom header for Capillary internal APIs, when set to true, captures platform logs from all services processing the request, not just Neo.True or false <br>Default: FalseYes <br><br>You can also use the Dev Console to set or change the value of this header.
x-cap-neo-dag-scopeA custom header in Capillary’s Neo platform that defines the scope of execution.Org, global, parent <br>Default: orgYes
x-cap-api-attribution-entity-codeA custom header for Capillary internal APIs used to specify the code associated with a particular entity type.If the value is in the incoming request, Neo uses it. If not, Neo ignores it. However, setting a value in the block properties overrides the request value.Yes
x-cap-api-attribution-entity-typeA custom header for Capillary internal APIs that specifies the type of entity posting the data.If the value is in the incoming request, Neo uses it. If not, Neo ignores it. However, setting a value in the block properties overrides the request value.Yes
x-cap-request-idA custom header that uniquely identifies each request. The system uses this header for tracking and logging. This is applicable for Capillary internal APIs.If the value is in the incoming request, Neo uses it. If not, Neo ignores it. However, setting a value in the block properties overrides the request value.Yes
x-cap-direct-replayA custom header that determines whether the system processes the request synchronously or asynchronously. This is applicable for Capillary internal APIs.If the value is in the incoming request, Neo uses it. If not, Neo ignores it. However, setting a value in the block properties overrides the request value.Yes
x-cap-neo-slaA custom header to route non-critical or long-running requests to a separate instance optimised for lower-priority processing, ensuring they do not interfere with high-priority, real-time traffic.no-slaYes

Handling Bulk API Call Errors

When Neo executes multiple APIs in a single request, it handles the error as follows:

  • If any individual call fails, the respective API Request Block's response displays "msg": "failed" .
  • Neo continues executing the remaining calls and collects all responses, including the successful ones.

Below is a sample response when Neo executes multiple APIs in a single request.

{
  "api1Output": "1234fjefenjkrfknj4rvjkn",
  "api2Output": {
    "code": 500,
    "message": "{\"code\":500,\"message\":\"UNKNOWN EXCEPTION\",\"err\":\"TypeError: Cannot set properties of undefined (setting 'x-cap-neo-error-msg')\"}",
    "err": {
      "message": "{\"code\":500,\"message\":\"UNKNOWN EXCEPTION\",\"err\":\"TypeError: Cannot set properties of undefined (setting 'x-cap-neo-error-msg')\"}"
    }
  },
  "api3Output": "1234fjefenjkrfknj4rvjkn",
  "msg": "failed"
}

Explanation

  • api1Output, api2Output, and api3Output are the names of the individual API calls.
  • api1Output and api3Output contains successful responses.
  • api2Output contains a 500 error response with detailed metadata.

The msg field shows the overall status. It reads "failed" because api2Output failed.

Using Private APIs

You can use the API Request block to invoke private APIs. To use the output in subsequent blocks, add a Script block after the API Request block and use the DAO function getOut() to retrieve the response.

Example use case

Requirement
Retrieve a customer's expired points using the private API getExpiredPointsByCustomerIdAndYear, and transform the data into a cleaned-up, format with only the fields customerId, year, earned, and expired from the output, which is in an array format.

Solution
Add a Script block after the API Request block. Use the DAO function getOut() to extract the output from the API Request block, then transform the array into the required summarised format.

Below is a sample script from the Script block to achieve the same.

import dao from "neo/dao";
import logger from "neo/logger";
//These are some dao methods already imported.
//Other methods on dao you can use by typing `dao.` and editor will suggest few available methods.
const {
    getBody,
    getEffectiveHeaders,
    getIn,
    getApiRequest,
    getOut,
} = dao;




const script = {


    execute: () => {
      var payload = dao.getOut();
      logger.info("test"+JSON.stringify(payload));
      //return payload;
      //logger.info(JSON.stringify(payload, null, 2));
        //Write your code here.
      const result =  transformPointsData(payload);
      logger.info(JSON.stringify(result, null, 2));
      return {
              "http": {
                   "res": {
                       "json": result,
                       "status": 200
                   }
               }
 }
    }
}


/**
 * Transforms an array of point-earning records into a summarized format.
 *
 * @param {Array<Object>} inputData The array of original point records.
 * @returns {Array<Object>} The array of transformed objects.
 */
function transformPointsData(inputData) {
  // Get the current year to compare against the creation year.
  const currentYear = new Date().getFullYear();


  // Use the map function to iterate over each item and transform it.
  return inputData.map(item => {
    // Create a Date object from the timestamp (which is in milliseconds).
    const createdDate = new Date(item.created_on);
    const createdYear = createdDate.getFullYear();


    // Determine the value for 'expired'. If the points were earned in the
    // current year, 0 points have expired. Otherwise, all earned points
    // are considered expired for this transformation.
    const expiredPoints = (currentYear === createdYear) ? 0 : item.earned;


    // Return the new object with the desired structure and keys.
    return {
      customerId: item.customer_id, // Renaming 'customer_id' to 'customerId'
      year: createdYear,
      earned: item.earned,
      expired: expiredPoints
    };
  });
}


export {
    script as default
}