Skip to main content

Track a List of Containers

This tutorial guides you through the process of tracking a list of shipments using the Visiwise API. You can use a container number, a bill of lading, or a booking number to start tracking. By the end of this guide, you will be able to submit a shipment import and retrieve consolidated tracking data from multiple sources, including carriers, AIS, terminals, and railways.

Here are the steps you will follow:

  1. Get your Visiwise API Key.
  2. Authenticate your API requests.
  3. Prepare a list of containers & shipments to track.
  4. Submit your list to create a shipment import.
  5. Check the status of the import.
  6. Retrieve the detailed tracking information for your shipments.

Step 1: Get Your Visiwise API Key

To begin, you need to get your Visiwise API Key from your account dashboard by following the instructions in the Authentication section.

Step 2: Authenticate Your API Requests

The Visiwise API uses token-based authentication. To authenticate your requests, you must include your API Key in the Authorization header as a Bearer token.

Here is an example of an authenticated request using cURL:

curl -X GET "https://www.visiwise.co/api/v1/shipments/" \
-H "Authorization: Bearer YOUR_VISIWISE_API_KEY"

Understanding Tracking Identifiers

Before you submit a request, it's helpful to understand the different ways you can identify a shipment. You can use a container number, bill_of_lading number, or booking number.

  • A Container number is a unique identifier physically marked on the container itself.
  • A Bill of Lading or Booking number is a document number issued by a carrier. A single bill of lading or booking can include multiple containers.

Tracking by container number is easy and direct, but it's important to know that containers are reused. A single container number could have multiple past journeys. For example, a container might complete a journey from Shanghai to New York, and a few days later, be assigned to a new journey from New York to Hamburg. If you track only by its number, you might see data from a previous trip.

tip

To ensure you are tracking the correct, current journey, we recommend using the bill of lading number or booking number whenever possible. This links the container to a specific voyage.

Step 3: Prepare Your Tracking Data

To start tracking, you need to create a list of objects. Each object represents a single Shipment Request and tells Visiwise what to track.

Here are the fields for each shipment request object:

Field NameRequiredTypeExampleDescription
referenceYesString"order-984572"Your unique internal identifier for this shipment. You can use this reference later to retrieve tracking information.
tracking_numberYesString"DFSU7162007"The number you want to track.
tracking_typeYesString"container"The type of number provided. Must be one of container, bill_of_lading, or booking.
carrier_scacYesString"AUTO"The SCAC code for the shipping line. If tracking_type is container, you can set this to "AUTO" to let Visiwise detect the carrier automatically.
nameNoString"Machine Parts"A friendly name for this shipment. If a shipment with the same reference already exists, this will update its name.

Let's prepare a sample list in Python with 5 containers and 3 bills of lading.

shipments_to_track = [
# Tracking via Container Number (Auto-detecting carrier)
{
"reference": "ref-C001",
"tracking_number": "MRKU4398344",
"tracking_type": "container",
"carrier_scac": "AUTO",
"name": "Electronics Shipment"
},
# Tracking via Container Number (Specifying carrier)
{
"reference": "ref-C002",
"tracking_number": "DFSU7162007",
"tracking_type": "container",
"carrier_scac": "MSCU",
"name": "Auto Parts"
},
{
"reference": "ref-C003",
"tracking_number": "TTNU8871655",
"tracking_type": "container",
"carrier_scac": "ONEY",
"name": "Textiles"
},
{
"reference": "ref-C004",
"tracking_number": "MAGU5231120",
"tracking_type": "container",
"carrier_scac": "OOLU",
"name": "Frozen Goods"
},
{
"reference": "ref-C005",
"tracking_number": "SMCU1188845",
"tracking_type": "container",
"carrier_scac": "SMLM",
"name": "Furniture"
},
# Tracking via Bill of Lading
{
"reference": "ref-B001",
"tracking_number": "MEDUOO753422",
"tracking_type": "bill_of_lading",
"carrier_scac": "MSCU",
"name": "Industrial Machinery"
},
{
"reference": "ref-B002",
"tracking_number": "258496299",
"tracking_type": "bill_of_lading",
"carrier_scac": "MAEU",
"name": "Pharmaceuticals"
},
{
"reference": "ref-B003",
"tracking_number": "NJEX5H314200",
"tracking_type": "bill_of_lading",
"carrier_scac": "SMLM",
"name": "Retail Apparel"
}
]

Step 4: Start a Shipment Import

Now that you have your list, you can send it to Visiwise. You do this by making a POST request to the /v1/shipments/imports endpoint. This creates a job that will process all your shipment requests.

The API will respond immediately with a ShipmentRequestBatch object, which includes a unique id. You will use this id in the next step to check the status of your import.

import requests
import json

BASE_URL = "https://www.visiwise.co"
API_KEY = "YOUR_VISIWISE_API_KEY"

headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}

url = f"{BASE_URL}/api/v1/shipments/imports"
response = requests.post(url, headers=headers, data=json.dumps(shipments_to_track, indent=2))

if response.status_code == 202:
shipment_request_batch = response.json()
batch_id = shipment_request_batch["id"]
print(f"Successfully created shipment request batch with ID: {batch_id}")
print(json.dumps(shipment_request_batch, indent=2))
else:
print(f"Error: {response.status_code}")
print(response.text)

Sample Response

The API will return a batch object with a status of processing.

{
"id": "71fb1be9-c191-4372-b881-d111ec65d93d",
"status": "processing",
"created_at": "2025-09-15T14:28:10.531Z",
"results": [
{
"id": "422b3486-7250-4984-afd2-cde9bea2e367",
"reference": "ref-C002",
"tracking_type": "container",
"tracking_number": "DFSU7162007",
"carrier_scac": "MSCU",
"creation_status": "created",
"tracking_status": "processing",
"shipment_id": "17a56f91-88b0-48a2-bbee-7e07e3a0c0da",
"name": "Auto Parts",
...
},
...
]
}
See the API Reference for the complete response schema.

Step 5: Check the Import Status

Because tracking can take some time, the process is asynchronous. You need to periodically check the status of the batch until it changes from processing to completed. You can do this by making a GET request to /v1/shipments/imports/{batch_id}.

This script checks the status every 15 seconds until the batch is complete.

import time

# Assume 'batch_id' is from the previous step
url_status = f"{BASE_URL}/api/v1/shipments/imports/{batch_id}"

while True:
response = requests.get(url_status, headers=headers)
shipment_request_batch_result = response.json()
status = shipment_request_batch_result.get("status")

print(f"Current batch status: {status} ({shipment_request_batch_result.get('completed_requests')}/{shipment_request_batch_result.get('total_requests')} completed)")

if status != "processing":
print("Batch processing finished.")
print(json.dumps(shipment_request_batch_result, indent=2))
break

time.sleep(15)

Sample Response

Once all requests are processed, the status will update to completed.

{
"id": "71fb1be9-c191-4372-b881-d111ec65d93d",
"status": "completed",
"created_at": "2025-09-15T14:28:10.531Z",
"results": [
{
"id": "422b3486-7250-4984-afd2-cde9bea2e367",
"reference": "ref-C002",
"tracking_type": "container",
"tracking_number": "DFSU7162007",
"carrier_scac": "MSCU",
"creation_status": "created",
"tracking_status": "succeeded",
"shipment_id": "17a56f91-88b0-48a2-bbee-7e07e3a0c0da",
"name": "Auto Parts",
...
},
...
]
}
See the API Reference for the complete response schema.

Step 6: Retrieve Shipment Details

After the batch status is completed, you can retrieve the detailed tracking information for all shipments created in that batch. To do this, you make a GET request to the /v1/shipments/ endpoint and filter the results using the batch_id as a query parameter.

# Assume 'batch_id' is from the previous steps
url = f"{BASE_URL}/api/v1/shipments/"
params = {
"batch_id": batch_id
}

response = requests.get(url, headers=headers, params=params)
shipments = response.json().get("data")

print(f"Retrieved {len(shipments)} shipments for batch {batch_id}:")
print(json.dumps(shipments, indent=2))

Sample Response

The response will be a paginated list of Shipment objects, each containing comprehensive tracking data from all available sources.

{
"data": [
{
"id": "17a56f91-88b0-48a2-bbee-7e07e3a0c0da",
"reference": "ref-C002",
"tracking_number": "DFSU7162007",
"tracking_type": "container",
"carrier_scac": "MSCU",
"last_process_status": "track_succeeded",
"last_process_failure_reason": null,
"data_status": "success",
"container_stage": null,
"custom_fields": {},
"tracking": {
"tracking_freshness": "ok",
"pre": {
...
},
"pol": {
...
},
"pod": {
...
},
"pde": {
...
},
"containers_uri": "/api/v1/shipment/17a56f91-88b0-48a2-bbee-7e07e3a0c0da/containers",
...
}
},
...
],
"pagination": {
...
}
}
See the API Reference for the complete response schema.

Final Example Code

shipments_to_track = [
# Tracking via Container Number (Auto-detecting carrier)
{
"reference": "ref-C001",
"tracking_number": "MRKU4398344",
"tracking_type": "container",
"carrier_scac": "AUTO",
"name": "Electronics Shipment"
},
# Tracking via Container Number (Specifying carrier)
{
"reference": "ref-C002",
"tracking_number": "DFSU7162007",
"tracking_type": "container",
"carrier_scac": "MSCU",
"name": "Auto Parts"
},
{
"reference": "ref-C003",
"tracking_number": "TTNU8871655",
"tracking_type": "container",
"carrier_scac": "ONEY",
"name": "Textiles"
},
{
"reference": "ref-C004",
"tracking_number": "MAGU5231120",
"tracking_type": "container",
"carrier_scac": "OOLU",
"name": "Frozen Goods"
},
{
"reference": "ref-C005",
"tracking_number": "SMCU1188845",
"tracking_type": "container",
"carrier_scac": "SMLM",
"name": "Furniture"
},
# Tracking via Bill of Lading
{
"reference": "ref-B001",
"tracking_number": "MEDUOO753422",
"tracking_type": "bill_of_lading",
"carrier_scac": "MSCU",
"name": "Industrial Machinery"
},
{
"reference": "ref-B002",
"tracking_number": "258496299",
"tracking_type": "bill_of_lading",
"carrier_scac": "MAEU",
"name": "Pharmaceuticals"
},
{
"reference": "ref-B003",
"tracking_number": "NJEX5H314200",
"tracking_type": "bill_of_lading",
"carrier_scac": "SMLM",
"name": "Retail Apparel"
}
]

import requests
import json

BASE_URL = "https://www.visiwise.co"
API_KEY = "YOUR_VISIWISE_API_KEY"

headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}

url = f"{BASE_URL}/api/v1/shipments/imports"
response = requests.post(url, headers=headers, data=json.dumps(shipments_to_track, indent=2))

if response.status_code == 202:
shipment_request_batch = response.json()
batch_id = shipment_request_batch["id"]
print(f"Successfully created shipment request batch with ID: {batch_id}")
print(json.dumps(shipment_request_batch, indent=2))
else:
print(f"Error: {response.status_code}")
print(response.text)


import time

# Assume 'batch_id' is from the previous step
url_status = f"{BASE_URL}/api/v1/shipments/imports/{batch_id}"

while True:
response = requests.get(url_status, headers=headers)
shipment_request_batch_result = response.json()
status = shipment_request_batch_result.get("status")

print(f"Current batch status: {status} ({shipment_request_batch_result.get('completed_requests')}/{shipment_request_batch_result.get('total_requests')} completed)")

if status != "processing":
print("Batch processing finished.")
print(json.dumps(shipment_request_batch_result, indent=2))
break

time.sleep(15)


# Assume 'batch_id' is from the previous steps
url = f"{BASE_URL}/api/v1/shipments/"
params = {
"batch_id": batch_id
}

response = requests.get(url, headers=headers, params=params)
shipments = response.json().get("data")

print(f"Retrieved {len(shipments)} shipments for batch {batch_id}:")
print(json.dumps(shipments, indent=2))

Wrap-up

Congratulations! You have successfully submitted a shipment import for tracking and retrieved their detailed visibility data. You can now integrate this workflow into your applications to automate shipment tracking at scale.