project44
Переход с project44 на Cargotime API v2: ключи доступа, запросы и обработка ответов
Руководство описывает переход с project44 Unified API и Ocean API v4 на Cargotime API v2 для морских перевозок. Методы Unified и Ocean отмечены отдельно, поскольку их параметры и ответы отличаются.
Общий порядок переноса номеров и настройки уведомлений приведён в порядке перехода. Полные схемы Cargotime — в справочнике API.
Аутентификация
project44 использует OAuth с учётными данными приложения и заголовок Authorization: Bearer …. При выгрузке исходных данных используйте региональный адрес project44, настроенный для вашего аккаунта: NA или EU.
Для перехода на Cargotime:
- Создайте ключ в личном кабинете Cargotime.
- Замените базовый адрес на
https://tracking.cargotime.ru/v2. Например, полный адрес запроса отслеживания —https://tracking.cargotime.ru/v2/tracking. - Передавайте новый ключ в параметре URL
api_keyкаждого запроса, включая пакетные задачи и управление вебхуками. Ключи и токены прежнего сервиса не подходят.
Правила использования ключа и ограничения запросов — в разделе аутентификации.
Отслеживания и идентификаторы
| project44 | Cargotime | Что изменить |
|---|---|---|
Unified shipment.id / Ocean masterShipmentId | shipment.id (частично) | Создайте отслеживание по номеру контейнера, коносамента или букинга. Сохраните связь нового ID с исходным masterShipmentId. |
Ocean oceanLegId | shipment.id + ваша таблица этапов | Сохраните oceanLegId вместе с исходным masterShipmentId и новым ID. Отдельный объект морского этапа в новом API не создаётся. |
equipmentIdentifier / identifiers | track_number + containers[] | Выберите основной номер для запроса. Номера контейнеров из результата обрабатывайте отдельно от внутренних ID project44. |
events / positions / states | events[] / route_info / shipment_status | Получайте события, текущую точку и состояние из отдельных полей. Историю всех позиций и смены состояний сохраните до отключения project44. |
Соответствие операций
| project44 | Cargotime | Что изменить |
|---|---|---|
Unified: POST /api/v4/shipments/tracking | POST /v2/tracking/batch → GET /v2/tracking/batch | Передайте основные номера в пакетном запросе, получите результат задачи и сохраните постоянные ID отслеживаний. |
Unified: PUT /api/v4/shipments/tracking | Нет прямого аналога | Для нового номера создайте новое отслеживание. Изменения плана перевозки и связей между этапами храните в своей системе. |
Unified: GET /api/v4/shipments/{shipmentId}/tracking | GET /v2/shipments | Получите страницы списка и выберите запись по новому ID из таблицы соответствий. Отдельного запроса получения по ID нет. |
Unified: GET /api/v4/shipments/{shipmentId}/eventhistory, /positionhistory, /tracking/history | GET /v2/shipments?need_route=true (частично) | Используйте список для получения текущих данных и маршрута. Историю событий, координат и прошлых ответов project44 выгрузите отдельно. |
Ocean: POST /api/v4/ocean/shipments | POST /v2/tracking/batch → GET /v2/tracking/batch | Передайте номер контейнера и SCAC. Сохраните task_id, получите результат и свяжите новый ID с исходными masterShipmentId и oceanLegId. |
Ocean: GET /api/v4/ocean/shipments/{shipmentId}/statuses | GET /v2/shipments | Найдите запись по новому ID и получите данные из tracked_item.data.data. Если нужна текущая точка, добавьте need_route=true. |
Unified: DELETE /api/v4/shipments/{shipmentId}/tracking, Ocean: DELETE /api/v4/ocean/shipments/{shipmentId} | DELETE /v2/shipments | Передайте новые ID в массиве shipmentIds. Условия остановки, архивации и удаления описаны в жизненном цикле. |
GET /api/v4/shipments/{shipmentId}/attributes | note + ваша система | Перенесите одну подпись до 40 символов в note. Остальные атрибуты храните в своей системе. |
GET/PUT /api/v4/webhooks, GET/DELETE /api/v4/webhooks/{webhookId} | /v2/webhooks | Создайте вебхуки заново через /v2/webhooks. Обновите методы управления, проверку подписи и обработчик уведомлений по руководству. |
Параметры запроса
| project44 | Cargotime | Что изменить |
|---|---|---|
Unified identifiers: CONTAINER_ID / BILL_OF_LADING / BOOKING_NUMBER | tracked_items[].track_number.value + type | Передайте выбранный номер в track_number.value. Преобразуйте CONTAINER_ID в container, BILL_OF_LADING в bl, BOOKING_NUMBER в bk. |
Unified identifiers: CARRIER_SCAC | tracked_items[].company | Возьмите значение идентификатора CARRIER_SCAC, проверьте его в GET /v2/companies и передайте в company. |
Ocean equipmentIdentifier | tracked_items[].track_number | Для equipmentIdentifier.type: "CONTAINER_ID" передайте его value и укажите track_number.type: "container". |
Ocean carrierSCACCode | tracked_items[].company | Передайте значение carrierSCACCode в company после проверки перевозчика в GET /v2/companies. |
Ocean includePositionData | need_route=true | Добавьте параметр URL need_route=true. Он включает маршрут и текущую точку, но не полную историю AIS. |
attributes / plan / relatedShipments / accessGroups | note + ваша система | Одну подпись сохраните в note отдельным PATCH. План, связи перевозок и группы доступа перенесите в свою систему. |
Поля ответа
В ответе GET /v2/shipments выберите запись из data.data[]. Пути, начинающиеся с tracked_item, указаны относительно этой записи. Контейнеры находятся в tracked_item.data.data.containers[], события — в events[] каждого контейнера. В ответе GET /v2/tracking данные перевозки находятся сразу в data.
| project44 | Cargotime | Как обработать ответ |
|---|---|---|
Unified id / Ocean shipment.oceanLegId | data.task_id → results[].data.tracking_metadata.id | После запуска получите результат задачи и сохраните постоянный data.results[].data.tracking_metadata.id. Свяжите его с обоими исходными ID project44. |
Unified GET tracking: identifiers / plan / routeInfo | tracked_item и данные перевозки | В списке берите номер из tracked_item.track_number, сведения о перевозке из tracked_item.data.data. Отдельной копии плана project44 в ответе нет. |
Ocean trackedShipment.equipmentIdentifier.value | tracked_item.data.data.containers[].number | Найдите нужный контейнер по containers[].number. Не сравнивайте его номер с внутренним ID записи. |
Ocean trackedShipment.events[] | tracked_item.data.data.containers[].events[] | Получайте код из status_code, дату из date, признак фактического события из actual. Учитывайте порт и этап при преобразовании кода project44. |
Ocean trackedShipment.stops / vessels | summary / locations / events[].vessel | Место события найдите по location в locations. Название судна получите из строки vessel самого события. |
Ocean trackedShipment.positions / states | route_info / shipment_status | Используйте route_info.current_position для текущей точки, shipment_status для состояния перевозки. Полных массивов истории positions и states нет. |
Ocean shipmentId | masterShipmentId в исходной системе | В исходных данных используйте актуальный masterShipmentId вместо устаревшего shipmentId. Ни один из них не заменяет новый ID отслеживания. |
Примеры ответов
В каждой паре подписаны ответы прежнего сервиса и Cargotime. Большие JSON-примеры можно раскрыть отдельно от таблиц сопоставления. Это сокращённые примеры с условными данными. Над каждым JSON указан путь к показанной части ответа. Пути в следующей таблице начинаются от этой части.
Unified: идентификаторы и пользовательская подпись
project44 — GET /api/v4/shipments/{shipmentId}/tracking
Ответ, сокращённо.
{
"id": "33333333-3333-4333-8333-333333333333",
"identifiers": [
{
"type": "CONTAINER_ID",
"value": "MSCU1234567"
},
{
"type": "CARRIER_SCAC",
"value": "MSCU"
},
{
"type": "BOOKING_NUMBER",
"value": "BOOKING123"
}
],
"attributes": [
{
"name": "order",
"values": ["Order 123"]
}
],
"relatedShipments": [
{
"id": "66666666-6666-4666-8666-666666666666"
}
]
}Cargotime — GET /v2/shipments
Фрагмент: data.data[0].
{
"id": "11111111-1111-4111-8111-111111111111",
"status": "ACTIVE",
"note": "Order 123",
"track_number": "MSCU1234567",
"tracked_item": {
"track_number": "MSCU1234567",
"track_number_type": "container",
"data": {
"success": true,
"status": "OK",
"data": {
"summary": {
"company": {
"name": "MSC",
"scacs": ["MEDU", "MSCU"]
}
},
"containers": [
{
"number": "MSCU1234567"
}
],
"references": {
"booking_numbers": ["BOOKING123"]
}
}
}
}
}Как сопоставить
| project44 | Cargotime | Что изменить |
|---|---|---|
id = "33333333-3333-4333-8333-333333333333" | id = "11111111-1111-4111-8111-111111111111" | Сохраните соответствие исходного и нового ID. Для управления отслеживанием используйте новый id. |
identifiers[0].value = "MSCU1234567" | tracked_item.track_number = "MSCU1234567" | Передайте номер без изменения и задайте тип container. В списке номер находится в tracked_item.track_number. |
identifiers[1].value = "MSCU" | tracked_item.data.data.summary.company.scacs = ["MEDU","MSCU"] | Получайте коды перевозчика из массива scacs и проверяйте наличие нужного кода в нём. |
identifiers[2].value = "BOOKING123" | tracked_item.data.data.references.booking_numbers = ["BOOKING123"] | Дополнительный номер букинга может появиться в references.booking_numbers. Он не меняет основной тип отслеживания с container на bk. |
attributes[0].values[0] = "Order 123" | note = "Order 123" | Сохраните Order 123 в note после получения постоянного ID. Остальные атрибуты перенесите в свою базу. |
relatedShipments | Нет прямого аналога | Храните связи с другими перевозками у себя. В новом ответе массива relatedShipments нет. |
Ocean: событие, порт, судно и состояние
project44 — GET /api/v4/ocean/shipments/{shipmentId}/statuses
Фрагмент: trackedShipment.
{
"masterShipmentId": "33333333-3333-4333-8333-333333333333",
"oceanLegId": "44444444-4444-4444-8444-444444444444",
"equipmentIdentifier": {
"type": "CONTAINER_ID",
"value": "MSCU1234567"
},
"carrierSCACCode": "MSCU",
"events": [
{
"eventCode": "LOADED",
"timeStamp": "2026-10-01T04:00:00Z",
"stopNumber": 10,
"vesselNumber": 5
}
],
"stops": [
{
"stopNumber": 10,
"stopType": "PORT_OF_LOADING",
"name": "Singapore",
"portLocode": "SGSIN",
"geoCoordinates": {
"latitude": 1.25,
"longitude": 103.75
}
}
],
"vessels": [
{
"vesselNumber": 5,
"name": "EXAMPLE VESSEL",
"imo": 9000003
}
],
"states": [
{
"stateCode": "ON_WATER",
"startTime": "2026-10-01T06:00:00Z",
"vesselNumber": 5
}
]
}Cargotime — GET /v2/shipments
Фрагмент: data.data[0].tracked_item.data.data.
{
"shipment_status": "IN_TRANSIT",
"summary": {
"company": {
"name": "MSC",
"scacs": ["MEDU", "MSCU"]
}
},
"locations": [
{
"id": 0,
"name": "Singapore",
"country": "Singapore",
"lat": 1.25,
"lng": 103.75
}
],
"containers": [
{
"number": "MSCU1234567",
"events": [
{
"location": 0,
"status": "Loaded",
"status_code": "CLL",
"date": "2026-10-01T12:00:00",
"actual": true,
"vessel": "EXAMPLE VESSEL"
}
]
}
]
}Как сопоставить
| project44 | Cargotime | Что изменить |
|---|---|---|
equipmentIdentifier.value = "MSCU1234567" | containers[0].number = "MSCU1234567" | Выберите контейнер по containers[].number. В этом примере номер остаётся MSCU1234567. |
events[0].eventCode = "LOADED" | containers[0].events[0].status_code = "CLL" | Здесь LOADED относится к PORT_OF_LOADING, поэтому соответствует CLL. Для погрузки при перегрузке нужен другой код. |
events[0].stopNumber = 10 | containers[0].events[0].location = 0 | Вместо поиска по stopNumber найдите объект в locations, у которого id равен event.location. |
events[0].vesselNumber = 5 | containers[0].events[0].vessel = "EXAMPLE VESSEL" | Получайте название судна прямо из event.vessel. Поиск по vesselNumber в отдельном массиве больше не нужен. |
states[0].stateCode = "ON_WATER" | shipment_status = "IN_TRANSIT" | Для показанной перевозки в пути используйте shipment_status: "IN_TRANSIT". Историю состояний states[] храните отдельно. |
events[0].timeStamp = "2026-10-01T04:00:00Z" | containers[0].events[0].date = "2026-10-01T12:00:00" | В примере 04:00 UTC соответствует 12:00 в Сингапуре. Сравнивайте даты с учётом часового пояса, а не только строки времени. |
Ocean: история позиций и текущая точка
project44 — GET /api/v4/ocean/shipments/{shipmentId}/statuses?includePositionData=true
Фрагмент: 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
}
]
}Cargotime — GET /v2/shipments?need_route=true
Фрагмент: data.data[0].tracked_item.data.data.route_info.
{
"current_position": [1.25, 103.75],
"last_updated": "2026-10-03T09:00:00"
}Как сопоставить
| project44 | Cargotime | Что изменить |
|---|---|---|
positions[1].geoCoordinates | current_position = [1.25,103.75] | Получайте текущую точку из массива [широта, долгота]. Не ожидайте массив всей истории координат. |
positions[1].timeStamp = "2026-10-03T09:00:00Z" | last_updated = "2026-10-03T09:00:00" | last_updated относится к обновлению текущей позиции, а не всей геометрии маршрута. Сохраняйте исходную метку project44 отдельно: источник позиции и часовой пояс могут отличаться. |
positions | Нет прямого аналога | Выгрузите прошлые позиции project44 отдельно. route[].path описывает линию маршрута и не является журналом измерений AIS. |
Что сохранить отдельно
Сохраните исходные masterShipmentId и oceanLegId вместе с новым ID отслеживания. План перевозки, связи этапов, прогнозы, историю позиций и правила доступа перенесите отдельно. При обработке событий учитывайте этап: в приведённом примере LOADED соответствует CLL только потому, что погрузка происходит в порту отправления.
Обновлено