Общие правила обмена
Как Заездо сопоставляет данные внешней системы, применяет изменения и обрабатывает повторные запросы.
На этой странице
Как устроен обмен#
Обмен через API позволяет внешней системе передавать данные в Заездо и получать результат их обработки. Внешняя система отправляет HTTPS-запрос на адрес https://app.zaezdo.pro/api/v1 с указанием нужного метода, а Заездо возвращает HTTP-статус и ответ в формате JSON.
Каждый запрос авторизуется отдельно: в заголовке Authorization передаётся Bearer Token интеграции. Тело запросов, которые передают данные, должно быть в формате JSON с заголовком Content-Type: application/json. Получение токена и первый рабочий обмен показаны в «Быстром старте»; здесь рассматриваются правила, на которых строится дальнейшая интеграция.
Разные методы выполняют разные действия. GET читает сведения и не изменяет данные. PUT создаёт или обновляет записи справочников. POST создаёт визит, ссылаясь на подготовленные записи, но не создаёт их внутри себя. Поэтому основа обмена — не только передача реквизитов, но и однозначное сопоставление одних и тех же объектов в двух системах.
Как сопоставляются записи#
Одна площадка, контрагент, автомобиль или водитель могут присутствовать и во внешней системе, и в Заездо. Чтобы очередной запрос относился к нужному объекту, используется source_id — идентификатор записи во внешней системе. Он связывает эту запись с соответствующей записью Заездо; знать внутренний id Заездо для такого сопоставления не требуется.
Например, если за складом закреплён идентификатор "WH-SEVER", дальнейшие обращения к этому складу должны использовать то же значение. Регистр символов учитывается. В PUT идентификатор передаётся в пути запроса, а в визите — в соответствующем поле ссылки на справочник. Допустимый формат и ограничения указаны в параметрах конкретного метода; идентификатор из пути PUT не нужно повторять в JSON.
Такой же принцип связывает существующего пользователя Заездо с ответственным во внешней системе. Пользователи не создаются через API: им заранее задаётся соответствие в Заездо. Проверка пользователя и его прав описана в методе «Пользователи».
Сопоставление отделяет вопрос «какая это запись» от вопроса «какие сведения о ней передаются». Благодаря этому изменение реквизитов не требует создавать новый объект: следующий запрос с прежним source_id обращается к той же записи.
Как создаются и обновляются справочники#
Когда запись определена по source_id, PUT выполняет одно из двух действий. Если записи ещё нет, Заездо создаёт её. Если она существует, обновляет её реквизиты, сохраняя внутренний id и связи. Отдельно выбирать между созданием и обновлением во внешней системе не требуется.
При этом PUT передаёт не отдельные изменившиеся поля, а полное состояние реквизитов, которыми управляет данный метод. Поэтому при изменении названия контрагента нужно повторно передать и остальные значения, которые должны сохраниться. Отсутствие поля в запросе не означает «оставить как было».
Для необязательных строк отсутствие поля, null или пустая строка означают очистку значения; обязательные поля должны быть заполнены при каждом запросе. Если у отдельного реквизита есть особое правило или значение по умолчанию, оно указано в описании метода. Полный набор управляемых полей приведён на страницах площадок, контрагентов, автомобилей и водителей.
Эта полнота относится только к реквизитам, которые предусмотрены методом, а не ко всей карточке объекта в Заездо. Это различие определяет границу между синхронизацией справочных данных и управлением работой сервиса.
Какие данные остаются под управлением Заездо#
Помимо передаваемых реквизитов, у записи могут быть настройки и связи, которыми соответствующий PUT-метод не управляет. Они сохраняются без изменений. Добавить произвольное поле в запрос, чтобы изменить такую настройку, нельзя: неизвестный параметр приводит к ошибке, а не игнорируется.
Один из примеров — активность записи справочника. Она показывает, включена запись в Заездо или отключена. Вновь созданная через PUT запись активна. Если позднее её отключили в Заездо, обновление реквизитов не включает её обратно: текущая активность сохраняется. Поле is_active можно получить в ответе, но нельзя изменить этим PUT.
Сопоставление пользователя также не меняет его роли и права на площадки. Возможность выполнить действие проверяется отдельно от наличия нужной записи. Таким образом, успешная синхронизация справочника не заменяет настройку прав и остальных условий работы в Заездо.
Когда границы изменений определены, остаётся учесть повторную отправку данных. В регулярном обмене она может понадобиться как для очередного обновления, так и после потери ответа; эти ситуации важно различать.
Повторные запросы и конфликты#
Повторный PUT с тем же source_id обращается к прежней записи и не создаёт ещё одну. Одинаковое содержимое повторно передаёт те же значения, а изменённое — обновляет управляемые реквизиты. Поэтому после временного сбоя запрос можно повторить, сохранив исходный идентификатор и данные.
Для визита действует другой принцип: POST предназначен для создания, а не обновления. Чтобы повторная отправка одной заявки не создавала новый визит, используется external_id — её идентификатор во внешней системе. Тот же external_id с теми же исходными данными возвращает ранее созданный визит; с изменёнными данными — конфликт. Сравнивается исходный запрос, а не карточка, которую могли позже отредактировать в Заездо. Подробности приведены в разделе «Повторная отправка визита».
От повторного запроса нужно отличать совпадение с другой записью справочника. Объект мог быть создан в Заездо вручную и ещё не иметь нужного source_id. Если переданные реквизиты совпадают с реквизитами такой записи по правилам конкретного справочника, возникает конфликт. В проверке участвуют и отключённые записи; автоматическое объединение не выполняется.
В такой ситуации сначала проверяют, действительно ли найдена та же сущность. Если соответствие подтверждено, в существующей карточке указывают правильный «Идентификатор для синхронизации с 1С» и повторяют исходный PUT. Критерии совпадения и причины отказа приведены в описании соответствующего метода. Чтобы внешняя система могла отличить конфликт от временного сбоя, ей необходимо обрабатывать не только тело ответа, но и его HTTP-статус.
Как обрабатывать результаты и ошибки#
HTTP-статус сообщает общий результат выполнения запроса, а JSON содержит сведения для дальнейших действий. При создании записи возвращаются HTTP 201 и created: true; при обновлении справочника или успешном повторе создания визита — HTTP 200 и created: false. Для чтения данных успешным ответом также служит HTTP 200. Состав ответа и смысл возвращаемых состояний зависят от метода.
При ошибке важно сначала определить её причину. HTTP 401 и 403 указывают на проблему авторизации или доступа компании; 400 и 415 — на формат запроса; 404 — на отсутствие необходимой записи; 422 — на нарушение требований к данным или условий выполнения операции; 409 — на конфликт. Это разные ситуации: повтор без исправлений не устраняет отсутствующую запись, неверные данные или несогласованное сопоставление.
В стандартном ответе об ошибке code предназначен для программной обработки, message — для объяснения человеку, а errors[] при наличии раскрывает конкретные причины: поле, код и сообщение. request_id позволяет связать ошибку с запросом при обращении в поддержку. У проверки подключения GET /ping есть особенность: ошибки авторизации возвращаются в detail; её формат описан на странице метода.
Проверки выполняются последовательно. Ответ содержит независимые ошибки того этапа, на котором запрос остановился; причины из разных этапов не смешиваются. Поэтому после исправления формата могут обнаружиться ошибки поиска или условий операции. Порядок этапов, точные коды и сообщения приведены у каждого метода — общая страница не заменяет эти описания.
Временная недоступность требует другого действия. При HTTP 429 учитывайте Retry-After. При 500, 503 или потере ответа повторите запрос после паузы, используя описанные выше правила: для PUT сохраните source_id и содержимое, для создания визита — external_id и исходное тело. Потеря ответа сама по себе не означает, что операция не выполнена. Если вместо JSON пришёл ответ сетевого шлюза, ориентируйтесь на HTTP-статус: request_id в нём может отсутствовать.