# CARGO.RUN Логистика
> Полная машиночитаемая версия. Источник: https://cargorun-ru.github.io/cargo.run-api-docs/products/cargorun-logistics/
---
Source: products/cargorun-logistics/index.md
# CARGO.RUN Logistics — Документация по API
Добро пожаловать в документацию по интеграции с **CARGO.RUN Логистика**.
Здесь собраны:
- правила работы с API (форматы данных, статусы, обязательные поля),
- сценарии интеграции с учетными системами (1С и др.),
- справочник методов API (по доменам: заявки, заказы, справочники, ЭТРН и пр.).
---
## 1. С чего начать
1. Прочитать общие принципы и архитектуру интеграции:
[Введение](./introduction.md)
2. Ознакомиться с базовыми понятиями и терминами:
[Глоссарий](./glossary.md)
3. Посмотреть, какие форматы данных используются во всех методах:
[Форматы данных](./formats.md)
4. Понять, какие статусы бывают у заявок, контрагентов, ЭТРН и т.д.:
[Статусные модели](./statuses.md)
5. Уточнить минимальные требования к полям при создании сущностей:
[Минимальные требования к запросам](./minimal-requirements.md)
---
## 2. Сценарии интеграции
Раздел для аналитиков и интеграторов, отвечающих за поток данных между CARGO.RUN и учетной системой (1С, ERP и др.):
- Общий обзор интеграции
[Общий обзор](./integration/overview.md)
- Сценарий: заявка создается в CARGO.RUN
[CARGO.RUN → учетная система](./integration/scenario-cr-to-external.md)
- Сценарий: заявка создается во внешней системе
[Учетная система → CARGO.RUN](./integration/scenario-external-to-cr.md)
- Синхронизация справочников и статусов
[Синхронизация данных](./integration/sync.md)
- Асинхронная синхронизация заявок
[Синхронизация заявок API 2.0](./integration/async-sync-v2.md)
- Примеры интеграции с 1С
[Примеры для 1С](./integration/examples-1c.md)
---
## 3. API Reference
Технический справочник методов API, сгруппированных по доменам.
Раздел для разработчиков, которые пишут интеграцию.
- Общие принципы работы API, заголовки, ошибки
[Обзор API](./api/overview.md)
- Авторизация и работа с токенами
[Auth API](./api/auth.md)
- Справочники
[API справочников](./api/directories.md)
- Контрагенты, договоры и адреса
[Контрагенты API](./api/counterparties.md)
- Пользовательские справочники
[Пользовательские справочники API](./api/custom-catalogs.md)
- Заявки и рейсы
[Bids API](./api/bids.md)
- Асинхронные задания API 2.0
[Очередь API 2.0](./api/async-tasks.md)
- Заказы / распределительные заявки
[Distribution bids API](./api/distribution-bids.md)
- Транзакции заправок
[Refueling Transactions API](./api/refueling-transactions.md)
- Трекеры и привязка к ТС
[Trackers API](./api/trackers.md)
- Электронные транспортные накладные (ЭТРН)
[ЭТРН API](./api/etrn.md)
---
## 4. Для LLM и ИИ-агентов
Для подключения документации к ИИ-ассистенту, базе знаний или агенту используйте
[машиночитаемые материалы и правила безопасной работы](./for-ai.md).
---
Source: products/cargorun-logistics/introduction.md
# Введение
Этот документ описывает правила интеграции с системой **CARGO.RUN Логистика** через REST API.
API предназначен для обмена данными между CARGO.RUN и внешними учётными системами (1С, ERP, WMS, мобильными приложениями, внешними сервисами и т.д.).
Документация разделена на три большие части:
1. общие правила и форматы данных;
2. сценарии интеграции;
3. API Reference (справочник методов).
---
## 1. Назначение API CARGO.RUN
API предоставляет доступ к данным и функциям системы:
- создание и редактирование заявок и заказов,
- работа с маршрутами,
- синхронизация справочников (контрагенты, водители, техника, организации),
- управление статусами заявок, титулов и ЭТРН,
- получение событий и информации о ходе перевозок,
- работа с данными сотрудников, трекеров и мобильных клиентов.
API предназначено для систем:
- 1С и её конфигураций,
- собственных ERP клиентов,
- CRM,
- внешних логистических платформ,
- сервисов телематики,
- приложений мобильных водителей,
- корпоративных интеграционных решений.
---
## 2. Архитектура интеграции
Архитектурно API CARGO.RUN устроено как REST API:
- обмен данными осуществляется по HTTPS;
- запросы и ответы передаются в формате JSON UTF-8;
- каждый метод соответствует ресурсу или действию;
- авторизация выполняется через токен.
REST-подход обеспечивает простоту интеграции, предсказуемость и совместимость с клиентскими библиотеками.
---
## 3. Версионирование
API стремится сохранять обратную совместимость. Обновления вносятся в соответствии с принципами:
- новые поля добавляются без нарушения обратной совместимости;
- изменение обязательности полей всегда оговаривается заранее;
- разрушительные изменения должны сопровождаться новой версией API и планом миграции.
Текущие методы используют пути без номера версии (`/api/...`). Поэтому перед
обновлением интеграции проверяйте журнал изменений и согласовывайте разрушительные
изменения с владельцем API.
---
## 4. Базовый URL API
Фактический адрес среды предоставляется при подключении интеграции. В документации
он обозначается как `` и **не включает** суффикс `/api`.
Примеры формирования URL:
- `GET /api/bids/GetListForExternal`
- `POST /api/TruckingBids/Apply`
- `POST /api/tasks/queue`
---
## 5. Формат запросов и ответов
- Все запросы — JSON.
- Успешные ответы обычно передаются в JSON. Ошибки отдельных методов могут быть
JSON-объектом или обычным текстом; это указано в описании форматов.
- Кодировка — UTF-8.
- При необходимости передавать вложенные структуры используются стандартные JSON-объекты и массивы.
Во всех примерах документации используется форматирование, совместимое с JSONLint.
---
## 6. Авторизация
Доступ к API выполняется через выдачу токена.
В интеграции используется схема: Authorization: Bearer
Токен выдаётся методом авторизации и имеет срок действия.
Обновление токена (refresh) выполняется через соответствующий метод API.
Все методы, взаимодействующие с данными клиента, требуют авторизации.
---
## 7. Ограничения и квоты
API может вводить ограничения:
- лимиты на количество запросов в единицу времени (rate limit),
- ограничения на размер запросов,
- требования к обязательным полям,
- набор допустимых статусов и переходов для сущностей.
Эти ограничения фиксируются по мере необходимости в описаниях методов.
---
## 8. Следующие шаги
Для дальнейшей работы рекомендуется:
1. Ознакомиться с форматами данных:
[Форматы данных](./formats.md)
2. Изучить статусные модели:
[Статусы сущностей](./statuses.md)
3. Посмотреть минимальные требования к обязательным полям:
[Минимальные требования](./minimal-requirements.md)
4. Перейти к обзору сценариев интеграции:
[Сценарии интеграции](./integration/overview.md)
5. Для оперативного обмена изменениями заявок изучить:
[Синхронизация заявок API 2.0](./integration/async-sync-v2.md)
---
Source: products/cargorun-logistics/minimal-requirements.md
# Минимальные требования к данным
Этот раздел содержит минимальные обязательные поля, которые необходимы при создании сущностей через API **CARGO.RUN Логистика**.
Значения обязательных полей должны присутствовать в запросах, иначе метод вернёт ошибку валидации.
Если метод требует дополнительные поля, они указаны в описании соответствующего метода в API Reference.
---
# 1. Создание заявки (Bid)
Минимальный набор полей зависит от того, создаётся ли заявка полностью в CARGO.RUN или поступает из внешней системы (1С, ERP).
| Поле | Тип | Описание |
|------|------|----------|
| `cargoOwnerDictionaryItemId` | number | Идентификатор заказчика (контрагента). |
| `paymentTypeId` | number | Тип оплаты. |
| `ndsTypeId` | number | Тип НДС. |
| `price` | number | стоимость в рублях (с НДС). |
| `driver` | object | Идентификатор водителя. |
| `carOption` | object | Идентификатор автомобиля (тягача). |
| `trailerOption` | object | Идентификатор полуприцепа. |
| `bidPoints` | array | Маршрутные точки (минимум две: погрузка и выгрузка). |
Для порожней заявки передайте `isEmptyMileageBid = true`. Текущая валидация также
требует технические заполнители, хотя при обработке порожней заявки их значения
игнорируются:
- `price`: например, `1`;
- `cargos`: непустой массив, например `[ { "id": 0, "name": null } ]`;
- `paymentTypeId` и `ndsTypeId`: существующие ID из справочников целевой организации.
Не придумывайте ID типов оплаты и НДС: получите допустимые значения до запуска
интеграции. `cargoOwnerDictionaryItemId` для порожней заявки можно не передавать.
Если в организации включён учёт причин порожнего пробега, объект `emptyMileageBid`
обязателен.
---
# 2. Создание заказа (DistributionBid)
| Поле | Тип | Описание |
|------|------|----------|
| `bidPoints` | array | Маршрутные точки (минимум две: погрузка и выгрузка). |
---
# 3. Создание контрагента (Counterparty)
| Поле | Тип | Описание |
|------|------|----------|
| `name` | string | Наименование организации. |
| `inn` | string | ИНН. |
| `kpp` | string (nullable) | КПП (опционально)|
---
# 4. Создание водителя (Driver)
| Поле | Тип | Описание |
|------|------|----------|
| `firstName` | string | Имя водителя. |
| `lastName` | string | Фамилия водителя. |
| `phoneNumber` | string | Телефон в формате +7XXXXXXXXXX. |
---
# 5. Создание автомобиля (Car)
| Поле | Тип | Описание |
|------|------|----------|
| `number` | string | Госномер. |
---
# 6. Создание прицепа (Trailer)
| Поле | Тип | Описание |
|------|------|----------|
| `number` | string | Госномер. |
---
# 7. Общие правила
1. Все числовые идентификаторы (`xxxId`) должны существовать в справочниках.
2. Поля, указанные как обязательные, не могут быть `null`.
3. Любые дополнительные поля передавайте только если они описаны в соответствующем разделе API Reference.
4. Если описание конкретного метода требует больший набор полей, используйте требования этого метода.
---
# 8. Что делать при ошибке валидации
Если обязательное поле опущено или не соответствует типу:
- сервер возвращает ошибку `400 Bad Request`,
- тело ответа может быть обычным текстом или объектом `ValidationApiResult` с полем `errorMessage`; клиент должен уметь сохранить оба варианта.
Рекомендуется логировать ошибки на стороне внешней системы.
---
Source: products/cargorun-logistics/formats.md
# Форматы данных
В этом разделе приведены единые форматы данных, используемые во всех методах API **CARGO.RUN Логистика**.
---
## 1. Формат даты и времени
### Основной формат
API использует ISO 8601, но трактовка часового пояса зависит от поля.
| Категория | Формат | Трактовка |
|---|---|---|
| Технические метки (`createdAt`, `updatedAt`) и границы OData-фильтров | `YYYY-MM-DDTHH:mm:ssZ` | UTC |
| Поля с суффиксом `Offset` | `YYYY-MM-DDTHH:mm:ss±HH:mm` | Момент времени с явным смещением |
| `bidPoints[].planEnterDate` и другие явно локальные плановые даты | `YYYY-MM-DDTHH:mm:ss` | Локальное время адреса точки; зона определяется по геоданным точки |
Примеры:
- `2025-03-12T15:20:00Z`
- `2025-03-12T18:20:00+03:00`
- `2025-03-12T18:20:00`
Исключение: метод получения пробегов `/api/car/getcarmileageforperiod`
В нем используется формат без часового пояса: `YYYY-MM-DDTHH:mm:ss`
Пример: `/api/car/getcarmileageforperiod?carid=694385&start=2025-10-31T21:00:00&end=2025-11-17T20:59:59`
### Особенности
- Для `updatedAt` и других технических меток используйте UTC с `Z`.
- Для `planEnterDate` передавайте локальное время точки без `Z`; геозона должна
позволять системе определить часовой пояс.
- Не добавляйте `Z` к локальной дате: это изменит смысл времени.
- Если конкретный метод задаёт другой формат, его описание имеет приоритет.
- Доли секунды не используйте, если они не показаны в описании метода.
---
## 2. Числовые идентификаторы (ID)
Идентификаторы сущностей передаются **только как целые числа**.
Правильно:
`12345`
Неправильно:
`"12345"`
Это требование распространяется на:
- заявки (`bidId`)
- заказы (`orderId`)
- контрагентов (`counterpartyId`)
- водителей (`driverId`)
- автомобили (`carId`)
- прицепы (`trailerId`)
- организации (`organizationId`)
- сотрудников (`employeeId`)
- трекеры (`trackerId`)
---
## 3. Телефонные номера
Телефон передаётся в международном формате:
`+7XXXXXXXXXX`
Где:
- нет пробелов,
- нет дефисов,
- код страны обязательно `+7`.
Пример:
`+79991234567`
---
## 4. Координаты
Координаты передаются в виде двух числовых значений:
- **latitude** — широта
- **longitude** — долгота
Формат:
```json
{
"latitude": 55.7558,
"longitude": 37.6176
}
```
Допускается использование вложенных структур (например, GeoJSON), если это описано в конкретном методе API.
---
## 5. Адреса
Адрес всегда содержит следующие элементы (если применимо):
- строка адреса,
- город,
- регион,
- страна,
- геокоординаты,
- дополнительные комментарии.
Используемые поля зависят от конкретного эндпоинта.
---
## 6. Денежные значения и ставки
Стоимость, суммы, ставки и другие денежные поля передаются как числа с фиксированной точностью:
- только число, без строк;
- без символа валюты;
- разделитель — точка.
Примеры:
- `1000`
- `12000.5`
- `0.0`
---
## 7. Boolean (логические значения)
Используются стандартные JSON-значения:
- `true`
- `false`
Недопустимо:
- `"true"`
- `"yes"`
- `"0"`
- `"1"`
---
## 8. Строки
Строки передаются в кодировке UTF-8.
Допускается использование:
- точек,
- запятых,
- спецсимволов JSON,
- Unicode.
---
## 9. Enum-значения
Если поле принимает фиксированный набор значений (например, статус заявки или тип прицепа), то:
- значение должно быть строго равно одному из элементов перечисления;
- формат перечислений приведён в разделе "Статусы".
---
## 10. Списки и массивы
Если поле является массивом:
```json
[
{ ... },
{ ... }
]
```
Особенности:
- массив должен содержать однородные элементы;
- порядок элементов — значимый, если указано в описании метода.
---
## 11. Пагинация
Некоторые методы API поддерживают постраничную выборку.
Используются два механизма:
1. Классическая пагинация:
- `page` — номер страницы (начиная с 1);
- `pageSize` — количество элементов на странице.
2. OData-пагинация:
- `$top` — максимальное количество записей;
- `$skip` — количество записей, которые нужно пропустить.
Конкретный механизм для метода указан в описании эндпоинта (API Reference).
Если метод принимает `page`/`pageSize`, их значения должны быть целыми числами ≥ 1.
Если метод принимает `$top`/`$skip`, рекомендуется использовать их в духе OData:
- `$top` — ограничение выборки (например, 100);
- `$skip` — смещение (например, 0, 100, 200...).
---
## 12. Параметры OData
Ряд методов поддерживает фильтрацию и выборку данных в стиле OData.
В описаниях методов могут использоваться следующие параметры:
- `$filter` — фильтрация по условиям;
- `$select` — выбор отдельных полей;
- `$expand` — раскрытие связанных сущностей;
- `$orderBy` — сортировка;
- `$top` — ограничение числа записей;
- `$skip` — пропуск указанного числа записей;
- `$count` — запрос количества записей.
Конкретный синтаксис выражений в `$filter`, `$orderBy` и правила комбинации параметров следует смотреть в описании соответствующих методов API.
---
## 13. Ошибки API { #api-errors }
При ошибках бизнес-валидации API CARGO.RUN возвращает:
- HTTP-код 400 (`Bad Request`)
- тело ответа в виде обычного текста либо объекта `ValidationApiResult` с полем `errorMessage` — в зависимости от метода
Формат ответа:
```
400 Bad Request
<текст ошибки>
```
Пример:
```
400 Bad Request
Driver cannot be deleted because he has active bids
```
Клиенту не следует предполагать единственный `Content-Type` ошибки. Сначала проверьте
тип содержимого ответа; если получен JSON, прочитайте `errorMessage`, иначе сохраните
текст ответа целиком.
---
Source: products/cargorun-logistics/statuses.md
# Статусы сущностей
В этом разделе собраны статусные модели ключевых сущностей **CARGO.RUN Логистика**.
---
# 1. Статусы заявок (BidStatus)
Статус отражает текущее состояние заявки.
Заявка проходит несколько этапов — от создания до завершения или отмены.
| Статус | Код | Описание |
|---|---:|---|
| `New` | `0` | Заявка создана, находится в статусе черновика. |
| `Planned` | `5` | Запланирована к выполнению. |
| `Started` | `10` | Начата, запущена в работу. |
| `Canceled` | `20` | Заявка отменена. |
| `Done` | `30` | Заявка выполнена. |
### Примечания
- Статус `New` означает, что заявка еще не запущена логистом.
- Статус `Planned` означает, что заявку попытались запустить, но транспортное средство
занято другой заявкой и у организации включено планирование. Этот статус назначает
система; передавать `Planned` в `SetStatus` вручную нельзя.
- При запросе `Started` итоговый статус может оказаться `Planned`. Проверяйте ответ
команды и повторно читайте заявку.
- Переходы между статусами контролируются бизнес-логикой системы.
---
# 2. Статусы оплаты заявки
Статусы отражают состояние расчётов по заявке со стороны заказчика.
| Статус | Описание |
|--------|----------|
| `NotPaid` | Оплата по заявке не поступила. |
| `PartiallyPaid` | Оплачена частично. |
| `Paid` | Полностью оплачена. |
| `Expired` | Истёк срок оплаты. |
---
# 3. Статусы контрагентов
Контрагенты могут иметь различный статус, определяющий возможность работы с ними в системе.
| Статус | Описание |
|--------|----------|
| `None` | Ограничения отсутствуют. |
| `Priority` | Приоритетный контрагент. |
| `Suspended` | Работа временно приостановлена. |
---
# 4. Статусы титулов (ЭТРН)
Электронная транспортная накладная (ЭТРН) включает несколько титулов и уровней подписания.
Фактические статусы могут отличаться в зависимости от провайдера ЭТРН, поэтому здесь указаны статусы `WaybillTitleStatus`, используемые в API.
| Статус | Описание |
|--------|----------|
| `ReceivedOrCreated` | Титул получен или создан системой. |
| `Accepted` | Титул принят водителем или внешней системой. |
| `Signed` | Титул подписан. |
| `Sent` | Титул передан на отправку в ЭДО. |
| `Processed` | Титул обработан провайдером ЭТРН. |
| `Declined` | Титул отклонён. |
| `Failed` | При обработке титула возникла ошибка. |
---
Source: products/cargorun-logistics/glossary.md
# Глоссарий
Этот раздел содержит основные термины, используемые в документации и API **CARGO.RUN Логистика**.
Определения даны в техническом и интеграционном контексте.
---
## Заявка (Bid)
Основная сущность планирования перевозки. Содержит:
- информацию о контрагенте (заказчике),
- параметры груза,
- маршрутные точки,
- сроки посещения точек,
- стоимость и условия оплаты,
- транспортное средство,
- водитель,
- полуприцеп.
Заявка является основой для формирования рейса.
---
## Заказ (DistributionBid)
Сущность планирования перевозки, аналогичная Заявке, но без указанных транспортного средства, водителя, полуприцепа.
Используется для управления нераспределёнными рейсами.
---
## Маршрутная точка (BidPoints)
Элемент маршрута, включающий:
- адрес,
- геокоординаты,
- даты,
- вид операции (погрузка, выгрузка, пересортировка).
Передаются массивом в сущности Заявка (Bid).
---
## Контрагент (Counterparty)
Юридическое лицо заказчика перевозки:
В API используются поля `counterpartyId` и связанные справочники.
---
## Организация (Organization)
Юридическое лицо перевозчика (транспортной компании).
---
## Водитель (Driver)
Сотрудник транспортной компании, закреплённый за рейсом.
Связан с мобильным приложением CARGO.RUN Driver.
---
## Машина (Car)
Транспортное средство — тягач или грузовик.
В API содержит:
- государственный номер,
- модель и марка,
- привязанный трекер.
---
## Прицеп / Полуприцеп (Trailer)
Дополнительное транспортное средство, используемое с тягачом.
В API содержит:
- государственный номер,
- модель и марка,
- тип полуприцепа (тент, изотерм, рефрижератор).
Может иметь привязанный трекер.
---
## Трекер (Tracker)
Устройство телематики, передающее координаты и технические данные.
В API используются методы привязки/отвязки трекеров.
---
## ЭТРН / Электронная транспортная накладная (Waybill)
Электронный аналог транспортной накладной, содержащий:
- сведения о грузе,
- отправителе,
- перевозчике,
- водителе,
- маршруте,
- титулы подписей.
API позволяет получать статусы ЭТРН, передавать титулы, QR-коды, электронные подписи и изменять статусы титулов.
---
## Сотрудник (Employee)
Человек, имеющий доступ в систему или связанный с операционными процессами:
- логист,
- водитель,
- администратор,
- бухгалтер.
---
## Статус (Status)
Текущее состояние сущности:
- заявки,
- оплаты,
- контрагента,
- ЭТРН.
Перечни статусов находятся в разделе "[Статусы](./statuses.md)".
---
## Идентификатор (ID)
Числовое значение, определяющее сущность в системе.
Все идентификаторы передаются как числа (не строки).
---
## Токен (Token)
Ключ авторизации в API, выдаётся методом авторизации.
Передаётся в заголовке: Authorization: Bearer
---
## Обновление данных (Sync / Synchronization)
Регулярное сравнение данных между внешней системой (1С, ERP) и CARGO.RUN:
- синхронизация справочников,
- обновление заявок,
- передача статусов.
Описано в разделе "[Синхронизация данных](./integration/sync.md)".
---
Source: products/cargorun-logistics/integration/overview.md
# Обзор интеграции
Этот документ описывает архитектуру и общие принципы интеграции между CARGO.RUN Logistics 2.0 и внешними системами (1С, ERP, WMS, CRM, внешние логистические платформы).
Он служит отправной точкой перед изучением сценариев и конкретных методов API.
---
# 1. Общая архитектура интеграции
Интеграция выполняется через REST API:
- обмен осуществляется по HTTPS;
- данные передаются в формате JSON;
- доступ — по токену авторизации;
- для выборок и фильтрации используется система query-параметров (включая OData-стиль).
Архитектура интеграции предполагает два возможных источника данных:
1. **CARGO.RUN → внешняя система**
данные создаются в CARGO.RUN, внешняя система их получает;
2. **Внешняя система → CARGO.RUN**
данные создаются во внешней системе и передаются в CARGO.RUN для планирования и исполнения.
Обе модели полностью поддерживаются.
---
# 2. Роль CARGO.RUN в потоке данных
CARGO.RUN выступает как:
- система планирования маршрутов и рейсов,
- система контроля исполнения перевозок,
- система мониторинга транспорта,
- хранилище заявок и статусов,
- точка сборки всех событий по перевозке.
Внешние системы (ERP, 1С, WMS) обычно отвечают за:
- учёт грузов,
- расчёты и финансы,
- ведение справочников,
- учёт заказчиков и заказов.
---
# 3. Базовые интеграционные возможности
API CARGO.RUN предоставляет возможности:
- создавать заявки (Bid) и заказы (DistributionBids);
- обновлять статусы заявок и ЭТРН;
- передавать маршрутные точки и параметры груза;
- синхронизировать справочники:
- контрагенты,
- водители,
- автомобили,
- прицепы,
- организации;
- управлять трекерами (привязка/отвязка);
- получать данные о рейсах и событиях выполнения;
- получать статусы титулов ЭТРН.
Для заявок используются два канала синхронизации: асинхронная очередь API 2.0
для оперативных изменений и `GetListForExternal` для первичной загрузки,
статусов, удалений и контрольной сверки. См.
[Синхронизация заявок API 2.0](./async-sync-v2.md).
---
# 4. Двусторонняя интеграция
Интеграция может быть:
## 4.1. Односторонняя
Только внешняя система отправляет данные в CARGO.RUN
Или наоборот, CARGO.RUN передаёт события во внешнюю систему.
## 4.2. Двусторонняя
Обе системы создают данные, обновляют статусы и синхронизируют справочники.
Типовой пример двусторонней интеграции:
- 1С создаёт заявку;
- заявка передаётся в CARGO.RUN;
- CARGO.RUN планирует и исполняет рейс;
- статусы и результаты выполнения возвращаются в 1С.
---
# 5. Основные потоки данных
Интеграция покрывает три больших направления:
## 5.1. Справочники
Передаются регулярно или по событию:
- контрагенты,
- водители,
- автомобили,
- прицепы,
- организации.
Справочники должны быть синхронизированы до создания заявок.
---
## 5.2. Документы (заявки и заказы)
Потоки данных:
1. Внешняя система создаёт заявку/заказ → отправка в CARGO.RUN.
2. CARGO.RUN создаёт заявку → внешняя система получает её через API.
3. Обновление заявок обеими сторонами.
4. Отслеживание статусов заявок.
---
## 5.3. События перевозки
CARGO.RUN может передавать или предоставлять:
- время прибытия/отъезда,
- времена начала/завершения погрузки/выгрузки,
- пробег,
- задержки,
- отклонения от маршрута.
Эти данные используются внешними системами для:
- аналитики,
- расчётов,
- контроля SLA,
- контроля выполнения перевозок.
---
# 6. Потоки статусов
Статусы меняются:
- со стороны логиста,
- со стороны ЭТРН-провайдера,
- со стороны исполнителя (водитель),
- автоматически (например, при успешном закрытии рейса).
Внешние системы могут:
- получать статусы через API,
- сверять статусы заявок,
- сохранять историю изменений у себя.
---
# 7. Требования к идентификаторам
Для корректной интеграции обязательны:
- единые ID справочников;
- фиксированные значения статусных моделей;
- строгое соответствие названий полей, указанным в API Reference.
Дубликаты или ошибки в идентификаторах приводят к конфликтам в данных.
---
# 8. Принципы синхронизации данных
- Данные синхронизируются по методу «запрос → ответ».
- Для выборок поддерживаются фильтры и пагинация.
- Для оптимизации могут использоваться:
- `updatedAt`,
- `$filter` c условиями,
- `$top` / `$skip`,
- `$orderby`.
Синхронизация справочников и заявок описана в посвящённом разделе.
---
# 9. Что изучать дальше
Для продолжения работы:
1. Сценарий: заявка создаётся в CARGO.RUN
→ [CARGO.RUN → внешняя система](./scenario-cr-to-external.md)
2. Сценарий: заявка создаётся во внешней системе
→ [Внешняя система → CARGO.RUN](./scenario-external-to-cr.md)
3. Синхронизация справочников
→ [Синхронизация данных](./sync.md)
---
Source: products/cargorun-logistics/integration/scenario-cr-to-external.md
# Сценарий: заявка создаётся в CARGO.RUN
Этот сценарий описывает ситуацию, когда заявка (Bid) создаётся и редактируется в системе CARGO.RUN, а внешняя система (1С, ERP или другое приложение) должна получать эти данные, реагировать на изменения и использовать их в собственных процессах.
---
# 1. Структура процесса
Процесс синхронизации в этом сценарии включает три части:
1. **CARGO.RUN создаёт и изменяет заявки.**
2. **Внешняя система получает новые или обновлённые заявки через API 2.0 и выполняет контрольную сверку.**
3. **Внешняя система сохраняет данные и обновляет статусы у себя.**
Внешняя система не должна создавать заявку в CARGO.RUN — только принимать и обрабатывать.
---
# 2. Создание заявки в CARGO.RUN
Заявки формируются логистами CARGO.RUN:
- выбор контрагента,
- указание маршрута и точек,
- выбор водителя и автомобиля,
- назначение стоимости и НДС,
- уточнение условий перевозки.
После сохранения заявка получает статус `New` или `Planned`, в зависимости от процесса клиента.
---
# 3. Получение заявок внешней системой
Внешняя система должна периодически выполнять запрос на получение заявок, созданных или обновлённых после определенного момента времени.
Типовой алгоритм:
1. Хранить границу последнего полностью обработанного окна синхронизации.
2. Для оперативных изменений использовать `POST/GET /api/tasks/queue` и
`ReadConfirmation`; вызывать чтение чаще одного раза в час.
3. Зафиксировать новую верхнюю границу и выполнить первичную или контрольную выборку
методом `GET /api/bids/GetListForExternal`.
4. Получать фиксированное окно порциями по 50 записей через `$top=50` и `$skip`.
5. Сортировать результат по `updatedAt,id` и идемпотентно сохранять по `id` и `updatedAt`.
6. Учитывать `isDeleted = true`, а не отбрасывать удалённые заявки.
7. Продвигать границу только после успешной обработки всех страниц; следующее окно
начинать с перекрытием для защиты от совпадающих меток времени.
Пример запроса:
```http
GET /api/bids/GetListForExternal
?$filter=updatedAt ge 2024-01-23T21:00:00Z
and updatedAt le 2024-01-25T20:59:59Z
and createdAt ge 2022-09-30T21:00:00Z
&$top=50
&$orderby=updatedAt,id
&$skip=0
```
Подробный алгоритм приведён в разделах [Синхронизация данных](./sync.md) и
[Синхронизация заявок API 2.0](./async-sync-v2.md).
---
# 4. Синхронизация справочников перед обработкой заявок
Перед обработкой новых заявок внешняя система должна обеспечить актуальность справочников:
- контрагенты,
- водители,
- автомобили,
- прицепы,
- организации.
Если у заявки указан водитель с `driverId`, который отсутствует в внешней базе, система должна либо:
- предварительно загрузить справочник водителей,
- либо запросить данные этого водителя.
---
# 5. Обработка статусов заявок
CARGO.RUN управляет статусами заявки (этапы выполнения рейса).
Внешняя система должна регулярно получать актуальные статусы через
`GET /api/bids/GetListForExternal`. API 2.0 пока не гарантирует доставку каждой смены
статуса и удаления, поэтому очередь не заменяет контрольную выборку.
Статусы, которые важно отслеживать:
- `Planned`
- `New`
- `Done`
- `Canceled`
Внешняя система должна обновлять свои записи в соответствии с полученными статусами.
---
# 6. Обработка событий перевозки
Дополнительно могут передаваться:
- фактические времена прибытия,
- времена начала/завершения погрузки/выгрузки,
- пробег,
- задержки,
- отклонения от маршрута.
Эти данные используются во внешних системах для:
- расчёта KPI,
- учёта времени,
- проверки SLA,
- расчётов с перевозчиком.
---
# 7. Частота синхронизации
Подходы:
- **периодически** — каждые 1–5 минут (рекомендуемый вариант),
- **по расписанию** — например, каждые 15 минут,
- **только вручную** — если система не требует оперативного обновления (не рекомендуется).
При высокой нагрузке возможно использовать:
- `$top=50`
- `$skip` для перехода к следующей странице
- `$orderby=updatedAt`
- инкрементальные загрузки.
Не запрашивайте полный список без ограничения количества записей. Для минимизации нагрузки на сервер списки нужно получать порциями по 50 записей; при тяжелых запросах пользователь может быть временно заблокирован системой.
---
# 8. Обработка ошибок и конфликтов
Внешняя система должна корректно обрабатывать:
- отсутствие данных,
- некорректные значения справочников,
- недоступность API,
- устаревшие timestamp (если синхронизация задержалась).
При ошибке желательно:
- повторить запрос,
- логировать ситуацию,
- не терять timestamp последней успешной синхронизации.
---
# 9. Что изучать дальше
- Сценарий обратного направления:
[Внешняя система → CARGO.RUN](./scenario-external-to-cr.md)
- Механизмы синхронизации:
[Синхронизация данных](./sync.md)
- Минимальные требования к данным:
[Минимальные требования](../minimal-requirements.md)
---
Source: products/cargorun-logistics/integration/scenario-external-to-cr.md
# Сценарий: заявка создаётся во внешней системе
Этот сценарий описывает процесс, в котором внешняя система (1С, ERP, WMS или другая учетная система) является источником создания заявок.
CARGO.RUN принимает данные, формирует рейсы, управляет маршрутом, контролирует исполнение и возвращает статусы во внешнюю систему.
---
## 1. Общая последовательность процесса
Процесс включает следующие этапы:
1. Внешняя система формирует заявку или заказ.
2. Перед отправкой заявка проходит проверку данных.
3. Внешняя система отправляет заявку в CARGO.RUN.
4. CARGO.RUN создаёт заявку **в статусе `New` (Черновик)**.
5. Внешняя система **запускает заявку в работу**.
6. CARGO.RUN планирует и исполняет рейс.
7. Внешняя система регулярно получает обновления статусов заявки.
---
## 2. Требования к данным перед отправкой
Перед тем как создать заявку в CARGO.RUN, внешняя система должна убедиться:
- все необходимые справочники синхронизированы:
- контрагенты,
- водители,
- автомобили,
- прицепы,
- организации;
- обязательные поля заполнены (см. раздел "Минимальные требования"):
- `cargoOwnerDictionaryItemId`,
- `paymentTypeId`,
- `ndsTypeId`,
- `carId`,
- `driverId`,
- `bidPoints`.
- значения идентификаторов (`xxxId`) существуют в системе.
Если справочники не синхронизированы, система вернет ошибку валидации.
---
## 3. Создание заявки во внешней системе
Обычно внешняя система формирует заявку на основе внутренних процессов:
- формирование груза,
- данные клиента,
- информация по отправителю/получателю,
- планируемая дата доставки,
- параметры перевозки.
После формирования заявки данные приводятся к структуре JSON, соответствующей требованиям API CARGO.RUN.
---
## 4. Создание черновика заявки в CARGO.RUN
Отправка выполняется запросом:
```
POST /api/TruckingBids/Apply
Content-Type: application/json
Authorization: Bearer
```
### Требование к адресу (геокодирование)
Для корректности адресов рекомендуется использовать геокодер CARGO.RUN:
```
POST /api/Map/GetAddresses
```
Тело запроса:
```json
{
"address": ""
}
```
Метод возвращает структурированные данные:
- координаты,
- регион,
- город,
- район,
- улицу и номер дома,
- федеральный округ.
Рекомендуется всегда использовать результаты геокодера для `bidPoints.geozone`.
---
### Пример создания черновика заявки
```json
{
"id": 0,
"cargoOwnerDictionaryItemId": 10638021,
"paymentTypeId": 41,
"ndsTypeId": 40,
"price": 234000,
"cargos": [
{
"name": "ТНП",
"typeId": 707,
"extendedProperties": []
}
],
"typeOptions": [
{
"entityOptionId": 14655740,
"id": 14655282
}
],
"bidPoints": [
{
"order": 0,
"type": "LoadPoint",
"planEnterDate": "2021-01-07T04:33:00",
"geozone": {
"location": {
"type": "Point",
"coordinates": [
52.41153359413148,
55.71049164294613
]
},
"address": "Россия, Республика Татарстан, Набережные Челны, Транспортный проезд, 15",
"city": "Набережные Челны",
"state": "Республика Татарстан",
"county": "городской округ Набережные Челны",
"street": "Транспортный проезд",
"houseNumber": "15",
"federalDistrict": "Приволжский федеральный округ",
"radius": 0
}
},
{
"order": 1,
"type": "UnloadPoint",
"planEnterDate": "2021-01-07T13:33:00",
"geozone": {
"location": {
"type": "Point",
"coordinates": [
48.39303731918335,
54.30654645200388
]
},
"address": "Россия, Ульяновск, улица Минаева, 48Б",
"city": "Ульяновск",
"state": "Ульяновская область",
"county": "городской округ Ульяновск",
"street": "улица Минаева",
"houseNumber": "48Б",
"federalDistrict": "Приволжский федеральный округ",
"radius": 0
},
"cargoOwnerDictionaryItemId": null
}
],
"driver": {
"id": 16309296
},
"carOption": {
"carId": 10483431
},
"trailerOption": {
"trailerId": 17758587
}
}
```
### Важные детали
- Поле `id` должно быть равно **0**.
- `externalId` можно использовать как атрибут для сопоставления, но он не уникален:
```json
"externalId": "string"
```
После создания сохраните возвращённый `id` CARGO.RUN. Все обновления, смены статуса
и удаления выполняйте по нему, а не по `externalId`.
### Порожняя заявка
```json
{
"isEmptyMileageBid": true,
"price": 1,
"paymentTypeId": 41,
"ndsTypeId": 40,
"cargos": [
{
"id": 0,
"name": null
}
],
"emptyMileageBid": {
"logisticReasonTypeId": 12345,
"technicalReason": null
}
}
```
При порожней заявке:
- `price`, `paymentTypeId`, `ndsTypeId` и непустой `cargos` передаются как технические
заполнители для валидации; их значения при обработке порожней заявки игнорируются;
- `paymentTypeId` и `ndsTypeId` должны ссылаться на существующие значения справочников;
- контрагент `cargoOwnerDictionaryItemId` можно не указывать.
`logisticReasonTypeId` берётся из справочника причин порожнего пробега. Для
технической порожней заявки вместо него передайте `technicalReason` (не более
256 символов). Эти два поля взаимоисключающие. Обязательность объекта
`emptyMileageBid` зависит от настройки учёта причин в организации.
---
## 5. Запуск заявки в работу
После создания черновика необходимо запустить заявку:
```
POST /api/TruckingBids/SetStatus
```
Тело запроса:
```json
{
"bidId": 123456,
"status": "Started"
}
```
Здесь `123456` — `id`, возвращённый при создании заявки. Значение `0` используется
только при создании и не подходит для последующего изменения статуса.
---
## 6. Получение статусов и списка заявок во внешней системе
Для инкрементальной синхронизации с внешней системой используется метод:
```
GET /api/bids/GetListForExternal
```
Метод возвращает HTTP-статус `200` и массив заявок.
### Принцип работы синхронизации
У каждой заявки в CARGO.RUN есть поле:
```text
updatedAt
```
Это дата последнего обновления заявки.
В процессе синхронизации используется следующий алгоритм:
1. Внешняя система фиксирует верхнюю границу окна и запрашивает заявки, у которых
`updatedAt` попадает в это окно.
2. Все страницы окна обрабатываются идемпотентно по `id` и `updatedAt`.
3. Верхняя граница сохраняется как новый рубеж только после успешной обработки всех страниц.
4. Следующее окно начинается с небольшим перекрытием; дубликаты допустимы и отбрасываются.
Полный алгоритм и его ограничения описаны в разделе
[Синхронизация данных](./sync.md#sync-updated-at).
### Пример запроса
```text
/api/bids/GetListForExternal
?$filter=updatedAt ge 2024-01-23T21:00:00Z
and updatedAt le 2024-01-25T20:59:59Z
and createdAt ge 2022-09-30T21:00:00Z
&$top=50
&$orderby=updatedAt,id
&$skip=0
```
Запрос вернёт список заявок:
- с датой обновления больше `24.01.2024 00:00` (МСК)
(`23.01.2024 21:00:00` UTC);
- с датой обновления меньше `25.01.2024 23:59` (МСК)
(`25.01.2024 20:59:59` UTC);
- с датой создания больше `30.09.2022` (если необходимо ограничение по дате создания);
- первые `50` заявок (параметр `$top`), начиная с `0` (`$skip=0`);
- отсортированные по полю `updatedAt`.
---
## 7. Обработка ошибок и корректировка данных
Типовые причины ошибок при создании и обновлении заявок:
- несоответствие идентификаторов справочников (водители, автомобили, прицепы, контрагенты);
- некорректные адреса и геозоны;
- некорректная структура массива `bidPoints`;
- отсутствие обязательных полей.
Рекомендуется:
- логировать все ошибки на стороне внешней системы;
- отображать текст ошибки операторам;
- повторять запрос после исправления данных.
---
## 8. Обновление заявки
Для обновления заявки поддерживаются два подхода.
### 8.1. Полное обновление заявки
Вызовите `POST /api/TruckingBids/Apply` и передайте полную актуальную модель заявки
с её `id > 0`. Каждый вызов полностью перезаписывает заявку: отсутствующие значения
могут быть потеряны или сброшены. Перед обновлением получите актуальную карточку и
объедините изменения.
### 8.2. Частичное обновление заявки
Вызовите `POST /api/TruckingBids/Patch`. Для вложенных коллекций действуют особые
правила: массив `bidPoints` передаётся целиком, даже при изменении одной точки.
Подробности и ограничения приведены в [справочнике методов заявок](../api/bids.md#bid-patch).
---
Source: products/cargorun-logistics/integration/sync.md
# Синхронизация справочников и заявок
Этот документ описывает порядок синхронизации данных между внешней системой (1С/ERP/WMS) и CARGO.RUN.
Синхронизация одинакова для обоих сценариев интеграции: когда заявка создаётся в CARGO.RUN и когда она создаётся во внешней системе.
---
## 1. Общие принципы синхронизации
Синхронизация выполняется через REST API CARGO.RUN по протоколу HTTPS с использованием токена авторизации.
Каждый объект (водитель, машина, прицеп, контрагент, организация, заявка):
- имеет уникальный идентификатор `id` в CARGO.RUN;
- при создании в CARGO.RUN возвращает этот `id`, который должен быть сохранён во внешней системе;
- содержит поле `updatedAt`, отражающее дату и время последнего изменения.
Поле `updatedAt` используется как основа для инкрементальной синхронизации.
Для заявок применяйте два взаимодополняющих канала:
- [асинхронную очередь API 2.0](./async-sync-v2.md) — для оперативного обмена;
- `GET /api/bids/GetListForExternal` — для первичной загрузки, статусов, удалений и
контрольной сверки.
---
## 2. Справочники, подлежащие синхронизации
### 2.1. Справочники, данные которых поступают из внешней системы
Эти справочники всегда считаются первичными во внешней системе:
- Водители
- Машины
- Прицепы
- Контрагенты
- Организации
Для них внешний идентификатор является источником истины, а CARGO.RUN — получателем.
Синхронизация выполняется через методы:
- `/api/Driver/Apply`, `/api/Driver/Delete`, `/api/Driver/Restore`, `/api/Driver/GetList`
- `/api/Car/Apply`, `/api/Car/Delete`, `/api/Car/GetList`, `/api/Car/GetForEdit`
- `/api/Trailer/Apply`, `/api/Trailer/Delete`, `/api/Trailer/GetList`
- `/api/CargoOwnerDictionary/Apply`, `/api/CargoOwnerDictionary/Delete`, `/api/CargoOwnerDictionary/Get`
- `/api/LegalPersons/Apply`, `/api/LegalPersons/Delete`, `/api/LegalPersons/GetList`
**Рекомендуемая частота синхронизации: не больше чем раз в 1 минуту.**
---
### 2.2. Ограничения на удаление водителей, машин и прицепов
При удалении объектов-справочников (водителей, машин, прицепов) действуют бизнес-ограничения.
Система не позволяет удалить объект, если он используется в актуальных данных, например:
- водитель назначен на активную или запланированную заявку;
- машина участвует в активной заявке;
- прицеп привязан к активной заявке или рейсу.
В этих случаях:
- операция удаления завершается ошибкой (HTTP-статус 4xx);
- в ответе возвращается текстовое пояснение причины, например что объект используется в заявке и не может быть удалён.
Рекомендуется при интеграции:
- логировать текст ошибки;
- отображать комментарий пользователю внешней системы;
- при необходимости реализовать бизнес-процесс «вывода из эксплуатации» (деактивацию) вместо физического удаления.
---
### 2.3. Справочники, данные которых поступают из CARGO.RUN
- Тип оплаты (`PaymentType`)
- Тип НДС (`NDSType`)
- Тип груза (`CargoType`)
- Типы машин (`CarType`)
- Типы прицепов (`TrailerType`)
- Бренды машин (`CarBrandType`)
- Бренды прицепов (`TrailerBrandType`)
Получение выполняется методом:
```
GET /api/catalogs/getSimple?$filter=externalId eq null&$orderby=id desc
```
Метод поддерживает OData-фильтры.
---
## 3. Использование справочников при создании заявок
Поля, заканчивающиеся на `TypeId` (например, `paymentTypeId`, `ndsTypeId`, `typeId`, `brandTypeId`) должны заполняться значениями из общих справочников.
Некорректные идентификаторы приведут к ошибке валидации.
---
## 4. Синхронизация заявок (Bid)
Заявка — основной объект интеграции.
Синхронизация выполняется по полю:
```
updatedAt
```
Существует два направления синхронизации:
1. **Внешняя система → CARGO.RUN**
(создание/обновление через `/api/TruckingBids/Apply` или `/api/TruckingBids/Patch`)
2. **CARGO.RUN → внешняя система**
(оперативные изменения через `/api/tasks/queue`, первичная загрузка и сверка через
`/api/bids/GetListForExternal`)
---
## 5. Обработка `updatedAt` { #sync-updated-at }
Не используйте максимальный `updatedAt` последней страницы как единственный курсор:
несколько заявок могут иметь одинаковую метку времени, а состав выборки меняется во
время постраничного чтения.
Рекомендуемый алгоритм:
1. До начала цикла зафиксировать верхнюю границу `windowEnd` в UTC.
2. Взять нижнюю границу `windowStart` из состояния последней **полностью успешной**
синхронизации и отступить назад на небольшой интервал перекрытия.
3. Запросить фиксированное окно `updatedAt ge windowStart and updatedAt le windowEnd`
с `$orderby=updatedAt,id`, `$top=50` и последовательным `$skip`.
4. Обработать все страницы; повторные записи безопасно обновлять по паре `id` и
`updatedAt`. Учитывать записи с `isDeleted = true`.
5. Только после успешной обработки всего окна атомарно сохранить `windowEnd` как
новый завершённый рубеж.
6. При ошибке не продвигать рубеж и повторить окно. Периодически выполнять
контрольную сверку за более длинный период.
Перекрытие и дедупликация дают семантику «как минимум один раз», а не «ровно один
раз». Документация API пока не определяет составной серверный курсор для записей с
одинаковым `updatedAt`, поэтому обработчик должен быть идемпотентным.
---
## 6. Получение списка заявок из CARGO.RUN
Основной метод для инкрементальной синхронизации:
```
GET /api/bids/GetListForExternal
```
### Пример запроса
```
/api/bids/GetListForExternal
?$filter=updatedAt ge 2024-01-23T21:00:00Z
and updatedAt le 2024-01-25T20:59:59Z
and createdAt ge 2022-09-30T21:00:00Z
&$top=50
&$orderby=updatedAt,id
&$skip=0
```
Запрос возвращает заявки:
- обновлённые не раньше `24.01.2024 00:00 МСК` (`2024-01-23T21:00:00Z`);
- обновлённые не позже `25.01.2024 23:59:59 МСК` (`2024-01-25T20:59:59Z`);
- созданные после `01.10.2022 00:00 МСК` (`2022-09-30T21:00:00Z`), если нужно ограничить выборку по дате создания;
- первые 50 записей, начиная с позиции 0;
- отсортированные по дате обновления и ID: `updatedAt,id`.
Все списки рекомендуется получать порциями по 50 записей. Не запрашивайте полный список без ограничения количества: тяжелые запросы увеличивают нагрузку на сервер и могут привести к временной блокировке пользователя системой.
---
Source: products/cargorun-logistics/integration/async-sync-v2.md
# Синхронизация заявок API 2.0
Этот сценарий предназначен для 1С/ERP, которая должна получать изменения заявок
из CARGO.RUN и надёжно подтверждать их обработку.
## 1. Какие каналы нужны
| Канал | Назначение |
|---|---|
| `GET /api/bids/GetListForExternal` | Первичная загрузка, статусы, удаления, периодическая сверка |
| `POST/GET /api/tasks/queue` | Оперативное асинхронное получение накопленных изменений |
API 2.0 не заменяет `GetListForExternal`: он не гарантирует все смены статуса и
удаления.
## 2. Первичная загрузка
1. Зафиксируйте `windowEnd` перед началом выборки.
2. Прочитайте все страницы `GetListForExternal` до `windowEnd`.
3. Используйте `$orderby=updatedAt,id`, фиксированный `$top` и последовательный `$skip`.
4. Сохраняйте заявки по `id` CARGO.RUN. `externalId` не уникален.
5. Обрабатывайте `isDeleted = true` как изменение.
6. Продвигайте курсор только после успешной обработки всех страниц.
## 3. Оперативный цикл
1. Отдельный пользователь интеграции вызывает `POST /api/tasks/queue` с `Read` для `Bid`.
2. Вызов выполняется чаще одного раза в час. Окно изменений в текущей реализации
равно одному часу.
3. Клиент сохраняет ID задания и ожидает `Completed` или `Error`.
4. Клиент проверяет `objects[].status` и сохраняет каждый `Success` вместе с `id` и `version`.
5. После фиксации в локальной транзакции клиент отправляет `ReadConfirmation`.
6. При `VersionMismatch` клиент повторно читает объект и подтверждает уже новую версию.
Несколько быстрых изменений одной заявки могут объединиться. API 2.0 передаёт
последнюю версию объекта, а не журнал всех промежуточных событий.
## 4. Защита от эха
Изменения, записанные тем же пользователем синхронизации, не ставятся ему в очередь
входящих изменений. Поэтому:
- используйте для интеграции отдельного пользователя;
- не ожидайте, что собственная запись вернётся через `Read`;
- после изменяющего запроса проверяйте ответ или повторно читайте объект по `id`.
## 5. Контрольная сверка
Выполняйте её:
- по расписанию;
- после перерыва в работе длиннее часа;
- после ошибки `Read`, `ReadConfirmation` или локальной транзакции;
- для получения гарантированных смен статуса и удалений.
Выборка должна иметь фиксированные границы по `updatedAt`, небольшое перекрытие и дедупликацию
по `id + updatedAt`. Подробности: [Синхронизация справочников и заявок](./sync.md).
## 6. Восстановление
Если курсор API 2.0 потерян, не пытайтесь восстановить его из ID последнего задания.
Запустите контрольную выборку `GetListForExternal` от последней надёжно сохранённой границы.
Технический контракт очереди: [Асинхронная очередь API 2.0](../api/async-tasks.md).
---
Source: products/cargorun-logistics/integration/examples-1c.md
# Пример интеграции CARGO.RUN и 1С
Этот пример описывает типовую схему интеграции между:
- **CARGO.RUN** — система управления перевозками;
- **1С** — учётная система Клиента.
Пример показывает, как:
- настроить обмен справочниками и заявками;
- организовать инкрементальную синхронизацию;
- обрабатывать обновления заявок из CARGO.RUN в 1С;
- решать конфликты изменений.
---
## 1. Общая архитектура интеграции
В 1С рекомендуется реализовать отдельный слой для интеграции со следующей логикой:
1. **Создать дополнительную таблицу для интеграции**, в которой хранить:
- ссылки на элементы справочников (водитель, машина, прицеп, контрагент, организация);
- ссылки на заявки;
- идентификатор объекта в CARGO.RUN (`id`);
- внешний атрибут `externalId`, если он нужен проекту, но не как уникальный ключ;
- дату обновления объекта в CARGO.RUN (`updatedAt`);
- дату обновления объекта в 1С.
2. При создании или обновлении:
- элемента справочника,
- заявки,
необходимо:
- записывать запись в интеграционную таблицу;
- при первом создании объекта в CARGO.RUN сохранять его `id` в 1С;
- при последующих обновлениях — всегда передавать этот `id` в запросах к API CARGO.RUN.
`externalId` заявки не уникален. Первичный ключ интеграционной таблицы должен
однозначно связывать локальный объект с `id` CARGO.RUN.
3. **Периодически (например, раз в 15 минут)**:
- выбирать из интеграционной таблицы все элементы справочников и заявки, созданные или изменённые за этот период;
- отправлять их в CARGO.RUN через соответствующие методы (`/api/driver/apply`, `/api/car/apply`, `/api/trailer/apply`, `/api/truckingbids/apply` и т.д.).
4. В 1С у каждого элемента справочника и заявки рекомендуется хранить две даты:
- «Дата обновления в CARGO.RUN»;
- «Дата обновления в 1С».
Эти даты используются для анализа изменений и разрешения конфликтов.
---
## 2. Обновление данных заявок из CARGO.RUN в 1С
Если данные заявки могут изменяться в CARGO.RUN (например, фактические времена
въезда/выезда, пробег, факт выполнения), 1С должна получать оперативные изменения
через API 2.0 и периодически выполнять контрольную выборку `GetListForExternal`.
Очередь API 2.0 не гарантирует каждую смену статуса и удаление. См.
[Синхронизация заявок API 2.0](./async-sync-v2.md).
### 2.1. Основные шаги
1. При создании или обновлении заявки в 1С сохранять:
- дату обновления заявки в 1С;
- последнюю известную дату обновления заявки в CARGO.RUN (`updatedAt`).
2. В CARGO.RUN получать список заявок и их дату обновления `updatedAt`.
3. Для выполненных заявок особый интерес представляют:
- статус заявки: `status = "Done"`;
- фактический километраж: `factMileage`;
- по точкам загрузки/выгрузки:
- дата въезда в геозону: `bidPoints -> autoEnteredAt`;
- дата выезда из геозоны: `bidPoints -> autoLeavedAt`.
### 2.2. Пример запроса по выполненным заявкам
Пример OData-запроса (с фильтрацией по статусу и дате обновления):
```text
GET /api/bids/GetListForExternal
?$filter=Status eq 'Done'
and updatedAt gt 2019-11-20T06:00:00Z
&$orderby=updatedAt,id
&$top=50
&$skip=0
```
После получения данных:
- если дата обновления заявки в CARGO.RUN (`updatedAt`) более поздняя, чем дата обновления заявки в 1С — необходимо обновить данные заявки в 1С.
### 2.3. Пользовательские поля (extendedProperties)
При получении данных по заявке пользовательские поля передаются в массиве `extendedProperties`:
```json
"extendedProperties": [
{
"propertyName": "Due_date",
"value": "12"
}
]
```
- `propertyName` — имя пользовательского поля;
- `value` — значение, заданное пользователем.
### 2.4. Пользовательские справочники (typeOptions)
Пользовательские справочники заявки описываются в массиве `typeOptions`:
```json
"typeOptions": [
{
"id": 3795270,
"entityOptionId": 3794317
}
]
```
- `id` — идентификатор справочника в организации клиента;
- `entityOptionId` — идентификатор справочника в CARGO.RUN.
---
## 3. Варианты обновления данных заявки
При обновлении данных по заявке из CARGO.RUN в 1С возможны четыре базовые ситуации:
1. Заявка не изменилась в CARGO.RUN, не изменилась в 1С.
2. Заявка не изменилась в CARGO.RUN, изменилась в 1С.
3. Заявка изменилась в CARGO.RUN, не изменилась в 1С.
4. Заявка изменилась и в CARGO.RUN, и в 1С.
Для анализа используются три даты:
- дата обновления заявки в CARGO.RUN;
- дата обновления заявки в 1С;
- дата последней синхронизации.
Ниже рассмотрены все варианты.
### 3.1. Заявка не изменилась в CARGO.RUN, не изменилась в 1С
Условия:
- Дата последней синхронизации > Дата обновления заявки в CARGO.RUN.
- Дата последней синхронизации > Дата обновления заявки в 1С.
Итог:
- Обновление данных не требуется.
---
### 3.2. Заявка не изменилась в CARGO.RUN, изменилась в 1С
Условия:
- дата последней синхронизации не меньше `updatedAt` заявки CARGO.RUN;
- дата изменения заявки в 1С больше даты последней синхронизации.
Итог:
- если 1С является владельцем изменённых полей, отправить изменения в CARGO.RUN;
- перечитать заявку и сохранить новое `updatedAt`;
- помнить, что `Apply` полностью перезаписывает заявку: перечитать объект, объединить
изменения и не отправлять устаревшие значения полей, владельцем которых является CARGO.RUN.
---
### 3.3. Заявка изменилась в CARGO.RUN, не изменилась в 1С
Условия:
- `updatedAt` заявки CARGO.RUN больше даты последней синхронизации;
- дата изменения заявки в 1С не больше даты последней синхронизации.
Итог:
- обновить запись 1С данными CARGO.RUN;
- сохранить полученное `updatedAt` и время успешной синхронизации.
---
### 3.4. Заявка изменилась и в CARGO.RUN, и в 1С
Условия:
- `updatedAt` заявки CARGO.RUN больше даты последней синхронизации;
- дата изменения заявки в 1С больше даты последней синхронизации.
Это конфликт. Не выбирайте победителя только по более позднему времени: часы систем
могут различаться, а системы могут владеть разными полями.
Рекомендуемый порядок:
1. Разделить поля по владельцу. Например, 1С может владеть номером первичного
документа и данными оплаты, а CARGO.RUN — оперативным статусом, фактическими
событиями и назначенной техникой. Конкретную матрицу утверждают до запуска.
2. Автоматически объединять только изменения в непересекающихся группах полей.
3. Если одно поле изменено с обеих сторон, создать запись конфликта и передать её
ответственному сотруднику; не выполнять `Apply` автоматически.
4. После разрешения перечитать заявку, сохранить итоговое `updatedAt` и зафиксировать
время успешной синхронизации.
### 3.5. Обязательная матрица владельцев данных
До внедрения двусторонней синхронизации зафиксируйте для каждой группы полей:
| Группа | Владелец | Допустимое направление | Правило конфликта |
|---|---|---|---|
| Статус исполнения | CARGO.RUN | CARGO.RUN → 1С | Не перезаписывать из 1С |
| Фактические события точек | CARGO.RUN | CARGO.RUN → 1С | Не перезаписывать из 1С |
| Данные оплаты | Утверждается проектом | Одно направление | Ручное разрешение при расхождении |
| Пользовательские поля | Для каждого поля отдельно | По утверждённой схеме | По владельцу поля |
Таблица выше — безопасный шаблон, а не универсальное распределение ответственности.
Добавьте в неё все поля, которые интеграция разрешает изменять.
---
Source: products/cargorun-logistics/api/overview.md
# Обзор API CARGO.RUN
Этот документ содержит общие принципы работы API и служит вводной точкой перед изучением детальных сценариев.
---
## 1. Стиль и структура API
API CARGO.RUN построен на REST и использует:
- протокол HTTPS,
- методы HTTP (`GET`, `POST`),
- формат JSON,
- авторизацию через токен.
Все структуры данных, обязательные поля и параметры приведены в соответствующих разделах API Reference. Если для метода нужна модель запроса или ответа, она описывается рядом с методом.
---
## 2. Авторизация
Большинство методов требует токен:
```
Authorization: Bearer
```
Полное описание авторизации приведено в разделе:
[Auth API](./auth.md)
---
## 3. Модели и данные
Структуры объектов описаны в разделах конкретных методов: таблицах полей, примерах JSON и перечнях допустимых значений.
Для оперативной инкрементальной синхронизации заявок используйте асинхронную
очередь API 2.0:
```
POST /api/tasks/queue
GET /api/tasks/queue?id={taskId}
```
Для первичной загрузки, получения статусов и удалений, а также контрольной сверки
используйте:
```
GET /api/bids/GetListForExternal
```
API-методы по справочникам не поддерживают фильтрацию по `updatedAt`.
API 2.0 пока не гарантирует доставку каждой смены статуса и удаления. Подробности:
[Синхронизация заявок API 2.0](../integration/async-sync-v2.md).
---
## 4. Правила работы с API
### 4.1. Формат данных
API принимает и возвращает JSON.
Подробные правила работы с форматами описаны в:
[Форматы данных](../formats.md)
---
### 4.2. Даты и время
В документации даты обозначаются типом:
```
string (date-time)
```
Это формат ISO 8601.
Используйте формат ISO 8601 со смещением часового пояса. В интеграционных примерах обычно используется UTC (`Z` или `+00:00`).
---
### 4.3. Пагинация и фильтрация
Поддерживаются параметры OData:
- `$filter`
- `$orderby`
- `$top`
- `$skip`
Они применимы только к методам, в описании которых явно указаны соответствующие query-параметры.
---
### 4.4. Регистрозависимость URL
API CARGO.RUN регистронезависим.
Однако для единообразия во всей документации используется **нижний регистр URL**.
---
### 4.5. Ошибки
Универсальная JSON-структура ошибок не используется для всех методов.
API возвращает:
- HTTP 4xx при бизнес‑ограничениях,
- текстовое пояснение причины ошибки.
---
### 4.6. Используемые HTTP‑методы
API CARGO.RUN использует **только два HTTP‑метода**:
- **GET** — получение данных
- **POST** — создание, обновление, удаление, отмена, восстановление, смена статусов
Методы `DELETE`, `PUT`, `PATCH` **не используются**.
Примеры POST-команд:
```
POST /api/bids/delete
POST /api/bids/restore
POST /api/truckingbids/revert
POST /api/truckingbids/setstatus
POST /api/truckingbids/forcecomplete
```
---
### 4.7. Общий паттерн создания и обновления объектов
Для большинства сущностей используется единый подход:
#### Создание объекта
```
POST /api/.../apply
{
"id": 0,
...
}
```
#### Обновление объекта
```
POST /api/.../apply
{
"id": <фактический идентификатор объекта>,
...
}
```
---
## 5. Сценарии интеграции
### Заявка создаётся в CARGO.RUN
[CARGO.RUN → учетная система](../integration/scenario-cr-to-external.md)
### Заявка создаётся во внешней системе
[Учетная система → CARGO.RUN](../integration/scenario-external-to-cr.md)
Общая синхронизация справочников и заявок:
[Синхронизация данных](../integration/sync.md)
---
## 6. Дополнительные материалы
- Пример интеграции с 1С:
[Примеры для 1С](../integration/examples-1c.md)
- Минимальные требования к данным:
[Минимальные требования к запросам](../minimal-requirements.md)
- Глоссарий терминов:
[Глоссарий](../glossary.md)
---
Source: products/cargorun-logistics/api/auth.md
# Авторизация и доступ к API
Этот раздел описывает, как получить доступ к API CARGO.RUN и как передавать токен авторизации в запросах.
---
## 1. Общие принципы
Доступ к API CARGO.RUN защищён с помощью **JWT-токена**, который передаётся в HTTP-заголовке:
```http
Authorization: Bearer
```
Заголовок передается во все методы, которым требуется авторизация. Формат значения: слово `Bearer`, пробел и токен доступа.
---
## 2. Базовый URL
Базовый URL API определяется для конкретного клиента при подключении:
```text
https://api.app.cargorun.ru/
https://api.test.cargorun.ru/
https://api..cargorun.ru/
```
Во всех примерах далее используется абстрактный ``.
---
## 3. Получение токена доступа
Для получения токена используется метод:
```
POST /api/Account/GenerateToken
```
### 3.1. Модель запроса
```json
{
"userName": "string",
"password": "string",
"code": "string"
}
```
Для интеграции поле `code` может быть проигнорировано. Используется для авторизации водителей.
Полученный токен имеет ограниченный срок действия и не требует повторного запроса
при каждой операции. До его истечения или после ответа `401` обновите пару токенов.
Не вычисляйте срок действия самостоятельно: используйте `accessToken.expiresIn`
из ответа. Значение задаётся сервером и может отличаться между средами.
### 3.2. Пример запроса
```http
POST /api/Account/GenerateToken
Content-Type: application/json
{
"userName": "user@example.com",
"password": "P@ssw0rd",
"code": "999999"
}
```
### 3.3. Успешный ответ
Основные поля ответа:
| Поле | Тип | Описание |
|---|---|---|
| `accessToken.token` | `string` | JWT для заголовка `Authorization` |
| `accessToken.expiresIn` | `integer` | Срок действия access token в секундах |
| `refreshToken` | `string` | Токен для обновления пары токенов |
| `requiresTwoFactor` | `boolean` | Требуется ли второй фактор |
| `twoFactorToken` | `object?` | Временный токен второго фактора, если он требуется |
| `currentUser` | `object?` | Данные текущего пользователя |
Сокращённый пример без пользовательских данных:
```json
{
"accessToken": {
"token": "",
"expiresIn": 1800
},
"refreshToken": "",
"requiresTwoFactor": false,
"twoFactorToken": null
}
```
### 3.4. Ограничения метода
Метод `/api/Account/GenerateToken` не предназначен для регулярного или частого вызова. На стороне сервера действуют ограничения (cooldown), и при слишком частом запросе токена сервер может вернуть ошибку `429`.
Причина введения ограничения:
- метод должен использоваться только для начальной авторизации пользователя;
- дальнейшая работа с API должна выполняться через механизм обновления токена (`RefreshToken`).
---
## 4. Обновление токена
Для обновления токена необходимо использовать метод:
```
POST /api/Account/RefreshToken
```
### 4.1. Модель запроса
```json
{
"accessToken": "string",
"refreshToken": "string"
}
```
### 4.2. Пример запроса
```http
POST /api/Account/RefreshToken
Content-Type: application/json
{
"accessToken": "<старый_access_token>",
"refreshToken": ""
}
```
При успехе метод возвращает новую пару в том же формате. Сохраните оба новых
значения атомарно; не продолжайте использовать прежний refresh token, если сервер
вернул новый.
---
## 5. Передача токена в запросах
```http
Authorization: Bearer
```
Пример:
```http
GET /api/bids/GetListForExternal
Authorization: Bearer eyJhbGciOiJIUzI1...
```
---
## 6. Ошибки авторизации
### 401 Unauthorized
- отсутствует заголовок
- токен просрочен или недействителен
### 403 Forbidden
- недостаточно прав
---
## 7. Рекомендации по безопасности
- не хранить токены в логах;
- ограничить доступ к файлам конфигурации;
- использовать только HTTPS;
- при утечке токена немедленно перевыпустить.
---
## 8. Связанные разделы
- [Общий обзор](../integration/overview.md)
- [Синхронизация справочников](../integration/sync.md)
- [Примеры для 1С](../integration/examples-1c.md)
---
Source: products/cargorun-logistics/api/bids.md
# Работа с заявками (Bids)
Этот раздел описывает методы API CARGO.RUN, использующиеся для создания, обновления, получения, удаления и управления статусами заявок.
Общие правила работы API, в том числе паттерн `Apply`, приведены в файле:
- [Обзор API](./overview.md)
Минимальные обязательные поля заявки — в:
- [Минимальные требования к запросам](../minimal-requirements.md)
Сценарии интеграции описаны в:
- [CARGO.RUN → учетная система](../integration/scenario-cr-to-external.md)
- [Учетная система → CARGO.RUN](../integration/scenario-external-to-cr.md)
- [Синхронизация данных](../integration/sync.md)
- [Синхронизация заявок API 2.0](../integration/async-sync-v2.md)
---
# 1. Создание и обновление заявки
## 1.1. Полное создание или обновление заявки {#truckingbids-apply}
```http
POST /api/truckingbids/apply
```
### Назначение
- Создание новой заявки (`id = 0`)
- Полное обновление существующей заявки (`id > 0`)
В теле запроса передается полная модель заявки. При каждом вызове `Apply` модель
перезаписывает сохранённое состояние заявки. Для обновления (`id > 0`) сначала
получите актуальную карточку, объедините изменения и передайте все значения, которые
должны сохраниться. Для изменения отдельных полей используйте `Patch`.
`externalId` не уникален и не обеспечивает идемпотентность. После создания сохраните
возвращённый `id` CARGO.RUN и используйте именно его для всех последующих операций.
### Основные поля тела запроса
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | `0` для создания новой заявки, ID существующей заявки для обновления |
| `cargoOwnerDictionaryItemId` | `long?` | Да, кроме порожней заявки | ID заказчика/контрагента |
| `paymentTypeId` | `long?` | Да | Тип оплаты; для порожней заявки требуется валидный технический ID, значение игнорируется |
| `ndsTypeId` | `long?` | Да | Тип НДС; для порожней заявки требуется валидный технический ID, значение игнорируется |
| `price` | `double?` | Да | Стоимость заявки; для порожней заявки передайте техническое значение, например `1`, оно игнорируется |
| `driver` | `object?` | Да | Водитель |
| `carOption` | `object?` | Да | Автомобиль/тягач |
| `trailerOption` | `object?` | Да | Прицеп |
| `bidPoints` | `BidPointEditModel[]` | Да | Маршрутные точки, минимум две: погрузка и выгрузка |
| `cargos` | `CargoModel[]?` | Да | Грузы; для порожней заявки нужен непустой технический массив, значения игнорируются |
| `typeOptions` | `TypeOptionModel[]?` | Нет | Пользовательские справочники и дополнительные опции |
| `externalId` | `string?` | Нет | Внешний ID заявки; не уникален и не заменяет `id` CARGO.RUN |
| `comment` | `string?` | Нет | Комментарий |
| `clientBidNumber` | `string?` | Нет | Номер заявки клиента |
| `clientBidDate` | `date-time?` | Нет | Дата заявки клиента |
| `isEmptyMileageBid` | `boolean?` | Нет | Признак порожней заявки |
| `emptyMileageBid` | `EmptyMileageBidModel?` | Условно | Причина порожнего пробега; обязательна, если в организации включён учёт причин |
### Поля `bidPoints[]`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | `0` для новой точки, ID существующей точки для обновления |
| `order` | `int` | Да | Порядковый номер точки в маршруте |
| `type` | `BidPointType` | Да | Тип точки, например погрузка или выгрузка |
| `customPointTypeId` | `long?` | Нет | Тип пользовательской точки, если `type = CustomPoint` |
| `planEnterDate` | `date-time?` | Нет | Плановое время прибытия |
| `secondaryPlanEnterDate` | `date-time?` | Нет | Дополнительное плановое время |
| `geozone` | `MapObjectEditModel?` | Да | Геозона/адрес точки |
| `counterpartyId` | `long?` | Нет | Контрагент точки |
| `contactPerson` | `object?` | Нет | Контактное лицо точки |
| `comment` | `string?` | Нет | Комментарий к точке |
| `loadOptions` | `object[]?` | Нет | Опции погрузки/выгрузки |
### Значения `BidPointType`
| Значение | Код | Описание |
|---|---:|---|
| `StartPoint` | `0` | Стартовая точка маршрута |
| `LoadPoint` | `1` | Точка погрузки |
| `UnloadPoint` | `2` | Точка выгрузки |
| `CustomPoint` | `3` | Пользовательская точка маршрута. Для нее можно передать `customPointTypeId` |
### Поля `bidPoints[].geozone`
`geozone` описывает адрес и географию точки маршрута.
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | ID геообъекта. Для новой точки обычно передается `0` |
| `location` | `PointEditModel` | Да | Координаты точки |
| `city` | `string?` | Нет | Город |
| `address` | `string?` | Нет | Полный адрес |
| `village` | `string?` | Нет | Населенный пункт |
| `state` | `string?` | Нет | Регион |
| `county` | `string?` | Нет | Район |
| `street` | `string?` | Нет | Улица |
| `houseNumber` | `string?` | Нет | Номер дома |
| `federalDistrict` | `string?` | Нет | Федеральный округ |
| `radius` | `double?` | Нет | Радиус геозоны |
| `type` | `MapObjectType` | Да | Тип геообъекта |
### Поля `bidPoints[].geozone.location`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `coordinates` | `double[]?` | Нет | Координаты точки. Обычно передаются в формате `[долгота, широта]` |
### Значения `MapObjectType`
| Значение | Код | Описание |
|---|---:|---|
| `None` | `0` | Тип не задан |
| `BidPoint` | `1` | Точка заявки |
| `RouteSupportPoint` | `2` | Опорная точка маршрута |
| `GasStation` | `3` | АЗС |
| `StartBidPoint` | `4` | Стартовая точка заявки |
| `PostamatPoint` | `5` | Постамат |
| `ItemChangePoint` | `6` | Точка перецепки или пересменки |
| `ServicePoint` | `7` | Сервисная точка |
| `CounterpartyPoint` | `8` | Точка контрагента |
| `TripCouplingPoint` | `9` | Точка сцепки рейса |
### Поля `bidPoints[].contactPerson`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | ID контактного лица |
| `name` | `string?` | Нет | Имя контактного лица |
| `phoneNumber` | `string?` | Нет | Телефон контактного лица |
### Поля `bidPoints[].loadOptions[]`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | ID опции погрузки или выгрузки |
### Как читать массивы, справочники и перечисления
| Признак в поле | Что означает | Примеры |
|---|---|---|
| Тип заканчивается на `[]` | Поле содержит массив объектов или значений | `bidPoints`, `cargos`, `typeOptions`, `loadOptions`, `accessPermitIds` |
| Название заканчивается на `Id` или `Ids` | Поле ссылается на существующий объект или элемент справочника | `counterpartyId`, `paymentTypeId`, `ndsTypeId`, `driverId`, `accessPermitIds` |
| Тип указан как отдельная модель с обязательным `id` | Нужно передать ссылку на существующий объект и, если требуется, дополнительные поля модели | `contactPerson`, `loadOptions` |
| Тип имеет фиксированный список значений | Это перечисление, а не справочник | `BidPointType`, `MapObjectType` |
### Поля `cargos[]`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | `0` для нового груза, ID существующего груза для обновления |
| `typeId` | `long?` | Нет | Тип груза |
| `name` | `string?` | Нет | Наименование груза |
| `weight` | `double?` | Нет | Вес |
| `volume` | `double?` | Нет | Объем |
| `length` | `double?` | Нет | Длина |
| `width` | `double?` | Нет | Ширина |
| `height` | `double?` | Нет | Высота |
| `loadingTypeId` | `long?` | Нет | Тип погрузки |
| `unloadingTypeId` | `long?` | Нет | Тип выгрузки |
| `comment` | `string?` | Нет | Комментарий к грузу |
### Поля `typeOptions[]`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | ID элемента пользовательского справочника |
| `entityOptionId` | `long` | Да | ID настройки/свойства справочника |
### Поля `emptyMileageBid`
Используются только при `isEmptyMileageBid = true`.
| Поле | Тип | Описание |
|---|---|---|
| `logisticReasonTypeId` | `long?` | Причина из справочника `EmptyMileageBidReasonType` для обычной порожней заявки |
| `technicalReason` | `string?` | Текст технической причины, не более 256 символов, для технической порожней заявки |
Передавайте **одно** из этих полей в соответствии с типом заявки. Для обычной
порожней заявки `technicalReason` должен быть `null`; для технической заявки
`logisticReasonTypeId` должен быть `null`. Если у организации отключён учёт причин,
объект может быть опущен.
### Особенности
- поддерживает как создание, так и полное обновление;
- при создании статус заявки — `New` (черновик);
- при ошибках валидации API возвращает HTTP 4xx с текстом ошибки.
### Пример создания заявки
В примере показан запрос на создание черновика заявки. Он адаптирован из payload фронта: служебные поля интерфейса и поля состояния не передаются, а `id` новых объектов указаны как `0`.
```json
{
"id": 0,
"cargoOwnerDictionaryItemId": 129647034,
"legalPersonId": 127039077,
"paymentTypeId": 41,
"ndsTypeId": 129493473,
"price": 45000,
"isVatTop": false,
"contractNumber": "324352352352",
"paymentPeriodType": "InCalendarDays",
"responsibleId": 1466813,
"isDriverForwarder": false,
"isEmptyMileageBid": false,
"createDocumentAssignment": false,
"driver": {
"id": 1478168
},
"carOption": {
"carId": 1465629
},
"trailerOption": {
"trailerId": 128820197
},
"bidPoints": [
{
"id": 0,
"order": 0,
"type": "LoadPoint",
"comment": "Комментарий к первой точке",
"planEnterDate": "2026-07-15T10:58:00",
"cargoOwnerDictionaryItemId": 129647035,
"geozone": {
"id": 0,
"location": {
"type": "Point",
"coordinates": [
47.4720139,
55.86623
]
},
"city": "Цивильск",
"address": "Россия, Чувашская Республика — Чувашия, Цивильск, улица Гагарина",
"state": "Чувашская Республика — Чувашия",
"county": "Цивильский муниципальный округ",
"street": "улица Гагарина",
"houseNumber": null,
"federalDistrict": "Приволжский федеральный округ",
"radius": 2000,
"type": "BidPoint"
},
"contactPerson": {
"id": 129417981,
"phoneNumber": "+7 964 781-40-98",
"name": "Александр Пушкин"
},
"loadOptions": [
{
"id": 4612889
}
],
"typeOptions": [],
"extendedProperties": []
},
{
"id": 0,
"order": 1,
"type": "UnloadPoint",
"comment": "Комментарий к выгрузке",
"planEnterDate": "2026-07-16T11:10:00",
"cargoOwnerDictionaryItemId": 129647014,
"geozone": {
"id": 0,
"location": {
"type": "Point",
"coordinates": [
55.9507846,
54.7017154
]
},
"city": "Уфа",
"address": "Россия, Республика Башкортостан, Уфа, Сарапульская улица, 35",
"state": "Республика Башкортостан",
"county": "городской округ Уфа",
"street": "Сарапульская улица",
"houseNumber": "35",
"federalDistrict": "Приволжский федеральный округ",
"radius": 1999,
"type": "BidPoint"
},
"contactPerson": {
"id": 129417982,
"phoneNumber": "8 914 781 07 01",
"name": "Михаил Лермонтов"
},
"loadOptions": [
{
"id": 4612889
}
],
"typeOptions": [],
"extendedProperties": []
}
],
"cargos": [
{
"id": 0,
"name": "Крышки",
"weight": 20,
"volume": 5,
"length": 6,
"height": 8,
"width": 7,
"typeId": 712,
"packType": "Паллеты",
"comment": "Комментарий к грузу",
"extendedProperties": [],
"typeOptions": []
}
],
"extendedProperties": [
{
"propertyName": "CustomeFieldForDemo",
"value": "Пример заполнения кастомного поля"
}
],
"typeOptions": [],
"documents": [],
"accessPermitIds": []
}
```
### Успешный ответ
При успехе метод возвращает служебный результат сохранения, включая идентификатор заявки и ее статус. Набор полей может быть шире примера, поэтому интеграция должна читать нужные поля и допускать появление дополнительных.
```http
HTTP/1.1 200 OK
Content-Type: application/json
```
```json
{
"entityId": 123456,
"status": "New"
}
```
Сохраните `entityId` как ID заявки CARGO.RUN. Перед запуском при необходимости перечитайте заявку, затем измените статус отдельным методом.
---
## 1.2. Частичное обновление заявки (Patch) { #bid-patch }
```http
POST /api/truckingbids/patch
```
### Назначение
- обновление только изменённых полей заявки.
### Ограничения
- нельзя частично изменить вложенные структуры (`bidPoints`, `cargos`, `typeOptions` и др.);
- если нужно изменить маршрутные точки — необходимо передать **весь массив** `bidPoints`, включая неизменённые точки.
---
# 2. Управление статусами и жизненным циклом
## 2.1. Запуск заявки в работу
```http
POST /api/truckingbids/setstatus
```
### Тело запроса
```json
{
"bidId": 123456,
"status": "Started"
}
```
`bidId` — фактический идентификатор существующей заявки.
Вручную поддерживается запуск со значением `Started`. Если машина занята и для
организации включено планирование, система может сохранить заявку как `Planned`.
Значение `Planned` нельзя устанавливать этим методом напрямую.
При успехе метод возвращает:
```json
{
"id": 123456
}
```
---
## 2.2. Отмена заявки
```http
POST /api/bids/cancel
```
### Тело запроса
```json
{
"bidId": 123456
}
```
---
## 2.3. Закрытие заявки вручную
```http
POST /api/truckingbids/forcecomplete
```
### Тело запроса
```json
{
"bidId": 123456,
"reason": "string",
"mileage": 0,
"useOdometerMileage": true,
"bidPoints": [
{
"id": 654321,
"enteredAtByLogist": "2025-05-07T07:15:04Z",
"loadUnloadedAtByLogist": "2025-05-07T07:15:04Z",
"loadUnloadStatus": "AtLoading"
}
]
}
```
---
## 2.4. Возврат заявки в черновик
```http
POST /api/truckingbids/revert
```
### Тело запроса
```json
{
"bidId": 123456
}
```
---
# 3. Удаление и восстановление
## 3.1. Удаление заявки
```http
POST /api/bids/delete
```
### Тело запроса
```json
{
"bidId": 123456
}
```
Заявка должна быть предварительно переведена в статус `New` (через `/api/truckingbids/revert`).
---
## 3.2. Восстановление удалённой заявки
```http
POST /api/bids/restore
```
### Тело запроса
```json
{
"bidId": 123456
}
```
---
# 4. Получение заявок
## 4.1. Получение заявки для редактирования
```http
GET /api/bids/get
```
Параметры:
- `id` — идентификатор заявки.
---
## 4.2. Получение списка заявок (инкрементальная синхронизация)
```http
GET /api/bids/getlistforexternal
```
Метод возвращает список заявок по фильтру для внешних сервисов с более подробной информацией. Используется OData-формат параметров.
У каждой заявки есть поле `updatedAt` — дата последнего изменения заявки в CARGO.RUN.
Для инкрементальной синхронизации обрабатывайте фиксированные окна времени с
перекрытием и дедупликацией по `id` и `updatedAt`. Не продвигайте границу окна до
успешной обработки всех страниц. Подробный алгоритм приведён в разделе
[Синхронизация данных](../integration/sync.md#sync-updated-at).
Поддерживает:
- `$filter`
- `$orderby`
- `$top`
- `$skip`
Пример запроса:
```http
GET /api/bids/GetListForExternal
?$filter=updatedAt ge 2024-01-23T21:00:00Z
and updatedAt le 2024-01-25T20:59:59Z
and createdAt ge 2022-09-30T21:00:00Z
&$top=50
&$orderby=updatedAt
&$skip=0
```
Запрос возвращает заявки:
- дата обновления которых больше или равна `24.01.2024 00:00 МСК` (`2024-01-23T21:00:00Z`);
- дата обновления которых меньше или равна `25.01.2024 23:59:59 МСК` (`2024-01-25T20:59:59Z`);
- дата создания которых больше или равна `01.10.2022 00:00 МСК` (`2022-09-30T21:00:00Z`), если нужно ограничить выборку по дате создания;
- первые 50 записей, начиная с позиции 0;
- отсортированные по дате обновления `updatedAt`.
Все списки необходимо получать порциями по 50 записей для минимизации нагрузки на сервер. Если получать полные списки без ограничения количества, пользователь может быть временно заблокирован системой.
Подробное описание в:
- [Синхронизация данных](../integration/sync.md)
### Основные поля ответа `BidForExternalSyncModel`
Метод возвращает массив заявок. Общее количество записей передается в заголовке `X-MetaCount`.
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID заявки |
| `status` | `BidStatus` | Статус заявки |
| `price` | `double?` | Цена |
| `priceWithoutVatOnTop` | `double?` | Цена без НДС, если НДС сверху |
| `createdAt` | `date-time` | Дата создания заявки |
| `updatedAt` | `date-time` | Дата последнего изменения |
| `externalUpdatedAt` | `date-time?` | Дата обновления из внешней системы |
| `createdById` | `long` | ID пользователя, создавшего заявку |
| `approvedById` | `long?` | ID пользователя, согласовавшего заявку |
| `approvedAt` | `date-time?` | Дата согласования |
| `responsibleId` | `long?` | ID ответственного |
| `salesManagerId` | `long?` | ID менеджера по продажам |
| `carLogistId` | `long?` | ID логиста автомобиля на момент создания заявки |
| `paymentTypeId` | `long` | Тип оплаты |
| `ndsTypeId` | `long` | Тип НДС |
| `isVatTop` | `boolean` | НДС начисляется сверху |
| `counterpartyId` | `long?` | ID контрагента |
| `contractId` | `long?` | ID договора контрагента |
| `distributionBidId` | `long?` | ID заказа, из которого создана заявка |
| `routeId` | `long?` | ID маршрута |
| `driverId` | `long?` | ID текущего водителя |
| `secondaryDriverId` | `long?` | ID второго водителя |
| `isDriverForwarder` | `boolean` | Водитель является экспедитором |
| `acceptedByDriverAt` | `date-time?` | Дата принятия заявки водителем |
| `acceptedByDriverForwarderAt` | `date-time?` | Дата принятия водителем-экспедитором |
| `car` | `CarSimpleModel?` | Автомобиль |
| `trailer` | `TrailerListViewModel?` | Прицеп |
| `legalPerson` | `IdModel?` | Юридическое лицо |
| `bidPoints` | `BidPointViewModel[]?` | Точки маршрута |
| `cargos` | `CargoModel[]?` | Грузы |
| `typeOptions` | `TypeOptionModel[]?` | Пользовательские справочники и дополнительные опции |
| `temperatureRegime` | `BidTemperatureRegimeModel?` | Температурный режим |
| `temperature` | `TemperatureValueModel?` | Текущая температура |
| `documents` | `RelatedDocumentModel[]?` | Документы |
| `extendedProperties` | `ExtendedPropertyJsonObject[]?` | Дополнительные поля заявки |
| `externalId` | `string?` | Внешний ID |
| `contractNumber` | `string?` | Номер договора |
| `comment` | `string?` | Комментарий |
| `clientBidNumber` | `string?` | Номер заявки клиента |
| `clientBidDate` | `date-time?` | Дата заявки клиента |
| `paymentPeriodInDays` | `int?` | Срок оплаты в днях |
| `paymentPeriodType` | `PaymentPeriodType?` | Вариант срока оплаты |
| `sourceType` | `SourceType` | Источник заявки |
| `hasFactoring` | `boolean` | Заявка отправлена на факторинг |
| `isEmptyMileageBid` | `boolean` | Порожняя заявка |
| `isInternational` | `boolean` | Международная заявка |
| `hasItemsChange` | `boolean` | Есть перецепка/пересменка |
| `isDeleted` | `boolean` | Заявка удалена |
| `createDocumentAssignment` | `boolean` | Создавать задание сдачи документов после завершения |
| `hasServicePoints` | `boolean` | Есть точки сервисных работ |
| `isPreBid` | `boolean` | Предзаявка |
| `payment` | `BidPaymentGetModel?` | Информация об оплате |
| `accessPermitIds` | `long[]?` | Допуски и разрешения |
### Поля `extendedProperties[]`
`extendedProperties` содержит пользовательские дополнительные поля заявки.
| Поле | Тип | Описание |
|---|---|---|
| `propertyName` | `string` | Имя пользовательского поля |
| `value` | `string?` | Значение, заданное пользователем |
### Поля `typeOptions[]`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID элемента пользовательского справочника |
| `entityOptionId` | `long` | ID настройки/свойства справочника |
Чтобы получить человекочитаемое значение элемента, запросите `GET /api/Catalogs/GetItems?$filter=id eq {typeOptions[].id}`. Подробнее: [Пользовательские справочники](./custom-catalogs.md).
---
# 5. Получение связанных данных
## 5.1. Связанные документы
```http
GET /api/bids/getbiddocumentassignmentsforbid
```
Возвращает связанные документы (внешние файлы) по заявке.
---
## 5.2. Данные по точкам заявки
Изменение точек выполняется:
- через `/apply` — полная передача модели,
- через `/patch` — но с передачей **всего массива `bidPoints`**.
## 5.3. Получение данных по перецепкам в заявке
```http
GET /api/truckingbids/gettrailerreplacements
```
### Назначение
Получение данных о перецепках (замене прицепа) в рамках конкретной заявки.
### Параметры
- `bidId` — идентификатор заявки (query-параметр).
### Комментарии
Метод возвращает список всех событий замены прицепа, зафиксированных по заявке: старый и новый прицеп, время замены, источник данных и комментарий (если задан).
### Основные поля ответа
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID события замены |
| `bidId` | `long` | ID заявки |
| `oldTrailerId` | `long?` | ID старого прицепа |
| `oldTrailerNumber` | `string?` | Номер старого прицепа |
| `newTrailerId` | `long?` | ID нового прицепа |
| `newTrailerNumber` | `string?` | Номер нового прицепа |
| `replacedAt` | `date-time?` | Дата и время замены |
| `sourceType` | `SourceType?` | Источник данных |
| `comment` | `string?` | Комментарий |
---
## 5.4. Обновление данных по оплате заявки
```http
POST /api/TruckingBids/ApplyBidPayment
```
### Назначение
Установка или изменение данных по оплате заявки.
Используйте `ApplyBidPayment`, если внешняя система (например, 1С) фиксирует оплату по заявке и должна передать в CARGO.RUN статус оплаты, дату оплаты, плановую дату оплаты, сумму остатка или комментарий.
### Тело запроса
Тело описано моделью `BidPaymentWrapperModel`:
```json
{
"bidId": 123456,
"payment": {
"paymentStatus": "Paid",
"factPaymentDate": "2026-06-30",
"planPaymentDate": "2026-07-05",
"invoiceDate": "2026-06-29",
"remainingPayment": 0,
"comment": "Оплата получена"
}
}
```
Поля:
- `bidId` — идентификатор заявки;
- `payment` — данные оплаты (`BidPaymentModel`);
- `payment.paymentStatus` — статус оплаты, обязательное поле;
- `payment.factPaymentDate` — фактическая дата оплаты;
- `payment.planPaymentDate` — плановая дата оплаты;
- `payment.invoiceDate` — дата счёта;
- `payment.remainingPayment` — остаток к оплате;
- `payment.comment` — комментарий по оплате.
### Поддерживаемые значения
Поддерживаемые значения `payment.paymentStatus`:
- `NotPaid`
- `PartiallyPaid`
- `Paid`
- `Expired`
---
# 6. Ошибки
Возможные ошибки:
- невалидные данные (`paymentTypeId`, `ndsTypeId`, элементы геозон и т.д.);
- попытка удалить заявку без предварительного `revert`;
- частичное обновление вложенных структур через `/patch`.
Поведение API:
- ошибки бизнес-валидации возвращаются с HTTP-статусом `400`;
- тело ошибки может быть обычным текстом или JSON-объектом `ValidationApiResult`;
- не повторяйте запрос с теми же данными после `400`: сначала исправьте payload;
- при `401` обновите токен и повторите запрос один раз;
- при `429` или временной ошибке `5xx` используйте ограниченные повторы с увеличивающейся задержкой.
Общий формат обработки ошибок описан в разделе [Форматы данных](../formats.md#api-errors).
---
Source: products/cargorun-logistics/api/async-tasks.md
# Асинхронная очередь API 2.0
API 2.0 выполняет чтение и запись объектов в фоновой очереди. Обычный
клиент 1С/ERP работает с методами:
```http
POST /api/tasks/queue
GET /api/tasks/queue?id={taskId}
```
`/api/iris/queue` — алиас тех же методов. В новых интеграциях используйте
`/api/tasks/queue`.
!!! warning
`/api/integrations/Tasks/Queue` относится к отдельному партнёрскому API с другой
авторизацией. Не используйте его вместо `/api/tasks/queue`.
## 1. Подготовка
Администратор организации должен создать настройку внешней системы и привязать
к ней отдельного пользователя:
```http
GET /api/SyncSystems/Get
POST /api/SyncSystems/Apply
POST /api/SyncSystems/Delete
```
Основные поля `SyncSystemModel`:
| Поле | Значение |
|---|---|
| `id` | `0` для новой настройки, ID для изменения |
| `userId` | Пользователь, от имени которого работает интеграция |
| `behavior` | `0` — очистка при чтении; `1` — очистка только после `ReadConfirmation` |
| `trackingType` | `0` — не отслеживать; `1` — все изменения; `2` — изменения экспедиции |
| `callback.target` | HTTPS URL для уведомления о завершении задания |
| `callback.secret` | Секрет HMAC-SHA256; не передавайте его в журналах |
Для надёжной синхронизации используйте `behavior = 1` и `trackingType = 1`.
## 2. Постановка задания
```http
POST /api/tasks/queue
Authorization: Bearer
Idempotency-Key: sync-bids-20261012-1200
Content-Type: application/json
```
```json
{
"commands": [
{
"action": 1,
"objects": [
{
"type": 1,
"modelType": 0
}
]
}
]
}
```
Пример ставит в очередь чтение накопленных изменений заявок. `Idempotency-Key`
необязателен, имеет длину не более 100 символов и в течение 24 часов возвращает
те же задания для повторного запроса.
Сервер возвращает HTTP `202 Accepted`:
```json
{
"latencyMsec": 25,
"enqueuedInMsec": 3,
"commands": [
{
"id": 731245,
"action": 1,
"status": 0,
"readyInMsec": 25,
"message": null
}
]
}
```
Каждая команда ставится в очередь независимо. Проверяйте `commands[].status`: `0` —
успех, `1` — команда не попала в очередь. `commands[].id` — ID задания, а не ID заявки.
## 3. Действия
| Код | Имя | Назначение |
|---:|---|---|
| `0` | `Write` | Создание или полное обновление |
| `1` | `Read` | Чтение объектов или накопленных изменений |
| `2` | `ReadConfirmation` | Подтверждение обработанной версии |
| `3` | `ReadQuery` | Чтение по OData-запросу |
| `4` | `Delete` | Удаление по ID CARGO.RUN |
Типы объектов: `1` — `Bid`, `2` — `DistributionBid`, `3` — `Car`, `4` — `Trailer`,
`5` — `Driver`, `6` — `Counterparty`.
Основные поля `objects[]`:
| Поле | Правило |
|---|---|
| `id` | Внутренний ID CARGO.RUN; `null`/`0` при `Write` создаёт объект |
| `key` | Внешний корреляционный ключ до 64 символов; не уникален и не заменяет `id` |
| `version` | UUID версии; передача при `Write` включает проверку конкурентного изменения |
| `modelType` | `0` — основная модель; другие значения используйте только в описанном сценарии |
| `body` | Полная модель для `Write` |
| `query` | OData-запрос для `ReadQuery`; в этом объекте `id`, `version` и `key` должны быть пустыми |
`externalId` заявки и `objects[].key` не уникальны. Обновление, чтение, подтверждение
и удаление выполняйте по `objects[].id` CARGO.RUN.
## 4. Получение результата
```http
GET /api/tasks/queue?id=731245
Authorization: Bearer
```
Статусы задания: `0` — `Awaiting`, `1` — `InProgress`, `2` — `Completed`, `3` — `Error`.
- При `InProgress` сервер передаёт `Retry-After` в секундах.
- При `Awaiting` ориентируйтесь на `nextRetryAt`.
- `Completed` не означает успех всех объектов. Проверьте каждый `objects[].status`.
- Неизвестное или недоступное задание может вернуть HTTP `200` с `null`.
Статусы объекта: `0` — `Created`, `1` — `Success`, `2` — `Error`, `3` — `VersionMismatch`.
При `VersionMismatch` в ответе передаётся текущая версия: перечитайте объект и не
подтверждайте устаревшую версию.
Обработка задания выполняется до трёх раз. После ошибок используются задержки 5 и 10
секунд. Завершённые задания хранятся примерно три дня; забирайте результат без отлагательств.
## 5. Надёжное чтение с подтверждением
Для `behavior = 1`:
1. поставьте `Read` для типа `Bid`;
2. дождитесь `Completed`;
3. надёжно сохраните каждый успешный объект вместе с `id` и `version`;
4. только после успешной локальной транзакции отправьте `ReadConfirmation`:
```json
{
"commands": [
{
"action": 2,
"objects": [
{
"type": 1,
"modelType": 0,
"id": 123456,
"version": "2f1ac0f8-1da7-4e74-b69d-1a94de150803"
}
]
}
]
}
```
Изменения, сделанные тем же пользователем синхронизации, не возвращаются ему как
входящие изменения. Это предотвращает эхо синхронизации.
## 6. Callback
Если в `SyncSystemModel` задан `callback.target`, CARGO.RUN отправляет `POST` после завершения
задания. Проверяйте:
```text
HMAC_SHA256(callback.secret, ".")
```
Заголовки: `X-Cargorun-Task-Id`, `X-Cargorun-Webhook-Event`,
`X-Cargorun-Webhook-Timestamp`, `X-Cargorun-Webhook-Signature: sha256=`.
Callback выполняется до пяти раз с задержками 10, 20, 40 и 80 секунд. Повтор
выполняется при сетевой ошибке, HTTP `408`, `429` или `5xx`.
`callbackStatus` и счётчики callback возвращаются в `GET /api/tasks/queue`.
## 7. Границы гарантий
- В выборку `Read` попадают накопленные изменения не старше одного часа. Это
намеренное ограничение. Вызывайте синхронизацию чаще одного раза в час.
- Несколько изменений одного объекта могут объединяться: клиент получит последнюю
версию, а не журнал каждого промежуточного события.
- API 2.0 пока не гарантирует доставку всех смен статуса и удалений. Для
них используйте контрольную синхронизацию через `GET /api/bids/GetListForExternal`.
Полный алгоритм: [Синхронизация заявок API 2.0](../integration/async-sync-v2.md).
---
Source: products/cargorun-logistics/api/distribution-bids.md
# Заказы на распределение (DistributionBids)
Этот раздел описывает методы API CARGO.RUN для работы с заказами на распределение (DistributionBids).
Общие принципы работы API см. в:
- [Обзор API](../api/overview.md)
- [Auth API](../api/auth.md)
Минимальные требования к данным заказа на распределение приведены в:
- [Минимальные требования к запросам](../minimal-requirements.md)
---
## 1. Создание и обновление заказов
### 1.1. Пакетное создание/обновление заказов
```http
POST /api/distributionbids/apply
```
### Назначение
Создание и изменение заказов на распределение.
- При `id = 0` в элементах массива — создаётся новый заказ.
- При `id > 0` — обновляется существующий заказ.
### Тело запроса
Тело запроса описано моделью `DistributionBidBatchEditModel`:
```json
{
"items": [
{
// DistributionBidEditModel
}
]
}
```
Модель `DistributionBidEditModel` содержит поля заказа.
Обязательные поля указаны в разделе:
- [Минимальные требования к запросам](../minimal-requirements.md)
### Основные поля `DistributionBidEditModel`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | `0` для создания нового заказа, ID существующего заказа для обновления |
| `counterpartyId` | `long?` | Нет | ID контрагента |
| `legalPersonId` | `long?` | Нет | ID юридического лица |
| `sourceId` | `long?` | Нет | ID источника заказа |
| `trailerTypeId` | `long?` | Нет | ID типа прицепа |
| `contactPerson` | `object?` | Нет | Контактное лицо |
| `temperatureRegime` | `object?` | Нет | Температурный режим |
| `carId` | `long?` | Нет | ID автомобиля |
| `driverId` | `long?` | Нет | ID водителя |
| `trailerId` | `long?` | Нет | ID прицепа |
| `externalStatus` | `ExternalDistributionBidStatus` | Да | Внешний статус заказа |
| `cargos` | `DistributionBidCargoModel[]?` | Нет | Грузы |
| `bidPoints` | `DistributionBidPointEditModel[]?` | Нет | Точки заказа |
| `key` | `string?` | Нет | Ключ или внешний код заказа |
| `comment` | `string?` | Нет | Комментарий |
| `paymentTypeId` | `long?` | Нет | Тип оплаты |
| `ndsTypeId` | `long?` | Нет | Тип НДС |
| `price` | `double?` | Нет | Стоимость |
| `isVatTop` | `boolean?` | Нет | НДС начисляется сверху |
| `externalId` | `string?` | Нет | Внешний ID |
### Поля `bidPoints[]`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | `0` для новой точки, ID существующей точки для обновления |
| `order` | `int` | Да | Порядковый номер точки в маршруте |
| `type` | `BidPointType` | Да | Тип точки заказа |
| `customPointTypeId` | `long?` | Нет | Тип пользовательской точки, если `type = CustomPoint` |
| `planEnterDate` | `date-time?` | Нет | Плановое время прибытия |
| `secondaryPlanEnterDate` | `date-time?` | Нет | Дополнительное плановое время |
| `geozone` | `MapObjectEditModel?` | Нет | Геозона/адрес точки |
| `counterpartyId` | `long?` | Нет | Контрагент точки |
| `contactPerson` | `ContactPersonModel?` | Нет | Контактное лицо точки |
| `comment` | `string?` | Нет | Комментарий к точке |
| `loadOptions` | `LoadOptionModel[]?` | Нет | Опции погрузки/выгрузки |
### Значения `BidPointType`
| Значение | Код | Описание |
|---|---:|---|
| `StartPoint` | `0` | Стартовая точка маршрута |
| `LoadPoint` | `1` | Точка погрузки |
| `UnloadPoint` | `2` | Точка выгрузки |
| `CustomPoint` | `3` | Пользовательская точка маршрута. Для нее можно передать `customPointTypeId` |
### Поля `bidPoints[].geozone`
`geozone` описывает адрес и географию точки заказа.
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | ID геообъекта. Для новой точки обычно передается `0` |
| `location` | `PointEditModel` | Да | Координаты точки |
| `city` | `string?` | Нет | Город |
| `address` | `string?` | Нет | Полный адрес |
| `village` | `string?` | Нет | Населенный пункт |
| `state` | `string?` | Нет | Регион |
| `county` | `string?` | Нет | Район |
| `street` | `string?` | Нет | Улица |
| `houseNumber` | `string?` | Нет | Номер дома |
| `federalDistrict` | `string?` | Нет | Федеральный округ |
| `radius` | `double?` | Нет | Радиус геозоны |
| `type` | `MapObjectType` | Да | Тип геообъекта |
### Поля `bidPoints[].geozone.location`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `coordinates` | `double[]?` | Нет | Координаты точки. Обычно передаются в формате `[долгота, широта]` |
### Значения `MapObjectType`
| Значение | Код | Описание |
|---|---:|---|
| `None` | `0` | Тип не задан |
| `BidPoint` | `1` | Точка заявки или заказа |
| `RouteSupportPoint` | `2` | Опорная точка маршрута |
| `GasStation` | `3` | АЗС |
| `StartBidPoint` | `4` | Стартовая точка заявки или заказа |
| `PostamatPoint` | `5` | Постамат |
| `ItemChangePoint` | `6` | Точка перецепки или пересменки |
| `ServicePoint` | `7` | Сервисная точка |
| `CounterpartyPoint` | `8` | Точка контрагента |
| `TripCouplingPoint` | `9` | Точка сцепки рейса |
### Поля `bidPoints[].contactPerson`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | ID контактного лица |
| `name` | `string?` | Нет | Имя контактного лица |
| `phoneNumber` | `string?` | Нет | Телефон контактного лица |
### Поля `bidPoints[].loadOptions[]`
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | ID опции погрузки или выгрузки |
### Пример создания заказа
В примере показано создание заказа на распределение с двумя точками маршрута, грузом, наемным транспортом и пользовательским дополнительным полем.
```json
{
"items": [
{
"id": 0,
"externalStatus": "None",
"counterpartyId": 129647035,
"legalPersonId": 127039078,
"responsibleId": 1466813,
"price": 120000,
"paymentTypeId": 41,
"ndsTypeId": 129493473,
"paymentPeriodType": "InCalendarDays",
"paymentPeriodInDays": 30,
"invoiceTriggerType": "ByOriginal",
"trailerTypeId": 94325,
"hasHiredCar": true,
"isMandatory": true,
"hiredCarCounterpartyId": 129647034,
"hiredCarPrice": 115000,
"hiredCarCompletedAt": "2026-07-15T00:00:00",
"hiredCarNdsTypeId": 129493473,
"hiredCarPaymentTypeId": 41,
"hiredCarInvoiceTriggerType": "AtUnloading",
"hiredCarPaymentPeriodType": "InCalendarDays",
"hiredCarPaymentPeriodInDays": 30,
"hiredCarId": 301,
"hiredTrailerId": 182,
"hiredDriverId": 242,
"contractNumber": "324352352352",
"comment": "Произвольный комментарий к заказу",
"contactPerson": {
"name": "Владимир Высоцкий",
"phoneNumber": "+7 (962) 568-85-39"
},
"bidPoints": [
{
"id": 0,
"order": 0,
"type": "LoadPoint",
"planEnterDate": "2026-07-13T13:55",
"counterpartyId": 129647035,
"comment": "Произвольный комментарий к точке загрузки",
"geozone": {
"id": 0,
"location": {
"type": "Point",
"coordinates": [
44.697292211870554,
43.03449472631854
]
},
"address": "Россия, Республика Северная Осетия — Алания, Владикавказ, Пушкинская улица, 58А",
"geocoderSourceType": "Yandex",
"city": "Владикавказ",
"state": "Республика Северная Осетия — Алания",
"county": "городской округ Владикавказ",
"street": "Пушкинская улица",
"houseNumber": "58А",
"federalDistrict": "Северо-Кавказский федеральный округ",
"radius": null,
"coordinates": null,
"type": "BidPoint"
},
"contactPerson": {
"phoneNumber": "+7 964 781-40-98",
"name": "Александр Пушкин"
},
"loadOptions": [
{
"id": 4612889
},
{
"id": 4612891
},
{
"id": 4675966
}
],
"extendedProperties": []
},
{
"id": 0,
"order": 1,
"type": "UnloadPoint",
"planEnterDate": "2026-07-15T00:00",
"counterpartyId": 5225295,
"comment": "Произвольный комментарий к точке выгрузки",
"geozone": {
"id": 0,
"location": {
"type": "Point",
"coordinates": [
52.224350311291346,
52.80040289067903
]
},
"address": "Россия, Оренбургская область, Бузулук, улица Гая, 69",
"geocoderSourceType": "Yandex",
"city": "Бузулук",
"state": "Оренбургская область",
"county": "городской округ Бузулук",
"street": "улица Гая",
"houseNumber": "69",
"federalDistrict": "Приволжский федеральный округ",
"radius": null,
"coordinates": null,
"type": "BidPoint"
},
"contactPerson": {
"phoneNumber": "8 914 781 07 01",
"name": "Михаил Лермонтов"
},
"loadOptions": [
{
"id": 4612890
}
],
"extendedProperties": []
}
],
"cargos": [
{
"id": 0,
"name": "Кирпичи",
"typeId": 713,
"comment": "Произвольный комментарий к грузу",
"packType": "паллеты",
"volume": 18,
"length": 82,
"width": 13,
"height": 8,
"extendedProperties": []
}
],
"extendedProperties": [
{
"propertyName": "CustomeFieldForDemo",
"value": "Пример заполнения кастомного поля"
}
],
"typeOptions": [],
"documents": []
}
]
}
```
При ошибках валидации возвращается HTTP 4xx и текстовое описание ошибки.
---
## 2. Получение списков заказов
### 2.1. Список заказов для внешних сервисов
```http
GET /api/distributionbids/getlistforexternal
```
### Назначение
Получение списка заказов по фильтру для внешних сервисов с более подробной информацией. Поддерживается формат OData.
### Параметры
- `$filter` — фильтр по полям `DistributionBidForExternalSyncModel`;
- `$orderBy` — сортировка;
- `$top` — ограничение количества;
- `$skip` — смещение;
- `$count` — запрос количества записей;
- `$select` — выбор отдельных полей, если поддерживается в подключении;
- `$expand` — раскрытие связанных сущностей, если поддерживается в подключении.
Ответ — массив `DistributionBidForExternalSyncModel`.
### Основные поля ответа `DistributionBidForExternalSyncModel`
Метод возвращает массив заказов на распределение. Общее количество записей передается в заголовке `X-MetaCount`.
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID заказа |
| `bidId` | `long?` | ID заявки, созданной на основании заказа; `null`, если заказ не распределен |
| `status` | `DistributionBidStatus` | Внутренний статус заказа |
| `counterpartyId` | `long?` | ID контрагента |
| `counterparty` | `CounterpartyViewModel?` | Контрагент |
| `contractId` | `long?` | ID договора контрагента |
| `contactPersonId` | `long?` | ID контактного лица |
| `contactPerson` | `ContactPersonViewModel?` | Контактное лицо |
| `createdAt` | `date-time` | Дата создания |
| `updatedAt` | `date-time` | Дата последнего изменения |
| `createdById` | `long` | ID создателя |
| `createdBy` | `ShortNameModel?` | Пользователь, создавший заказ |
| `paymentTypeId` | `long?` | Тип оплаты |
| `ndsTypeId` | `long?` | Тип НДС |
| `hourlyPrice` | `double?` | Почасовая ставка |
| `price` | `double?` | Стоимость |
| `priceWithoutVatOnTop` | `double?` | Стоимость без НДС, если НДС сверху |
| `isVatTop` | `boolean?` | НДС начисляется сверху |
| `externalId` | `string?` | Внешний ID |
| `contractNumber` | `string?` | Номер договора |
| `comment` | `string?` | Комментарий |
| `clientBidNumber` | `string?` | Номер заявки клиента |
| `clientBidDate` | `date-time?` | Дата заявки клиента |
| `sourceType` | `SourceType` | Источник заказа |
| `paymentPeriodInDays` | `int?` | Срок оплаты в днях |
| `paymentPeriodType` | `PaymentPeriodType?` | Вариант срока оплаты |
| `invoiceTriggerType` | `InvoiceTriggerType?` | Основание для выставления счета |
| `documents` | `RelatedDocumentModel[]?` | Документы |
| `hasHiredCar` | `boolean` | Используется наемный транспорт |
| `hiredCarCounterpartyId` | `long?` | ID перевозчика наемного транспорта |
| `hiredCarId` | `long?` | ID наемного транспорта |
| `hiredTrailerId` | `long?` | ID прицепа наемного транспорта |
| `hiredDriverId` | `long?` | ID водителя наемного транспорта |
| `hiredCarPrice` | `double?` | Стоимость наемного транспорта |
| `isHiredCarVatTop` | `boolean` | НДС сверху по наемному транспорту |
| `hiredCarNdsTypeId` | `long?` | Тип НДС наемного транспорта |
| `hiredCarPaymentTypeId` | `long?` | Тип оплаты перевозчику |
| `hiredCarPaymentPeriodInDays` | `int?` | Срок оплаты перевозчику |
| `hiredCarCompletedAtOffset` | `date-time?` | Ручная дата выполнения со смещением часового пояса |
| `hiredCarCompletedAt` | `date-time?` | Ручная дата выполнения |
| `lastSyncStatus` | `SyncEntityStatus` | Последний статус синхронизации |
| `legalPersonId` | `long?` | ID юридического лица |
| `isMandatory` | `boolean` | Обязательный заказ |
| `isDeleted` | `boolean` | Заказ удален |
| `createDocumentAssignment` | `boolean` | Создавать задание сдачи документов после завершения |
| `extendedProperties` | `ExtendedPropertyJsonObject[]?` | Дополнительные поля |
| `hiredCarCounterparty` | `CounterpartyViewModel?` | Перевозчик наемного транспорта |
| `hiredCar` | `HiredVehicleViewModel?` | Наемный транспорт |
| `hiredTrailer` | `HiredVehicleViewModel?` | Прицеп наемного транспорта |
| `hiredDriver` | `HiredDriverViewModel?` | Водитель наемного транспорта |
| `cargos` | `CargoModel[]?` | Грузы |
| `bidPoints` | `DistributionBidPointViewModel[]?` | Точки заказа |
| `typeOptions` | `TypeOptionModel[]?` | Пользовательские справочники и настраиваемые опции |
| `hasUploadedFile` | `boolean` | Загружен файл заказа |
| `isPreBid` | `boolean` | Предзаявка |
| `accessPermitIds` | `long[]?` | Допуски и разрешения |
### Поля `extendedProperties[]`
`extendedProperties` содержит пользовательские дополнительные поля заказа.
| Поле | Тип | Описание |
|---|---|---|
| `propertyName` | `string` | Имя пользовательского поля |
| `value` | `string?` | Значение, заданное пользователем |
### Поля `typeOptions[]`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID элемента пользовательского справочника |
| `entityOptionId` | `long` | ID настройки/свойства справочника |
Чтобы получить значение элемента, запросите `GET /api/Catalogs/GetItems?$filter=id eq {typeOptions[].id}`. Подробнее: [Пользовательские справочники](./custom-catalogs.md).
---
### 2.2. Получение статусов внешних заказов
```http
GET /api/distributionbids/getlistforexternalstatuses
```
### Назначение
Получение заказов по идентификаторам с информацией о статусах (для сценариев экспедиции).
### Параметры
- `Ids` — массив идентификаторов заказов;
- `$filter`, `$orderBy`, `$top`, `$skip`, `$count`, `$select`, `$expand` — как в методе `getlist`.
Ответ — массив `ExternalDistributionBidStatusModel`.
---
## 3. Получение одного заказа
### 3.1. Получение заказа по идентификатору
```http
GET /api/distributionbids/get/{id}
```
### Параметры
- `id` — идентификатор заказа (path-параметр).
Ответ — `DistributionBidViewModel`.
---
### 3.2. Получение заказа по заявке
```http
GET /api/distributionbids/getforbid/{id}
```
### Параметры
- `id` — идентификатор заявки.
Ответ — модель заказа, связанного с указанной заявкой.
---
## 4. Управление жизненным циклом заказа
### 4.1. Отмена заказа
```http
POST /api/distributionbids/cancel
```
### Тело запроса
```json
{
"id": 0,
"comment": "Причина отмены"
}
```
| Поле | Тип | Обязательность | Описание |
|---|---|---|---|
| `id` | `long` | Да | ID заказа на распределение |
| `comment` | `string?` | Нет | Комментарий или причина отмены, если используется в подключении |
---
### 4.2. Удаление заказа
```http
POST /api/distributionbids/delete
```
### Назначение
Удаление заказа, если по нему не создана заявка.
### Тело запроса
```json
{
// DistributionBidDeleteModel
}
```
---
### 4.3. Восстановление удалённого заказа
```http
POST /api/distributionbids/restore
```
### Тело запроса
```json
{
// DistributionBidRestoreModel
}
```
---
### 4.4. Возврат отменённого заказа
```http
POST /api/distributionbids/revert
```
### Назначение
Возвращает отменённый заказ в исходный статус («Без заявки»).
### Тело запроса
```json
{
// DistributionBidRevertModel
}
```
---
## 5. Сводная таблица методов
| Метод | Описание |
|-------|----------|
| `POST /api/DistributionBids/Apply` | Создание и обновление заказов на распределение |
| `GET /api/DistributionBids/GetListForExternal` | Список заказов для внешней синхронизации |
| `GET /api/DistributionBids/GetListForExternalStatuses` | Получение статусов внешних заказов |
| `GET /api/DistributionBids/Get/{id}` | Получение одного заказа по ID |
| `GET /api/DistributionBids/GetForBid/{id}` | Получение заказа по ID заявки |
| `POST /api/DistributionBids/Cancel` | Отмена заказа |
| `POST /api/DistributionBids/Delete` | Удаление заказа |
| `POST /api/DistributionBids/Restore` | Восстановление удаленного заказа |
| `POST /api/DistributionBids/Revert` | Возврат отмененного заказа |
---
Source: products/cargorun-logistics/api/counterparties.md
# Контрагенты API
Раздел описывает работу с контрагентами CARGO.RUN Логистика: создание, удаление, получение списка и одного элемента, а также работу с договорами и адресами/точками контрагента.
Контрагенты используются в заявках и заказах через поля `counterpartyId`, `cargoOwnerDictionaryItemId`, `contractId` и связанные адресные точки.
---
## 1. Контрагенты
### 1.1. Создание или обновление контрагента
```http
POST /api/CargoOwnerDictionary/Apply
```
Метод создает нового контрагента или обновляет существующего.
Если `id = 0`, создается новый контрагент. Если `id` содержит ID существующего контрагента, метод обновляет его данные.
#### Основные поля запроса `CounterpartyEditModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | `0` для создания, ID контрагента для обновления |
| `name` | `string?` | Наименование |
| `inn` | `string?` | ИНН |
| `kpp` | `string?` | КПП |
| `ogrn` | `string?` | ОГРН |
| `address` | `string?` | Юридический адрес полностью |
| `city`, `street`, `houseNumber` | `string?` | Части юридического адреса |
| `mailingAddress` | `string?` | Почтовый адрес |
| `settlementAccount` | `string?` | Расчетный счет |
| `correspondentAccount` | `string?` | Корреспондентский счет |
| `bankName` | `string?` | Название банка |
| `bankId` | `string?` | БИК |
| `counterpartyGroupId` | `long?` | ID группы контрагентов |
| `comment` | `string?` | Комментарий |
| `management` | `Management?` | Руководитель |
| `contactPerson` | `CounterpartyContactPersonModel?` | Контактное лицо |
| `documents` | `CounterpartyDocumentModel[]?` | Документы |
| `platforms` | `CounterpartyPlatformModel[]?` | Площадки/платформы |
| `noteForDrivers` | `string?` | Примечание для водителей |
| `analyzeStrictOffsetHours` | `int?` | Смещение для учета посещений точки |
| `status` | `CounterpartyStatus?` | Статус контрагента |
| `isInsolvent` | `boolean` | Контрагент неплатежеспособен |
| `insolvencyComment` | `string?` | Комментарий о неплатежеспособности |
#### Пример
```json
{
"id": 0,
"name": "ООО \"ЦИФРОВИЗАЦИЯ ТРАНСПОРТА\"",
"inn": "1650379003",
"kpp": "165001001",
"status": "Priority",
"analyzeStrictOffsetHours": 48,
"comment": "Произвольный комментарий по контрагенту",
"noteForDrivers": "Произвольное примечание по контрагенту, которое отображается водителям",
"management": {},
"platforms": [
{
"name": "Атракс",
"url": "https://www.atrucks.su/",
"representativeFullName": "Иван Цыплаков",
"representativeEmail": "example@example.com",
"representativePhoneNumber": "+74343434344",
"paymentTypeId": 41,
"paymentPeriodType": "InCalendarDays",
"paymentMethodType": "ByUnloading"
}
],
"manual": true
}
```
### 1.2. Получение списка контрагентов
```http
GET /api/CargoOwnerDictionary/Get
```
Метод возвращает список контрагентов в OData-формате. Общее количество записей приходит в заголовке `X-MetaCount`.
#### Query-параметры
| Параметр | Описание |
|---|---|
| `withDeleted` | Включить удаленных контрагентов |
| `onlyInsolvent` | Вернуть только неплатежеспособных контрагентов |
| `$filter` | Фильтр по полям модели, например `Id eq 1` |
| `$orderby` | Сортировка, например `CreatedAt desc` |
| `$top` | Количество записей |
| `$skip` | Смещение |
| `$count` | Запросить количество записей |
#### Основные поля ответа `CounterpartyListModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID контрагента |
| `name` | `string?` | Наименование |
| `inn` | `string?` | ИНН |
| `kpp` | `string?` | КПП |
| `email` | `string?` | Email организации |
| `hasAccess` | `boolean` | Есть доступ к просмотру заявок |
| `linkedOrganizationId` | `long?` | ID прикрепленной организации |
| `comment` | `string?` | Комментарий |
| `status` | `CounterpartyStatus` | Статус контрагента |
| `insolvencyRegistryEntry` | `InsolvencyRegistryEntryGetModel?` | Данные из реестра неплатежеспособности |
| `counterpartyGroupId` | `long?` | ID группы контрагента |
| `counterpartyGroupName` | `string?` | Название группы контрагента |
| `documents` | `CounterpartyDocumentModel[]?` | Документы |
| `points` | `CounterpartyPointModel[]?` | Точки/адреса контрагента |
| `isDeleted` | `boolean` | Контрагент удален |
### 1.3. Получение одного контрагента
```http
GET /api/CargoOwnerDictionary/Get({id})
```
Метод возвращает карточку контрагента по ID.
#### Параметры
| Параметр | Тип | Описание |
|---|---|---|
| `id` | `long` | ID контрагента в path |
#### Основные поля ответа `CounterpartyModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID контрагента |
| `isDeleted` | `boolean` | Контрагент удален |
| `name`, `inn`, `kpp`, `ogrn` | `string?` | Реквизиты контрагента |
| `address`, `mailingAddress` | `string?` | Юридический и почтовый адрес |
| `city`, `street`, `houseNumber` | `string?` | Части адреса |
| `email` | `string?` | Email организации |
| `management` | `Management?` | Руководитель |
| `bankName`, `bankId` | `string?` | Банк и БИК |
| `settlementAccount`, `correspondentAccount` | `string?` | Расчетный и корреспондентский счет |
| `regionId` | `long?` | ID региона |
| `flags` | `CounterpartyFlag` | Флаги контрагента |
| `type` | `CounterpartyType` | Тип контрагента |
| `contactPerson` | `CounterpartyContactPersonModel?` | Контактное лицо |
| `hasAccess` | `boolean` | Есть доступ к просмотру заявок |
| `linkedOrganizationId` | `long?` | ID прикрепленной организации |
| `comment` | `string?` | Комментарий |
| `noteForDrivers` | `string?` | Примечание для водителей |
| `status` | `CounterpartyStatus` | Статус |
| `isInsolvent` | `boolean` | Контрагент неплатежеспособен |
| `insolvencyComment` | `string?` | Комментарий о неплатежеспособности |
| `counterpartyGroupId`, `counterpartyGroupName` | `long?`, `string?` | Группа контрагента |
| `documents` | `CounterpartyDocumentModel[]?` | Документы |
| `points` | `CounterpartyPointModel[]?` | Точки/адреса |
| `platforms` | `CounterpartyPlatformModel[]?` | Площадки |
| `documentTemplates` | `CounterpartyDocumentTemplateModel[]?` | Шаблоны документов |
### 1.4. Удаление контрагента
```http
POST /api/CargoOwnerDictionary/Delete
```
Метод удаляет контрагента, если это не запрещено бизнес-правилами.
#### Тело запроса `CounterpartyDeleteModel`
```json
{
"id": 57398
}
```
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID контрагента |
---
## 2. Договоры контрагентов
Договоры привязаны к контрагенту и используются в заявках/заказах через `contractId`.
### 2.1. Создание или обновление договора
```http
POST /api/CargoOwnerDictionary/ApplyContract
```
Если `id = 0`, создается новый договор. Если `id` содержит ID договора, метод обновляет существующий договор.
#### Поля запроса `CounterpartyContractEditModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | `0` для создания, ID договора для обновления |
| `counterpartyId` | `long` | ID контрагента |
| `legalPersonId` | `long` | ID организации/юридического лица |
| `name` | `string?` | Название договора |
| `number` | `string?` | Номер договора |
| `date` | `date` | Дата договора |
| `settlementCurrency` | `string?` | Валюта взаиморасчетов |
| `billingOptionId` | `long?` | Вариант выставления счета |
| `invoiceTriggerType` | `InvoiceTriggerType?` | Основание для выставления счета |
| `paymentPeriod` | `int?` | Срок оплаты |
| `paymentTypeId` | `long?` | Тип оплаты |
| `paymentPeriodType` | `PaymentPeriodType?` | Вариант срока оплаты |
| `debtCeiling` | `double?` | Лимит задолженности |
| `currentDebt` | `double?` | Текущая задолженность |
| `isMain` | `boolean?` | Основной договор |
#### Пример
```json
{
"id": 0,
"counterpartyId": 129762942,
"name": "999999 от 08.07.2026",
"isMain": true,
"legalPersonId": 127039078,
"number": "999999",
"date": "2026-07-08",
"invoiceTriggerType": "ByOriginal",
"settlementCurrency": "Руб",
"paymentPeriod": 30,
"paymentPeriodType": "InCalendarDays",
"paymentTypeId": 41,
"debtCeiling": 123000,
"currentDebt": 5000
}
```
### 2.2. Получение списка договоров
```http
GET /api/CargoOwnerDictionary/GetContracts?counterpartyId={counterparty_id}
```
Метод возвращает список договоров контрагента в OData-формате.
#### Query-параметры
| Параметр | Описание |
|---|---|
| `counterpartyId` | ID контрагента |
| `$filter` | Фильтр по полям модели |
| `$orderby` | Сортировка |
| `$top` | Количество записей |
| `$skip` | Смещение |
| `$count` | Запросить количество записей |
### 2.3. Получение одного договора
```http
GET /api/CargoOwnerDictionary/GetContract?counterpartyId={counterparty_id}&contractId={contract_id}
```
#### Параметры
| Параметр | Тип | Описание |
|---|---|---|
| `counterpartyId` | `long` | ID контрагента |
| `contractId` | `long` | ID договора |
#### Поля ответа `CounterpartyContractModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID договора |
| `name` | `string?` | Название договора |
| `number` | `string?` | Номер договора |
| `date` | `date` | Дата договора |
| `settlementCurrency` | `string?` | Валюта взаиморасчетов |
| `billingOptionId` | `long?` | Вариант выставления счета |
| `invoiceTriggerType` | `InvoiceTriggerType?` | Основание для выставления счета |
| `legalPersonId` | `long?` | ID организации/юридического лица |
| `legalPersonName` | `string?` | Название организации/юридического лица |
| `paymentPeriod` | `int?` | Срок оплаты |
| `paymentPeriodType` | `PaymentPeriodType?` | Вариант срока оплаты |
| `paymentTypeId` | `long?` | Тип оплаты |
| `debtCeiling` | `double?` | Лимит задолженности |
| `currentDebt` | `double?` | Текущая задолженность |
| `isMain` | `boolean` | Основной договор |
### 2.4. Удаление договора
```http
POST /api/CargoOwnerDictionary/DeleteContract
```
#### Тело запроса `CounterpartyContractDeleteModel`
```json
{
"id": 100500,
"counterpartyId": 57398
}
```
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID договора |
| `counterpartyId` | `long` | ID контрагента |
---
## 3. Адреса и точки контрагентов
Точки контрагента используются для сохранения часто используемых адресов погрузки, выгрузки или складов.
### 3.1. Создание или обновление точки
```http
POST /api/CargoOwnerDictionary/ApplyCounterpartyPoint
```
#### Поля запроса `CounterpartyPointEditModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | `0` для создания, ID точки для обновления |
| `counterpartyId` | `long` | ID контрагента |
| `organizationId` | `long` | ID организации |
| `name` | `string?` | Наименование точки |
| `client` | `string?` | Клиент |
| `geozone` | `MapObjectEditModel` | Геоданные точки |
| `lastUsedAt` | `date-time` | Дата последнего использования |
#### Основные поля `geozone`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID геообъекта |
| `location` | `PointEditModel` | Координаты |
| `address` | `string?` | Полный адрес |
| `city`, `village`, `state`, `county`, `street`, `houseNumber` | `string?` | Компоненты адреса |
| `federalDistrict` | `string?` | Федеральный округ |
| `coordinates` | `array?` | Координаты полигона |
| `radius` | `double?` | Радиус |
| `type` | `MapObjectType` | Тип точки |
#### Пример
```json
{
"id": 0,
"counterpartyId": 129647035,
"name": "Филиал IV",
"geozone": {
"location": {
"type": "Point",
"coordinates": [
47.28185386175986,
56.06857967426879
]
},
"address": "Россия, Чувашская Республика — Чувашия, Чебоксары, микрорайон Альгешево, улица Розы Люксембург, 2",
"geocoderSourceType": "Yandex",
"city": "Чебоксары",
"state": "Чувашская Республика — Чувашия",
"county": "городской округ Чебоксары",
"street": "улица Розы Люксембург",
"houseNumber": "2",
"federalDistrict": "Приволжский федеральный округ",
"radius": 500,
"coordinates": null,
"type": "CounterpartyPoint"
}
}
```
### 3.2. Получение списка точек
```http
GET /api/CargoOwnerDictionary/GetCounterpartyPoints?counterpartyId={counterparty_id}
```
Метод возвращает список точек контрагента в OData-формате.
### 3.3. Получение одной точки
```http
GET /api/CargoOwnerDictionary/GetCounterpartyPoint/{id}
```
#### Поля ответа `CounterpartyPointModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID точки |
| `counterpartyId` | `long` | ID контрагента |
| `name` | `string?` | Наименование |
| `client` | `string?` | Клиент |
| `geozone` | `MapObjectModel` | Геоданные точки |
| `lastUsedAt` | `date-time` | Дата последнего использования |
### 3.4. Удаление точки
```http
POST /api/CargoOwnerDictionary/DeleteCounterpartyPoint
```
#### Тело запроса `CounterpartyPointDeleteModel`
```json
{
"id": 2435200
}
```
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID точки контрагента |
### 3.5. Восстановление точки
```http
POST /api/CargoOwnerDictionary/RestoreCounterpartyPoint
```
Метод восстанавливает ранее удаленную точку контрагента.
---
Source: products/cargorun-logistics/api/directories.md
# Справочники API CARGO.RUN
Этот раздел описывает методы работы со справочниками, которые участвуют в интеграции:
- водители;
- автомобили;
- прицепы;
- организации;
- общие каталоги (типы, бренды и др.).
Подробные правила синхронизации справочников приведены в документе:
- [Синхронизация данных](../integration/sync.md)
Здесь описаны именно **методы API** для работы со справочниками.
---
## 1. Общие принципы
Для всех справочников используются общие правила:
- формат данных — JSON;
- авторизация — по токену (см. [Auth API](../api/auth.md));
- операции создания и обновления выполняются по паттерну `Apply`:
- `id = 0` — создание;
- `id > 0` — обновление;
- операции удаления и восстановления выполняются через `POST`-методы (`.../delete`, `.../restore`);
- при ошибках валидации возвращается HTTP 4xx и текстовое описание ошибки.
Минимальные требования к полям см. в:
- [Минимальные требования к запросам](../minimal-requirements.md)
---
## 2. Водители
### 2.1. Создание и обновление водителя
```http
POST /api/driver/apply
```
Назначение:
- создание нового водителя (`id = 0`);
- обновление существующего водителя (`id > 0`).
Минимальные обязательные поля и структура объекта описаны в `minimal-requirements.md`.
#### Пример создания водителя
```json
{
"id": 0,
"firstName": "Николай",
"lastName": "Миклухо-Маклай",
"patronymic": "Николаевич",
"phoneNumber": "+73222323233",
"comment": "Ссылка на яндекс-диск",
"needsShiftChangeComment": "Произвольный текст",
"needsUrgentShiftChange": true,
"accessPermitIds": [
5,
16
]
}
```
#### Пример обновления паспортных данных и водительского удостоверения
Паспортные данные и данные водительского удостоверения передаются в модели водителя. Для обновления существующего водителя укажите его `id`.
```json
{
"id": 128943713,
"passportSeries": "9292",
"passportNumber": "122345",
"passportGivenBy": "Электротехническим ОВД г. Кукуево",
"passportGivenWhen": "2026-07-09",
"departmentCode": "178-787",
"driverLicenseSeries": "2323",
"driverLicenseNumber": "123213",
"driverLicenseGivenWhen": "2026-06-30",
"driverLicenseValidUntil": "2026-06-30"
}
```
---
### 2.2. Удаление водителя
```http
POST /api/driver/delete
```
Тело запроса содержит идентификатор водителя.
Особенности:
- водитель не может быть удалён, если участвует в активных или запланированных заявках;
- в случае бизнес-ошибки возвращается HTTP 4xx и текстовое пояснение.
---
### 2.3. Восстановление водителя
```http
POST /api/driver/restore
```
Используется для восстановления ранее удалённого водителя.
---
### 2.4. Получение списка водителей
```http
GET /api/driver/getlist
```
Метод возвращает список водителей с основными атрибутами.
Метод поддерживает стандартные параметры списков, если они включены для конкретного подключения:
| Параметр | Описание |
|---|---|
| `$filter` | Фильтр по полям списка водителей |
| `$orderby` | Сортировка |
| `$top` | Ограничение количества записей |
| `$skip` | Смещение |
---
## 3. Автомобили
### 3.1. Создание и обновление автомобиля
```http
POST /api/car/apply
```
Назначение:
- создание нового автомобиля (`id = 0`);
- обновление существующего автомобиля (`id > 0`).
Минимальные поля и структура приведены в `minimal-requirements.md`.
#### Пример создания автомобиля
```json
{
"id": 0,
"number": "А232ОО/122",
"brandTypeId": 2716,
"typeId": 164,
"logistId": 1466813,
"trackerId": 109918,
"mechanic": {
"name": "Максим Горький",
"phoneNumber": "+7 (962) 568-00-89"
},
"columnDispatcher": {
"name": "Владимир Набоков",
"phoneNumber": "+7 (962) 6463232"
},
"comment": "Ссылка на яндекс-диск",
"needsMaintenanceComment": "Произвольный текст",
"needsUrgentMaintenance": true,
"isInRefuelingSyncList": true,
"accessPermitIds": [
1,
2
],
"fuelTanks": [
{
"minimumVolume": 10,
"currentVolume": 0,
"totalVolume": 800,
"fuelConsumption": 33,
"minimumFuelTankVolume": 120,
"type": "Diesel"
}
]
}
```
---
### 3.2. Удаление автомобиля
```http
POST /api/car/delete
```
Особенности:
- автомобиль не может быть удалён, если используется в активных заявках;
- при попытке удалить такой автомобиль API вернёт ошибку с пояснением.
---
### 3.3. Получение списка автомобилей
```http
GET /api/car/getlist
```
Возвращает список автомобилей.
---
### 3.4. Получение автомобиля для редактирования
```http
GET /api/car/getforedit
```
Метод возвращает подробные данные по одному автомобилю для редактирования.
---
## 4. Прицепы
### 4.1. Создание и обновление прицепа
```http
POST /api/trailer/apply
```
По паттерну `Apply`:
- `id = 0` — создание прицепа;
- `id > 0` — обновление.
#### Пример создания прицепа
```json
{
"id": 0,
"number": "КК2323/232",
"brandTypeId": 2720,
"typeId": 15470,
"loadUnloadOptions": [
{
"id": 4612889
},
{
"id": 4612891
},
{
"id": 4612890
}
],
"mechanic": {
"name": "Максим Горький",
"phoneNumber": "+7 (927) 200-66-00"
},
"comment": "Ссылка на яндекс-диск",
"trackerId": 4137,
"isInRefuelingSyncList": true,
"accessPermitIds": [
4,
7
],
"fuelTanks": [
{
"minimumVolume": 0,
"currentVolume": 0,
"totalVolume": 120,
"fuelConsumption": 33,
"minimumFuelTankVolume": 120,
"type": "Diesel"
}
]
}
```
---
### 4.2. Удаление прицепа
```http
POST /api/trailer/delete
```
Удаление возможно только при отсутствии использования в активных заявках.
При нарушении этого ограничения возвращается бизнес-ошибка.
---
### 4.3. Получение списка прицепов
```http
GET /api/trailer/getlist
```
Возвращает список прицепов.
---
## 5. Контрагенты, договоры и адреса
Контрагенты вынесены в отдельный раздел, потому что кроме самой карточки контрагента там описаны договоры и адреса/точки контрагентов.
- [Контрагенты API](./counterparties.md)
---
## 6. Организации
### 6.1. Создание и обновление организации
```http
POST /api/legalpersons/apply
```
Применяется для создания/обновления юридических лиц, используемых в CARGO.RUN.
---
### 6.2. Удаление организации
```http
POST /api/legalpersons/delete
```
Удаление ограничено бизнес-правилами (нельзя удалить организацию, которая используется в действующих данных).
---
### 6.3. Получение списка организаций
```http
GET /api/legalpersons/getlist
```
Возвращает список юридических лиц.
---
## 7. Общие каталоги (типы, бренды и др.)
Для получения различных типовых справочников (типы машин, типы прицепов, типы груза, бренды и пр.) используется единый метод:
```http
GET /api/catalogs/getSimple
```
Список общих справочников со значениями можно получить так:
```http
GET /api/catalogs/getSimple?$filter=externalId eq null&$orderby=id desc
```
В URL пробелы кодируются как `%20`:
```http
https://app.cargorun.ru/api/catalogs/getSimple?$filter=externalId%20eq%20null&$orderby=id%20desc
```
`externalId eq null` возвращает общие справочники CARGO.RUN, а `$orderby=id desc` сортирует их по ID в обратном порядке. Набор доступных каталогов зависит от подключения клиента.
Минимальный набор параметров:
| Параметр | Описание |
|---|---|
| `$filter` | Фильтр по элементам каталога |
| `$orderby` | Сортировка |
| `$top` | Ограничение количества записей |
| `$skip` | Смещение |
Примеры каталогов:
- типы оплаты;
- типы НДС;
- типы машин;
- типы прицепов;
- бренды машин;
- бренды прицепов;
- типы грузов.
### Пример ответа
Ниже показан сокращенный пример ответа: в реальном ответе может быть больше справочников и больше элементов внутри каждого справочника.
```json
[
{
"id": 30,
"displayName": "НДС",
"propertyName": "NDSType",
"type": "NDSType",
"externalId": null,
"items": [
{
"id": 38,
"displayName": "Без НДС",
"propertyName": "Without",
"isDeleted": false,
"isHidden": false
},
{
"id": 39,
"displayName": "10%",
"propertyName": "10%",
"isDeleted": false,
"isHidden": false
},
{
"id": 40,
"displayName": "20%",
"propertyName": "20%",
"isDeleted": false,
"isHidden": false
}
]
},
{
"id": 25,
"displayName": "Типы прицепов/полуприцепов",
"propertyName": "TrailerType",
"type": "TrailerType",
"externalId": null,
"items": [
{
"id": 44,
"displayName": "Бензовоз",
"propertyName": "Gasoline",
"isDeleted": false,
"isHidden": false
},
{
"id": 45,
"displayName": "Автоцистерна",
"propertyName": "Tank",
"isDeleted": false,
"isHidden": false
},
{
"id": 46,
"displayName": "Цементовоз",
"propertyName": "Cement",
"isDeleted": false,
"isHidden": false
}
]
},
{
"id": 31,
"displayName": "Тип оплаты",
"propertyName": "PaymentType",
"type": "PaymentType",
"externalId": null,
"items": [
{
"id": 41,
"displayName": "Безналичный",
"propertyName": "NonCash",
"isDeleted": false,
"isHidden": false
},
{
"id": 42,
"displayName": "Наличный",
"propertyName": "Cash",
"isDeleted": false,
"isHidden": false
},
{
"id": 88752941,
"displayName": "Платежная карта",
"propertyName": "Платежная карта",
"isDeleted": false,
"isHidden": false
}
]
}
]
```
Использование этих каталогов описано в:
- [Минимальные требования к запросам](../minimal-requirements.md)
- [Синхронизация данных](../integration/sync.md)
- [Пользовательские справочники](./custom-catalogs.md)
---
Source: products/cargorun-logistics/api/custom-catalogs.md
# Пользовательские справочники API
Пользовательские, или кастомные, справочники — это несистемные справочники, которые клиент создает в своем аккаунте CARGO.RUN. Они используются только внутри организации клиента и могут быть привязаны к заявкам или заказам.
В выгрузке заявок и заказов такие значения приходят в массиве `typeOptions`.
---
## 1. Как связаны `typeOptions` и справочники
В методах:
```http
GET /api/bids/GetListForExternal
GET /api/DistributionBids/GetListForExternal
```
может приходить массив:
```json
{
"typeOptions": [
{
"id": 129619121,
"entityOptionId": 126364242
}
]
}
```
Поля `TypeOptionModel`:
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID элемента справочника |
| `entityOptionId` | `long` | ID настройки/свойства справочника, к которому относится значение |
Чтобы получить текстовое значение элемента справочника, используйте `id` из `typeOptions[]` и запросите элемент через `GET /api/Catalogs/GetItems`.
```http
GET /api/Catalogs/GetItems?$filter=id eq 129619121
```
В ответе будет элемент справочника, где значение лежит в `displayName`.
---
## 2. Получение списка справочников
```http
GET /api/Catalogs/GetCatalogs
```
Метод возвращает список доступных справочников, включая пользовательские справочники организации. Поддерживает OData-фильтры и пагинацию.
### Query-параметры
| Параметр | Описание |
|---|---|
| `$filter` | Фильтр по полям модели |
| `$orderby` | Сортировка |
| `$top` | Количество записей |
| `$skip` | Смещение |
| `$count` | Запросить количество |
### Основные поля `CatalogListModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID справочника |
| `displayName` | `string?` | Название справочника |
| `propertyName` | `string?` | Системное имя свойства |
| `type` | `CatalogType?` | Тип справочника |
| `entityType` | `EntityType?` | Тип сущности, к которой относится справочник |
| `entityOptions` | `CatalogEntityOptionModel[]?` | Настройки привязки к сущностям |
| `flags` | `CatalogFlag` | Флаги справочника |
| `intFlags` | `int` | Числовое представление флагов |
| `organizationId` | `long?` | ID организации, если справочник пользовательский |
| `description` | `string?` | Описание |
| `externalId` | `string?` | Внешний ID |
| `version` | `uuid?` | Версия справочника |
---
## 3. Получение элементов справочника
```http
GET /api/Catalogs/GetItems
```
Метод возвращает элементы справочников. Для получения одного значения из `typeOptions[]` фильтруйте по `id` элемента.
### Пример получения значения по ID элемента
```http
GET /api/Catalogs/GetItems?$filter=id eq 129619121
```
### Пример получения элементов конкретного справочника
Если во внешней системе хранится ID справочника, можно фильтровать элементы по полям, которые включены в настройки конкретного клиента. Для точного значения из `GetListForExternal` достаточно запроса по `id`.
### Основные поля `CatalogListItemSimpleViewModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID элемента справочника |
| `displayName` | `string?` | Значение элемента, которое нужно показывать пользователю |
| `propertyName` | `string?` | Системное имя |
| `isDeleted` | `boolean` | Элемент удален |
| `isHidden` | `boolean` | Элемент скрыт |
| `externalId` | `string?` | Внешний ID элемента |
---
## 4. Получение справочников вместе с элементами
```http
GET /api/Catalogs/Get
GET /api/Catalogs/GetSimple
```
Оба метода возвращают справочники с вложенным массивом `items`.
`GetSimple` дополнительно поддерживает параметр:
| Параметр | Описание |
|---|---|
| `showObsolete` | Показывать устаревшие значения |
### Основные поля `CatalogListWithItemsModel`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID справочника |
| `displayName` | `string?` | Название справочника |
| `propertyName` | `string?` | Системное имя свойства |
| `organizationId` | `long?` | ID организации для пользовательского справочника |
| `description` | `string?` | Описание |
| `externalId` | `string?` | Внешний ID справочника |
| `items` | `CatalogListItemSimpleModel[]?` | Элементы справочника |
### Основные поля `items[]`
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID элемента |
| `displayName` | `string?` | Значение элемента |
| `propertyName` | `string?` | Системное имя |
| `isDeleted` | `boolean` | Элемент удален |
| `isHidden` | `boolean` | Элемент скрыт |
| `options` | `object?` | Дополнительные свойства элемента |
| `itemEntityOptions` | `CatalogItemEntityOptionSimpleModel[]?` | Привязки элемента к настройкам сущностей |
---
## 5. Рекомендуемый алгоритм для интеграции
1. Получить заявки или заказы через `GET /api/bids/GetListForExternal` или `GET /api/DistributionBids/GetListForExternal`.
2. В каждом объекте проверить массив `typeOptions`.
3. Для каждого элемента взять `typeOptions[].id`.
4. Получить значение справочника:
```http
GET /api/Catalogs/GetItems?$filter=id eq {typeOptions[].id}
```
5. Использовать `displayName` из ответа как человекочитаемое значение.
Пример:
```json
{
"typeOptions": [
{
"id": 129619121,
"entityOptionId": 126364242
}
]
}
```
Запрос:
```http
GET /api/Catalogs/GetItems?$filter=id eq 129619121
```
Ответ:
```json
[
{
"id": 129619121,
"displayName": "Значение справочника",
"propertyName": null,
"isDeleted": false,
"isHidden": false,
"externalId": null
}
]
```
---
Source: products/cargorun-logistics/api/etrn.md
# Электронные транспортные накладные (ЭТРН)
Этот раздел описывает методы API CARGO.RUN для работы с электронными транспортными накладными (ЭТРН) со стороны внешних систем, включая 1С и провайдеров ЭТРН.
Общие принципы работы API и авторизации см.:
- [Обзор API](./overview.md)
- [Auth API](../api/auth.md)
---
## 1. Методы для 1С
### 1.1. Получение списка титулов со статусами
```http
GET /api/1c/bills/gettitles
```
#### Назначение
Получение списка титулов ЭТРН с их текущими статусами в формате OData.
Метод возвращает коллекцию `TitleExternalModel`, в которой для каждого титула указаны:
- `id` — идентификатор титула;
- `type` — тип титула (`TitleType`);
- `status` — статус (`WaybillTitleStatus`);
- `statusDate` — дата и время изменения статуса;
- `bill` — данные по накладной (`WaybillExternalModel`).
[Статусы титулов ЭТРН](../statuses.md)
#### Параметры запроса
Метод поддерживает стандартные OData-параметры:
- `$filter` — фильтр по полям модели `TitleExternalModel`;
- `$orderBy` — сортировка;
- `$top` — ограничение количества;
- `$skip` — смещение;
- `$count` — возврат количества записей;
- `$select` — выбор полей.
Примеры:
1. Получить все титулы в статусе `ReceivedOrCreated`:
```text
GET /api/1c/bills/gettitles?$filter=status eq 'ReceivedOrCreated'
```
2. Получить первые 50 титулов, отсортированных по дате статуса:
```text
GET /api/1c/bills/gettitles?$orderby=statusDate desc&$top=50
```
### 1.2. Получение титула по заявке
```http
GET /api/1c/Bills/GetTitle?titleId={titleId}&bidId={bidId}&bidExternalId={bidExternalId}
```
#### Назначение
Получение данных одного титула ЭТРН.
Метод может искать титул:
- по идентификатору заявки и по идентификатору титула;
- по внешнему идентификатору заявки и по идентификатору титула.
#### Параметры запроса
Метод поддерживает следующие query-параметры:
- `titleId` — идентификатор титула (int64);
- `bidId` — идентификатор заявки (int64);
- `bidExternalId` — внешний идентификатор заявки (string).
Ответ — модель `TitleWithRemarksExternalModel`, содержащая:
- данные титула;
- статус и дату статуса;
- комментарии и замечания, если есть.
### 1.3. Смена статуса титула
```http
POST /api/1c/bills/applystatus
```
#### Назначение
Изменение статуса титула ЭТРН со стороны внешней системы.
Метод позволяет:
- подтвердить титул;
- отклонить титул;
- передать новый статус обработки титула в CARGO.RUN.
#### Тело запроса
Тело описано моделью `TitleStatusApplyExternalModel`:
```json
{
"id": 0,
"status": "Accepted",
"bidId": 0,
"bidExternalId": "string"
}
```
Поля:
- `id` — идентификатор титула, обязательное поле;
- `status` — новый статус титула, обязательное поле;
- `bidId` — идентификатор заявки;
- `bidExternalId` — внешний идентификатор заявки.
#### Поддерживаемые значения статуса
Список статусов задаётся enum `WaybillTitleStatus`:
| Значение | Описание |
|----------|----------|
| `ReceivedOrCreated` | Титул получен или создан системой. |
| `Accepted` | Титул принят. |
| `Signed` | Титул подписан. |
| `Sent` | Титул передан на отправку. |
| `Processed` | Титул обработан. |
| `Declined` | Титул отклонён. |
| `Failed` | При обработке титула возникла ошибка. |
---
## 2. Методы внешней Waybill-интеграции
Эти методы используются внешним сервисом ЭТРН для обмена данными с CARGO.RUN.
| Метод | Описание |
|-------|----------|
| `GET /api/waybill/Bids/Get/{bidId}` | Получение данных заявки по идентификатору. |
| `GET /api/waybill/Bids/GetLoadPoints` | Получение активных точек загрузки для формирования первого титула. |
| `POST /api/waybill/Bids/BatchMarkBidPoints` | Отметка точек заявки как переданных в обработку. |
| `POST /api/waybill/Bids/ApplyTitle` | Сохранение титула в заявке. |
| `GET /api/waybill/Bids/GetAcceptedTitles` | Получение принятых титулов для последующей генерации QR-кодов. |
| `POST /api/waybill/Bids/BatchMarkTitles` | Отметка титулов как переданных в обработку. |
| `POST /api/waybill/Bids/ApplyQrCodes` | Сохранение QR-кодов в заявке. |
| `GET /api/waybill/Bids/GetTitleSignatures` | Получение электронных подписей титулов. |
| `POST /api/waybill/Bids/BatchMarkTitleSignatures` | Отметка подписей как переданных в обработку. |
| `GET /api/waybill/Bids/GetPaymentDetailsList` | Получение данных для оплаты. |
---
## 3. Enum'ы
### 3.1. WaybillProviderType
Флаговый enum провайдера ЭТРН:
| Значение | Код | Описание |
|----------|-----|----------|
| `ProviderEmulator` | `0` | Эмулятор провайдера. |
| `Astral` | `1` | Провайдер Астрал. |
| `Kontur` | `2` | Провайдер Контур. |
### 3.2. WaybillTitleStatus
| Значение | Код | Описание |
|----------|-----|----------|
| `ReceivedOrCreated` | `0` | Титул получен или создан системой. |
| `Accepted` | `1` | Титул принят. |
| `Signed` | `2` | Титул подписан. |
| `Sent` | `3` | Титул передан на отправку. |
| `Processed` | `4` | Титул обработан. |
| `Declined` | `5` | Титул отклонён. |
| `Failed` | `6` | При обработке титула возникла ошибка. |
### 3.3. Дополнительные значения
| Enum | Значение | Код |
|------|----------|-----|
| `FeatureModuleType` | `Waybills` | `32` |
| `Role` | `WaybillIntegrationAccount` | `180` |
| `UserMessageType` | `Waybills` | `80` |
| `PushType` | `WaybillQrCodes` | `8` |
| `PushTemplateType` | `WaybillQrCodes` | `12` |
---
Source: products/cargorun-logistics/api/refueling-transactions.md
# Транзакции заправок
Метод загрузки транзакций с АЗС для формирования отчёта план‑факт по посещению АЗС и сопоставления с маршрутом.
- Запрос может выполняться как с `X-Api-Key`, так и с JWT.
- При запросе с `X-Api-Key` без JWT — доступ ко всем транзакциям.
- При запросе с JWT — доступ ограничен текущей организацией; чужие трекеры отфильтровываются.
---
## 1. Создание транзакций
```http
POST /api/refuelingTransactions/create
Content-Type: application/json
```
### Тело запроса
```json
{
"transactions": [
{
"deviceNumber": "string",
"cardNumber": "string",
"externalId": "string",
"createdAt": "2025-12-01T12:42",
"volume": 1.0,
"cost": 1.0,
"description": "string",
"address": "string",
"x": 55.23123,
"y": 69.42
}
]
}
```
### Обязательность и ограничения полей
- Идентификатор: обязателен один из `deviceNumber` или `cardNumber` или `externalId`. Если не указан ни один — элемент пропускается и вернётся в `errors`.
- Остальные обязательные поля: `createdAt`, `volume`, `cost`, `address`, `x`, `y`.
- `deviceNumber`: max 128 символов.
- `cardNumber`: max 128 символов.
- `externalId`: max 512 символов.
- `createdAt`: не ранее 2023 года, не позже текущее время + 6 часов (UTC).
- `address`: max 1024 символа.
- `description`: необязательное, max 2048 символов.
- `x` (долгота): диапазон [-90, 90], точность до 6 знаков после запятой.
- `y` (широта): диапазон [-180, 180], точность до 6 знаков после запятой.
- `transactions`: максимум 4096 элементов.
### Идемпотентность и ключи
Транзакция определяется одним из ключей (приоритет сверху вниз):
1. `deviceNumber` + `createdAt`
2. `cardNumber` + `createdAt`
3. `externalId` + `createdAt`
- Если указаны все три — используется `deviceNumber`, остальные игнорируются.
- При наличии записи с тем же ключом данные обновляются, а не дублируются.
- Если внутри одного запроса есть несколько элементов с одинаковым ключом, применяется последний по порядку.
- Обновление существующих транзакций возможно только для дат не старше четырёх месяцев; более поздние транзакции вернутся с ошибкой.
- Если `deviceNumber` или `cardNumber` не существуют в системе, такие транзакции просто игнорируются (не попадут в `errors`).
---
## 2. Ответы сервера
- `201` — все транзакции сохранены; тело ответа пустое.
- `200` — часть транзакций не принята:
```json
{
"errors": [
{
"message": "Причина, почему не создалась транзакция",
"transaction": { }
}
]
}
```
- `400` или `500` — текстовая ошибка; ни одна транзакция не сохранена.
- `401` — не указан `X-Api-Key` и отсутствует валидный токен.
- `403` (если нет `X-Api-Key`) — недостаточно прав/нет нужной роли у пользователя.
---
## 3. Назначение и сценарии
- Загрузка транзакций с АЗС для отчёта план‑факт по маршруту.
- Поля `deviceNumber`/`cardNumber` позволяют связать транзакцию с трекером и топливной картой; `externalId` помогает дедуплицировать данные из внешних систем.
- Координаты и адрес используются для сопоставления с плановыми точками заправки на маршруте.
---
Source: products/cargorun-logistics/api/trackers.md
# Трекеры и привязка к транспортным средствам
Этот раздел описывает только те методы работы с трекерами, которые используются во внешней интеграции:
- привязка трекера к машине или прицепу;
- получение списка трекеров;
- отвязка трекера от машины или прицепа.
Общие принципы работы API описаны в:
- [Обзор API](../api/overview.md)
- [Auth API](../api/auth.md)
---
## 1. Привязка трекера к машине или прицепу
```http
POST /api/trackers/attach
```
### Назначение
Привязать трекер к конкретному транспортному средству:
- грузовому автомобилю;
- прицепу.
### Тело запроса
```json
{
"id": 0,
"entityId": 0,
"type": "Car"
}
```
Поля:
- `id` — идентификатор трекера в CARGO.RUN;
- `entityId` — идентификатор объекта (машина или прицеп);
- `type` — тип объекта:
- `Car` — грузовой автомобиль;
- `Trailer` — прицеп.
### Комментарии
- Для привязки необходимо знать **id трекера** и **id машины/прицепа**.
- Идентификатор трекера можно получить через метод `GET /api/trackers/get`, отфильтровав по номеру устройства (`deviceNumber`).
Пример (поиск трекера по номеру устройства в OData):
```text
GET /api/trackers/get?$filter=deviceNumber eq '1234567890'
```
Из полученного списка выбирается нужный трекер, и его `id` используется в теле запроса `POST /api/trackers/attach`.
---
## 2. Получение списка трекеров
```http
GET /api/trackers/get
```
### Назначение
Получение списка трекеров, доступных организации.
Метод поддерживает OData-фильтрацию.
### Параметры OData
Метод поддерживает стандартные параметры:
```text
?$filter=
&$orderBy=
&$top=
&$skip=
&$count=
&$select=
&$expand=
```
Примеры использования:
1. Поиск трекера по номеру устройства:
```text
GET /api/trackers/get?$filter=deviceNumber eq '1234567890'
```
2. Получение первых 50 трекеров:
```text
GET /api/trackers/get?$top=50
```
### Основные поля ответа
| Поле | Тип | Описание |
|---|---|---|
| `id` | `long` | ID трекера |
| `deviceNumber` | `string?` | Номер устройства / идентификатор трекера |
| `entityId` | `long?` | ID машины или прицепа, к которому привязан трекер |
| `type` | `string?` | Тип привязанного объекта: `Car` или `Trailer` |
| `isDeleted` | `boolean?` | Признак удаления, если поле возвращается в подключении |
| `updatedAt` | `date-time?` | Дата последнего изменения, если поле возвращается в подключении |
---
## 3. Отвязка трекера от машины или прицепа
```http
POST /api/trackers/attach
```
### Назначение
Отвязать трекер от машины или прицепа.
### Тело запроса
```json
{
"id": 0,
"entityId": null,
"type": "Car"
}
```
Поля:
- `id` — идентификатор трекера;
- `entityId` — `null` (означает, что объект отвязывается);
- `type` — тип объекта:
- `Car` — если трекер был привязан к машине;
- `Trailer` — если трекер был привязан к прицепу.
### Комментарии
Для отвязки трекера необходимо:
- указать корректный `id` трекера;
- указать `entityId = null`;
- задать `type` в соответствии с тем, к какому типу объекта трекер был привязан (`Car` или `Trailer`).
---
## 4. Сводка используемых методов
| Метод | Описание |
|-------|----------|
| `POST /api/trackers/attach` | Привязка трекера к машине или прицепу |
| `GET /api/trackers/get` | Получение списка трекеров (с поддержкой OData) |
| `POST /api/trackers/attach` + `entityId = null` | Отвязка трекера от машины или прицепа |
---
Source: products/cargorun-logistics/for-ai.md
# Для LLM и ИИ-агентов
Этот раздел предназначен для ИИ-ассистентов и автономных агентов, которые анализируют
интеграцию, генерируют код или выполняют операции через API **CARGO.RUN Логистика**.
## Машиночитаемые материалы
- [Краткий индекс `cargorun-logistics-llms.txt`](../../cargorun-logistics-llms.txt) — карта разделов и порядок чтения.
- [Полная документация `cargorun-logistics-llms-full.txt`](../../cargorun-logistics-llms-full.txt) — весь раздел одним Markdown-документом.
- [Skill `cargorun-logistics`](../../skills/cargorun-logistics/SKILL.md) — готовые правила и сценарии для ИИ-агента.
Используйте краткий индекс, если агент может открывать ссылки. Полный файл подходит
для базы знаний, RAG-системы или среды без доступа к сайту.
## Приоритет источников
Если описания расходятся, агент не должен угадывать контракт. Используйте такой порядок:
1. описание конкретного метода в разделе API;
2. общие форматы, статусы и минимальные требования;
3. интеграционный сценарий;
4. пример payload.
Пример не отменяет таблицу полей. Если расхождение влияет на запрос, остановите
автоматическое выполнение и запросите подтверждение у владельца интеграции.
## Правила выполнения операций
1. Получите `` и учётные данные из защищённой конфигурации. Не помещайте
пароль, access token, refresh token и персональные данные в промпт, журнал или отчёт.
2. Получите токен через `GenerateToken`, затем обновляйте его через `RefreshToken`.
Не вызывайте `GenerateToken` перед каждым запросом.
3. Перед созданием заявки сопоставьте справочники и проверьте все `...Id`.
4. Для новой заявки передайте `id = 0`; для обновления — фактический `id` CARGO.RUN.
5. Сохраните связь локального первичного ключа с возвращённым `id` CARGO.RUN, а также
значение `updatedAt`. `externalId` не уникален и не подходит как ключ обновления.
6. После создания используйте возвращённый `id` для запуска, отмены или изменения заявки.
7. Считайте операции создания, обновления, смены статуса и удаления изменяющими данные.
Перед их выполнением агент должен показать целевой объект и получить разрешение,
если такое разрешение не было явно дано в исходной задаче.
8. После изменяющего запроса прочитайте объект повторно и проверьте результат.
## Повторы и ошибки
| Результат | Действие агента |
|---|---|
| `2xx` | Проверить тело ответа и сохранить идентификаторы/курсор синхронизации |
| `400` | Не повторять без изменений; разобрать текст или `errorMessage`, исправить payload |
| `401` | Обновить токен и повторить один раз |
| `403` | Остановиться и сообщить о нехватке прав |
| `404` | Проверить ``, регистр пути и ID; не создавать замену автоматически |
| `409` | Повторно прочитать объект и разрешить конфликт с участием владельца данных |
| `429`, `5xx` | Ограниченные повторы с экспоненциальной задержкой и случайным сдвигом |
## Инкрементальная синхронизация
- Для оперативного обмена используйте асинхронную очередь API 2.0 и подтверждайте
обработанные версии через `ReadConfirmation`.
- Вызывайте чтение API 2.0 чаще одного раза в час: текущее окно изменений намеренно
ограничено одним часом, а несколько изменений объекта могут объединяться в последнее.
- API 2.0 пока не гарантирует каждую смену статуса и удаление. Получайте заявки через
`GET /api/bids/GetListForExternal` порциями по 50 записей для начальной загрузки и
контрольной сверки.
- Используйте фильтр по `updatedAt` и стабильную сортировку, поддерживаемую методом.
- Не продвигайте сохранённую верхнюю границу синхронизации, пока не обработаны все страницы.
- Делайте небольшое перекрытие временных окон и устраняйте дубликаты по `id` и `updatedAt`.
- Обрабатывайте `isDeleted`: удалённая заявка также является изменением.
- Периодически выполняйте контрольную сверку, а не полагайтесь только на последний курсор.
Подробный алгоритм: [Синхронизация заявок API 2.0](./integration/async-sync-v2.md).
## Минимальный контекст для агента
Перед генерацией или выполнением запроса передайте агенту:
- целевой сценарий и допустимые изменяющие операции;
- базовый URL среды без секретов;
- описание конкретного метода;
- таблицы полей и enum, используемых в запросе;
- правила форматов и ошибок;
- локальные соответствия внешних идентификаторов и ID CARGO.RUN.
Не передавайте агенту всю документацию, если достаточно одного метода и связанных моделей.