Пошаговые инструкции Для начинающих 12 мин

Webhook в n8n: как принять JSON и вернуть ответ

Практическая инструкция: готовый workflow из пяти узлов, POST из Windows, проверка двух полей, ответы 200 и 422, Test и Production URL.

n8n webhook JSON

Webhook в n8n - адрес, на который другая программа отправляет данные и запускает workflow. В этой инструкции вы отправите учебный JSON с компьютера, проверите два поля и получите собственный ответ. Это основа для приёма заявок и запуска AI-сценариев, но сам webhook не является ИИ-агентом.

Результат инструкции

Рабочая цепочка состоит из пяти узлов: Webhook → Validate Input → Build Reply → Respond OK. При неверных данных Validate Input переключает выполнение на Respond Invalid. Правильный запрос получает HTTP 200 и три поля: status, request_id, message. Неверный - HTTP 422 и объяснение ошибки. Никаких писем, списаний и записей в CRM здесь нет.

Пример рассчитан на локальный n8n и PowerShell в Windows. Для n8n Cloud логика узлов такая же, но адрес берётся из вашего облачного экземпляра. Бесплатного локального запуска достаточно: аккаунт нейросети и API-ключ не нужны.

Что понадобится

  • Запущенный локальный n8n с доступом в редактор. Если его ещё нет, сначала установите по инструкции ниже.
  • PowerShell, curl.exe и любой текстовый редактор. Команды запускайте на том же компьютере, где открыт локальный n8n.
  • Отдельный пустой workflow. Не вставляйте пример поверх рабочей схемы и не используйте настоящие клиентские данные.

Установить n8n локально через Docker

Шаг 1. Скачайте готовую схему

Скачать workflow n8n-webhook-json-demo.json

Сохраните JSON на компьютер. Если браузер показывает содержимое, сохраните страницу как файл с расширением .json. Это учебная схема без credentials, ключей и внешних запросов. Файл не содержит ID существующего workflow и не включает публикацию автоматически. Перед импортом всё равно проверьте, что работаете в новой схеме.

Шаг 2. Создайте новый workflow и вставьте узлы

Откройте Overview → Create workflow. Откройте скачанный JSON в текстовом редакторе, выделите всё и скопируйте. В пустом редакторе n8n щёлкните свободную область схемы и нажмите Ctrl+V. Если в меню More actions есть Import from File, можно выбрать тот же файл вместо вставки.

Должно появиться пять узлов с названием workflow ezgpt-webhook-json-demo. Нажмите Zoom to Fit, если часть узлов ушла за экран. Проверьте соединения: true у Validate Input ведёт к Build Reply, false - к Respond Invalid. Если узлы не появились, не продолжайте на пустом полотне: проверьте, что скопировали весь JSON, а фокус не остался в поле имени.

Шаг 3. Проверьте метод, путь и режим ответа

Откройте сам узел Webhook двойным щелчком по его значку. На вкладке Parameters должны быть HTTP Method = POST, Path = ezgpt-json-demo и Respond = Using 'Respond to Webhook' Node. Authentication = None допустимо только для этого учебного примера на localhost, не для открытого адреса в интернете.

Если такой путь уже занят другим workflow, выберите уникальный, например ezgpt-json-demo-2, и используйте его во всех последующих URL. Нельзя зарегистрировать одну и ту же комбинацию метода и пути для двух работающих схем. Случайное имя пути не заменяет авторизацию.

n8n: настройки Webhook

Шаг 4. Различите Test URL и Production URL

Адрес Когда работает Как проверять
/webhook-test/ezgpt-json-demo При ожидании тестового события Запустить Execute workflow, затем POST
/webhook/ezgpt-json-demo После публикации workflow Отправить POST, открыть Executions

В панели Webhook есть переключатель этих адресов. Домен и порт должны вести именно к вашему экземпляру. Ниже используется http://localhost:5679 - замените его на адрес, по которому вы действительно открываете n8n. Если редактор на 5679, а узел показывает 5678, для локального запроса используйте доступный с компьютера порт 5679, сохранив путь.

Такое несовпадение бывает при перенаправлении порта Docker. В полноценном серверном развёртывании оператор настраивает внешний адрес webhook, а не просит клиентов вручную угадывать порт. Не меняйте настройки существующего сервера ради этого теста.

n8n: внешний адрес Webhook за reverse proxy

Шаг 5. Проверьте обязательные поля

Откройте Validate Input - это узел If. Условие должно иметь тип Boolean и оператор is true. В левом значении выберите Expression. В импортированной схеме выражение уже вставлено:

javascript
={{ typeof $json.body?.request_id === 'string' && $json.body.request_id.trim().length > 0 && $json.body.request_id.trim().length <= 80 && typeof $json.body?.message === 'string' && $json.body.message.trim().length > 0 && $json.body.message.trim().length <= 1000 }}

Выражение принимает только строки: request_id не пустой и длиной до 80, message не пустой и длиной до 1000 после удаления пробелов по краям. Это простая проверка двух полей, а не полноценная проверка JSON Schema. Число вместо строки, пропущенное поле и строка из пробелов уходят в ветку false. Длина считается JavaScript-свойством length: некоторые emoji занимают больше одной единицы.

Данные из JSON находятся в $json.body. $json.query относится к параметрам URL, а не к телу POST. Не заменяйте body на query, чтобы случайно прошёл один тест: это изменит договорённость о входных данных.

Шаг 6. Проверьте сборку успешного ответа

Откройте Build Reply - это Edit Fields (Set) в режиме Manual Mapping. В нём ровно три строковых поля. status имеет фиксированное значение received. request_id и message - выражения ниже. Include Other Input Fields выключен: заголовки запроса и лишние данные не должны попадать в ответ.

text
status: received (Fixed, String)
request_id: {{ $json.body.request_id.trim() }} (Expression, String)
message: {{ $json.body.message.trim() }} (Expression, String)

Не собирайте ответ конкатенацией сырого JSON с пользовательским текстом. Здесь n8n формирует объект из отдельных полей, поэтому кавычки и переносы строки внутри message не ломают JSON.

n8n: Edit Fields (Set)

Шаг 7. Проверьте две ветки ответа

В Respond OK установлено Respond With = First Incoming Item, а в Options - Response Code = 200. Узел возвращает объект, собранный в Build Reply. В Respond Invalid установлено Respond With = JSON и Response Code = 422. Его Response Body:

json
{"status":"rejected","error":"request_id must be a nonempty string up to 80 characters; message must be a nonempty string up to 1000 characters"}

Не соединяйте обе ветки с двумя последовательными ответами: один запрос должен закончиться одним Respond to Webhook. Код 200 сам по себе ещё не доказывает успех - проверяйте тело. Если ответный узел не выполняется, n8n может вернуть стандартный ответ вместо вашего JSON.

n8n: Respond to Webhook

Шаг 8. Подготовьте учебный запрос

Создайте на компьютере отдельную папку для теста и откройте в ней PowerShell. Следующая команда создаёт payload.json в этой папке в UTF-8 без BOM. Не запускайте её там, где уже есть важный файл с таким именем.

powershell
$payload = '{"request_id":"demo-001","message":"Hello webhook"}'
[IO.File]::WriteAllText((Join-Path (Get-Location) 'payload.json'), $payload, [Text.UTF8Encoding]::new($false))

Файл содержит только вымышленные данные. Использование файла снимает часть проблем с кавычками командной строки Windows. Здесь нужен именно curl.exe, а не сокращение curl, которое в некоторых версиях PowerShell обозначает другую команду.

Шаг 9. Запустите всю цепочку и отправьте POST

Закройте панель узла и нажмите Execute workflow внизу редактора. Дождитесь Waiting for trigger event. Затем выполните команду в PowerShell. При другом адресе n8n замените localhost:5679.

powershell
curl.exe --include --max-time 15 --request POST "http://localhost:5679/webhook-test/ezgpt-json-demo" --header "Content-Type: application/json" --data-binary "@payload.json"

В начале ответа ожидается HTTP 200, а ниже - объект:

json
{"status":"received","request_id":"demo-001","message":"Hello webhook"}

В редакторе должны выполниться Webhook, Validate Input, Build Reply и Respond OK. Respond Invalid не должен выполняться. Если вы нажали только Listen for test event внутри Webhook, проверяется сам триггер: можно получить его данные, но не собственный ответ всей цепочки. Для этого результата используйте Execute workflow.

Тестовое ожидание ограничено по времени; документация описывает окно 120 секунд. После его завершения или для следующей ручной проверки запустите Execute workflow снова. Если получили 404, сначала проверьте ожидание, метод POST и точный путь, а не переписывайте выражения.

n8n: тестовый и рабочий режим Webhook

Шаг 10. Проверьте отказ на неверные данные

Перезапишите только учебный payload.json следующим содержимым. Затем снова нажмите Execute workflow и повторите ту же curl.exe-команду из шага 9.

powershell
$payload = '{"request_id":"demo-002"}'
[IO.File]::WriteAllText((Join-Path (Get-Location) 'payload.json'), $payload, [Text.UTF8Encoding]::new($false))

Ожидается HTTP 422 и status = rejected: message отсутствует. В схеме работает ветка false и Respond Invalid; Build Reply не выполняется. Это намеренный отказ вашей проверки, не авария n8n.

Дополнительно попробуйте message из пробелов и числовой request_id - оба должны получить 422. Верните исходный правильный пример: он снова должен получить 200. Если неверный запрос получил received, посмотрите Input и Output Validate Input и убедитесь, что не оставили закреплённые тестовые данные через Pin data.

Шаг 11. Опубликуйте workflow и проверьте рабочий URL

Верните правильный payload.json командой из шага 8. Нажмите Publish в верхней части редактора, при появлении окна оставьте или укажите имя версии и подтвердите Publish. Дождитесь Published. В n8n 2.x обычное сохранение черновика не равно публикации; изменения должны попасть в опубликованную версию.

powershell
curl.exe --include --max-time 15 --request POST "http://localhost:5679/webhook/ezgpt-json-demo" --header "Content-Type: application/json" --data-binary "@payload.json"

Ответ должен содержать HTTP 200 и прежние три поля. Для этого адреса не нужно нажимать Execute workflow. Во вкладке Executions откройте новое выполнение, сверив время, request_id и ветку узлов. Повторите плохой пример: ожидается 422. В нашем примере выполнение отклонённого запроса может быть отмечено успешным, потому что схема штатно вернула отказ; это не означает принятие данных.

n8n: публикация workflow

Шаг 12. Зафиксируйте результат и завершите тест

  • Правильный POST получает 200 и status = received. В ответе нет headers, query и других входных полей.
  • POST без message получает 422 и status = rejected. Build Reply не запускается.
  • Кавычки, русский текст и перенос строки сохраняются в значении message без поломки JSON.
  • Test URL без запущенного ожидания получает 404, а опубликованный Production URL работает без ручного запуска.

Сохраните workflow. Если пример больше не нужен, откройте меню рядом с Published и выберите Unpublish: это отключит рабочий webhook, но сохранит схему. Повторная отправка на его Production URL после снятия публикации должна получить 404. Не удаляйте другие workflows и не останавливайте общий n8n.

Если результат отличается

Симптом Вероятная причина Что проверить
404 на Test URL Нет текущего ожидания Execute workflow, POST и путь
404 на Production URL Не опубликовано или неверный адрес Published, порт, путь и метод
422 с rejected Данные не прошли проверку Строковые поля request_id и message
200 без нужного JSON Тестировался только триггер или нет ответной ветки Полный запуск и Respond to Webhook
Соединение не установлено Неверный порт или n8n остановлен Адрес редактора и Docker Desktop
Ответ не отражает правки В работе предыдущая публикация Повторная Publish и новое выполнение

Если клиент ждёт слишком долго, не увеличивайте тайм-аут бесконечно: проверьте, дошло ли выполнение до ответного узла. Параметр --max-time 15 ограничивает ожидание curl, а не гарантирует остановку workflow. Не повторяйте платёж или отправку письма по этой схеме без защиты от дублей.

Перед подключением сайта или AI-агента

Оставляйте Authentication = None только в локальном упражнении, доступном на вашем компьютере. Перед внешним подключением нужны HTTPS, проверка отправителя (например, Header Auth через credentials), ограничение доступа и нагрузки, а также согласованный формат данных. CORS не является авторизацией. В эту инструкцию открытие доступа извне не входит.

localhost относится к компьютеру, который выполняет запрос. Сайт в интернете, n8n Cloud и приложение в другом контейнере не могут обратиться к вашему n8n по своему localhost. Для реальной интеграции нужен корректно развёрнутый доступный адрес; не выставляйте учебный порт в интернет без защиты.

request_id в примере - метка для проверки, не защита от повторов. Каждый одинаковый POST запускает новое выполнение. Если добавите CRM, рассылку, публикацию или платный вызов модели, сначала настройте хранение обработанных идентификаторов, обработку повторов и ручное подтверждение опасных действий. Наш workflow ничего из этого не делает.

Следующий шаг: ИИ-агент в n8n

Что проверено редакцией

8 октября 2026 года пример проверен на локальном n8n 2.42.4. В редакторе создан отдельный workflow, выполнен полный ручной запуск и публикация. Через Production URL прошли восемь HTTP-проверок: обычный JSON, русский текст с кавычками и переносом строки, пропущенное поле, неверный тип, пробелы, превышение длины и два граничных случая. Правильные данные возвращали 200, отклонённые - 422. Test URL без ожидания и запрос неверным методом возвращали 404. n8n Cloud, внешний сервер, авторизацию внешнего отправителя и платные модели не тестировали. Обложка - редакционная иллюстрация, не снимок интерфейса.

Частые вопросы

Почему webhook n8n возвращает 404?

Для Test URL запустите Execute workflow и отправьте POST во время ожидания. Для Production URL нужна опубликованная версия workflow. В обоих случаях проверьте порт, точный путь и метод. Открытие ссылки браузером отправляет GET, а в примере настроен POST.

Почему приходит 200, но нет моего JSON?

Проверьте, что запустили весь workflow, а не только Listen for test event внутри Webhook. В Webhook должен быть режим ответа через Respond to Webhook; успешная ветка должна дойти до Respond OK. Сверяйте тело ответа, а не только HTTP-код.

Где искать поля отправленного JSON в n8n?

Для нашего запроса с Content-Type: application/json данные находятся в $json.body. Параметры URL находятся в $json.query. Нужны строковые request_id и message. Другие типы содержимого следует проверять отдельно, а не считать совместимыми с этим примером.

Можно ли отправить запрос с сайта на localhost?

Внешний сайт или облачный сервис не увидит ваш локальный n8n по своему localhost. Нужен доступный защищённый серверный адрес или собственный безопасный способ связи. В упражнении запрос отправляется с того же компьютера, где работает n8n.

Можно ли сразу добавить к webhook ИИ-агента?

Сначала добейтесь проверенного приёма данных и ответа без модели. Затем добавляйте AI-узел после проверки входа, отдельно проверяя тайм-ауты, расходы и ошибки. Webhook сам по себе не является ИИ-агентом; request_id в этом примере не предотвращает повторное выполнение.

Дальше по теме

Похожие материалы