TimeToCargo

project44

Migrate from project44 to TimeToCargo API v2: authentication, requests and response handling

This guide covers ocean tracking migration from project44 Unified API and Ocean API v4 to TimeToCargo API v2. Unified and Ocean operations are labelled separately because their parameters and responses differ.

See the migration workflow for importing references and setting up notifications. Full TimeToCargo schemas are in the API reference.

Authentication

project44 uses OAuth client credentials and the Authorization: Bearer … header. When exporting source data, keep the project44 regional host configured for your account: NA or EU.

To switch to TimeToCargo:

  1. Create a key in your TimeToCargo account.
  2. Change the base URL to https://tracking.timetocargo.com/v2. For example, the full tracking endpoint is https://tracking.timetocargo.com/v2/tracking.
  3. Send the new key in the api_key query 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

project44TimeToCargoRequired change
Unified shipment.id / Ocean masterShipmentIdshipment.id (partial)Create tracking for a container, bill of lading or booking reference. Map the new ID to the source masterShipmentId.
Ocean oceanLegIdshipment.id + your leg mappingKeep oceanLegId alongside the source masterShipmentId and new tracking ID. The new API does not create a separate ocean-leg object.
equipmentIdentifier / identifierstrack_number + containers[]Choose the primary reference for the request. Handle returned container numbers separately from internal project44 IDs.
events / positions / statesevents[] / route_info / shipment_statusRead events, the current position and progress from separate fields. Export full position and state histories before switching off project44.

Operation mapping

project44TimeToCargoRequired change
Unified: POST /api/v4/shipments/trackingPOST /v2/tracking/batch → GET /v2/tracking/batchSubmit primary references in a batch, retrieve the task result, and save permanent tracking IDs.
Unified: PUT /api/v4/shipments/trackingNo direct equivalentCreate new tracking for a new reference. Maintain transport-plan changes and leg relationships in your own system.
Unified: GET /api/v4/shipments/{shipmentId}/trackingGET /v2/shipmentsFetch list pages and select the record using the new ID from your mapping table. There is no individual GET by ID.
Unified: GET /api/v4/shipments/{shipmentId}/eventhistory, /positionhistory, /tracking/historyGET /v2/shipments?need_route=true (partial)Use the list for current data and route information. Export project44 event, position and response history separately.
Ocean: POST /api/v4/ocean/shipmentsPOST /v2/tracking/batch → GET /v2/tracking/batchSubmit the container number and SCAC. Save task_id, retrieve the result, and map the new ID to the source masterShipmentId and oceanLegId.
Ocean: GET /api/v4/ocean/shipments/{shipmentId}/statusesGET /v2/shipmentsFind the record by its new ID and read tracked_item.data.data. Add need_route=true if you need the current position.
Unified: DELETE /api/v4/shipments/{shipmentId}/tracking, Ocean: DELETE /api/v4/ocean/shipments/{shipmentId}DELETE /v2/shipmentsPass new IDs in the shipmentIds array. See the lifecycle guide for stopping, archiving and deletion rules.
GET /api/v4/shipments/{shipmentId}/attributesnote + your own storeMove one label of up to 40 characters into note. Keep other attributes in your own system.
GET/PUT /api/v4/webhooks, GET/DELETE /api/v4/webhooks/{webhookId}/v2/webhooksRecreate webhooks through /v2/webhooks. Update management methods, signature checks and notification handling using the webhook guide.

Request parameters

project44TimeToCargoRequired change
Unified identifiers: CONTAINER_ID / BILL_OF_LADING / BOOKING_NUMBERtracked_items[].track_number.value + typePut the selected reference in track_number.value. Map CONTAINER_ID to container, BILL_OF_LADING to bl, and BOOKING_NUMBER to bk.
Unified identifiers: CARRIER_SCACtracked_items[].companyTake the CARRIER_SCAC identifier value, verify it through GET /v2/companies, and pass it in company.
Ocean equipmentIdentifiertracked_items[].track_numberFor equipmentIdentifier.type: "CONTAINER_ID", copy its value and set track_number.type to container.
Ocean carrierSCACCodetracked_items[].companyCopy carrierSCACCode into company after checking the carrier through GET /v2/companies.
Ocean includePositionDataneed_route=trueAdd the need_route=true query parameter. It requests the route and current point, not full AIS history.
attributes / plan / relatedShipments / accessGroupsnote + your own storeSave one label as note with a separate PATCH. Maintain the plan, shipment relationships and access groups in your system.

Response fields

Select a record from data.data[] in the GET /v2/shipments response. Paths starting with tracked_item are relative to that record. Containers are in tracked_item.data.data.containers[], with events in each container's events[]. In GET /v2/tracking, shipment data is directly under data.

project44TimeToCargoResponse handling
Unified id / Ocean shipment.oceanLegIddata.task_id → results[].data.tracking_metadata.idRetrieve the task result after submission and save the permanent data.results[].data.tracking_metadata.id. Map it to both source project44 IDs.
Unified GET tracking: identifiers / plan / routeInfotracked_item + tracking dataIn the list, read the reference from tracked_item.track_number and shipment data from tracked_item.data.data. The response does not include a copy of the project44 plan.
Ocean trackedShipment.equipmentIdentifier.valuetracked_item.data.data.containers[].numberFind the required container by containers[].number. Do not compare the number with the internal record ID.
Ocean trackedShipment.events[]tracked_item.data.data.containers[].events[]Read the code from status_code, the date from date, and the actual flag from actual. Consider the port and journey stage when mapping project44 codes.
Ocean trackedShipment.stops / vesselssummary / locations / events[].vesselResolve the event's location through locations. Read the vessel name from the event's own vessel string.
Ocean trackedShipment.positions / statesroute_info / shipment_statusUse route_info.current_position for the current point and shipment_status for progress. Full positions and states history arrays are not provided.
Ocean shipmentIdmasterShipmentId in the source systemIn source data, use the current masterShipmentId instead of deprecated shipmentId. Neither replaces the new tracking ID.

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.

Unified: identifiers and custom label

How to map

project44TimeToCargoRequired change
id = "33333333-3333-4333-8333-333333333333"id = "11111111-1111-4111-8111-111111111111"Map the source ID to the new one. Use the new id for tracking management.
identifiers[0].value = "MSCU1234567"tracked_item.track_number = "MSCU1234567"Keep the number unchanged and set the type to container. In the list, the number is in tracked_item.track_number.
identifiers[1].value = "MSCU"tracked_item.data.data.summary.company.scacs = ["MEDU","MSCU"]Read carrier codes from the scacs array and check whether it contains the required code.
identifiers[2].value = "BOOKING123"tracked_item.data.data.references.booking_numbers = ["BOOKING123"]An additional booking reference may appear in references.booking_numbers. It does not change the primary tracking type from container to bk.
attributes[0].values[0] = "Order 123"note = "Order 123"Save Order 123 as note after obtaining the permanent ID. Move other attributes to your database.
relatedShipmentsNo direct equivalentMaintain links to other shipments locally. The new response has no relatedShipments array.

Ocean: event, port, vessel and state

How to map

project44TimeToCargoRequired change
equipmentIdentifier.value = "MSCU1234567"containers[0].number = "MSCU1234567"Select the container by containers[].number. The example number remains MSCU1234567.
events[0].eventCode = "LOADED"containers[0].events[0].status_code = "CLL"Here, LOADED occurs at PORT_OF_LOADING, so it corresponds to CLL. Transshipment loading requires a different code.
events[0].stopNumber = 10containers[0].events[0].location = 0Instead of looking up stopNumber, find the locations entry whose id equals event.location.
events[0].vesselNumber = 5containers[0].events[0].vessel = "EXAMPLE VESSEL"Read the vessel name directly from event.vessel. A separate lookup by vesselNumber is no longer needed.
states[0].stateCode = "ON_WATER"shipment_status = "IN_TRANSIT"For the journey shown, use shipment_status: "IN_TRANSIT". Retain the states[] history separately.
events[0].timeStamp = "2026-10-01T04:00:00Z"containers[0].events[0].date = "2026-10-01T12:00:00"In this example, 04:00 UTC corresponds to 12:00 in Singapore. Compare dates using time zones, not just timestamp strings.

Ocean: position history and current point

project44 — GET /api/v4/ocean/shipments/{shipmentId}/statuses?includePositionData=true

Fragment: trackedShipment.

{
    "positions": [
        {
            "geoCoordinates": {
                "latitude": 1.2,
                "longitude": 103.7
            },
            "timeStamp": "2026-10-03T08:30:00Z",
            "vesselNumber": 5
        },
        {
            "geoCoordinates": {
                "latitude": 1.25,
                "longitude": 103.75
            },
            "timeStamp": "2026-10-03T09:00:00Z",
            "vesselNumber": 5
        }
    ]
}

TimeToCargo — GET /v2/shipments?need_route=true

Fragment: data.data[0].tracked_item.data.data.route_info.

{
    "current_position": [1.25, 103.75],
    "last_updated": "2026-10-03T09:00:00"
}

How to map

project44TimeToCargoRequired change
positions[1].geoCoordinatescurrent_position = [1.25,103.75]Read the current point as a [latitude, longitude] array. Do not expect a full position history array.
positions[1].timeStamp = "2026-10-03T09:00:00Z"last_updated = "2026-10-03T09:00:00"last_updated refers to the current position update, not the entire route geometry. Retain the original project44 timestamp: the position source and time zone may differ.
positionsNo direct equivalentExport past project44 positions separately. route[].path describes route geometry, not a log of AIS measurements.

Data to retain separately

Keep the source masterShipmentId and oceanLegId alongside the new tracking ID. Migrate transport plans, leg relationships, predictions, position history and access rules separately. Account for the journey stage when handling events: the example maps LOADED to CLL because loading occurs at the origin port.

Last updated on