How to get access to Visiwise API

Last Update on January 28, 2024  

API URL: https://www.visiwise.co/api-graphql/
Also, there is an interactive playground to test the API which includes the API documentation on itself.
Visiwise API Playground

To access the API you need to be authorized using Authorization HTTP header like this Authorization: Token <YourAPIToken>.

To get API access send an email to [email protected].

Introduction to the Shipment and Tracking

Currently, in Visiwise, three tracking types are supported which are Container, BL, and Booking.
So to track a reference, three fields should be provided:

  • Tracking reference
  • Shipping line name that carries the reference
  • Tracking type (Container/BL/Booking)

After request to track, an object would be created based on the tracking type, which will be ContainerTracking, BLTracking, or BookingTracking. These objects have all the information about the tracked reference (like arrival time, route, location, vessel, …).

The access way to different tracking types and other Visiwise features on tracking (like automatic email notifications for tracking updates, …) is a model called Shipment. The Shipment model is on top of the ContainerTracking, BLTracking, or BookingTracking models:

class Shipment {
  containerTracking: ContainerTracking
  blTracking: BLTracking
  bookingTracking: BookingTracking
  emailNotification: Boolean # indicates that shipment notification is turned on or not.
  ...
}

TLDR: To track a reference, a shipment should be created and it can be used to get tracking information and other features like email notification.

How to track a reference (Container/BL/Booking)?

  1. Create Shipment using tracking reference and its shipping line and tracking type (Container/BL/Booking).
  2. Get created shipment and polling tracking result using shipment id returned in the previous step.

Let’s start by creating a shipment, we want to track container DFSU7162007 from MSC shipping line (the list of the available shipping lines is accessible with the keyname field of AvailableShippingLines query. ). We should execute the createShipment mutation like below:

Query

mutation CreateShipment($createShipmentInput: CreateShipmentInput!) {
  createShipment(createShipmentInput: $createShipmentInput) {
    createdShipment {
      id
    }
  }
}

Variables

{
  "createShipmentInput": {
    "trackingInput": {
      "trackingReference": "DFSU7162007",
      "shippingLine": "MSC", // IMPORTANT: use the keyname field (not name) from AvailableShippingLines query
      "trackingType": "ContainerTracking"
    },
    "withTracking": true
  }
}

Response

{
  "data": {
    "createShipment": {
      "createdShipment": {
        "id": "U2hpcG1lbnRUeXBlOjE="
      }
    }
  }
}

Now, we use id in the response to get the shipment and its tracking information using shipment query.

Query

query Shipment($shipmentId: ID!) {
  shipment(id: $shipmentId) {
    id
    trackingReference
    containerTracking {
      id
      trackStatus {
        status
        exception
      }
    }
    blTracking {
      id
      trackStatus {
        status
        exception
      }
    }
    bookingTracking {
      id
      trackStatus {
        status
        exception
      }
    }
  }
}

Variables

{
  "shipmentId": "U2hpcG1lbnRUeXBlOjE=" // shipmentId is the id returend in createShipment mutation
}

Response

{
  "data": {
    "shipment": {
      "id": "U2hpcG1lbnRUeXBlOjE=",
      "trackingReference": "DFSU7162007",
      "containerTracking": {
        "id": "Q29udGFpbmVyVHJhY2tpbmdUeXBlOjE=",
        "trackStatus": {
          "status": "Is-Tracking", // this indicates that the tracking process is going on.
          "exception": null // have value if the tracking status be Track-Failed
        },
        "shippingLine": {
          "name": "MSC",
          "keyname": "msc"
        },
        "carriage": null // no tracking result yet.
      },
      "blTracking": null,
      "bookingTracking": null
    }
  }
}

Now, the response shows that shipment.containerTracking.trackStatus.status value is Is-Tracking which means Visiwise server is getting the information, and the tracking process is not completed yet, usually, it takes about 20-30 seconds to be resolved. We should retry in a specific interval (for example every 5 seconds) until the track status changes to Track-Succeeded or Track-Failed.
More details about trackStatus

Pseudo-code for handling the trackStatus:

trackStatus = "Is-Tracking";

while (trackStatus == "Is-Tracking") {
  shipment = executeShipmentQuery(shipmentId);
  trackStatus = shipment.containerTracking.trackStatus.status;

  sleep(3000); // 3 seconds
}

if(trackStatus == "Track-Failed") {
  // handle track failed case
  print("There was a problem in tracking: " + trackStatus.exception);

} else if(trackStatus == "Track-Succeeded") {
  print("Hooray! container will be arrived at " + shipment.containerTracking.carriage.arrivalTime);
}

Response (after tracking has been succeeded)

{
  "data": {
    "shipment": {
      "id": "U2hpcG1lbnRUeXBlOjE=",
      "trackingReference": "DFSU7162007",
      "containerTracking": {
        "id": "Q29udGFpbmVyVHJhY2tpbmdUeXBlOjE=",
        "trackStatus": {
          "status": "Track-Succeeded", // this indicates that the tracking process completed successfully.
          "exception": null
        },
        "shippingLine": {
          "name": "MSC",
          "keyname": "msc"
        },
        "carriage": {
          "arrivalTime": "2021-03-04T09:24:00+00:00",
          "status": "Container was gated out from Toamasina on March 10, 2021, 11:30 a.m. ",
          "route": {
            "fromPort": {
              "name": "Port Klang"
            },
            "toPort": {
              "name": "Toamasina"
            }
          }
        }
      },
      "blTracking": null,
      "bookingTracking": null
    }
  }
}

How to update a shipment and its tracking?

  1. Request to update Shipment and its tracking result by executing updateShipment mutation with shipment.id.
  2. Get shipment data by executing shipment query with shipment.id.

First, we execute the updateShipment mutation to initiate the updating process.

Query

mutation UpdateShipment($shipmentId: ID!) {
  updateShipment(shipmentId: $shipmentId) {
    success
  }
}

Variables

{
  "shipmentId": "U2hpcG1lbnRUeXBlOjE="
}

Response

{
  "data": {
    "updateShipment": {
      "success": true
    }
  }
}

This mutation will set the trackStatus.status of the shipments tracking to Is-Tracking.
You can use the previous section logic to get tracking and shipment information.

trackStatus behaviour detail

The status field in trackStatus can have four different values depending on the state of the container tracking.

  • Is-Tracking: Already being tracked by servers.
  • Track-Succeeded: track successfully completed.
  • Track-Failed: track failed with a trackStatus.exception error
  • Not-Started: the track is not started at the moment or was succeeded previously.

After the server completely updated a tracking, the trackStatus.status would change from Is-Tracking to Track-Succeeded or Track-Failed.

Track-Failed status would provide the client an exception, message, and remainingLockTime which is useful for error handling.

How to track a Bill of Lading (BL)

The BLTracking model has a containers field which is a list of ContainerTracking objects:

class BLTracking {
  trackStatus: TrackStatus
  containers: [ContainerTracking]
  # ... BL result data
}

1. Create a shipment with BL reference

Query

mutation CreateShipment($createShipmentInput: CreateShipmentInput!) {
  createShipment(createShipmentInput: $createShipmentInput) {
    createdShipment {
      id
    }
  }
}

Variables

{
  "createShipmentInput": {
    "trackingInput": {
      "trackingReference": "HLCUSS5201107911",
      "shippingLine": "Hapag-Lloyd",
      "trackingType": "BLTracking"
    },
    "withTracking": true
  }
}

2. Retrive a shipment with BL tracking information

Query

query Shipment($shipmentId: ID!) {
  shipment(id: $shipmentId) {
    id
    trackingReference
    blTracking {
      number
      lastSuccessfulTrackTime
      trackStatus {
        status
      }
      shippingLine {
        name
      }
      placeOfReceipt {
        name
      }
      portOfLoading {
        name
      }
      portOfDischarge {
        name
      }
      placeOfDelivery {
        name
      }
      containers {
        id
        number
        trackStatus {
          status
        }
        carriage {
          arrivalTime
        }
      }
    }
  }
}

Variables

{
  "shipmentId": "U2hpcG1lbnRUeXBlOjE="
}

An example object of blTracking
For example, this BL has two Containers.

{
  "data": {
    "shipment": {
      "id": "U2hpcG1lbnRUeXBlOjE=",
      "trackingReference": "HLCUSS5201107911",
      "blTracking": {
        "number": "HLCUSS5201107911",
        "lastSuccessfulTrackTime": "2021-03-28T09:46:26.428725+00:00",
        "trackStatus": {
          "status": "Track-Succeeded",
        },
        "shippingLine": {
          "name": "Hapag-Lloyd",
        },
        "placeOfReceipt": null,
        "portOfLoading": {
          "name": "Santos"
        },
        "portOfDischarge": {
          "name": "Dar-es-salaam"
        },
        "placeOfDelivery": null,
        "containers": [
          {
            "id": "Q29udGFpbmVyVHJhY2tpbmdUeXBlOjI=",
            "number": "HLXU3476420",
            "trackStatus": {
              "status": "Track-Succeeded",
            },
            "carriage": {
              "arrivalTime": "2021-03-26T18:54:00+00:00"
            }
          },
          {
            "id": "Q29udGFpbmVyVHJhY2tpbmdUeXBlOjM=",
            "number": "HLXU3253576",
            "trackStatus": {
              "status": "Track-Succeeded",
            },
            "carriage": {
              "arrivalTime": "2021-03-26T18:54:00+00:00"
            }
          },
        ]
      }
    }
  }
}

How to get available shipping lines

If you want to use a certain shipping line that is not supported by Visiwise, Don’t hesitate to contact us.

Query

query AvailableShippingLines {
  containerTrackingAvailableLines {
    name
    keyname
  }
  bookingTrackingAvailableLines {
    name
    keyname
  }
  blTrackingAvailableLines {
    name
    keyname
  }
}

Response

{
  "data": {
    "containerTrackingAvailableLines": [
      { "name": "ACL", "keyname": "ACL" },
      { "name": "ANL", "keyname": "ANL" },
      { "name": "APL", "keyname": "APL" },
      { "name": "CMA CGM", "keyname": "CMA-CGM" },
      { "name": "CNC", "keyname": "CNC" },
      { "name": "COSCO", "keyname": "COSCO" },
      { "name": "CULines", "keyname": "CULINES" },
      { "name": "Evergreen", "keyname": "EVERGREEN" },
      { "name": "Gold Star", "keyname": "GOLD-STAR" },
      { "name": "Grimaldi", "keyname": "GRIMALDI" },
      { "name": "Hamburg Sud", "keyname": "HAMBURG-SUD" },
      { "name": "Hapag-Lloyd", "keyname": "HAPAG-LLOYD" },
      { "name": "HMM", "keyname": "HMM" },
      { "name": "KMTC", "keyname": "KMTC" },
      { "name": "Maersk", "keyname": "MAERSK" },
      { "name": "Matson", "keyname": "MATSON" },
      { "name": "Messina", "keyname": "MESSINA" },
      { "name": "MSC", "keyname": "MSC" },
      { "name": "Namsung", "keyname": "NAMSUNG" },
      { "name": "One", "keyname": "ONE" },
      { "name": "OOCL", "keyname": "OOCL" },
      { "name": "PIL", "keyname": "PIL" },
      { "name": "Safmarine", "keyname": "SAFMARINE" },
      { "name": "SCI", "keyname": "SCI" },
      { "name": "Sealand", "keyname": "SEALAND" },
      { "name": "Seth Shipping", "keyname": "SETH-SHIPPING" },
      { "name": "SM Line", "keyname": "SM-LINE" },
      { "name": "Turkon", "keyname": "TURKON" },
      { "name": "Wan Hai", "keyname": "WAN-HAI" },
      { "name": "WEC Lines", "keyname": "WEC-LINES" },
      { "name": "Yang Ming", "keyname": "YANG-MING" },
      { "name": "ZIM", "keyname": "ZIM" }
    ],
    "bookingTrackingAvailableLines": [
      { "name": "ACL", "keyname": "ACL" },
      { "name": "ANL", "keyname": "ANL" },
      { "name": "APL", "keyname": "APL" },
      { "name": "CMA CGM", "keyname": "CMA-CGM" },
      { "name": "CNC", "keyname": "CNC" },
      { "name": "COSCO", "keyname": "COSCO" },
      { "name": "CULines", "keyname": "CULINES" },
      { "name": "Evergreen", "keyname": "EVERGREEN" },
      { "name": "Gold Star", "keyname": "GOLD-STAR" },
      { "name": "Grimaldi", "keyname": "GRIMALDI" },
      { "name": "Hamburg Sud", "keyname": "HAMBURG-SUD" },
      { "name": "Hapag-Lloyd", "keyname": "HAPAG-LLOYD" },
      { "name": "HMM", "keyname": "HMM" },
      { "name": "KMTC", "keyname": "KMTC" },
      { "name": "Maersk", "keyname": "MAERSK" },
      { "name": "Matson", "keyname": "MATSON" },
      { "name": "MSC", "keyname": "MSC" },
      { "name": "Namsung", "keyname": "NAMSUNG" },
      { "name": "One", "keyname": "ONE" },
      { "name": "OOCL", "keyname": "OOCL" },
      { "name": "PIL", "keyname": "PIL" },
      { "name": "Safmarine", "keyname": "SAFMARINE" },
      { "name": "Sealand", "keyname": "SEALAND" },
      { "name": "Seth Shipping", "keyname": "SETH-SHIPPING" },
      { "name": "SM Line", "keyname": "SM-LINE" },
      { "name": "Turkon", "keyname": "TURKON" },
      { "name": "Wan Hai", "keyname": "WAN-HAI" },
      { "name": "Yang Ming", "keyname": "YANG-MING" },
      { "name": "ZIM", "keyname": "ZIM" }
    ],
    "blTrackingAvailableLines": [
      { "name": "ACL", "keyname": "ACL" },
      { "name": "ANL", "keyname": "ANL" },
      { "name": "APL", "keyname": "APL" },
      { "name": "CMA CGM", "keyname": "CMA-CGM" },
      { "name": "CNC", "keyname": "CNC" },
      { "name": "COSCO", "keyname": "COSCO" },
      { "name": "CULines", "keyname": "CULINES" },
      { "name": "Evergreen", "keyname": "EVERGREEN" },
      { "name": "Gold Star", "keyname": "GOLD-STAR" },
      { "name": "Grimaldi", "keyname": "GRIMALDI" },
      { "name": "Hamburg Sud", "keyname": "HAMBURG-SUD" },
      { "name": "Hapag-Lloyd", "keyname": "HAPAG-LLOYD" },
      { "name": "HMM", "keyname": "HMM" },
      { "name": "KMTC", "keyname": "KMTC" },
      { "name": "Maersk", "keyname": "MAERSK" },
      { "name": "Matson", "keyname": "MATSON" },
      { "name": "MSC", "keyname": "MSC" },
      { "name": "Namsung", "keyname": "NAMSUNG" },
      { "name": "One", "keyname": "ONE" },
      { "name": "OOCL", "keyname": "OOCL" },
      { "name": "PIL", "keyname": "PIL" },
      { "name": "Safmarine", "keyname": "SAFMARINE" },
      { "name": "Sealand", "keyname": "SEALAND" },
      { "name": "Seth Shipping", "keyname": "SETH-SHIPPING" },
      { "name": "SM Line", "keyname": "SM-LINE" },
      { "name": "Turkon", "keyname": "TURKON" },
      { "name": "Wan Hai", "keyname": "WAN-HAI" },
      { "name": "WEC Lines", "keyname": "WEC-LINES" },
      { "name": "Yang Ming", "keyname": "YANG-MING" },
      { "name": "ZIM", "keyname": "ZIM" }
    ]
  }
}

Shipment tags

Shipment tags enable the categorization and labeling of shipments with custom tags. These tags provide a way to add additional information or attributes to shipments for easier organization and filtering.

Get shipment tags

This query allows you to retrieve the tags associated with a specific shipment. You need to provide the shipmentId as a variable to get the relevant information.

Query

query Shipment($shipmentId: ID!) {
    shipment(id: $shipmentId) {
        id
        tags {
            name
        }
    }
}

Variables

{
    "shipmentId": "U2hpcG1lbnRUeXBlOjE="
}

Response

{
    "data": {
        "shipment": {
            "id": "U2hpcG1lbnRUeXBlOjE=",
            "tags": [
                {
                    "name": "Export"
                }
            ]
        }
    }
}

The response returns the shipment associated tags. In this example, the shipment has one tag named "Export".

Get all created tags

With this query, you can retrieve all the previously created tags by the user. It returns an array of tag names.

Query

query UserShipmentTags { 
    userShipmentTags {
        name
    }
}

Response

{
    "data": {
        "userShipmentTags": [
            {
                "name": "Export"
            },
            {
                "name": "Import"
            }
        ]
    }
}

The response provides a list of all the user-created shipment tags. In this example, the response includes two tags: "Export" and "Import".

Add new tags to a shipment

By using this mutation, you can add a new tag or list of tags to a shipment. You need to provide the shipmentId and the tags as variables. The response will include the updated list of tags associated with the shipment.

Mutation

mutation AddShipmentTag($shipmentId: ID!, $tags: [String]!) {
    addShipmentTag(shipmentId: $shipmentId, tags: $tags) {
        tags {
            name
        }
    }
}

Variables

{
    "shipmentId": "U2hpcG1lbnRUeXBlOjE=",
    "tags": [
        "Unspecified"
    ]
}

Response

{
    "data": {
        "addShipmentTag": {
            "tags": [
                {
                    "name": "Export"
                },
                {
                    "name": "Unspecified"
                }
            ]
        }
    }
}

The response confirms the addition of a new tag to the shipment. It includes the updated list of tags associated with the shipment, which now includes the newly added tag.

Remove tags from a shipment

This mutation enables you to remove a tag or list of tags from a shipment. You need to provide the shipmentId and the tags to be removed as variables. The response will include the updated list of tags associated with the shipment after the removal.

Mutation

mutation RemoveShipmentTag($shipmentId: ID!, $tags: [String]!) {
    removeShipmentTag(shipmentId: $shipmentId, tags: $tags) {
        tags {
            name
        }
    }
}

Variables

{
    "shipmentId": "U2hpcG1lbnRUeXBlOjE=",
    "tags": [
        "Export"
    ]
}

Response

{
    "data": {
        "removeShipmentTag": {
            "tags": [
                {
                    "name": "Unspecified"
                }
            ]
        }
    }
}

The response confirms the removal of a tag from the shipment and provides the updated list of remaining tags. In this example, the removed tag is "Export," and the remaining tag is "Unspecified".

Exploring available variables and values

You can use Visiwise API Playground to explore available variables and values and type of them.

  1. Go to Visiwise API Playground; on top right of the page click on the "Docs" button.

  2. A sidebar will be opened. You can see available query/mutations and explore them.

In example above, you can find which data is available in containerTracking query.

Support and contact information

Email address: [email protected]