Qubictron
Migrate from Qubictron to TimeToCargo API v2: authentication, requests and response handling
This guide covers migration from Qubictron Container Tracking API v1 to TimeToCargo API v2. Qubictron requests route data through the route_details parameter of /ocean.
See the migration workflow for importing references and setting up notifications. Full TimeToCargo schemas are in the API reference.
Authentication
Qubictron uses the x-api-key header. The Qubictron base URL is https://api.qubictron.com/tracking/v1.
To switch to TimeToCargo:
- Create a key in your TimeToCargo account.
- Change the base URL to
https://tracking.timetocargo.com/v2. For example, the full tracking endpoint ishttps://tracking.timetocargo.com/v2/tracking. - Send the new key in the
api_keyquery parameter of every request, including batch tasks and webhook management. Keys and tokens from the former provider cannot be reused.
See authentication for key usage and request limits.
Tracking records and identifiers
| Qubictron | TimeToCargo | Required change |
|---|---|---|
shipment | data | Read shipment summary data from data.summary and containers from data.containers instead of the shipment object. |
facilities / locations | terminals / locations | Resolve event locations and terminals using location and terminal in the new response arrays. Source numeric IDs are not retained. |
transports | containers[].events[].vessel / voyage | Read the vessel name and voyage from each event's vessel and voyage. There is no separate transports array. |
Operation mapping
| Qubictron | TimeToCargo | Required change |
|---|---|---|
GET /ocean | GET /v2/tracking | Pass the reference as value, its type as type, and the carrier SCAC as company. Use POST /v2/tracking/batch for several references. |
GET /ocean/carriers | GET /v2/companies | Match the carrier by SCAC and check support for your reference type in cn, bl and bk. |
Request parameters
| Qubictron | TimeToCargo | Required change |
|---|---|---|
reference_number | value | Copy reference_number into the value query parameter without changing the reference. |
reference_type | type | Use container for a container, bl for a bill of lading, and bk instead of booking for a booking. The type is required. |
carrier_code | company | Verify carrier_code through GET /v2/companies and pass the matching SCAC in company. |
route_details | need_route | Replace route_details=true with need_route=true. Update response handling to use the route_info structure. |
Response fields
Paths in this table start at the root of a GET /v2/tracking response. In /v2/shipments, shipment data is nested inside each record at tracked_item.data.data. See the webhook guide for notification formats.
| Qubictron | TimeToCargo | Response handling |
|---|---|---|
success / status_code | success / status | Check JSON success and status even when HTTP status is 200. Update error handling for the new status values. |
data.shipment.reference_number | request.track_number.value | Read the requested reference from request.track_number.value. Save the separate data.tracking_metadata.id for tracking management. |
data.shipment.carrier | data.summary.company | Replace carrier.code handling with the company.scacs array. Read the name from company.name or company.full_name. |
data.shipment.status | data.shipment_status | Read shipment progress from data.shipment_status and update the set of values your application handles. |
events[].datetime / is_actual | events[].date / actual | In container events, replace datetime with date and is_actual with actual. Keep actual and planned dates distinct. |
events[].event_code | events[].status_code | Check the loading stage: origin-port LOAD corresponds to CLL, while transshipment loading corresponds to CLT. Do not use one replacement for every LOAD. |
events[].location_id / facility_id | events[].location / terminal | Match location to an id in data.locations and terminal to one in data.terminals. Do not reuse Qubictron numeric IDs. |
data.route | data.summary | Read the loading port from data.summary.pol and the discharge port from data.summary.pod. Route geometry is separate in data.route_info. |
data.containers[].route_details | data.route_info | Read the path from route_info.route[].path and the current point from route_info.current_position. Qubictron-specific AIS fields may be absent. |
Response examples
Each pair labels the former-provider and TimeToCargo responses. Expand the longer JSON examples when you need them; the mapping tables remain visible. These are shortened examples with illustrative data. The path above each JSON block identifies the part shown. Paths in the following table start from that part.
Reference, carrier and equipment type
Qubictron — GET /ocean
Shortened response.
{
"success": true,
"status_code": "OK",
"data": {
"shipment": {
"reference_number": "MSCU1234567",
"reference_type": "CONTAINER",
"carrier": {
"code": "MSCU",
"name": "MSC"
},
"status": "IN_TRANSIT"
},
"containers": [
{
"number": "MSCU1234567",
"size": 40,
"type": "High Cube Dry",
"iso_code": "45G1"
}
]
}
}TimeToCargo — GET /v2/tracking
Shortened response.
{
"success": true,
"status": "OK",
"request": {
"track_number": {
"type": "container",
"value": "MSCU1234567"
},
"company": "MSCU"
},
"data": {
"summary": {
"company": {
"name": "MSC",
"scacs": ["MEDU", "MSCU"]
}
},
"shipment_status": "IN_TRANSIT",
"containers": [
{
"number": "MSCU1234567",
"type": "40' High Cube Dry"
}
],
"tracking_metadata": {
"id": "11111111-1111-4111-8111-111111111111",
"status": "ACTIVE"
}
}
}How to map
| Qubictron | TimeToCargo | Required change |
|---|---|---|
data.shipment.reference_type = "CONTAINER" | request.track_number.type = "container" | Use lowercase container in requests. Do not copy the source response value CONTAINER into type. |
data.shipment.reference_number = "MSCU1234567" | request.track_number.value = "MSCU1234567" | The reference is unchanged. Read it from request.track_number.value. |
data.shipment.carrier.code = "MSCU" | data.summary.company.scacs = ["MEDU","MSCU"] | Check whether scacs contains MSCU instead of comparing the field with one string. |
data.shipment.status = "IN_TRANSIT" | data.shipment_status = "IN_TRANSIT" | Read IN_TRANSIT from shipment_status. Check the subscription separately in tracking_metadata.status. |
data.containers[0].type = "High Cube Dry" | data.containers[0].type = "40' High Cube Dry" | Size and type are combined in the containers[].type string. Update how your application displays them. |
data.containers[0].iso_code = "45G1" | No direct equivalent | There is no separate iso_code. Retain the source code locally if equipment classification depends on it. |
Actual and planned events
Qubictron — GET /ocean
Fragment: data.
{
"locations": [
{
"id": 10,
"name": "Singapore",
"coordinates": {
"lat": 1.25,
"lng": 103.75
}
},
{
"id": 20,
"name": "Rotterdam",
"coordinates": {
"lat": 51.95,
"lng": 4.14
}
}
],
"transports": [
{
"id": 5,
"type": "VESSEL",
"name": "EXAMPLE VESSEL"
}
],
"containers": [
{
"number": "MSCU1234567",
"events": [
{
"event_code": "LOAD",
"description": "Loaded",
"datetime": "2026-10-01T12:00:00+08:00",
"is_actual": true,
"location_id": 10,
"location_type": "FIRST_PORT_OF_LOADING",
"transport_id": 5,
"voyage_number": "126E"
},
{
"event_code": "ARRI",
"description": "Vessel arrival",
"datetime": "2026-10-12T08:00:00+02:00",
"is_actual": false,
"location_id": 20,
"location_type": "FINAL_PORT_OF_DISCHARGE",
"transport_id": 5,
"voyage_number": "126E"
}
]
}
]
}TimeToCargo — GET /v2/tracking
Fragment: data.
{
"locations": [
{
"id": 0,
"name": "Singapore",
"country": "Singapore",
"lat": 1.25,
"lng": 103.75
},
{
"id": 1,
"name": "Rotterdam",
"country": "Netherlands",
"lat": 51.95,
"lng": 4.14
}
],
"containers": [
{
"number": "MSCU1234567",
"type": "40' High Cube Dry",
"events": [
{
"location": 1,
"status": "Vessel arrival",
"status_code": "VAD",
"date": "2026-10-12T08:00:00",
"actual": false,
"vessel": "EXAMPLE VESSEL",
"voyage": "126E"
},
{
"location": 0,
"status": "Loaded",
"status_code": "CLL",
"date": "2026-10-01T12:00:00",
"actual": true,
"vessel": "EXAMPLE VESSEL",
"voyage": "126E"
}
]
}
]
}How to map
| Qubictron | TimeToCargo | Required change |
|---|---|---|
containers[0].events[0].event_code = "LOAD" | containers[0].events[1].status_code = "CLL" | This example shows loading at the origin port, so use CLL. Transshipment loading uses CLT. |
containers[0].events[1].event_code = "ARRI" | containers[0].events[0].status_code = "VAD" | Vessel arrival at the discharge port is VAD. It does not itself confirm container discharge or delivery. |
containers[0].events[1].is_actual = false | containers[0].events[0].actual = false | false keeps the date marked as planned. Do not display this event as already completed. |
containers[0].events[0].location_id = 10 | containers[0].events[1].location = 0 | The event location has ID 0 in the new locations array. Look it up by this ID, not the former 10. |
containers[0].events[0].transport_id = 5 | containers[0].events[1].vessel = "EXAMPLE VESSEL" | The vessel name is now stored on the event. Remove the lookup by transport_id in transports. |
containers[0].events[0].voyage_number = "126E" | containers[0].events[1].voyage = "126E" | Read the voyage from event.voyage. The example value remains 126E. |
Dates illustrate field formats. Preserve source offset and timezone meaning: deleting Z or +08:00 is not a timezone conversion.
Geometry and current position
Qubictron — GET /ocean?route_details=true
Fragment: data.containers[0].route_details.
{
"predicted_position": {
"coordinates": {
"lat": 1.25,
"lng": 103.75
}
},
"latest_ais_data": {
"transport_id": 5,
"coordinates": {
"lat": 1.2,
"lng": 103.7
},
"timestamp": "2026-10-03T08:30:00Z"
},
"route_legs": [
{
"from_location_id": 10,
"to_location_id": 20,
"transport_mode": "VESSEL",
"route_path": [
[1.25, 103.75],
[1.1, 103.4]
]
}
]
}TimeToCargo — GET /v2/tracking?need_route=true
Fragment: data.route_info.
{
"current_position": [1.25, 103.75],
"last_updated": "2026-10-03T09:00:00",
"route": [
{
"type": "sea",
"path": [
[1.25, 103.75],
[1.1, 103.4]
]
}
]
}How to map
| Qubictron | TimeToCargo | Required change |
|---|---|---|
predicted_position.coordinates | current_position = [1.25,103.75] | Read the current position as a [latitude, longitude] array rather than an object with coordinate properties. |
route_legs[0].route_path | route[0].path | Iterate over route_info.route[] and each segment's path instead of route_legs[].route_path. |
route_legs[0].transport_mode = "VESSEL" | route[0].type = "sea" | For a sea segment, use type: "sea" instead of transport_mode: "VESSEL". |
latest_ais_data | No direct equivalent | Do not substitute the route position for the last AIS measurement. Retain the measurement and its timestamp separately if needed. |
Data to retain separately
Some Qubictron AIS fields and predictions may be absent from the TimeToCargo response. Check which fields your application uses and retain required data before switching. Qubictron webhook support is not described in the available public documentation. If you already receive these notifications, check your account settings and configure TimeToCargo webhooks separately using the webhook guide.
Last updated on