Webhook 1: Job Tracking Statuses

The InstaLeap Job Tracking Webhook provides a simple way to track all the changes of the jobs you created. Remember that a webhook works like a reverse API and you would have to provide a POST URL in which our systems are going to notify the changes.

Why?

In some steps of the fulfillment process, InstaLeap and your systems would need to communicate and react to certain changes. For example, to confirm the payment of the order and unblock a picker.

You can add up to 3 Webhooks to receive Job Notifications.

Events

Events are composed by type (take a look at the request payload), id, and job.

Event types

InstaLeap webhooks events have different types, that allow you to identify why the job has changed. They are also differentiated by category. The possible categories and their event types are:

Job-level events

  • CREATED
  • CANCELLED
  • RESCHEDULED
  • REFUSED
  • ALLOCATED
  • RE_ALLOCATED
  • EXTERNAL_DATA_UPDATED
  • STORE_CHANGED
  • JOB_COMMENT_UPDATED

Picking process

  • ITEMS_UPDATED
  • PACKAGES_CREATED
  • PACKAGES_UPDATED

Invoicing process

  • INVOICE_UPDATED
  • PRICES_UPDATED
  • PAYMENT_UPDATED

Steps & Tasks

Steps

  • GOING_TO_ORIGIN_STARTED
  • ARRIVED_TO_ORIGIN
  • PICKING_STARTED
  • PICKING_FINISHED
  • CHECKING_OUT_STARTED
  • CHECKED_OUT
  • TRANSFERRING_STARTED
  • TRANSFERRED
  • GOING_TO_DESTINATION_STARTED
  • ARRIVED_TO_DESTINATION
  • DELIVERING_STARTED
  • CLIENT_RECEIVED
  • STORING_STARTED
  • STORING_UPDATED
  • STORING_FINISHED

Zone Picking Steps:

  • ZONE_PICKING_STARTED
  • ZONE_PICKING_FINISHED
  • PARKING_STARTED
  • PARKING_FINISHED

Consolidation Steps:

  • PICKING_STARTED
  • PICKING_FINISHED
  • CHECKING_OUT_STARTED
  • CHECKED_OUT
  • STORING_STARTED
  • STORING_FINISHED

Tasks

  • PICKING
  • DELIVERY
  • FULL_SERVICE
  • STORAGE
  • PICKING_WITH_STORAGE
  • PICK_UP
  • DELIVERY_WITH_STORAGE
  • PICK_UP_FOR_DELIVERY
  • PICKING_AND_STORAGE
  • ZONE_PICKING
  • CONSOLIDATION

Tasks resets per operational models

  • Full Service
    TASK_RESET_FULL_SERVICE
  • Pick & Collect
    TASK_RESET_PICK_UP
    TASK_RESET_PICKING_WITH_STORAGE
  • Pick & Collect no transfer
    TASK_RESET_PICKING_AND_STORAGE
    TASK_RESET_PICK_UP
  • Pick & Delivery
    TASK_RESET_PICKING
    TASK_RESET_DELIVERY
  • Pick & Delivery with storage
    TASK_RESET_PICKING_WITH_STORAGE
    TASK_RESET_STORAGE
    TASK_RESET_PICK_UP_FOR_DELIVERY
    TASK_RESET_DELIVERY_WITH_STORAGE
  • Pick & Delivery with storage no transfer
    TASK_RESET_PICKING_AND_STORAGE
    TASK_RESET_PICK_UP_FOR_DELIVERY
    TASK_RESET_DELIVERY_WITH_STORAGE

Authentication

In order to protect your systems from external attacks, InstaLeap signs the webhook events it sends to your endpoints. We do so by including a signature in each event’s InstaLeap-Signature header. We have different security options that you can select to recognize where the events come from:

👍

Where Instaleap implement this auth?

The same auth type is going to be used for the following modules:

  • Status Webhooks events
  • Chat Webhooks
  • Replacements Search
  • Stock query

1. Security Instaleap signature:

This allows you to verify that the events were sent by InstaLeap, not by a third party. You can verify signatures using standard libraries such as crypto for NodeJS. The hash algorithm used is SHA-256 and it is hashed with a secret provided to you by InstaLeap for each environment.

How to check the signature?

To verify that the InstaLeap-Signature is valid, please follow these steps:

  1. Once you receive the request, create a string joining id, created_at, and type by an & character from the event payload.
  2. Hash the string with the secret provided to you, using an SHA-256 algorithm.
  3. Compare the resulting hash with the InstaLeap-Signature header.
  4. If the signature is correct, process the event in your system.

2. Static token:

To implement this type of authentication you should send two requirements:

  • Header: The header name where you want us to send the auth token.
  • Token: The static token that you want us to send to your services to perform the auth.

3. DynamicToken:

To implement this type of authentication we need the below requirements:

  • RenewURL: The URL where we should request new dynamic tokens.
  • Credentials: The credentials we should send to the renewURL to retrieve new dynamic tokens. This can be headers and body credentials depending on your auth server.
  • formatOfCredentials: The format in which we should send the credentials to the renewURL. It can be JSON or formData.
  • Response: The details of the response we will receive from auth server. The status code expected, the body expected, and the field name of the body where the dynamic token is located.

For DynamicToken we recommend you send us a Postman collection tested and work with his auth server to make things easier.

📘

formatOfCredentials - DynamicToken

We only support these formats:
• JSON
• formData
• urlEncoded

🚧

Added by

Explains who added the item into the job. Usual values are CLIENT, PICKER, ISSUE, AGENT, or CONTROL_TOWER

🚧

Job cancelled

CANCELLED event has a field called cancellationSource and the options could be CUSTOMER or CONTROL_TOWER

{
  "id": "5bf7128e-c481-48fe-86fa-d0d52282dde8",
  "created_at": "2023-06-02T15:42:44Z",
  "type": "ALLOCATED",
  "client_id": "CLIENT_NAME",
  "job": {
    "id": "c495056f-5154-4ab7-ab81-55f38b923b36",
    "status": "PROCESSING",
    “source”: “HEADLESS_ECOMMERCE_ANDROID”,
    "cancellation_source": “string”,
    "client_reference": "0000AG382N",
    "declared_value": 403.967,
    "payment_value": 403.97,
    "payment_method": "PREPAID",
    "operational_model": "FULL_SERVICE",
    "external_data": {},
    "slot": {
      "id": "4cdeed0e-a97a-49fe-99ac-1213d779e498",
      "from": "2023-06-02T12:00:00.000Z",
      "to": "2023-06-02T12:59:00.000Z",
      "expires_at": "2023-06-02T08:09:37.729Z"
    },
    "recipient": {
      "name": "Guillermo",
      "email": "[email protected]",
      "phone_number": "+52 2342342",
      "identification": {
        "iv": "3XqaWR5LR/p2Fge0SkqEgA==",
        "encrypted_data": "+lcgaUpnsNRt9RrOAlcu2Q=="
      }
    },
    "origin": {
      "name": "Super Xilotzingo",
      "address": "Boulevard Mexicano",
      "address_two": "",
      "description": "Cluster D",
      "country": "Mexico",
      "city": "Heroica Puebla de Zaragoza",
      "state": "",
      "zip_code": "",
      "latitude": 19.323232,
      "longitude": -78.323232,
      "store_reference": "391"
    },
    "destination": {
      "name": "Xilotzingo",
      "address": "Xilotzingo ",
      "address_two": "casa",
      "description": "casa",
      "country": "Mexico",
      "city": "Puebla",
      "state": "Puebla",
      "zip_code": "5576",
      "latitude": 18.24332423,
      "longitude": -98.2014662772417
    },
    "job_items": [
      {
        "id": "00020100700000",
        "name": "Chuleta de cerdo   por kilo",
        "status": "PENDING",
        "replacements": [],
        "is_substitute": false,
        "added_by": "CLIENT",
        "photo_url": "https://res.cloudinary.com/00020100700000L.jpg",
        "found_quantity": 0,
        "comment": "",
        "barcodes": [
          "201007000004"
        ],
        "package_name": null,
        "package_reference": null,
        "scanned_barcode": "",
        "replacement_mode": "SUGGESTED",
        "suggested_replaments": [“218648191212”],
        “lot”: ”string”,
        “picking_task_id”: string | null,
        “replacing_to”: any[],
        "attributes": {
          "ean": "201007000004",
          "sku": "00020100700000",
          "category": "Carne de cerdo",
          "posPrice": 97,
          "product_id": "148650",
          "originalPrice": 97
        },
        "quantity": 0.6,
        "sub_quantity": 1,
        "unit": "KG",
        "sub_unit": "KG",
        "price": 97,
        "weight": 1,
        "volume": 1
      },
      {
        "id": "00020100600000",
        "name": "Costilla de cerdo   por kilo",
        "status": "PENDING",
        "replacements": [],
        "is_substitute": false,
        "added_by": "CLIENT",
        "photo_url": "https://res.cloudinary.com/00020100600000L.jpg",
        "found_quantity": 0,
        "comment": "",
        "barcodes": [
          "201006000005"
        ],
        "package_name": null,
        "package_reference": null,
        "scanned_barcode": "",
        "replacement_mode": "SUGGESTED",
        "suggested_replaments": [“218648191212”],
        “lot”: ”string”,
        "attributes": {
          "ean": "201006000005",
          "sku": "00020100600000",
          "category": "Carne de cerdo",
          "posPrice": 127,
          "product_id": "148649",
          "originalPrice": 127
        },
        "quantity": 0.5,
        "sub_quantity": 1,
        "unit": "KG",
        "sub_unit": "KG",
        "price": 127,
        "weight": 1,
        "volume": 1
      },
      {
        "id": "00750045900015",
        "name": "Detergente en polvo Persil  universal 4.5 kg",
        "status": "PENDING",
        "replacements": [],
        "is_substitute": false,
        "added_by": "CLIENT",
        "photo_url": "https://res.cloudinary.com/00750045900015L.jpg",
        "found_quantity": 0,
        "comment": "",
        "barcodes": [
          "7500459000154"
        ],
        "package_name": null,
        "package_reference": null,
        "scanned_barcode": "",
        "replacement_mode": "NO_REPLACE",
        "suggested_replaments": [“218648191212”],
        "attributes": {
          "ean": "7500459000154",
          "sku": "00750045900015",
          "category": "Artículos de lavandería",
          "posPrice": 130,
          "product_id": "147128",
          "originalPrice": 130
        },
        "quantity": 2,
        "sub_quantity": 2,
        "unit": "pz",
        "sub_unit": "pz",
        "price": 130,
        "weight": 1,
        "volume": 1
      }
    ],
    "packages": [],
    "payment_info": {
      "prices": {
        "taxes": 0,
        "subtotal": 403.97,
        "discounts": 0,
        "order_value": 403.97,
        "shipping_fee": 0,
        "attributes": [],
        "additional_info": []
      },
      "invoice": null,
      "payment": {
        "id": null,
        "method": "PREPAID",
        "reference": null,
        "method_details": "PREPAGO",
        "blocking_policy": "EXIT_STORE",
        "payment_status_details": null,
        "payment_status": null,
        "value": 0,
        "metadata": null
      },
      "currency_code": "MXN"
    },
    "cancellation_source": null,
    "volume": 0,
    "weight": 0,
    "issue_of": null,
    "tasks": [
      {
        "id": "0c924f7f-be05-4c3c-944b-0e7c684876bf",
        "type": "FULL_SERVICE",
        "resource_id": "848d8f80-4eca-48d5-b6f3-6be778a0d3b2",
        "resource": {
          "dni": "11111111",
          "phone_number": "+549221499011",
          "email": "nico.pruebas@@.com",
          "first_name": "Nico",
          "last_name": "Pruebas",
          "fleet_id": "CLIENT_NAME",
          "id": "848d8f80-4eca-48d5-b6f3-6be778a0d3b2",
          "photo_url": "https://instaleap.s3.amazonaws.com/user-placeholder.png",
          "client_id": "CLIENT_NAME",
          "last_update_position": "2022-12-30T21:45:30.061Z",
          "position": {
            "longitude": -74.072092,
            "latitude": 4.710989
          },
          "vehicle": {
            "client_id": "CLIENT_NAME",
            "id": "0af1bd84-dc05-4479-a04c-114c87c788c2",
            "label": "Auto"
          }
        },
        "status": "DOING",
        "steps": [
          {
            "id": "8ea16d51-0370-4b8b-96b6-845b42a180df",
            "type": "GOING_TO_ORIGIN",
            "status": "DOING",
            "optimal_start": "2023-06-02T11:09:00.000Z",
            "optimal_end": "2023-06-02T11:24:00.000Z",
            "actual_start": "2023-06-02T15:42:44.389Z",
            "actual_end": ""
          },
          {
            "id": "dfb16037-2342-4b05-848c-2aff8a8de496",
            "type": "PICKING",
            "status": "PENDING",
            "optimal_start": "2023-06-02T11:24:00.000Z",
            "optimal_end": "2023-06-02T11:38:00.000Z",
            "actual_start": "",
            "actual_end": ""
          },
          {
            "id": "8571a529-4003-47d1-9520-36cf17cbc622",
            "type": "CHECKING_OUT",
            "status": "PENDING",
            "optimal_start": "2023-06-02T11:38:00.000Z",
            "optimal_end": "2023-06-02T11:45:00.000Z",
            "actual_start": "",
            "actual_end": ""
          },
          {
            "id": "63195375-5685-4fe6-9dbb-91ab8144cad6",
            "type": "GOING_TO_DESTINATION",
            "status": "PENDING",
            "optimal_start": "2023-06-02T11:45:00.000Z",
            "optimal_end": "2023-06-02T11:51:00.000Z",
            "actual_start": "",
            "actual_end": ""
          },
          {
            "id": "4f765940-e095-4a95-9bbd-62190a52179a",
            "type": "DELIVERING",
            "status": "PENDING",
            "optimal_start": "2023-06-02T11:51:00.000Z",
            "optimal_end": "2023-06-02T11:56:00.000Z",
            "actual_start": "",
            "actual_end": ""
          }
        ]
      }
    ],
    "original_prices": {
      "payment_value": 403.97,
      "shipping_fee": 0,
      "discounts": 0,
      "subtotal": 403.97,
      "taxes": 0
    },
    "updated_prices": {
      "payment_value": 403.97,
      "shipping_fee": 0,
      "discounts": 0,
      "subtotal": 403.97,
      "taxes": 0
    },
    "delivery_code": "9320",
    "created_at": "2023-06-02T07:55:01.582Z"
  }
}


Language
Click Try It! to start a request and see the response here!