Перейти к содержимому

Адрес приёма

Адрес приёма источника — POST https://имя.goodwink.ru/webhook/<секрет>. Он публичный: без входа и без кук, защищён секретом в адресе и лимитом.

  • обычную форму — application/x-www-form-urlencoded и multipart/form-data;
  • JSON-объект — одно событие;
  • JSON-массив объектов — пачку: каждый объект — отдельное событие;
  • query-параметры адреса — тоже поля события.

Состав полей любой, заранее его не настраивают: что прислали, то и сохранили. Поле, присланное несколько раз (tags[]), сохраняется списком. Файлы из формы не хранятся: в событии — имя файла, его тип и размер.

Что пришло Ответ
Объект (JSON, форма, query) 200 {"ok": true, "id": 412, "duplicate": false, "empty": false}
Массив объектов под application/json 200 {"ok": true, "count": 2, "results": [{"id": 412, "duplicate": false, "empty": false}, …]} — по строке на событие, в порядке пачки
Больше 100 объектов в пачке 413 {"ok": false, "error": "too_many_items", …}
Скаляр, массив не-объектов, битый JSON под заголовком JSON событие сохранено пустым, 400 {"ok": false, "error": "not_an_object" | "bad_json", "detail": …, "id": …}
Тело больше 1 МБ 413 too_large
Больше 60 обращений в минуту на источник или с одного IP 429 и заголовок Retry-After — через сколько секунд можно снова
Источник не найден, отключён или удалён 404
Адрес открыт в браузере (GET) 405 и заголовок Allow: POST: браузеру — страница словами, остальным — {"ok": false, "error": "method_not_allowed", …}
Обычная форма без JavaScript 303 на страницу «спасибо» источника; не задана — 200 и наша страница «спасибо»
  • id — номер события: тот же, что в столбце _event_id таблицы источника и в ленте GET /api/v1/events.
  • duplicate: true — повторная отправка (ниже).
  • empty: true — ни одного заполненного поля: пустое тело, {}, битый JSON, форма из пустых полей. Событие сохранено, вебхук по нему не уходит; интеграциям его стоит пропускать.
  • Тело, которое не разобралось как объект, лежит в событии служебными ключами: _raw — текст, _value — JSON не объект, _parse_error — почему не прочлось, словами и с местом ошибки: «тело не разобралось как JSON: строка 1, позиция 17».

То же тело на тот же источник в течение 5 минут — повторная отправка: событие сохраняется (события не отбрасываются), но помечается. В сырых данных у него repeat_of — номер первого события, строкой таблицы оно не становится, вебхук по нему не уходит. «То же тело» — те же поля с теми же значениями, порядок полей и пробелы не важны.

JSON — всегда UTF-8. Кодировку формы кабинет определяет сам: по заголовку, по служебному полю _charset_, которое браузер подставляет сам, и по самим данным — страницы в windows-1251 старых сайтов принимаются так же, как в UTF-8. Явная кодировка источника (UTF-8, Windows-1251 или Latin-1) побеждает любую догадку. Нераспознанный символ сохраняется символом замены �; нулевой байт и одиночный суррогат UTF-16 (\ud83d — так JavaScript отдаёт строку, обрезанную посреди эмодзи) тоже заменяются на �, а событие сохраняется.

Исходный запрос: тело до разбора (до 64 КБ), тип содержимого, IP отправителя и заголовки Referer, Origin, User-Agent, Accept-Language. Куки и авторизацию кабинет не хранит. Исходный запрос живёт 90 дней и удаляется сам; событие и строка остаются.