Работа с API
Интерфейс построен вокруг ресурсов: у каждой сущности свой адрес, а действие задаётся методом HTTP. Тело запроса и ответа — всегда JSON в UTF-8, никаких форм и никакого XML. Заголовок типа содержимого обязателен: без него запрос отклоняется до разбора тела.
Адреса и версии
Версия указывается в пути и меняется только при несовместимых правках. Добавление нового поля в ответ несовместимой правкой не считается, поэтому клиент обязан игнорировать незнакомые поля, а не падать на них. Старая версия живёт минимум год после выхода новой.
Все адреса ведут к одному хосту; балансировка и маршрутизация происходят внутри. Отдельных адресов для чтения и записи нет.
Пагинация и фильтры
Списки отдаются страницами. Размер страницы задаётся параметром, курсор следующей страницы приходит в ответе. Смещением не листаем: при активной записи оно даёт пропуски и дубликаты, курсор от этого защищён.
Фильтры складываются по «и». Фильтр по несуществующему полю — ошибка, а не пустой результат: молчаливое игнорирование опечатки обходится дороже, чем отказ.
Идемпотентность
Повторный вызов записи с тем же ключом идемпотентности не создаёт вторую сущность, а возвращает результат первой. Ключ придумывает клиент, платформа помнит его сутки. Без ключа повтор после сетевого таймаута — это реально второй объект, и разбираться с ним придётся вручную.