Полные примеры¶
Синхронное создание и отслеживание¶
1. POST /api/Account/Token
→ сохранить accessToken.token и expiresIn
2. GET /api/integrations/Organizations/Check?inn=7701234567
→ проверить canCreateBids и hasAccess
3. POST /api/integrations/Organizations/Apply
→ при необходимости создать организацию или получить доступ
4. POST /api/integrations/Bids/Apply
→ сохранить id заявки CARGO.RUN
5. GET /api/integrations/Bids/Get?id={id}
→ карточка, статус и ETA
6. GET /api/integrations/Bids/GetEvents?id={id}
→ события исполнения
7. GET /api/integrations/Bids/GetActualRoute?id={id}&coordinateIntervalSeconds=60
→ фактические координаты
8. GET /api/integrations/Bids/GetDriverMessages?id={id}
→ сообщения и временные ссылки на файлы
Асинхронное создание¶
Поставить задачу¶
POST <baseUrl>/api/integrations/Tasks/Queue
Authorization: Bearer <accessToken.token>
Content-Type: application/json
Idempotency-Key: write-order-2471970-v1
{
"commands": [
{
"action": "Write",
"objects": [
{
"type": "Bid",
"modelType": "Default",
"key": "ORDER-2471970",
"body": {
"inn": "7701234567",
"bid": {
"externalId": "ORDER-2471970",
"counterparty": {
"name": "ООО Ромашка",
"inn": "7701234567"
},
"vehicleType": {
"name": "Рефрижератор",
"tonnage": 20,
"volume": 82
},
"temperatureRegime": {
"minimum": 2,
"maximum": 6
},
"cargos": [
{
"name": "Паллетированный груз"
}
],
"bidPoints": [
{
"externalId": "POINT-LOAD-1",
"isLoadPoint": true,
"planEnterDate": "2026-10-08T10:00:00",
"geozone": {
"address": "Москва, улица Примерная, 1",
"location": { "coordinates": [37.6176, 55.7558] }
}
},
{
"externalId": "POINT-UNLOAD-1",
"isLoadPoint": false,
"planEnterDate": "2026-10-09T10:00:00",
"geozone": {
"address": "Казань, улица Примерная, 2"
}
}
],
"car": { "number": "А123АА777", "brandName": "КАМАЗ" },
"driver": {
"firstName": "Иван",
"lastName": "Иванов",
"phoneNumber": "+79991234567"
}
}
}
}
]
}
]
}
Ответ постановки задачи:
{
"latencyMsec": 25,
"enqueuedInMsec": 8,
"commands": [
{
"id": 90001,
"action": "Write",
"status": "Success",
"readyInMsec": 100,
"message": null
}
]
}
Если отдельная команда не поставлена в очередь, для неё возвращается status="Failed", поле id отсутствует, а причина находится в message.
Получить результат¶
{
"status": "Completed",
"origin": "Request",
"readyInMsec": 100,
"remainingObjectCount": 0,
"attemptCount": 1,
"maxAttemptCount": 3,
"callbackStatus": "Delivered",
"callbackAttemptCount": 1,
"callbackMaxAttemptCount": 5,
"objects": [
{
"key": "ORDER-2471970",
"type": "Bid",
"id": 12345,
"status": "Success",
"body": null,
"message": null
}
]
}
Обработка entity.changed¶
1. Прочитать raw body и заголовки.
2. Проверить допустимость X-Cargorun-Webhook-Timestamp.
3. Рассчитать HMAC_SHA256(secret, timestamp + "." + rawBody).
4. Сравнить с X-Cargorun-Webhook-Signature.
5. Проверить eventId на повтор.
6. Сохранить событие во внутреннюю очередь.
7. Вернуть HTTP 204.
8. Для каждого успешного объекта взять id.
9. Выполнить Read / Bid / Default.
10. Если нужны координаты — вызвать Bids/GetActualRoute.
Восстановление после недоступности webhook¶
{
"commands": [
{
"action": "ReadQuery",
"objects": [
{
"type": "Bid",
"modelType": "Default",
"query": "$filter=updatedAt gt 2026-10-07T07:59:55Z&$orderby=updatedAt,id&$top=100"
}
]
}
]
}
Интервал начинается немного раньше последнего курсора. Повторные записи удаляются по id, а более новые версии определяются по updatedAt.