<!-- source: https://nodbot.ru/integrations/amocrm/; markdown: /llms/pages/generated/integrations-amocrm.md; type: IntegrationGuide -->
---
title: "amoCRM и n8n: лиды, сделки и webhooks | Nodbot"
source_url: "https://nodbot.ru/integrations/amocrm/"
canonical_url: "https://nodbot.ru/integrations/amocrm/"
language: "ru"
content_type: "IntegrationGuide"
section: "integrations"
generated_at: "2026-05-30"
word_count_source: 1009
---

## AI summary

Практический гайд по amoCRM и n8n: как принимать заявки из форм и мессенджеров, нормализовать данные, искать контакт/сделку, создавать связку contact+lead, сохранять UTM, обрабатывать webhooks и не ломать воронку дублями.

## Best used for

Страница нужна интеграторам и владельцам n8n, которые хотят внедрить связку без дублей, ручного хаоса и потери данных.

## Key topics

- amoCRM API
- OAuth
- webhooks
- n8n
- contact lead upsert
- UTM
- дедупликация
- webhook loop

# amoCRM и n8n: интеграция форм, сделок и webhook без дублей

Обновлено: 2026-05-30

Используйте JSON как основу: замените credentials, URL порталов, поля CRM и правила дедупликации.

- Проблема и сценарии внедрения

- Архитектура интеграции

- Контракт данных

- Code Node и нормализация

- Готовый workflow JSON

- Пошаговая настройка

- Тесты перед production

- Production-риски

- Полезные ссылки

- Критерии готовности

Проблема: amoCRM легко подключить к форме, но сложнее сделать так, чтобы повторный лид не создавал вторую сделку, OAuth не падал в production, webhook не зацикливал workflow, а менеджер видел правильный pipeline и источник заявки.

Решение: выносить бизнес-логику в n8n: единый payload, нормализация phone/email, поиск контакта и открытой сделки, контролируемый create/update, отдельные поля для UTM, retry на API и журнал idempotency для webhook-событий.


## Проблема: почему связка amoCRM и n8n быстро создаёт хаос в воронке

Частая боль отдела продаж — одна и та же заявка приходит из Tilda, Telegram, email и рекламной формы, а amoCRM получает несколько открытых сделок по одному человеку. Менеджер не понимает, какую карточку вести, а отчёт по источникам становится недостоверным.

Вторая проблема — webhook из amoCRM. Если workflow слушает изменение сделки и сам же меняет эту сделку, легко получить цикл обновлений. Поэтому интеграция должна иметь idempotency key, фильтр событий, журнал обработанных webhook и понятный список полей, которые n8n имеет право менять.


## Архитектура интеграции amoCRM, n8n, форм и webhook

| Блок | Задача | Production-проверка |

| --- | --- | --- |

| Inbound source | получает форму, чат или письмо | source, external_id, consent, UTM |

| Normalize payload | готовит contact, lead и custom fields | phone +7, email lowercase, pipeline_id |

| Find contact/deal | ищет существующую карточку | открытые сделки, контакт по телефону/email |

| Upsert amoCRM | создаёт или обновляет contact+lead | custom_fields_values, tags, responsible_user_id |

| Webhook guard | фильтрует исходящие события amoCRM | event type, entity id, idempotency key |

| Monitoring | уведомляет о сбоях | 401/403 OAuth, 429, 5xx, DLQ |

Для простых форм можно начать с HTTP Request. Для сложной логики — community node, но контракт данных и дедупликацию всё равно лучше держать явно в workflow.


## Контракт заявки для amoCRM API

```json
{
  "source": "telegram",
  "external_id": "tg-88421",
  "name": "Илья",
  "phone": "+7 916 200-44-55",
  "email": "ilya@example.ru",
  "pipeline_id": 123456,
  "status_id": 654321,
  "utm_source": "telegram",
  "utm_medium": "bot",
  "comment": "Интересуется внедрением amoCRM и n8n"
}
```

Не пытайтесь парсить pipeline и статус из комментария. Для amoCRM они должны быть явными параметрами: иначе тестовая воронка и production-вронка быстро смешаются.


## Code Node: нормализация и контроль качества

```javascript
const src = $json.body ?? $json;
const rawPhone = String(src.phone ?? '').trim();
let digits = rawPhone.replace(/\D/g, '');
if (digits.length === 11 && digits.startsWith('8')) digits = `7${digits.slice(1)}`;
if (digits.length === 10) digits = `7${digits}`;
if (!/^7\d{10}$/.test(digits)) throw new Error(`Invalid amoCRM phone: ${rawPhone}`);
const email = String(src.email ?? '').trim().toLowerCase();
const pipelineId = Number(src.pipeline_id || $env.AMOCRM_DEFAULT_PIPELINE_ID);
const statusId = Number(src.status_id || $env.AMOCRM_DEFAULT_STATUS_ID);
return [{ json: {
  dedupe_key: `amocrm:${digits}:${email || 'no-email'}`,
  contact: { name: src.name || 'Новый контакт', phone: `+${digits}`, email },
  lead: {
    name: `Заявка: ${src.name || '+7 lead'}`,
    pipeline_id: pipelineId,
    status_id: statusId,
    price: Number(src.budget || 0),
    custom: { utm_source: src.utm_source || '', utm_medium: src.utm_medium || '', utm_campaign: src.utm_campaign || '', external_id: src.external_id || '' }
  },
  note: String(src.comment ?? '').slice(0, 2000)
}}];
```

Не обрабатывайте все события подряд. Фильтруйте только нужные изменения, храните idempotency key по entity_id + event_type + updated_at и не реагируйте на собственные технические теги.


## Готовый workflow JSON: скачать и импортировать

Скачать готовый workflow JSON Скачать тестовый payload

```json
{
  "name": "Nodbot - amoCRM integration blueprint with contact lead upsert",
  "nodes": [
    {
      "name": "Webhook input",
      "type": "n8n-nodes-base.webhook",
      "purpose": "Принять заявку или amoCRM webhook"
    },
    {
      "name": "Normalize amoCRM payload",
      "type": "n8n-nodes-base.code",
      "purpose": "Собрать contact, lead, note и dedupe key"
    },
    {
      "name": "Find contact and open lead",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Искать контакт/сделку до создания"
    },
    {
      "name": "Create or update amoCRM",
      "type": "n8n-nodes-base.httpRequest",
      "purpose": "Записать contact+lead и custom fields"
    },
    {
      "name": "Webhook loop guard",
      "type": "n8n-nodes-base.code",
      "purpose": "Отсечь повторные события"
    },
    {
      "name": "Respond",
      "type": "n8n-nodes-base.respondToWebhook",
      "purpose": "Вернуть безопасный ответ"
    }
  ],
  "connections": "Webhook input → Normalize amoCRM payload → Find contact and open lead → Create or update amoCRM → Webhook loop guard → Respond"
}
```


## Пошаговая настройка amoCRM OAuth, pipeline и n8n

- Создайте OAuth-интеграцию amoCRM и сохраните subdomain, client_id, client_secret и refresh token в credentials.

- Заведите custom fields для UTM, external_id и source, а не храните их в примечании.

- Импортируйте workflow JSON и задайте pipeline_id/status_id через ENV или параметры.

- Настройте поиск контакта по телефону/email и открытую сделку в нужной воронке.

- Добавьте webhook guard для событий amoCRM, чтобы workflow не реагировал на собственные изменения.


## Тесты перед production

```bash
curl -X POST "https://YOUR-N8N-DOMAIN/webhook/integration-amocrm-n8n" \
  -H "Content-Type: application/json" \
  --data @integration-amocrm-n8n-payload.json
```

- Повторите один payload дважды и проверьте, что не появилась вторая открытая сделка.

- Измените UTM при том же телефоне и проверьте, какое поле обновляется.

- Смоделируйте истёкший OAuth и убедитесь, что alert понятен.

- Отправьте webhook изменения сделки и проверьте, что нет бесконечного цикла.

- Проверьте, что notes не содержат токены и лишние персональные данные.


## Production-риски

- OAuth не обновляется. Workflow работает в тесте, но падает через несколько дней; нужен runbook обновления токена.

- Поиск только по контакту. У клиента может быть открытая сделка без обновлённого contact; проверяйте бизнес-правило.

- Смешаны воронки. Тестовые заявки попадают в production pipeline.

- Webhook loop. Изменение карточки из n8n снова вызывает входящее событие.

- UTM в note. Маркетинг теряет аналитику по каналам.


## Полезные ссылки и смежные материалы

- amoCRM API Reference

- amoCRM Webhooks

- Workflow Tilda → amoCRM

- Дедупликация amoCRM webhook через Postgres


## Критерии готовности

- Повторный лид обновляет существующую карточку или создаёт новую по явному правилу.

- OAuth credentials хранятся безопасно, есть инструкция обновления.

- UTM, source и external_id записаны в отдельные поля.

- Webhook события имеют idempotency и не создают цикл.

- Ошибки API уходят в alert или DLQ с ссылкой на execution.

Nodbot спроектирует n8n-слой под вашу воронку: OAuth, поля, дедупликация, webhooks, alerts и тесты.
