Quickstart

The speedy guide to generating Optimization solutions.

This Quickstart Guide demonstrates the basics for using Interplai API to create a zone, populate it with locations and vehicles, then trip and execute an optimized route solution.

1.) Create an API key.

An API Key needs to be created before users can begin to use the Interplai API. This is used to identify and authenticate users with their company's account. There are two types: API keys for production, and API keys for development (or testing). The type depends on whether the production or development server will be used for API calls.

To create API keys, users will need to set up an account in the Client Console. Once the user account has been created, API keys can be created by opening the Client Console (either production or development), going to the "Credentials" section, and selecting the "+ Create Credential" button at the top. For support or more information, check out Authentication.

Throughout this quickstart guide, api_url refers to the URL for either production or development environments.



2.) Set up a webhook subscription.

Interplai automatically posts optimization solution updates back to users when webhooks are enabled. Setting up a webhook subscription allows a quick response once a trip is optimized and a suggested solution is ready.

// Create new webhook subscription
const axios = require("axios");

const API_URL = "https://api.interplai.io/v2/";
const API_KEY = "YOUR_API_KEY";

createWebhookSubscription = async function (axios, api_url) {
  let newWebhookSubscription = {
    name: "Optimization Solution Subscription", 
    topic: "optimizationSolution", 
    action: "create",
    callBackUrl: "http://000.000.000.00:13000/optimizationsolutions", // <- replace IP address
  };
  
  let response = await axios.get(api_url + "/webhooksubscriptions");
  let webhookSubscriptions = response.data;
  console.log(webhookSubscriptions, "webhooksub");

  if (webhookSubscriptions.length == 0) {
    response = await axios.post(api_url + "/webhooksubscriptions", newWebhookSubscription);
    console.log(response.data);
  }
  
  return response;
};

Set up a callback endpoint.

// Callback endpoint for Interplai to post Optimization Solutions
callbackEndpoint = async function (axios, api_url, callBackBody) {
  let optimizationSolution = callBackBody.msg;
  console.log("Received new Optimization Solution: ", JSON.stringify(optimizationSolution));
  var result = await acceptOptimizationSolution(optimizationSolution, axios, api_url);
  
  console.log(result);
  
  return result;
};

3.) Define a zone.

In order to direct vehicles to service locations, a geographical region called a zone must be created. Interplai performs route optimization within the context of a zone. A demonstration of parameters for the optimization within the zone is displayed in the code below.

// Create new zone
const axios = require("axios");

const API_URL = "https://api.interplai.io/v2/";
const API_KEY = "YOUR_API_KEY";

// Create new zone
createZone = async function () {
  let newZone = {
    name: "CustomerZone", // <- this is the only required parameter
  };

  let response = await axios.post(API_URL + "/zones", newZone, { headers: { "x-api-key": API_KEY } });
  let zone = response.data;

  console.log("New zone has been created : ", zone);
  return;
};

createZone();

The only required field for creating a zone is the name. For example, the name could be a city or a region. While not specified, the size of a geographical area included in the zone is one of the factors that will affect the optimization time. If a user needs quick, continuous re-optimization they may consider taking a larger, more densely populated city and separating it into smaller regions.

The response for creating the zone is displayed with the code example. Since only the required field of name was included in the creation, and the default parameters are used. Distance fields are in meters, and time fields are in minutes. For details and options regarding these parameters visit Zone.


Use a recipe to guide you through a code example:



4.) Populate locations.

Once a zone has been created, the next step is to add locations. A location is a position in the zone defined by its latitude and longitude coordinates. Every destination that a vehicle may visit must be created, no matter the action performed at that location. An action may include the pickup or drop-off of cargo or people, or it may be a place where a vehicle must visit (such as a gas station). Each location only needs to be created once; in future API calls, a location may be called by its location id.

The following code shows how to create a location inside the zone.

const axios = require("axios");

const API_URL = "https://api.interplai.io/v2/";
const API_KEY = "YOUR_API_KEY";
const ZONE_ID = "637620e9ea9cabe7aae8919c";

// Create new locations
createLocation = async function () {
  let locations = [];
  let newLocation = {
    address: {
      street1: "3675, Waldenwood Dr",
      city: "Ann Arbor",
      stateProvince: "MI",
      postalCode: "48105",
      country: "USA",
    },
    coordinates: { lat: 42.288536, lng: -83.763064 },
    name: "Location1",
    userLocationId: "UserLocation  1",
    phoneNumber: "5556667712",
    allowsTextMessages: true,
    supportsPhoneCalls: true,
    supportsChatMessages: fasle,
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/locations", newLocation, {
    headers: { "x-api-key": API_KEY },
  });
  console.log("New location has been created : ", response.data);

  return locations;
};

createLocation();

New location has been created :
[
  Location_1 = {
    {
    "id": "6374e64b41d3a56e03ec430d",
    "zoneId": "637620e9ea9cabe7aae8919c",
    "name": "Location1",
    "userLocationId": "UserLocation  1",
    "address": {
    "street1": "3675, Waldenwood Dr",
    "city": "Ann Arbor",
    "stateProvince": "MI",
    "postalCode": "48105",
    "country": "USA"
  },
  "coordinates": {
  "lat": 42.288536,
  "lng": -83.763064
  },
    "phoneNumber": "5556667712",
    "allowsTextMessages": true,
    "createdTimestamp": "2022-11-16T13:31:55.078Z",
    "lastUpdatedTimestamp": "2022-11-16T13:31:55.078Z"
  }
]

When a location is created, the only required fields are the lat and lng coordinates. When posting a new location to the server, the zoneId is used in the URL to assign the location to a particular zone. The response gives fills in the optional fields with the default values, as well as gives the time the location was originally created by createdTimestamp and the last time the location was updated by lastUpdatedTimestamp.


Use a recipe to guide you through a code example:



5) Services.

Vehicles can carry a wide variety of services. For instance, the service may include food, groceries, laundry, etc.

The code below displays how service may be individually created.

const axios = require("axios");

const API_URL = "https://dev.api.interplai.io/v2/";
const API_KEY = "YOUR_API_KEY";
const ZONE_ID = "637620e9ea9cabe7aae8919c";

// Create new service
createService = async function () {
  let newService = {
    name: "Laundry",
    userServiceId: "User Service 1",
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/services", newService, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New service has been created : ", response.data);
  return;
};

createService();
New service has been created :
service 1 = {
  "id": "6374ea7e41d3a56e03ec4333",
  "zoneId": "637620e9ea9cabe7aae8919c",
  "name": "Laundry",
  "userServiceId": "User Service 1",
  "createdTimestamp": "2022-11-13T14:17:34.042Z",
  "lastUpdatedTimestamp": "2022-11-13T14:17:34.042Z"
}

6) Enter vehicles.

Any mode of transportation referred to as a vehicle, that may be used to complete a route must be created. When Interplai optimizes a route, it is important to know the current position of each vehicle in order to find the most efficient solution. The geographic coordinate for each vehicle is therefore required upon creation.

The code below displays how a vehicle may be individually created.

const axios = require("axios");

const API_URL = "https://dev.api.interplai.io/v2/";
const API_KEY = "YOUR_API_KEY";
const ZONE_ID = "637620e9ea9cabe7aae8919c";

// Create new vehicles
createVehicle = async function () {
  let newVehicle = {
    dutyMode: "onDuty", // <- required parameter
    capacity: 10,
    fixedCost: 30,
    coordinates: {			// <- required parameter
      lat: 22.673,
      lng: -83.7135,
    },
    userVehicleId: "Vehicle 1",
    speed: 11,
    driverName: "John",
    driverPhoneNumber: "5555777890",
    licensePlateNumber: "A-123-4567-8900",
  };
  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/vehicles", newVehicle, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New vehicle has been created : ", response.data);

  return;
};

createVehicle();
New vehicle has been created : 
vehicle1 = {
  "id": "637620e9ea9cabe7aae8919c",
  "zoneId": "637620e9ea9cabe7aae8919c",
  "userVehicleId": "Vehicle 2",
  "dutyMode": "onDuty",
  "status": "available",
  "speed": 12,
  "capacity": 13,
  "fixedCost": 50,
  "driverName": "Joe",
  "driverPhoneNumber": "5555777890",
  "licensePlateNumber": "A-333-4567-8912",
  "acceptedRouteId": "",
  "coordinates": {
    "lat": 22.2763
    "lng": -83.7135
  },
  "services": [
    {
      "serviceId": "6374ea7e41d3a56e03ec4333"
    }
  ],
  "createdTimestamp": "2022-11-16T14:01:46.226Z",
  "lastUpdatedTimestamp": "2022-11-16T14:01:46.226Z"
}

For Interplai to consider using a vehicle for a task, it must first be categorized as "available". The availability of a vehicle is determined by the dutyMode, a required field, and vehicles that are available to be assigned must be marked as onDuty. Additionally, the initial position of a vehicle is required, given by lat and lng coordinates. This allows Interplai to most efficiently assign vehicles based on proximity to the first waypoint location.

The response displays the expected return for creating the vehicles, where optional parameters are filled with the default values.


Use a recipe to guide you through a code example:



6.) Create a trip for a route.

A trip is an act of asking for a vehicle to be assigned to transport cargo or people. Each trip requires two or more waypoints, where a waypoint is a location and action associated with a route in sequence. For example, if a vehicle is meant to pick up a food order at a restaurant and drop it off to a customer, then the first waypoint includes the location of the restaurant with the action of pickup, and the second waypoint includes the customer's location with the action of dropoff.

The example below displays how a trip may be created.

const axios = require("axios");

const API_URL = "https://dev.api.interplai.io/v2/";
const API_KEY = "YOUR_API_KEY";
const ZONE_ID = "637620e9ea9cabe7aae8919c";

// Create trip
createTrip = async function () {
  let newTrip = {
    userTripId: "UserTripOne",
    routingSceanarioMode: "spsd", // <- required parameter
    maxStopsAllowed: 4,
    waypoints: [				// <- required parameter
      {
        location: {			// <- required parameter
          address: {	  
            street1: "123, Arbor",
            city: "Ann Arbor",
            stateProvince: "MI",
            postalCode: "48103",
            country: "USA",
          },
          coordinates: {		// <- required parameter
            lat: 12.909,
            lng: -89.909,
          },
          name: "Arbor",
          phoneNumber: "5556667777",
          allowsTextMessages: true,
        },
        demand: 0,
        serviceTime: 10,
        handlingSteps: [
          {
            name: "takePhoto",
          },
        ],
        manifestIds: ["6371dbd56a4d823398ee3d02"],
        waypointSequence: 0, // <- required parameter
        handlingInstructions: "Handle with care. ",
        action: "pickup", // <- required parameter
      },
      {
        location: {		 // <- required parameter
          address: {	 // <- required parameter
            street1: "133, WaldenWood St,",
            city: "Ann Arbor",
            stateProvince: "MI",
            postalCode: "48105",
            country: "USA",
          },
          coordinates: {		// <- required parameter
            lat: 43.909,
            lng: -80.909,
          },					
          name: "St Arbor",
          userLocationId: "UserDropOff",
          phoneNumber: "5556667777",
          allowsTextMessages: true,
        },
        demand: 0,
        serviceTime: 0,
        action: "dropoff", // <- required parameter
        waypointSequence: 1, // <- required parameter
      },
    ],
    manifests: [
      {
        items: [			// <- required parameter
          {
            dimensions: {
              length: 6,
              width: 4,
              height: 4,
            },
            name: "Utensils", // <- required parameter
            userManifestItemId: "UserManifestOne",
            description: "Porcelain",
            quantity: 2,
            price: 14,
            weight: 20,
          },
        ],
        id: "6371dbd56a4d823398ee3d02", // <- required parameter
        userManifestId: "FirstManifest",
        totalCost: 30,
        expectedChange: 0,
        paymentType: "prepaid",
        transactionType: "errand",
        currency: "usd",
      },
    ],
   mobileApp: {
         driverPay: {
           basePay: 10,
           peakPay: 12,
           customerTip: 5
       },
        settings: {
           verifyOrderItems: true,
           scanOrderItems: false,
           provideChangetoCustomer: false,
           displayAcceptButton: true,
           displayDeclineButton: false,
           displayTimer: true,
           displayTipText: true,
           displayPartnerDispatchButton: true,
           acceptanceTimeoutDuration: 60
       },
       customerRating: 5,
       customerFeedback: "Good"
     }
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/trips", newTrip, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New trip has been created : ", response);
  return;
};

createTrip();
{
  "id": "637620e9ea9cabe7aae8919c",
  "zoneId": "637620e9ea9cabe7aae8919c",
  "userTripId": "UserTripOne",
  "maxStopsAllowed": 4,
  "optimizationMode": "spsd",
  "optimizationTimeWindow": {
    "startTimestamp": "2022-11-16T14:32:00.000Z",
    "endTimestamp": "2022-11-16T15:32:00.000Z"
  },
  "waypoints": [
    {
      "id": "6374f46041d3a56e03ec43b4",
      "zoneId": "6374e33241d3a56e03ec4301",
      "location": {
        "id": "61b2ebe9a05558022d962fe1",
        "zoneId": "6374e33241d3a56e03ec4301",
        "name": "Arbor",
        "address": {
          "street1": "123, Arbor",
          "city": "Ann Arbor",
          "stateProvince": "MI",
          "postalCode": "48103",
          "country": "USA"
        },
        "coordinates": {
          "lat": 12.909,
          "lng": -89.909
        },
        "phoneNumber": "5556667777",
        "allowsTextMessages": true,
        "createdTimestamp": "2022-11-16T14:32:00.873Z",
        "lastUpdatedTimestamp": "2022-11-16T14:32:00.873Z"
      },
      "action": "pickup",
      "demand": 0,
      "serviceTime": 10,
      "waypointSequence": 0,
      "handlingInstructions": "Handle with care. ",
      "attachments": [],
      "handlingSteps": [
        {
          "name": "takePhoto"
        }
      ],
      "manifestIds": [
        "6371dbd56a4d823398ee3d02"
      ],
      "createdTimestamp": "2022-11-16T14:32:00.890Z",
      "lastUpdatedTimestamp": "2022-11-16T14:32:00.890Z"
    },
    {
      "id": "6374f46041d3a56e03ec43bc",
      "zoneId": "6374e33241d3a56e03ec4301",
      "location": {
        "id": "6371dbd56a5d823398ee3d02",
        "zoneId": "6374e33241d3a56e03ec4301",
        "name": "St Arbor",
        "userLocationId": "UserDropOff",
        "address": {
          "street1": "133, WaldenWood St,",
          "city": "Ann Arbor",
          "stateProvince": "MI",
          "postalCode": "48105",
          "country": "USA"
        },
        "coordinates": {
          "lat": 43.909,
          "lng": -80.909
        },
        "phoneNumber": "5556667777",
        "allowsTextMessages": true,
        "createdTimestamp": "2022-11-16T14:32:00.903Z",
        "lastUpdatedTimestamp": "2022-11-16T14:32:00.903Z"
      },
      "action": "dropoff",
      "demand": 0,
      "serviceTime": 0,
      "waypointSequence": 1,
      "attachments": [],
      "handlingSteps": [],
      "manifestIds": [],
      "createdTimestamp": "2022-11-16T14:32:00.911Z",
      "lastUpdatedTimestamp": "2022-11-16T14:32:00.911Z"
    }
  ],
  "excludedVehicles": [
    {
      "vehicleId": "6370fa7e5ae17c0ad30f5dd0"
    }
  ],
  "services": [
    {
      "serviceId": "6374ea7e41d3a56e03ec4333"
    }
  ],
  "manifests": [
    {
      "manifestId": "6371dbd56a4d823398ee3d02",
      "userManifestId": "FirstManifest",
      "pickupLocationId": "61b2ebe9a05558022d962fe1",
      "dropoffLocationId": "6371dbd56a5d823398ee3d02",
      "items": [
        {
          "manifestItemId": "5371dbd56a4d823398ee3d02",
          "userManifestItemId": "UserManifestOne",
          "name": "Utensils",
          "description": "Cooking utensils",
          "quantity": 2,
          "price": 14,
          "dimensions": {
            "length": 6,
            "width": 4,
            "height": 4
          },
          "weight": 20
        }
      ],
      "totalCost": 30,
      "expectedChange": 0,
      "paymentType": "prepaid",
      "transactionType": "errand",
      "currency": "usd"
    }
  ],
  "createdTimestamp": "2022-11-16T14:32:00.922Z",
  "lastUpdatedTimestamp": "2022-11-16T14:32:00.922Z"
}

Each trip must specify the routingScenarioMode, location, action, and waypoints.

routingScenarioMode: In the example above, spsd represents the scenario of “single pickup and single drop-off” which refers to the scenario where a vehicle will travel to a single pickup location to load the cargo (single pickup) and immediately travel to the drop-off location to unload the cargo (single drop-off) before being assigned other tasks. More information about the various routingScenarioMode options can be found under Usecase Scenarios].

action: The action indicates whether the vehicle will perform a pickup or dropoff at that location. This is to keep track of the vehicle's purpose and capacity.

waypoint: The waypointspecifies where a vehicle should go, what action must be taken at that location, and is positioned in a sequence of other waypoints. The waypoint will consist of two locations a pickup location and a dropoff location and the waypoint sequence can be named accordingly as 0 and 1.

The response for creating the trip is given with the default values for optional parameters.


Use a recipe to guide you through a code example:


7.) Create new request for quote.

The request for quote has to be created in order to fulfill the trips. In this quote document, providers are requested to provide price quotes for a particular trip. With Interplai, this option can be implemented by using the connect-api-keys of the Origin and Destination zones.

The example below displays how a request for quote may be created.

const axios = require("axios");

const API_URL = "INTERPLAI_API_URL";
const X_API_KEY = "YOUR_API_KEY";
const CONNECT_KEY_DEST1 = "DEST1_ZONE_CONNECT_KEY";
const CONNECT_KEY_DEST2 = "DEST2_ZONE_CONNECT_KEY";
const ZONE_ID = "YOUR_ZONE_ID";

createRequestForQuote = async function () {
  try {
    let newRequestForQuote = {
      userRequestForQuoteId: "rfq1",
      trip: {
        userTripId: "Trip-1",
        maxStopsAllowed: 2,
        routingScenarioMode: "spsd",    // <- required parameter
        waypoints: [
          {
            action: "pickup",     // <- required parameter
            location: {						// <- required parameter
              coordinates: {
                lat: 42.33681170950905,
                lng: -71.15153482855031,
              },
              name: "KFC",
              userLocationId: "pickup-location",
              address: {
                street1: "3564 Brighton Circle Road",
                city: "City:  Minneapolis",
                stateProvince: "Minnesota",
                country: "United States",
                postalCode: "55402",
              },
              phoneNumber: "+19999999999",
            },
            serviceTime: 10,
            waypointSequence: 0,      // <- required parameter
          },
          {
            action: "dropoff",      // <- required parameter
            location: {   					// <- required parameter
              coordinates: {
                lng: -71.11154075452369,
                lat: 42.34784451478156,
              },
              name: "Joe",
              userLocationId: "dropoff-location",
              address: {
                street1: "Cottage Farm Historic District",
                city: "Brookline",
                stateProvince: "Minnesota",
                country: "United States",
                postalCode: "55402",
              },
              phoneNumber: "+18888888888",
              supportsTextMessages: true,
            },
            serviceTime: 0,
            waypointSequence: 1,		// <- required parameter
          },
        ],
        transportationProviderPay: {
          currency: "usd",
          customerTip: 2,
        },
      },
    };

    let response = await axios.post(API_URL, +"/zones/" + ZONE_ID + "/rquestforquotes", newRequestForQuote, {
      headers: {
        "x-api-key": X_API_KEY,
        "connect-api-key": CONNECT_KEY_DEST1 + "," + CONNECT_KEY_DEST2,	
      },
    });

    console.log("Request for quote has been created : ", response.data);
    return;
  } catch (err) {
    console.log("createRequestForQuote error : ", err);
  }
};

createRequestForQuote();

connect-api-key: In the above example connect-api-key represents the connect keys of origin and destination zones, which referes to the zones of a requestor and the provider. More information about the connectoptions can be found under Connect Overview.



8.) Create new quote.

The quote document that is received by the requestor from different providers may include information such as taxes, labour costs and other factors influencing final pricing. It also includes the time that will be consumed to complete the trip and the time it will be valid.

The example below displays how a quote may be created.

const axios = require("axios");

const API_URL = "INTERPLAI_API_URL";
const X_API_KEY = "YOUR_API_KEY";
const ZONE_ID = "YOUR_ZONE_ID";
const REQUEST_FOR_QUOTE_ID = "YOUR_REQUEST_FOR_QUOTE_ID";

createQuote = async function () {
  try {
    let newQuote = {
      fee: 10,		// <- required parameter
      currency: "usd",		// <- required parameter
    };

    let response = await axios.post(
      API_URL,
      +"/zones/" + ZONE_ID + "/rquestforquotes/" + REQUEST_FOR_QUOTE_ID + "/quotes",
      newQuote,
      { headers: { "x-api-key": X_API_KEY } }
    );

    console.log("Quote has been created : ", response.data);
    return;
  } catch (err) {
    console.log("createQuote error : ", err);
  }
};

createQuote();

fee :In the example above, the fee is the amount charged by the provider. In addition, the currency in which the fees are charged. It can be any of the values such as USD, VEB, SVC, HNL, NIO, JMD, GTQ.



9.) Update quote action.

As the quote is submitted, it is important to update its action along the way. These actions help Interplai learn and make better optimization solutions. It helps the provider assign the trips.

When a quote is accepted, update the action to Accept.

const axios = require("axios");

const API_URL = "INTERPLAI_API_URL";
const X_API_KEY = "YOUR_API_KEY";
const ZONE_ID = "YOUR_ZONE_ID";
const REQUEST_FOR_QUOTE_ID = "YOUR_REQUEST_FOR_QUOTE_ID";
const QUOTE_ID = "YOUR_QUOTE_ID";
const QUOTE_ACTION = "YOUR_QUOTE_ACTION"; // Takes accept or reject

actionQuote = async function () {
  try {
    let newQuoteAction = {
      quoteId: QUOTE_ID,		// <- required parameter
      action: QUOTE_ACTION,		// <- required parameter
    };

    let response = await axios.post(
      API_URL,
      +"/zones/" + ZONE_ID + "/rquestforquotes/" + REQUEST_FOR_QUOTE_ID + "/quotes/action",
      newQuoteAction,
      { headers: { "x-api-key": X_API_KEY } }
    );

    console.log("Action has been performed on the quote : ", response.data);
    return;
  } catch (err) {
    console.log("actionQuote error : ", err);
  }
};

actionQuote();



10.) Retrieve optimization solutions.

Once a trip is sent to the API server, an optimization solution is created. A optimization solution is the returned result of the optimization. It contains a collection of routes and vehicle assignments based on the parameters included in the trip.

Retrieving an optimization solution can be done in several ways: with a query, Postman, or by setting up a Webhook to receive updates automatically. The code below shows how to retrieve and accept an optimization solution created for a specific zone with a query.

const axios = require("axios");

const API_URL = "https://dev.api.interplai.io/v2/";
const API_KEY = "YOUR_API_KEY";
const ZONE_ID = "637620e9ea9cabe7aae8919c";

getOptimizationSolution = async function () {
  let response = await axios.get(API_URL + "zones/" + ZONE_ID + "/optimizationsolutions", {
    headers: { "x-api-key": API_KEY },
  });
  let optimizationSolutions = response.data;

  console.log("Optimization solutions have been fetched : ", optimizationSolutions);
  return;
};

getOptimizationSolution();

When all the optimization solutions are retrieved, they are returned in descending order. This means the last created solution is given first, followed by the rest of the solutions in order by time.

The return for retrieving the latest optimization solution is displayed in the response tab above. It provides essential information for completing the mobility task. Each trip for which a successful optimization solution was created will appear in the assignedRequests object, with details of that particular solution in the routes object.


Use a recipe to guide you through a code example:



11.) Update waypoint and trip actions.

As a vehicle fulfills the route, it is important to update its actions along the way. These actions help Interplai learn and make better predictions. It helps the optimizer make better assignments based on the information it provides. Updating is also essential for businesses leveraging the Interplai Mobile App as well.

When a vehicle arrives at the first location, update the waypoint action to Arrive.

const axios = require("axios");

const API_URL = "https://dev.api.direct.interplai.io/v2/";
const API_KEY = "YOUR_API_KEY";
const ZONE_ID = "637620e9ea9cabe7aae8919c";
const TRIP_ID = "63762704ea9cabe7aae8938b";
const WAYPOINT_ID = "63762704ea9cabe7aae8938f";

executeWaypointAction = async function () {
  let waypointActions = [
    {
      waypointId: WAYPOINT_ID,
      action: "arrive",
    },
  ];

  let response = await axios.post(
    API_URL + "/zones/" + ZONE_ID + "/trips/" + TRIP_ID + "/waypoints/action",
    waypointActions,
    {
      headers: { "x-api-key": API_KEY },
    }
  );

  console.log("Waypoint action has been executed : ", response.data);
  return;
};

executeWaypointAction();

Next, update the trip action based on the purpose of visiting the waypoint. If a vehicle is picking up cargo, the trip action will be pickup. If cargo is being dropped off, the trip action will be dropoff.

executeTripAction = async function () {
  let tripActions = [
    {
      tripId: TRIP_ID,
      action: "dropoff",
    },
  ];

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/trips/action", tripActions, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("Trip action has been executed : ", response.data);
  return;
};

executeTripAction();

Once the trip action is complete, send a waypoint action todepart the waypoint.

executeWaypointAction = async function () {
  let waypointActions = [
    {
      waypointId: WAYPOINT_ID,
      action: "depart",
    },
  ];

  let response = await axios.post(
    API_URL + "/zones/" + ZONE_ID + "/trips/" + TRIP_ID + "/waypoints/action",
    waypointActions,
    {
      headers: { "x-api-key": API_KEY },
    }
  );

  console.log("Waypoint action has been executed : ", response.data);
  return;
};

executeWaypointAction();


Full Quickstart

// Create new webhook subscription
createWebhookSubscription = async function (axios, api_url) {
  let newWebhookSubscription = {
    name: "Optimization Solution Subscription", 
    topic: "optimizationSolution", 
    callBackUrl: "http://000.000.000.00:13000/optimizationsolutions", // <- replace IP address
  };
  
  let response = await axios.get(api_url + "/webhooksubscriptions");
  let webhookSubscriptions = response.data;
  console.log(webhookSubscriptions, "webhooksub");

  if (webhookSubscriptions.length == 0) {
    response = await axios.post(api_url + "/webhooksubscriptions", newWebhookSubscription);
    console.log(response.data);
  }
  
  return response;
};

// Callback endpoint for Interplai to post Optimization Solutions
callbackEndpoint = async function (axios, api_url, callBackBody) {
  let optimizationSolution = callBackBody.msg;
  console.log("Received new Optimization Solution: ", JSON.stringify(optimizationSolution));
  var result = await acceptOptimizationSolution(optimizationSolution, axios, api_url);
  
  console.log(result);
  
  return result;
};

// Create new zone
createZone = async function () {
  let newZone = {
    name: "CustomerZone", // <- this is the only required parameter
  };

  let response = await axios.post(API_URL + "/zones", newZone, { headers: { "x-api-key": API_KEY } });
  let zone = response.data;

  console.log("New zone has been created : ", zone);
  return;
};

createZone();

// Create new locations
createLocation = async function () {
  let locations = [];
  let newLocation = {
    address: {
      street1: "3675, Waldenwood Dr",
      city: "Ann Arbor",
      stateProvince: "MI",
      postalCode: "48105",
      country: "USA",
    },
    coordinates: { lat: 42.288536, lng: -83.763064 },
    name: "Location1",
    userLocationId: "UserLocation  1",
    phoneNumber: "5556667712",
    allowsTextMessages: true,
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/locations", newLocation, {
    headers: { "x-api-key": API_KEY },
  });
  console.log("New location has been created : ", response.data);

  return locations;
};

createLocation();


// Create new service
createService = async function () {
  let newService = {
    name: "Laundry",
    userServiceId: "User Service 1",
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/services", newService, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New service has been created : ", response.data);
  return;
};

createService();

// Create new vehicle
createVehicle = async function () {
  let newVehicle = {
    dutyMode: "onDuty", // <- required parameter
    capacity: 10,
    fixedCost: 30,
    coordinates: {			// <- required parameter
      lat: 22.673,
      lng: -83.7135,
    },
    userVehicleId: "Vehicle 1",
    speed: 11,
    driverName: "John",
    driverPhoneNumber: "5555777890",
    licensePlateNumber: "A-123-4567-8900",
  };
  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/vehicles", newVehicle, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New vehicle has been created : ", response.data);

  return;
};

createVehicle();

// Create new trip
createTrip = async function () {
  let newTrip = {
    maxStopsAllowed: 4,
    waypoints: [				// <- required parameter
      {
        location: {			// <- required parameter
          address: {	  
            street1: "123, Arbor",
            city: "Ann Arbor",
            stateProvince: "MI",
            postalCode: "48103",
            country: "USA",
          },
          coordinates: {		// <- required parameter
            lat: 12.909,
            lng: -89.909,
          },
          name: "Arbor",
          phoneNumber: "5556667777",
          allowsTextMessages: true,
        },
        demand: 0,
        serviceTime: 10,
        handlingSteps: [
          {
            name: "takePhoto",
          },
        ],
        manifestIds: ["6371dbd56a4d823398ee3d02"],
        waypointSequence: 0, // <- required parameter
        handlingInstructions: "Handle with care. ",
        action: "pickup", // <- required parameter
      },
      {
        location: {		 // <- required parameter
          address: {	 // <- required parameter
            street1: "133, WaldenWood St,",
            city: "Ann Arbor",
            stateProvince: "MI",
            postalCode: "48105",
            country: "USA",
          },
          coordinates: {		// <- required parameter
            lat: 43.909,
            lng: -80.909,
          },					 // <- required parameter
          name: "St Arbor",
          userLocationId: "UserDropOff",
          phoneNumber: "5556667777",
          allowsTextMessages: true,
        },
        demand: 0,
        serviceTime: 0,
        action: "dropoff", // <- required parameter
        waypointSequence: 1, // <- required parameter
      },
    ],
    manifests: [
      {
        items: [
          // <- required parameter
          {
            dimensions: {
              length: 6,
              width: 4,
              height: 4,
            },
            name: "Utensils", // <- required parameter
            userManifestItemId: "UserManifestOne",
            description: "Cooking utensils",
            quantity: 2,
            price: 14,
            weight: 20,
          },
        ],
        id: "6371dbd56a4d823398ee3d02", // <- required parameter
        userManifestId: "FirstManifest",
        totalCost: 30,
        expectedChange: 0,
        paymentType: "prepaid",
        transactionType: "errand",
        currency: "usd",
      },
    ],
    userTripId: "UserTripOne",
    routingScenarioMode: "spsd", // <- required parameter
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/trips", newTrip, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New trip has been created : ", response);
  return;
};

createTrip();

// Review the contents of the Optimization Solution and accept desired routes and/or segements

getOptimizationSolution = async function () {
  let response = await axios.get(API_URL + "zones/" + ZONE_ID + "/optimizationsolutions", {
    headers: { "x-api-key": API_KEY },
  });
  let optimizationSolutions = response.data;

  console.log("Optimization solutions have been fetched : ", optimizationSolutions);
  return;
};

getOptimizationSolution();


runQuickstart = async function () {
  await createWebhookSubscription(axios, api_url);
  let zone = await createZone(axios, api_url);
  let locations = await createLocations(zone, axios, api_url);
  await createVehicles(zone, axios, api_url);
  let tripData = await createTrip(zone, locations, axios, api_url);
};

runQuickstart();
  
// Create new webhook subscription
createWebhookSubscription = async function (axios, api_url) {
  let newWebhookSubscription = {
    name: "Optimization Solution Subscription", 
    topic: "optimizationSolution", 
    callBackUrl: "http://000.000.000.00:13000/optimizationsolutions", // <- replace IP address
  };
  
  let response = await axios.get(api_url + "/webhooksubscriptions");
  let webhookSubscriptions = response.data;
  console.log(webhookSubscriptions, "webhooksub");

  if (webhookSubscriptions.length == 0) {
    response = await axios.post(api_url + "/webhooksubscriptions", newWebhookSubscription);
    console.log(response.data);
  }
  
  return response;
};

// Callback endpoint for Interplai to post Optimization Solutions
callbackEndpoint = async function (axios, api_url, callBackBody) {
  let optimizationSolution = callBackBody.msg;
  console.log("Received new Optimization Solution: ", JSON.stringify(optimizationSolution));
  var result = await acceptOptimizationSolution(optimizationSolution, axios, api_url);
  
  console.log(result);
  
  return result;
};

// Create new zone
createZone = async function () {
  let newZone = {
    name: "CustomerZone", // <- this is the only required parameter
  };

  let response = await axios.post(API_URL + "/zones", newZone, { headers: { "x-api-key": API_KEY } });
  let zone = response.data;

  console.log("New zone has been created : ", zone);
  return;
};

createZone();

// Create new locations
createLocation = async function () {
  let locations = [];
  let newLocation = {
    address: {
      street1: "3675, Waldenwood Dr",
      city: "Ann Arbor",
      stateProvince: "MI",
      postalCode: "48105",
      country: "USA",
    },
    coordinates: { lat: 42.288536, lng: -83.763064 },
    name: "Location1",
    userLocationId: "UserLocation  1",
    phoneNumber: "5556667712",
    allowsTextMessages: true,
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/locations", newLocation, {
    headers: { "x-api-key": API_KEY },
  });
  console.log("New location has been created : ", response.data);

  return locations;
};

createLocation();


// Create new service
createService = async function () {
  let newService = {
    name: "Laundry",
    userServiceId: "User Service 1",
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/services", newService, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New service has been created : ", response.data);
  return;
};

createService();

// Create new vehicle
createVehicle = async function () {
  let newVehicle = {
    dutyMode: "onDuty", // <- required parameter
    capacity: 10,
    fixedCost: 30,
    coordinates: {			// <- required parameter
      lat: 22.673,
      lng: -83.7135,
    },
    userVehicleId: "Vehicle 1",
    speed: 11,
    driverName: "John",
    driverPhoneNumber: "5555777890",
    licensePlateNumber: "A-123-4567-8900",
  };
  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/vehicles", newVehicle, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New vehicle has been created : ", response.data);

  return;
};

createVehicle();

// Create new trip
createTrip = async function () {
  let newTrip = {
    maxStopsAllowed: 4,
    waypoints: [				// <- required parameter
      {
        location: {			// <- required parameter
          address: {	  
            street1: "123, Arbor",
            city: "Ann Arbor",
            stateProvince: "MI",
            postalCode: "48103",
            country: "USA",
          },
          coordinates: {		// <- required parameter
            lat: 12.909,
            lng: -89.909,
          },
          name: "Arbor",
          phoneNumber: "5556667777",
          allowsTextMessages: true,
        },
        demand: 0,
        serviceTime: 10,
        handlingSteps: [
          {
            name: "takePhoto",
          },
        ],
        manifestIds: ["6371dbd56a4d823398ee3d02"],
        waypointSequence: 0, // <- required parameter
        handlingInstructions: "Handle with care. ",
        action: "pickup", // <- required parameter
      },
      {
        location: {		 // <- required parameter
          address: {	 // <- required parameter
            street1: "133, WaldenWood St,",
            city: "Ann Arbor",
            stateProvince: "MI",
            postalCode: "48105",
            country: "USA",
          },
          coordinates: {		// <- required parameter
            lat: 43.909,
            lng: -80.909,
          },					 // <- required parameter
          name: "St Arbor",
          userLocationId: "UserDropOff",
          phoneNumber: "5556667777",
          allowsTextMessages: true,
        },
        demand: 0,
        serviceTime: 0,
        action: "dropoff", // <- required parameter
        waypointSequence: 1, // <- required parameter
      },
    ],
    manifests: [
      {
        items: [
          // <- required parameter
          {
            dimensions: {
              length: 6,
              width: 4,
              height: 4,
            },
            name: "Utensils", // <- required parameter
            userManifestItemId: "UserManifestOne",
            description: "Cooking utensils",
            quantity: 2,
            price: 14,
            weight: 20,
          },
        ],
        id: "6371dbd56a4d823398ee3d02", // <- required parameter
        userManifestId: "FirstManifest",
        totalCost: 30,
        expectedChange: 0,
        paymentType: "prepaid",
        transactionType: "errand",
        currency: "usd",
      },
    ],
    userTripId: "UserTripOne",
    routingScenarioMode: "spsd", // <- required parameter
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/trips", newTrip, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New trip has been created : ", response);
  return;
};

createTrip();

// Review the contents of the Optimization Solution and accept desired routes and/or segements

getOptimizationSolution = async function () {
  let response = await axios.get(API_URL + "zones/" + ZONE_ID + "/optimizationsolutions", {
    headers: { "x-api-key": API_KEY },
  });
  let optimizationSolutions = response.data;

  console.log("Optimization solutions have been fetched : ", optimizationSolutions);
  return;
};

getOptimizationSolution();


runQuickstart = async function () {
  await createWebhookSubscription(axios, api_url);
  let zone = await createZone(axios, api_url);
  let locations = await createLocations(zone, axios, api_url);
  await createVehicles(zone, axios, api_url);
  let tripData = await createTrip(zone, locations, axios, api_url);
};

runQuickstart();
  
// Create new webhook subscription
createWebhookSubscription = async function (axios, api_url) {
  let newWebhookSubscription = {
    name: "Optimization Solution Subscription", 
    topic: "optimizationSolution", 
    callBackUrl: "http://000.000.000.00:13000/optimizationsolutions", // <- replace IP address
  };
  
  let response = await axios.get(api_url + "/webhooksubscriptions");
  let webhookSubscriptions = response.data;
  console.log(webhookSubscriptions, "webhooksub");

  if (webhookSubscriptions.length == 0) {
    response = await axios.post(api_url + "/webhooksubscriptions", newWebhookSubscription);
    console.log(response.data);
  }
  
  return response;
};

// Callback endpoint for Interplai to post Optimization Solutions
callbackEndpoint = async function (axios, api_url, callBackBody) {
  let optimizationSolution = callBackBody.msg;
  console.log("Received new Optimization Solution: ", JSON.stringify(optimizationSolution));
  var result = await acceptOptimizationSolution(optimizationSolution, axios, api_url);
  
  console.log(result);
  
  return result;
};

// Create new zone
createZone = async function () {
  let newZone = {
    name: "CustomerZone", // <- this is the only required parameter
  };

  let response = await axios.post(API_URL + "/zones", newZone, { headers: { "x-api-key": API_KEY } });
  let zone = response.data;

  console.log("New zone has been created : ", zone);
  return;
};

createZone();

// Create new locations
createLocation = async function () {
  let locations = [];
  let newLocation = {
    address: {
      street1: "3675, Waldenwood Dr",
      city: "Ann Arbor",
      stateProvince: "MI",
      postalCode: "48105",
      country: "USA",
    },
    coordinates: { lat: 42.288536, lng: -83.763064 },
    name: "Location1",
    userLocationId: "UserLocation  1",
    phoneNumber: "5556667712",
    allowsTextMessages: true,
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/locations", newLocation, {
    headers: { "x-api-key": API_KEY },
  });
  console.log("New location has been created : ", response.data);

  return locations;
};

createLocation();


// Create new service
createService = async function () {
  let newService = {
    name: "Laundry",
    userServiceId: "User Service 1",
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/services", newService, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New service has been created : ", response.data);
  return;
};

createService();

// Create new vehicle
createVehicle = async function () {
  let newVehicle = {
    dutyMode: "onDuty", // <- required parameter
    capacity: 10,
    fixedCost: 30,
    coordinates: {			// <- required parameter
      lat: 22.673,
      lng: -83.7135,
    },
    userVehicleId: "Vehicle 1",
    speed: 11,
    driverName: "John",
    driverPhoneNumber: "5555777890",
    licensePlateNumber: "A-123-4567-8900",
  };
  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/vehicles", newVehicle, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New vehicle has been created : ", response.data);

  return;
};

createVehicle();

// Create new trip
createTrip = async function () {
  let newTrip = {
    maxStopsAllowed: 4,
    waypoints: [				// <- required parameter
      {
        location: {			// <- required parameter
          address: {	  
            street1: "123, Arbor",
            city: "Ann Arbor",
            stateProvince: "MI",
            postalCode: "48103",
            country: "USA",
          },
          coordinates: {		// <- required parameter
            lat: 12.909,
            lng: -89.909,
          },
          name: "Arbor",
          phoneNumber: "5556667777",
          allowsTextMessages: true,
        },
        demand: 0,
        serviceTime: 10,
        handlingSteps: [
          {
            name: "takePhoto",
          },
        ],
        manifestIds: ["6371dbd56a4d823398ee3d02"],
        waypointSequence: 0, // <- required parameter
        handlingInstructions: "Handle with care. ",
        action: "pickup", // <- required parameter
      },
      {
        location: {		 // <- required parameter
          address: {	 // <- required parameter
            street1: "133, WaldenWood St,",
            city: "Ann Arbor",
            stateProvince: "MI",
            postalCode: "48105",
            country: "USA",
          },
          coordinates: {		// <- required parameter
            lat: 43.909,
            lng: -80.909,
          },					 // <- required parameter
          name: "St Arbor",
          userLocationId: "UserDropOff",
          phoneNumber: "5556667777",
          allowsTextMessages: true,
        },
        demand: 0,
        serviceTime: 0,
        action: "dropoff", // <- required parameter
        waypointSequence: 1, // <- required parameter
      },
    ],
    manifests: [
      {
        items: [
          // <- required parameter
          {
            dimensions: {
              length: 6,
              width: 4,
              height: 4,
            },
            name: "Utensils", // <- required parameter
            userManifestItemId: "UserManifestOne",
            description: "Cooking utensils",
            quantity: 2,
            price: 14,
            weight: 20,
          },
        ],
        id: "6371dbd56a4d823398ee3d02", // <- required parameter
        userManifestId: "FirstManifest",
        totalCost: 30,
        expectedChange: 0,
        paymentType: "prepaid",
        transactionType: "errand",
        currency: "usd",
      },
    ],
    userTripId: "UserTripOne",
    routingScenarioMode: "spsd", // <- required parameter
  };

  let response = await axios.post(API_URL + "/zones/" + ZONE_ID + "/trips", newTrip, {
    headers: { "x-api-key": API_KEY },
  });

  console.log("New trip has been created : ", response);
  return;
};

createTrip();

// Review the contents of the Optimization Solution and accept desired routes and/or segements

getOptimizationSolution = async function () {
  let response = await axios.get(API_URL + "zones/" + ZONE_ID + "/optimizationsolutions", {
    headers: { "x-api-key": API_KEY },
  });
  let optimizationSolutions = response.data;

  console.log("Optimization solutions have been fetched : ", optimizationSolutions);
  return;
};

getOptimizationSolution();


runQuickstart = async function () {
  await createWebhookSubscription(axios, api_url);
  let zone = await createZone(axios, api_url);
  let locations = await createLocations(zone, axios, api_url);
  await createVehicles(zone, axios, api_url);
  let tripData = await createTrip(zone, locations, axios, api_url);
};

runQuickstart();