📖 Документация API ЛогистБиржи
Общее
Базовый адрес: https://a0v.ru/api/v1/. Все методы возвращают JSON (Content-Type: application/json), независимо от того, успешен запрос или нет.
Аутентификация
Нужен персональный API-ключ — получить его можно в личном кабинете на странице «🔌 API-доступ» (нужна хотя бы одна активная API-лицензия, см. тарифы). Ключ передаётся одним из двух способов:
- заголовком
Authorization: Bearer <ваш_ключ>(рекомендуется); - либо GET/POST-параметром
api_key=<ваш_ключ>.
Формат ошибок
При ошибке любой метод отвечает JSON вида {"error": "текст на русском"} (кроме /cargo_create.php, где ошибки валидации — отдельный формат, см. ниже) с соответствующим HTTP-статусом:
| HTTP-код | Когда возникает |
|---|---|
400 | В запросе не хватает обязательного параметра или он некорректен (например, не указан город). |
401 | Ключ не передан или не найден — проверьте заголовок Authorization или параметр api_key. |
403 | Ключ верный, но у аккаунта нет активной лицензии, нужной для этого метода (либо, для публикации груза, не подтверждён email). |
405 | Неверный HTTP-метод (например, GET вместо POST на /cargo_create.php). |
422 | Только у /cargo_create.php: запрос дошёл, но данные не прошли проверку (см. раздел метода) — ничего не создано. |
1. GET /api/v1/cities_search.php
Доступен по любой из трёх обычных API-лицензий (как и остальные методы поиска ниже)
Справочник городов сайта — тот же самый, что используется во всех остальных методах для from_city_id/to_city_id. Нужен, если у вас нет собственной базы городов и вы не знаете, какой city_id подставлять: этот метод позволяет либо найти город по названию (так же, как работает поле «Откуда»/«Куда» на сайте), либо получить все данные по уже известному id.
Параметры запроса (нужен ровно один из первых двух)
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
id | целое число | да, если не указан <code>q</code> | Вернуть один город по его id. Если такого id нет — ошибка 404. |
q | строка | да, если не указан <code>id</code> | Поиск по названию города, минимум 2 символа (регистр не важен). Возвращает до limit совпадений в том же порядке, что и автодополнение «Откуда»/«Куда» на сайте: сначала более точные совпадения, среди них — сначала Россия, затем более крупные населённые пункты. |
limit | целое число | нет, по умолчанию 20 | Только вместе с q. Диапазон 1–100. |
Пример запроса — поиск по названию
GET https://a0v.ru/api/v1/cities_search.php?q=Санкт-Петербург Authorization: Bearer ВАШ_КЛЮЧ
Ответ: {"count": 2, "items": [{"id": 85, "name": "Санкт-Петербург", ...}, {"id": 1600, "name": "Санкт-Петербург аэропорт Пулково", ...}]}
Пример запроса — по id
GET https://a0v.ru/api/v1/cities_search.php?id=85 Authorization: Bearer ВАШ_КЛЮЧ
Поля ответа (один и тот же вид что при поиске по id, что внутри items[] при поиске по q)
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
id | целое число | — | id города — используйте его как from_city_id/to_city_id в остальных методах. |
name | строка | — | Название города. |
display_name | строка или null | — | Полное название с районом/областью/страной, если есть в базе. |
region / district | строка или null | — | Регион/область и район, если известны. |
place_type | строка или null | — | Тип места: city/town/village/hamlet/suburb/locality/region/municipality и т.п. |
country_id / country_name | целое число или null / строка или null | — | Страна. |
lat / lon | число или null | — | Координаты, если известны. |
Ответ при ошибке
{"error": "Город с id=999999 не найден."} (HTTP 404) — если id не найден; {"error": "Укажите параметр id ... либо q ..."} (HTTP 400) — если не передан ни один из параметров.
2. GET /api/v1/route_distance.php
Доступен по любой из трёх обычных API-лицензий (как и cities_search.php)
Расстояние между двумя городами по прямой («по воздуху», формула гаверсинуса по координатам городов) — та же логика, что на публичной странице /distance.php. Это НЕ расстояние по дорогам — у нас нет своего маршрутизатора, поэтому цифра обычно меньше реального пути. Полезно для быстрой прикидки, не для точного расчёта топлива/времени в пути.
Параметры запроса (нужны оба города)
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
from_city_id / from | целое число / строка | да (в одном из двух видов) | Город отправления. |
to_city_id / to | целое число / строка | да (в одном из двух видов) | Город назначения. |
Пример запроса
GET https://a0v.ru/api/v1/route_distance.php?from=Москва&to=Казань Authorization: Bearer ВАШ_КЛЮЧ
Ответ: {"from_city_id": 1, "from_city": "Москва", "to_city_id": 2, "to_city": "Казань", "distance_km": 720.4, "distance_type": "straight_line"}
Ошибки: 400 — не удалось определить один из городов; 422 — оба города найдены, но у одного из них (или обоих) нет координат в базе.
3. GET /api/v1/price_prediction.php
Доступен по любой из трёх обычных API-лицензий
Более точный прогноз ставки на конкретный груз, чем price_stats.php ниже — учитывает не только маршрут, но и вес/тип груза/тип кузова, если они переданы. Сначала ищутся реальные похожие грузы на точном маршруте; если их слишком мало (< 3), прогноз считается через средний тариф ₽/км по всей базе, умноженный на расстояние маршрута — в этом случае в ответе is_approximated: true.
Параметры запроса
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
from_city_id / from | целое число / строка | да | Город отправления. |
to_city_id / to | целое число / строка | да | Город назначения. |
weight | число (т) | нет | Уточняет прогноз похожими по весу грузами (±30%). |
cargo_type_id | целое число | нет | id типа груза — уточняет прогноз. |
body_type_id | целое число | нет | id типа кузова — уточняет прогноз. |
Пример запроса
GET https://a0v.ru/api/v1/price_prediction.php?from=Москва&to=Казань&weight=15&body_type_id=1 Authorization: Bearer ВАШ_КЛЮЧ
Ответ: {"from_city_id": 1, "to_city_id": 2, "distance_km": 720.4, "avg_price": 45000, "min_price": 30000, "max_price": 70000, "count": 14, "is_approximated": false}
count — сколько реальных похожих грузов легло в основу прогноза (0, если использован тариф ₽/км). Любое из price-полей может быть null, если не удалось посчитать вообще ничего.
4. GET /api/v1/usage_stats.php
Доступен по любой из трёх обычных API-лицензий
Статистика ваших обращений к API (по журналу, который и так ведётся для каждого метода) — сколько запросов сделано сегодня/за 7 дней/за 30 дней/всего, по каждому методу отдельно и суммарно. Полезно для самостоятельного мониторинга использования.
В отличие от аналогичного метода у ATI.SU, здесь нет полей вроде monthly_limit/remaining — у наших тарифов нет фиксированного лимита запросов, лицензии ограничивают только доступ к методам, а не их количество.
Пример запроса
GET https://a0v.ru/api/v1/usage_stats.php Authorization: Bearer ВАШ_КЛЮЧ
Ответ: {"total": {"today": 5, "last_7_days": 40, "last_30_days": 150, "all_time": 900, "last_request_at": "2026-07-12 10:00:00"}, "by_endpoint": [{"endpoint": "active_carriers", "today": 3, ...}, ...]}
5. GET /api/v1/active_carriers.php
Тариф: «API поиска активных перевозчиков» (api_active_carriers)
Возвращает список активных объявлений транспорта (перевозчиков), готовых работать по заданному маршруту — автоматизированный аналог раздела «Поиск активных перевозчиков» на сайте, но без ограничения в 3/15 результатов.
Параметры запроса
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
from_city_id | целое число | да, если не указан <code>from</code> | id города отправления (id можно найти через одноимённое поле в ответах других методов или подбором по названию). |
from | строка | да, если не указан <code>from_city_id</code> | Название города отправления — будет автоматически найдено в справочнике (регистр не важен). |
to_city_id | целое число | нет | id города назначения — если не указан, маршрут не фильтруется по назначению. |
to | строка | нет | Название города назначения (альтернатива to_city_id). |
limit | целое число | нет, по умолчанию 20 | Сколько объявлений вернуть за один запрос. Диапазон 1–100. |
offset | целое число | нет, по умолчанию 0 | Сколько объявлений пропустить с начала списка — для постраничной выгрузки (например, offset=20 — вторая страница при limit=20). |
demo | true/1 | нет | Demo-режим — возвращает заготовленный пример ответа (2 объявления) БЕЗ обращения к базе и БЕЗ лицензии «api_active_carriers» — нужен только сам ключ. Удобно попробовать формат ответа до покупки тарифа. |
Пример запроса
GET https://a0v.ru/api/v1/active_carriers.php?from=Москва&to=Казань&limit=20 Authorization: Bearer ВАШ_КЛЮЧ
Пример без лицензии: https://a0v.ru/api/v1/active_carriers.php?demo=true
Поля ответа
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
count | целое число | — | Сколько объявлений реально вернулось в этом ответе (≤ limit). |
total | целое число | — | Сколько всего объявлений подходит под фильтр (для постраничной выгрузки). |
items[].listing_id | целое число | — | id объявления транспорта на сайте. |
items[].from_city / to_city | строка | — | Названия городов маршрута. to_city может быть null (машина готова ехать «куда угодно»). |
items[].ready_date | дата (ГГГГ-ММ-ДД) | — | Дата, когда транспорт готов к погрузке. |
items[].payment_wish | число или null | — | Желаемая ставка в рублях, если указана автором. |
items[].capacity_weight_t / capacity_volume_m3 | число или null | — | Грузоподъёмность (тонн) и объём (м³) машины. |
items[].body_type | строка или null | — | Тип кузова (например, «тент», «рефрижератор»). |
items[].contact | объект | — | Контакт: {"type": "company"|"private", "name", "phone", "email"}. Для частных лиц phone/email могут быть null, если пользователь скрыл их в настройках приватности. |
items[].url | строка | — | Относительный путь на страницу объявления на сайте (для ссылки в вашем интерфейсе). |
6. GET /api/v1/transport_search.php
Тариф: «API поиска транспорта» (api_transport_search)
Поиск свободного транспорта с теми же фильтрами, что в веб-разделе «Поиск машин» (/transport/list.php), но в виде JSON.
Параметры запроса
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
from_city_id / from | целое число / строка | нет | Город отправления (id или название) — без фильтра, если не указан. |
to_city_id / to | целое число / строка | нет | Город назначения (id или название). |
body_type_id[] | массив целых чисел | нет | Один или несколько id типов кузова, например body_type_id[]=1&body_type_id[]=2. |
payment[] | массив строк | нет | Фильтр по условиям оплаты. Допустимые значения: prepay, no_rate, cash, cashless_vat, cashless_no_vat, with_rate. |
extra[] | массив строк | нет | Доп. параметры. Допустимые значения: stanchions, round_trip, hide_permanent, hide_tender, hide_crew, adr, consolidated (сборный груз/LTL). |
capacity_from / capacity_to | число (тонн) | нет | Минимальная/максимальная грузоподъёмность машины. |
date_from | дата (ГГГГ-ММ-ДД) | нет | Показать машины, готовые не раньше этой даты. |
limit | целое число | нет, по умолчанию 20 | Диапазон 1–100. |
offset | целое число | нет, по умолчанию 0 | Для постраничной выгрузки. |
demo | true/1 | нет | Demo-режим — заготовленный пример ответа без обращения к базе и без лицензии «api_transport_search» (нужен только сам ключ). |
Пример запроса
GET https://a0v.ru/api/v1/transport_search.php?from_city_id=1&capacity_from=5&payment[]=cash&limit=20 Authorization: Bearer ВАШ_КЛЮЧ
Пример без лицензии: https://a0v.ru/api/v1/transport_search.php?demo=true
Поля ответа
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
count / total | целое число | — | Как в предыдущем методе. |
items[].listing_id | целое число | — | id объявления. |
items[].from_city / to_city | строка | — | Города маршрута. |
items[].ready_date | дата | — | Дата готовности машины. |
items[].payment_wish | число или null | — | Желаемая ставка. |
items[].capacity_weight_t / capacity_volume_m3 | число или null | — | Грузоподъёмность и объём. |
items[].body_type | строка или null | — | Тип кузова. |
items[].company_name | строка или null | — | Название компании-владельца, если объявление от компании (иначе null — частное лицо; контакты этот метод не отдаёт, за ними используйте active_carriers.php). |
items[].is_consolidated | true/false | — | Готов ли перевозчик брать сборные грузы (LTL). |
items[].url | строка | — | Путь на страницу объявления. |
7. GET /api/v1/price_stats.php
Тариф: «API средних ставок» (api_price_stats)
Средняя ставка на грузоперевозки по собственным данным биржи (не по внешним источникам) — та же логика, что на /stats/prices.php.
Параметры запроса
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
from_city_id / from | целое число / строка | нет | Город отправления. |
to_city_id / to | целое число / строка | нет | Город назначения. |
cargo_type_id | целое число | нет | id типа груза — сузить статистику до конкретного типа. |
demo | true/1 | нет | Demo-режим — заготовленный пример ответа без обращения к базе и без лицензии «api_price_stats» (нужен только сам ключ). |
Если не указан ни один из трёх параметров (и не передан demo) — метод вернёт общий топ-20 по типам груза вместо статистики по маршруту (см. ниже).
Пример запроса (по маршруту)
GET https://a0v.ru/api/v1/price_stats.php?from=Москва&to=Казань Authorization: Bearer ВАШ_КЛЮЧ
Ответ: {"count": 14, "avg_price": 48250.5, "min_price": 30000, "max_price": 70000} — count (целое) — сколько объявлений с указанной ценой найдено по фильтру; avg_price/min_price/max_price (число или null, если count равен 0) — средняя/минимальная/максимальная ставка в рублях.
Пример запроса (без параметров — общий топ)
GET https://a0v.ru/api/v1/price_stats.php Authorization: Bearer ВАШ_КЛЮЧ
Ответ: {"top_by_cargo_type": [{"cargo_type_id": 3, "cargo_type": "Стройматериалы", "count": 42, "avg_price": 51000, "min_price": 12000, "max_price": 120000}, ...]} — массив из ≤20 типов груза, отсортированных по числу объявлений (count) по убыванию.
8. POST /api/v1/cargo_create.php
Доступен с любой из трёх лицензий выше (api_active_carriers, api_transport_search или api_price_stats) — публикация груза на сайте, для интеграции с ТМС/1С/CRM.
Требует подтверждённого email на аккаунте (как и обычная форма добавления груза/CSV-импорт). Тело запроса — JSON (Content-Type: application/json), обычная форма (application/x-www-form-urlencoded) либо multipart/form-data (нужен только если сразу прикладываете фото, см. ниже).
Параметры тела запроса
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
from_city_id | целое число | да, если не указан <code>from</code> | id города отправления — должен реально существовать в справочнике городов, иначе ошибка. |
from | строка | да, если не указан <code>from_city_id</code> | Название города отправления (будет найдено автоматически). |
to_city_id / to | целое число / строка | да (в одном из двух видов) | Город назначения — так же обязателен, как и город отправления. |
loading_date | дата (ГГГГ-ММ-ДД) | нет | Дата погрузки. Год должен быть в пределах 2000–2100, иначе ошибка. |
weight | число (тонн) | нет | Вес груза. Допустимый диапазон: 0–200. |
volume | число (м³) | нет | Объём груза. Допустимый диапазон: 0–500. |
payment | число (₽) | нет | Предлагаемая ставка. Допустимый диапазон: 0–100 000 000. |
payment_type | строка | нет | Свободный текст способа оплаты (например, «Безналичный расчёт / Наличные») — то же поле «Форма оплаты», что и в обычной форме. Максимум 50 символов. |
expires_at | дата (ГГГГ-ММ-ДД) | нет | Дата, до которой объявление актуально (поле «Актуально до» в обычной форме). Если не указать — как и раньше, объявление автоматически уйдёт в архив через 14 дней после публикации. |
comment | строка | нет | Комментарий к грузу. Максимум 2000 символов. Ссылки и упоминания доменов (сайты, t.me/…, wa.me/… и т.п.) недопустимы — если обнаружены, груз всё равно создастся, но будет скрыт из публичного поиска до правки (см. раздел «Автоскрытие объявлений со ссылками» ниже). |
cargo_type_id | целое число | нет | id типа груза из справочника — если указан, должен реально существовать. |
body_type_id | целое число | нет | id типа кузова из справочника. |
loading_type_id | целое число | нет | id типа загрузки из справочника. |
payment_prepay, payment_cash, payment_cashless_vat, payment_cashless_no_vat | true/false (или 1/0) | нет | Условия оплаты — можно указать несколько сразу. |
has_stanchions, round_trip, is_permanent, is_tender, has_crew, is_adr, is_consolidated | true/false (или 1/0) | нет | Доп. параметры груза (с кониками, кругорейс, постоянный, тендер, с экипажем, опасный груз ADR, сборный груз LTL). |
photos[] | файл(ы) | нет | ТОЛЬКО при Content-Type: multipart/form-data — одно или несколько изображений (JPG/PNG/WEBP, до 5 МБ каждое, максимум 6 фото на объявление). См. отдельный пример ниже. |
Пример запроса (без фото, JSON)
POST https://a0v.ru/api/v1/cargo_create.php
Authorization: Bearer ВАШ_КЛЮЧ
Content-Type: application/json
{"from_city_id": 1, "to_city_id": 2, "weight": 12.5, "payment": 45000, "payment_type": "Безналичный расчёт", "expires_at": "2026-08-01", "comment": "Тент, паллеты"}
Пошагово: как указать срок актуальности и способ оплаты
- Добавьте в тело запроса поле
expires_atв форматеГГГГ-ММ-ДД(например,"2026-08-01") — объявление будет действовать до конца этого дня (23:59:59), затем само уйдёт в архив. Не указали — как и раньше, 14 дней с момента публикации. - Добавьте поле
payment_typeстрокой (например,"Безналичный расчёт / Наличные", максимум 50 символов) — это то же самое поле «Форма оплаты», что видно в форме на сайте. Если нужны ещё и структурированные флаги оплаты (предоплата, наличные, безнал с/без НДС) — добавьте отдельноpayment_prepay/payment_cash/payment_cashless_vat/payment_cashless_no_vat(true/false), это независимые поля. - Оба поля необязательны и работают при любом
Content-Typeтела запроса (JSON, форма или multipart) — можно использовать вместе с фото или без них.
Пошагово: как приложить фото объявления через API
- Соберите запрос как обычную HTML-форму с файлами —
Content-Type: multipart/form-data(при использованииcurl -Fзаголовок подставится автоматически, вручную его указывать не нужно). - Обычные поля (
from_city_id,to_city_id,weightи т.д.) передайте как отдельные части формы — так же, какpayment_type/expires_atвыше. - Каждое фото передайте отдельным полем с именем
photos[](квадратные скобки — можно приложить несколько файлов). - Поддерживаются только JPG/PNG/WEBP, до 5 МБ на файл, максимум 6 фото на объявление — как и в обычной форме на сайте. Файлы с ошибкой (неверный формат, слишком большой размер) просто пропускаются, а причина попадёт в поле
photo_warningsответа — само объявление при этом уже создано и не отменяется.
Пример запроса с фото (multipart/form-data)
curl -X POST -H "Authorization: Bearer ВАШ_КЛЮЧ" \ -F "from_city_id=1" -F "to_city_id=2" -F "weight=12.5" -F "payment=45000" \ -F "payment_type=Безналичный расчёт" -F "expires_at=2026-08-01" \ -F "comment=Тент, паллеты" \ -F "photos[]=@/путь/к/фото1.jpg" -F "photos[]=@/путь/к/фото2.jpg" \ "https://a0v.ru/api/v1/cargo_create.php"
Обратите внимание: с флагом -F у curl передавать Content-Type: application/json нельзя — тело запроса должно быть именно multipart-формой, иначе фото не распознаются.
Ответ при успехе — HTTP 201
{"success": true, "id": 1234, "url": "/cargo/view.php?id=1234"} — id (целое число) — id созданного объявления, url (строка) — относительный путь на страницу объявления.
Если в comment была обнаружена ссылка/домен, в ответе дополнительно появится поле warning (строка) — груз всё равно создаётся (со статусом «скрыто из поиска»), но с пояснением, что нужно поправить. Если при загрузке фото (только для multipart-запросов) что-то не подошло — появится поле photo_warnings (массив строк, по одной причине на каждый пропущенный файл).
Ответ при ошибке валидации — HTTP 422
{"success": false, "errors": ["Город отправления с id=999 не найден в справочнике.", "Поле вес (т) вне допустимого диапазона (0–200)."]} — errors (массив строк) — по одной строке на каждую найденную проблему, на русском языке, ничего не создаётся, пока не исправлены все.
9. POST /api/v1/transport_create.php
Доступен с любой из трёх лицензий выше — публикация СВОБОДНОЙ МАШИНЫ через API, симметрично cargo_create.php (там — публикация груза).
Требует подтверждённого email на аккаунте. Тело запроса — JSON, обычная форма либо multipart/form-data (для фото) — как и у cargo_create.php.
Параметры тела запроса
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
from_city_id / from | целое число / строка | да (в одном из двух видов) | Город, откуда готова машина. |
to_city_id / to | целое число / строка | нет | Город назначения — если не указан, машина готова ехать «куда угодно» (как в обычной форме на сайте). |
body_type_id | целое число | нет | id типа кузова из справочника. |
capacity_weight | число (т) | нет | Грузоподъёмность. Допустимый диапазон: 0–200. |
capacity_volume | число (м³) | нет | Объём кузова. Допустимый диапазон: 0–500. |
ready_date | дата (ГГГГ-ММ-ДД) | нет | Дата, когда машина готова к погрузке. |
payment_wish | число (₽) | нет | Желаемая ставка. Допустимый диапазон: 0–100 000 000. |
comment | строка | нет | До 2000 символов. Те же правила автоскрытия при ссылках/доменах, что и у груза (см. ниже). |
expires_at | дата (ГГГГ-ММ-ДД) | нет | Как у cargo_create.php — без него объявление действует 14 дней с публикации. |
payment_prepay, payment_cash, payment_cashless_vat, payment_cashless_no_vat | true/false (или 1/0) | нет | Условия оплаты. |
has_stanchions, round_trip, is_permanent, is_tender, has_crew, is_adr, is_consolidated | true/false (или 1/0) | нет | Доп. параметры машины. |
photos[] | файл(ы) | нет | ТОЛЬКО при Content-Type: multipart/form-data — как у cargo_create.php. |
Пример запроса
POST https://a0v.ru/api/v1/transport_create.php
Authorization: Bearer ВАШ_КЛЮЧ
Content-Type: application/json
{"from_city_id": 1, "to_city_id": 2, "capacity_weight": 20, "capacity_volume": 82, "ready_date": "2026-08-01", "payment_wish": 45000}
Ответ при успехе — HTTP 201
{"success": true, "id": 5678, "url": "/transport/view.php?id=5678"}
Ответ при ошибке валидации — HTTP 422
{"success": false, "errors": ["Не указан или не найден город отправления (from_city_id/from)."]}
10. POST /api/v1/cargo_import.php только для администраторов
В отличие от cargo_create.php, этот метод доступен ТОЛЬКО владельцу ключа с правами администратора сайта (не связано с лицензиями) — предназначен для собственных интеграций (например, импорт объявлений, спарсенных с других сайтов), а не для сторонних пользователей API.
Принимает все те же поля, что и cargo_create.php (см. раздел 8 выше — города, вес, объём, ставка, способ оплаты, срок актуальности, справочники, флаги, фото), плюс дополнительные:
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
contact_name | строка | нет | Имя и фамилия человека, разместившего объявление на исходном сайте (одной строкой, например «Иван Петров»). Максимум 150 символов. Если указано — на странице объявления вместо контактов аккаунта-импортёра показывается это имя. |
contact_phone | строка | нет | Телефон того же человека. Максимум 50 символов. Если указано — подменяет отображаемый телефон. |
from_external_id | целое | нет | id города отправления ИЗ БАЗЫ СТОРОННЕГО САЙТА (того, с которого парсите объявления) — у него своя нумерация городов, не совпадающая с нашей. Переводится в правильный локальный город через справочник external_city_map (см. /import_external_cities.php и /admin/city_mapping.php). Имеет приоритет над from_city_id/from, если переданы одновременно. |
to_external_id | целое | нет | То же самое для города назначения — приоритет над to_city_id/to. |
Если contact_name/contact_phone не переданы, объявление выглядит как обычное — с контактами аккаунта, от которого физически создана запись. Владелец записи (user_id) всегда — владелец API-ключа: право редактировать/удалять объявление и получать сообщения через сайт остаётся у него, переопределяются только отображаемые имя и телефон.
Если from_external_id/to_external_id указаны, но такого id ещё нет в справочнике (дамп городов стороннего сайта не загружен) или он есть, но пока не сопоставлен с нашим городом — вернётся ошибка 422 с понятным пояснением, что делать. Если сопоставление городов вообще не нужно (например, парсер уже знает название города текстом) — просто продолжайте использовать from_city_id/from и to_city_id/to как раньше, эти два новых поля необязательны.
Пример запроса
POST https://a0v.ru/api/v1/cargo_import.php
Authorization: Bearer КЛЮЧ_АДМИНИСТРАТОРА
Content-Type: application/json
{"from_city_id": 1, "to_city_id": 2, "weight": 12.5, "payment": 45000, "comment": "Тент, паллеты", "contact_name": "Иван Петров", "contact_phone": "+7 900 123-45-67"}
Ответы (коды, формат success/id/url/errors/photo_warnings) — такие же, как у cargo_create.php, плюс отдельный код 403, если ключ принадлежит не администратору: {"error": "Этот метод API доступен только администраторам сайта."}.
11. POST /api/v1/user_create.php только для администраторов
Создание пользователя через API. Доступен ТОЛЬКО владельцу ключа с правами администратора сайта (как и cargo_import.php — не связано с лицензиями).
| Параметр | Тип | Обязателен | Описание |
|---|---|---|---|
name | строка | да | Имя пользователя, до 150 символов. |
email | строка | да | Должен быть свободен — если уже зарегистрирован на сайте, вернётся ошибка. |
phone | строка | нет | До 50 символов. |
role | строка | нет | shipper / carrier / both (по умолчанию both). |
company_id | целое число | нет | id компании из справочника — если указан, должен существовать. |
email_verified | true/false | нет | По умолчанию true — email сразу считается подтверждённым (вызывающий администратор ручается за адрес). При false пользователю нужно будет подтвердить email самому, как после обычной регистрации. |
is_admin | true/false | нет | По умолчанию false. При true — сразу выдаётся полный доступ администратора сайта. Ограничить доступ отдельными разделами через API нельзя — для этого после создания зайдите на /admin/admins.php. |
notify_email | true/false | нет | По умолчанию true — отправлять ли письмо с временным паролем на email нового пользователя. |
Пароль ВСЕГДА генерируется сервером автоматически и не принимается от вызывающей стороны (та же логика, что и в /admin/user_create.php) — так через API нельзя завести аккаунт со слабым паролем. Пароль возвращается в ответе независимо от notify_email, чтобы интеграция могла сама передать его пользователю, если письмо решили не отправлять.
Пример запроса
POST https://a0v.ru/api/v1/user_create.php
Authorization: Bearer КЛЮЧ_АДМИНИСТРАТОРА
Content-Type: application/json
{"name": "Иван Петров", "email": "ivan@example.com", "phone": "+7 900 123-45-67", "role": "carrier"}
Ответ при успехе — HTTP 201
{"success": true, "id": 1234, "email": "ivan@example.com", "password": "Ab3xQ9kLmZ", "is_admin": false, "email_verified": true}
Ответ при ошибке валидации — HTTP 422
{"success": false, "errors": ["Пользователь с таким email уже зарегистрирован."]}
Автоскрытие объявлений со ссылками (касается всех способов создания груза/машины)
Чтобы обойти платный доступ к контактам, иногда в текст объявления вставляют ссылку на сторонний сайт или мессенджер вместо использования формы связи на бирже. Если в поле comment обнаружена ссылка (http(s)://, www.) или голое упоминание домена (например, t.me/..., site.ru), объявление создаётся, но получает статус «скрыто из поиска» — не показывается в /cargo/list.php, /transport/list.php и в остальных API-методах поиска, пока автор не уберёт ссылку и не сохранит объявление заново (через форму на сайте или повторным вызовом API с исправленным текстом). Это относится и к публикации через /api/v1/cargo_create.php//api/v1/transport_create.php, и к обычной форме, и к CSV-импорту.

