---
title: "Retry и DLQ в n8n: HTTP Request без потерь | Nodbot"
source_url: "https://nodbot.ru/workflows/retry-dlq-http-request/"
canonical_url: "https://nodbot.ru/workflows/retry-dlq-http-request/"
language: "ru"
content_type: "WorkflowTemplate"
section: "workflows"
generated_at: "2026-05-30"
word_count_source: 1088
---

# Retry и DLQ в n8n: безопасные HTTP-запросы без потерь и дублей

## AI summary

Практический workflow для устойчивых HTTP-интеграций: принять событие, собрать idempotency key, отправить запрос во внешний API, классифицировать ответ, повторить временные ошибки с backoff, а необработанные события положить в DLQ с понятным alert.

## Best used for

Полноценный Problem/Solution-мануал для внедрения в n8n: импортировать workflow JSON, настроить API, выполнить production-тесты и передать решение команде.

## Table of contents

- Проблема: где ломается сценарий
- Архитектура workflow
- Контракт входных данных
- Code Node: нормализация и контроль
- Готовый workflow JSON
- Пошаговая настройка
- Тесты перед production
- Production-риски
- Полезные ссылки и смежные workflow
- Критерии готовности

## Key topics

- n8n
- HTTP Request
- retry
- DLQ
- dead-letter queue
- idempotency
- API errors
- 429
- 5xx

## Source outline

Retry и DLQ в n8n: безопасные HTTP-запросы без потерь и дублей ¶ Обновлено: 2026-05-30 AI summary: Практический workflow для устойчивых HTTP-интеграций: принять событие, собрать idempotency key, отправить запрос во внешний API, классифицировать ответ, повторить временные ошибки с backoff, а необработанные события положить в DLQ с понятным alert. Шаблон для внедрения Скачать workflow JSON Скачать test payload Скопировать curl Импортируйте workflow, замените credentials и прогоните тестовый payload до включения production. Содержание Проблема: где ломается сценарий Архитектура workflow Контракт входных данных Code Node: нормализация и контроль Готовый workflow JSON Пошаговая настройка Тесты перед production Production-риски Полезные ссылки и смежные workflow Критерии готовности Проблема: внешний API может вернуть 429, 502 или timeout именно в момент, когда заявка уже принята бизнесом. Если n8n просто падает на HTTP Request, событие теряется или вручную перезапускается с риском дубля. Решение: строим retry/DLQ-слой в n8n: отделяем временные ошибки от постоянных, добавляем backoff, сохраняем payload и idempotency key, отправляем alert владельцу и даём команде безопасный способ переиграть событие. Workflow отправляет HTTP Request, классифицирует ответ, повторяет 429/5xx и сохраняет необработанные события в DLQ. Проблема: почему HTTP Request в n8n теряет события при 429 и 5xx ¶ Типичная интеграция выглядит безобидно: Webhook принимает заявку, HTTP Request отправляет её в CRM или склад, а дальше workflow завершается. Но production живёт иначе: API ограничивает частоту запросов, прокси рвёт соединение, токен истекает, а downstream-сервис отвечает 502 после того, как часть операции уже выполнена. Без retry и DLQ команда не понимает, какие события действительно обработаны, какие можно повторить, а какие нужно исправлять вручную. Эта статья решает конкретную боль интеграторов: как сделать HTTP Request в n8n устойчивым к временным сбоям и при этом не создать дубли при повторной отправке. Архитектура workflow retry/DLQ для HTTP-интеграции ¶ Нода Роль Что проверить Webhook or Trigger получает бизнес-событие event_id, source, payload, дедупликационный ключ Prepare API request собирает endpoint, headers и body нет секретов в тексте execution, timeout задан явно HTTP Request отправляет запрос во внешний API response code, response body, retryable network errors Classify response разделяет success, retry и DLQ 429/5xx/timeout не смешаны с 400/422 Retry with backoff повторяет временные ошибки attempt_count, next_retry_at, max attempts Dead-letter queue сохраняет необработанное событие payload, причина, владелец, ссылка на execution Главная SEO-и практическая разница между “retry” и “просто перезапустить workflow” — наличие контекста. В DLQ должен лежать исходный payload, статус API, число попыток, idempotency key и понятная причина, чтобы повтор был безопасным. Контракт входных данных для API-запроса ¶ { "event_id": "lead-10492", "source": "landing-webhook", "target": "crm-api", "idempotency_key": "landing:lead-10492", "customer": { "name": "Мария", "phone": "+7 (916) 555-12-34" }, "request": { "method": "POST", "url": "https://api.example.ru/leads", "body": { "name": "Мария", "phone": "+79165551234" } }, "attempt": 1 } `event_id` и `idempotency_key` обязательны. Если внешний API поддерживает заголовок `Idempotency-Key`, передавайте туда тот же ключ. Если не поддерживает — храните ключ в Postgres и не повторяйте бизнес-действие вслепую. Code Node: классификация ответа, retry и DLQ route ¶ const src = $json.body ?? $json; const status = Number(src.http_status ?? src.statusCode ?? 0); const attempt = Number(src.attempt ?? 1); const maxAttempts = Number(src.max_attempts ?? 5); const idempotencyKey = String(src.idempotency_key ?? src.event_id ?? '').trim(); if (!idempotencyKey) throw new Error('Missing idempotency_key for retry workflow'); const retryableStatus = [408, 409, 425, 429, 500, 502, 503, 504]; const isNetworkError = String(src.error ?? '').toLowerCase().includes('timeout'); const retryable = retryableStatus.includes(status) || isNetworkError; const permanentFailure = status >= 400 && status < 500 && !retryable; const delaySeconds = Math.min(900, Math.pow(2, attempt) * 15); let route = 'success'; if (retryable && attempt < maxAttempts) route = 'retry'; if (retryable && attempt >= maxAttempts) route = 'dlq'; if (permanentFailure) route = 'dlq'; return [{ json: { route, idempotency_key: idempotencyKey, attempt, max_attempts: maxAttempts, next_attempt: attempt + 1, retry_after_seconds: delaySeconds, status, reason: src.error ?? src.response?.message ?? 'classified_by_retry_policy', original_payload: src.original_payload ?? src } }]; Почему 400 и 500 нельзя обрабатывать одинаково 400/422 обычно означают ошибку данных и должны уходить в DLQ с описанием. 429/502/503 чаще временные: их можно повторять с backoff, но только с idempotency key и лимитом попыток. Готовый workflow JSON: скачать и импортировать ¶ Скачать готовый workflow JSON Скачать тестовый payload { "name": "Nodbot - HTTP Request retry and DLQ policy", "nodes": [ { "name": "Webhook input", "type": "n8n-nodes-base.webhook", "purpose": "Принять событие и idempotency key" }, { "name": "Prepare HTTP request", "type": "n8n-nodes-base.code", "purpose": "Собрать endpoint, headers, body и timeout" }, { "name": "Send HTTP Request", "type": "n8n-nodes-base.httpRequest", "purpose": "Отправить запрос во внешний API" }, { "name": "Classify API response", "type": "n8n-nodes-base.code", "purpose": "Разделить success/retry/DLQ" }, { "name": "Retry gate", "type": "n8n-nodes-base.if", "purpose": "Проверить лимит попыток и статус" }, { "name": "Write DLQ record", "type": "n8n-nodes-base.postgres", "purpose": "Сохранить payload, reason и execution URL" }, { "name": "Respond", "type": "n8n-nodes-base.respondToWebhook", "purpose": "Вернуть безопасный результат" } ], "connections": "Webhook input → Prepare HTTP request → Send HTTP Request → Classify API response → Retry gate → Write DLQ record → Respond" } Пошаговая настройка retry, backoff и DLQ в n8n ¶ Импортируйте workflow и замените endpoint внешнего API. Добавьте idempotency key в payload и, если API поддерживает, в header `Idempotency-Key`. Создайте таблицу DLQ с полями idempotency_key, payload, reason, attempt, status. Настройте retry policy: 429/5xx/timeout повторять, 400/422 отправлять в DLQ. Добавьте Telegram/Slack alert только после записи DLQ, чтобы не потерять контекст. Тесты перед production и проверка повторов ¶ curl -X POST "https://YOUR-N8N-DOMAIN/webhook/retry-dlq-http-request" \ -H "Content-Type: application/json" \ --data @retry-dlq-http-request-payload.json Сымитируйте 200 OK и проверьте, что запись не попадает в DLQ. Сымитируйте 429 и убедитесь, что route = retry, а delay растёт. Сымитируйте 422 и проверьте route = dlq без повторов. Запустите один и тот же event_id дважды и проверьте idempotency. Отключите внешний API и убедитесь, что после max_attempts событие попадает в DLQ. Production-риски retry и dead-letter queue ¶ Retry без idempotency. Повтор может создать вторую сделку, списание или заявку. Бесконечные повторы. Workflow забивает очередь и маскирует настоящую ошибку данных. DLQ без payload. Нельзя безопасно восстановить событие после инцидента. Alert до записи DLQ. Уведомление пришло, но контекст потерян при сбое. Все ошибки считаются временными. 400/422 будут повторяться зря и увеличивать нагрузку. Полезные ссылки и смежные workflow ¶ См. также webhook idempotency to Postgres , Error Workflow → Telegram alert , retry/DLQ pattern и ЮKassa → CRM с idempotency . Официальные документы: n8n HTTP Request node , n8n error handling и HTTP status codes . Визуальная карточка показывает route, attempt, статус API и следующий шаг обработки. Критерии готовности ¶ Retryable-статусы отделены от ошибок данных. Каждый повтор использует idempotency key. DLQ хранит исходный payload, reason, status и attempt_count. Есть лимит попыток и понятный backoff. Команда знает, как безопасно переиграть DLQ-событие. Нужно, чтобы API-интеграции не теряли события? Nodbot настроит retry/DLQ-слой в n8n: классификацию ошибок, idempotency, журнал восстановления, alert и безопасные повторы. Настроить надежный HTTP workflow

## Test payload

```json
{
  "event_id": "lead-10492",
  "source": "landing-webhook",
  "target": "crm-api",
  "idempotency_key": "landing:lead-10492",
  "customer": {
    "name": "Мария",
    "phone": "+7 (916) 555-12-34"
  },
  "request": {
    "method": "POST",
    "url": "https://api.example.ru/leads",
    "body": {
      "name": "Мария",
      "phone": "+79165551234"
    }
  },
  "attempt": 1
}
```

## Key implementation snippet

```javascript
const src = $json.body ?? $json;
const status = Number(src.http_status ?? src.statusCode ?? 0);
const attempt = Number(src.attempt ?? 1);
const maxAttempts = Number(src.max_attempts ?? 5);
const idempotencyKey = String(src.idempotency_key ?? src.event_id ?? '').trim();

if (!idempotencyKey) throw new Error('Missing idempotency_key for retry workflow');

const retryableStatus = [408, 409, 425, 429, 500, 502, 503, 504];
const isNetworkError = String(src.error ?? '').toLowerCase().includes('timeout');
const retryable = retryableStatus.includes(status) || isNetworkError;
const permanentFailure = status >= 400 && status < 500 && !retryable;
const delaySeconds = Math.min(900, Math.pow(2, attempt) * 15);

let route = 'success';
if (retryable && attempt < maxAttempts) route = 'retry';
if (retryable && attempt >= maxAttempts) route = 'dlq';
if (permanentFailure) route = 'dlq';

return [{
  json: {
    route,
    idempotency_key: idempotencyKey,
    attempt,
    max_attempts: maxAttempts,
    next_attempt: attempt + 1,
    retry_after_seconds: delaySeconds,
    status,
    reason: src.error ?? src.response?.message ?? 'classified_by_retry_policy',
    original_payload: src.original_payload ?? src
  }
}];
```

## Importable workflow structure

```json
{
  "name": "Nodbot - HTTP Request retry and DLQ policy",
  "nodes": [
    {
      "name": "Webhook input",
      "type": "n8n-nodes-base.webhook",
      "purpose": "Принять событие и idempotency key"
    },
    {
      "name": "Prepare HTTP request",
      "type": "n8n-nodes-base.code",
      "purpose": "Собрать endpoint, headers, body и timeout"
    },
    {
      "name": "Send HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Отправить запрос во внешний API"
    },
    {
      "name": "Classify API response",
      "type": "n8n-nodes-base.code",
      "purpose": "Разделить success/retry/DLQ"
    },
    {
      "name": "Retry gate",
      "type": "n8n-nodes-base.if",
      "purpose": "Проверить лимит попыток и статус"
    },
    {
      "name": "Write DLQ record",
      "type": "n8n-nodes-base.postgres",
      "purpose": "Сохранить payload, reason и execution URL"
    },
    {
      "name": "Respond",
      "type": "n8n-nodes-base.respondToWebhook",
      "purpose": "Вернуть безопасный результат"
    }
  ],
  "connections": "Webhook input → Prepare HTTP request → Send HTTP Request → Classify API response → Retry gate → Write DLQ record → Respond"
}
```

## Retrieval hints

- Использовать HTML как canonical source.
- Markdown удобен для LLM-ответов, извлечения workflow-контракта, кода и чеклистов.
- Для ссылок пользователю отдавать canonical URL.
