ShipsGo
Переход с ShipsGo на Cargotime API v2: ключи доступа, запросы и обработка ответов
Руководство описывает переход с ShipsGo Ocean API v2 на Cargotime API v2. Создание отслеживания, получение сохранённых данных и получение маршрута рассмотрены отдельно. Для старого ContainerService v1.2 параметры отличаются.
Общий порядок переноса номеров и настройки уведомлений приведён в порядке перехода. Полные схемы Cargotime — в справочнике API.
Аутентификация
ShipsGo передаёт токен в заголовке X-Shipsgo-User-Token. Базовый адрес ShipsGo Ocean v2 — https://api.shipsgo.com/v2.
Для перехода на Cargotime:
- Создайте ключ в личном кабинете Cargotime.
- Замените базовый адрес на
https://tracking.cargotime.ru/v2. Например, полный адрес запроса отслеживания —https://tracking.cargotime.ru/v2/tracking. - Передавайте новый ключ в параметре URL
api_keyкаждого запроса, включая пакетные задачи и управление вебхуками. Ключи и токены прежнего сервиса не подходят.
Правила использования ключа и ограничения запросов — в разделе аутентификации.
Отслеживания и идентификаторы
| ShipsGo | Cargotime | Что изменить |
|---|---|---|
shipment.id | shipment.id | Сохраните соответствие числового ID ShipsGo и нового ID отслеживания. Для управления записью используйте новый ID. |
shipment.containers[] | tracked_item.data.data.containers[] | В выбранной записи списка получайте контейнеры из tracked_item.data.data.containers[]. У одного коносамента их может быть несколько. |
shipment.reference / tags | note + ваша система | Перенесите одну подпись до 40 символов в note. Остальные теги и дополнительные сведения храните у себя. |
Соответствие операций
| ShipsGo | Cargotime | Что изменить |
|---|---|---|
POST /ocean/shipments | POST /v2/tracking/batch → GET /v2/tracking/batch | Отправьте номера через POST /v2/tracking/batch, получите результаты через GET /v2/tracking/batch и сохраните data.results[].data.tracking_metadata.id. |
GET /ocean/shipments | GET /v2/shipments | Получайте записи постранично через page и limit. Фильтр status выбирает действующие или архивные подписки. |
GET /ocean/shipments/{shipment_id} | GET /v2/shipments | Получите страницы списка и найдите запись по сохранённому новому ID. Отдельного запроса получения по ID нет. |
PATCH /ocean/shipments/{shipment_id} | PATCH /v2/shipments/{id} | Передайте в теле {"note":"ваша подпись"}. Допускается до 40 символов. Другие поля записи этим методом не изменяются. |
DELETE /ocean/shipments/{shipment_id} | DELETE /v2/shipments | Передайте новые ID в массиве shipmentIds. Учтите правила архивации и удаления из жизненного цикла. |
GET /ocean/shipments/{shipment_id}/geojson | GET /v2/shipments?need_route=true | Получайте route_info из сохранённой записи. Если карте нужен GeoJSON, преобразуйте массивы точек и поменяйте порядок координат. |
GET /ocean/carriers | GET /v2/companies | Найдите SCAC перевозчика и проверьте поддержку контейнеров, коносаментов или букингов в cn, bl, bk. |
POST /…/{shipment_id}/tags, DELETE /…/{shipment_id}/tags/{tag_id} | PATCH /v2/shipments/{id} (частично) | Используйте note только для одной подписи. Коллекцию тегов, добавление отдельных тегов и поиск по ним реализуйте в своей системе. |
POST/DELETE /…/followers | Нет прямого аналога | Перенесите адреса получателей в свою систему рассылки. Вебхуки отправляют HTTP-уведомления и не подписывают пользователей на письма. |
Параметры запроса
| ShipsGo | Cargotime | Что изменить |
|---|---|---|
container_number | tracked_items[].track_number.value | В теле пакетного запроса передайте номер в tracked_items[].track_number.value и укажите track_number.type: "container". |
booking_number | track_number.value + type | Определите, содержит поле номер букинга или коносамента. Передайте номер в track_number.value, а в type укажите соответственно bk или bl. |
carrier | tracked_items[].company | Замените код ShipsGo на SCAC из GET /v2/companies. Код вида SG_… нельзя передавать в company без сопоставления. |
reference / tags | note после создания | Сначала получите постоянный ID отслеживания, затем сохраните подпись через PATCH /v2/shipments/{id}. Поля note в пакетном запросе нет. |
filters / order_by / skip / take | status / page / limit | Замените skip и take на page и limit. Дополнительные фильтры и сортировку выполняйте у себя после получения нужных страниц. |
Поля ответа
В ответе GET /v2/shipments выберите запись из data.data[]. Пути, начинающиеся с tracked_item, указаны относительно этой записи. Контейнеры находятся в tracked_item.data.data.containers[], события — в events[] каждого контейнера. В ответе GET /v2/tracking данные перевозки находятся сразу в data.
| ShipsGo | Cargotime | Как обработать ответ |
|---|---|---|
shipment.id | data.data[].id | Получайте постоянный ID из data.data[].id и сохраняйте связь с исходным shipment.id. Временный task_id для этого не подходит. |
shipment.carrier.scac | tracked_item.data.data.summary.company.scacs[] | Получайте коды из summary.company.scacs. Поле содержит массив, поэтому проверяйте наличие нужного SCAC в нём. |
shipment.status | tracked_item.data.data.shipment_status | Для движения в пути используйте IN_TRANSIT вместо SAILING. Прибытие, выгрузку и доставку обрабатывайте как отдельные этапы. |
shipment.containers[].movements[] | tracked_item.data.data.containers[].events[] | Обрабатывайте containers[].events[]. Получайте время из date, признак факта из actual, код из status_code. |
shipment.route | tracked_item.data.data.summary / route_info | Получайте порты из summary.pol и summary.pod. Линию маршрута берите из route_info.route[].path при need_route=true. |
Примеры ответов
В каждой паре подписаны ответы прежнего сервиса и Cargotime. Большие JSON-примеры можно раскрыть отдельно от таблиц сопоставления. Это сокращённые примеры с условными данными. Над каждым JSON указан путь к показанной части ответа. Пути в следующей таблице начинаются от этой части.
Запись, подпись и состояние перевозки
ShipsGo — GET /ocean/shipments/{shipment_id}
Фрагмент: shipment.
{
"id": 1001,
"reference": "Order 123",
"container_number": "MSCU1234567",
"booking_number": null,
"carrier": {
"scac": "MSCU",
"name": "MSC"
},
"status": "SAILING",
"containers": [
{
"number": "MSCU1234567",
"size": 40,
"type": "High Cube Dry"
}
],
"tags": [
{
"id": 7,
"name": "IMPORT"
}
],
"discarded_at": null
}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"]
}
},
"shipment_status": "IN_TRANSIT",
"containers": [
{
"number": "MSCU1234567",
"type": "40' High Cube Dry"
}
]
}
}
}
}Как сопоставить
| ShipsGo | Cargotime | Что изменить |
|---|---|---|
id = 1001 | id = "11111111-1111-4111-8111-111111111111" | Сохраните пару «ID ShipsGo → новый ID». Значение 1001 не передаётся в методы управления новым отслеживанием. |
reference = "Order 123" | note = "Order 123" | Сохраните Order 123 в note отдельным запросом после создания отслеживания. Максимальная длина — 40 символов. |
container_number = "MSCU1234567" | tracked_item.track_number = "MSCU1234567" | Номер остаётся прежним. В записи списка он находится в tracked_item.track_number, тип — в tracked_item.track_number_type. |
status = "SAILING" | tracked_item.data.data.shipment_status = "IN_TRANSIT" | Для показанного этапа используйте shipment_status: "IN_TRANSIT" вместо SAILING. |
containers[0].type = "High Cube Dry" | tracked_item.data.data.containers[0].type = "40' High Cube Dry" | В новом ответе размер и тип контейнера объединены в containers[].type. Обновите отображение этих данных. |
tags | Нет прямого аналога | Если note уже занят номером заказа, сохраните теги отдельно. Несколько независимых тегов одним note не заменить. |
События контейнера, прогноз и места событий
ShipsGo — GET /ocean/shipments/{shipment_id}
Фрагмент: shipment.containers[0].
{
"number": "MSCU1234567",
"movements": [
{
"event": "LOAD",
"status": "ACT",
"timestamp": "2026-10-01T12:00:00+08:00",
"location": {
"code": "SGSIN",
"name": "Singapore",
"timezone": "Asia/Singapore",
"country": {
"code": "SG",
"name": "Singapore"
}
},
"vessel": {
"name": "EXAMPLE VESSEL",
"imo": 9000003
},
"voyage": "126E"
},
{
"event": "ARRV",
"status": "EST",
"timestamp": "2026-10-12T08:00:00+02:00",
"location": {
"code": "NLRTM",
"name": "Rotterdam",
"timezone": "Europe/Amsterdam",
"country": {
"code": "NL",
"name": "Netherlands"
}
},
"vessel": {
"name": "EXAMPLE VESSEL",
"imo": 9000003
},
"voyage": "126E"
}
]
}Cargotime — GET /v2/shipments
Фрагмент: data.data[0].tracked_item.data.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"
}
]
}
]
}Как сопоставить
| ShipsGo | Cargotime | Что изменить |
|---|---|---|
number = "MSCU1234567" | containers[0].number = "MSCU1234567" | Найдите нужный контейнер по containers[].number, затем обработайте его events. |
movements[0].event = "LOAD" | containers[0].events[1].status_code = "CLL" | Погрузка в порту отправления в этом примере обозначена CLL. Для погрузки при перегрузке проверяйте код CLT. |
movements[1].status = "EST" | containers[0].events[0].actual = false | Замените ACT на actual=true, EST на actual=false. Не считайте прогноз завершённым событием. |
movements[1].timestamp = "2026-10-12T08:00:00+02:00" | containers[0].events[0].date = "2026-10-12T08:00:00" | Разбирайте смещение +02:00, если оно есть в дате. Признак фактического события определяйте по actual, а не по формату времени. |
movements[0].location | locations[0] | Вместо вложенного объекта места найдите запись в locations по event.location. |
movements[0].vessel.name = "EXAMPLE VESSEL" | containers[0].events[1].vessel = "EXAMPLE VESSEL" | Получайте название судна из строки event.vessel. Не ожидайте вложенный объект с именем и IMO. |
Даты показывают форматы полей. При переносе учитывайте смещение и часовой пояс источника: удаление Z или +08:00 не является преобразованием времени.
GeoJSON и массив координат маршрута
ShipsGo — GET /ocean/shipments/{shipment_id}/geojson
Фрагмент: geojson.features[0].
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[103.75, 1.25],
[103.4, 1.1]
]
},
"properties": {
"status": "CURRENT",
"current": {
"index": 0,
"coordinates": [103.75, 1.25]
}
}
}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",
"route": [
{
"type": "sea",
"path": [
[1.25, 103.75],
[1.1, 103.4]
]
}
]
}
}Как сопоставить
| ShipsGo | Cargotime | Что изменить |
|---|---|---|
geometry.coordinates | route_info.route[0].path | При преобразовании GeoJSON поменяйте порядок каждой точки с [долгота, широта] на [широта, долгота]. |
properties.current.coordinates = [103.75,1.25] | route_info.current_position = [1.25,103.75] | Получайте текущую точку отдельно из route_info.current_position. Она также использует порядок [широта, долгота]. |
geometry.type = "LineString" | route_info.route[0].type = "sea" | Используйте sea как вид транспорта. LineString описывает форму GeoJSON и не является допустимой заменой sea. |
properties.status = "CURRENT" | Нет прямого аналога | Не преобразуйте CURRENT в статус перевозки или подписки. Это состояние участка маршрута ShipsGo, для которого здесь нет отдельного поля. |
Что сохранить отдельно
Для отображения уже сохранённого маршрута используйте GET /v2/shipments?need_route=true. Запросы GET /v2/tracking?need_route=true и POST /v2/tracking/batch?need_route=true запускают отслеживание и могут расходовать кредиты. Если ваша карта использует GeoJSON, преобразуйте точки из [широта, долгота] в [долгота, широта].
Обновлено