Чому потрібен посередник
API KeyCRM вимагає заголовок Authorization: Bearer і власну структуру JSON. Вебхук Formgong має фіксоване тіло і не додає власних заголовків. Тож вебхук напряму в KeyCRM отримає 401.
- Make: безкоштовний старт, без коду. Custom webhook → HTTP Make a request.
- n8n: Webhook node → HTTP Request node. Зручно, якщо у вас свій сервер.
- Власний скрипт: Cloudflare Worker або будь-яка HTTPS-адреса. Код — у кінці сторінки.
Підготуйте KeyCRM
- API-ключ: «Налаштування» → «Основні» → рядок «API-ключ» → «Згенерувати API ключ». Оновити ключ може лише власник CRM. Після оновлення старий ключ перестає працювати в усіх інтеграціях.
- Джерело: додайте джерело, наприклад «Форма на сайті», щоб бачити, звідки прийшла заявка. ID джерел повертає
GET /order/source. - Воронка: ID воронок повертає
GET /pipelines. Безpipeline_idKeyCRM бере першу воронку зі списку.
Картка чи замовлення? Для звернень і запитів ціни — картка у воронці (POST /pipelines/cards), їй потрібен лише contact. Для покупки з товарами — замовлення (POST /order), йому потрібні source_id і buyer.
Рецепт для Make
- Налаштуйте Custom webhook за інструкцією для Make і надішліть одну справжню заявку.
- Додайте фільтр:
eventдорівнюєsubmission.created. Тоді тестові доставки не створюватимуть карток. - Додайте HTTP → Make a request. URL
https://openapi.keycrm.app/v1/pipelines/cards, метод POST. - Authentication type — API key: створіть keychain, що надсилає заголовок
Authorizationзі значеннямBearerі ваш ключ. Додайте заголовокAccept: application/json. - Body content type — application/json, спосіб введення Data structure: так Make сам екранує лапки й переноси, які ввів відвідувач. Заповніть, як нижче.
- Parse response — Yes. Запустіть один раз і перевірте нову картку в KeyCRM.
{
"title": "{{1.form.name}}: {{1.submission.fields.name}}",
"source_id": 12,
"pipeline_id": 3,
"contact": {
"full_name": "{{1.submission.fields.name}}",
"email": "{{1.submission.fields.email}}",
"phone": "{{1.submission.fields.phone}}"
},
"manager_comment": "{{1.submission.fields.message}} | Сторінка: {{1.submission.page_url}} | Formgong ID: {{1.submission.id}}",
"utm_source": "{{1.submission.fields.utm_source}}"
}Замініть 12 і 3 на ID свого джерела й воронки. Ключі, яких не збираєте, приберіть.
Рецепт для n8n
- Налаштуйте Webhook node за інструкцією для n8n, з Only Run If
{{ $json.body.event === 'submission.created' }}. - Додайте вузол HTTP Request: метод POST, URL
https://openapi.keycrm.app/v1/pipelines/cards. - Authentication: Generic Credential Type → Header Auth, назва
Authorization, значенняBearerі ваш ключ. - Увімкніть Send Body, тип JSON, Specify Body: Using JSON.
JSON.stringifyне дасть лапкам у повідомленні зламати JSON. - У налаштуваннях вузла ввімкніть Retry On Fail, щоб пережити відповідь 429.
Тіло (вираз n8n)
{
"title": {{ JSON.stringify($json.body.form.name + ": " + ($json.body.submission.fields.name ?? "")) }},
"source_id": 12,
"pipeline_id": 3,
"contact": {
"full_name": {{ JSON.stringify($json.body.submission.fields.name ?? "") }},
"email": {{ JSON.stringify($json.body.submission.fields.email ?? "") }},
"phone": {{ JSON.stringify($json.body.submission.fields.phone ?? "") }}
},
"manager_comment": {{ JSON.stringify(($json.body.submission.fields.message ?? "") + " | Сторінка: " + ($json.body.submission.page_url ?? "") + " | Formgong ID: " + $json.body.submission.id) }},
"utm_source": {{ JSON.stringify($json.body.submission.fields.utm_source ?? "") }}
}Зіставлення полів
| Formgong | Картка KeyCRM |
|---|---|
fields.name | contact.full_name |
fields.email | contact.email |
fields.phone | contact.phone (міжнародний формат із +380) |
fields.message, page_url, submission.id | manager_comment |
fields.utm_source … utm_content | utm_source … utm_content |
| Усе інше | custom_fields з uuid поля з GET /custom-fields |
UTM-мітки потраплять у вебхук, лише якщо форма надсилає їх звичайними полями, наприклад прихованими input з іменем utm_source. KeyCRM зберігає час в UTC, як і поле created_at у Formgong.
Замовлення замість карток
Для форми замовлення шліть запит на /order. Запишіть submission.id у source_uuid — номер замовлення в джерелі. Так повторну доставку легко знайти.
POST https://openapi.keycrm.app/v1/order
Authorization: Bearer <your KeyCRM API key>
Content-Type: application/json
Accept: application/json
{
"source_id": 12,
"source_uuid": "<submission.id>",
"buyer": {
"full_name": "<fields.name>",
"email": "<fields.email>",
"phone": "<fields.phone>"
},
"buyer_comment": "<fields.message>",
"products": [
{ "sku": "<fields.sku>", "name": "<fields.product>", "price": 0, "quantity": 1 }
]
}Якщо щось не працює
- 401: ключ неправильний або бракує слова
Bearer. Після оновлення ключа замініть його в Make чи n8n. - 422: бракує обов'язкового поля, наприклад
contactу картці чиsource_idу замовленні. Дивіться тіло відповіді. - 429 Too Many Requests: понад 20 запитів на хвилину на ключ. За регулярні перевищення KeyCRM може заблокувати доступ до API, тож враховуйте й інші інтеграції.
- Та сама заявка двічі: Formgong повторив запит після повільної чи невдалої відповіді. Перед створенням шукайте за
source_uuidабо ID у коментарі. - Картки від тестів: додайте фільтр за
eventз кроків вище.
Без Make і n8n: невеликий скрипт
Не хочете додаткового сервісу — розмістіть маленький обробник. Він перевіряє підпис Formgong, будує тіло для KeyCRM і повертає помилку, якщо KeyCRM не прийняв запит. Тоді Formgong повторить спробу.
Cloudflare Worker (JavaScript)
// Env: FORMGONG_SECRET (signing secret), KEYCRM_KEY (KeyCRM API key)
export default {
async fetch(request, env) {
if (request.method !== "POST") return new Response("POST only", { status: 405 });
const raw = await request.text();
const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(env.FORMGONG_SECRET),
{ name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
const mac = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(raw));
const hex = [...new Uint8Array(mac)].map((b) => b.toString(16).padStart(2, "0")).join("");
if (request.headers.get("x-signature") !== "sha256=" + hex) return new Response("bad signature", { status: 401 });
const data = JSON.parse(raw);
if (data.event !== "submission.created") return new Response("ignored");
const f = data.submission.fields;
const res = await fetch("https://openapi.keycrm.app/v1/pipelines/cards", {
method: "POST",
headers: { authorization: "Bearer " + env.KEYCRM_KEY, "content-type": "application/json", accept: "application/json" },
body: JSON.stringify({
title: data.form.name + ": " + (f.name ?? ""),
source_id: 12,
contact: { full_name: f.name ?? "", email: f.email ?? "", phone: f.phone ?? "" },
manager_comment: (f.message ?? "") + " | Formgong ID: " + data.submission.id,
}),
});
// A non-2xx answer makes Formgong retry (30 s, 2 min, 10 min, 30 min).
return new Response(res.ok ? "ok" : "keycrm " + res.status, { status: res.ok ? 200 : 502 });
},
};Запитання й відповіді
Чи може Formgong слати заявки в KeyCRM без Make чи n8n?
Напряму ні. KeyCRM потребує заголовок із Bearer-ключем і свій JSON, а вебхук Formgong не додає заголовків і не змінює тіло. Посередником може бути і ваш невеликий скрипт.
Створювати картку чи замовлення?
Картку — для звернень і запитів ціни, їй потрібен лише контакт. Замовлення — коли форма оформлює покупку з товарами, тоді потрібні джерело і покупець.
Де зберігати API-ключ?
У keychain Make або в облікових даних n8n, ніколи не в коді сайту. Formgong його не бачить.
Повідомлення в Telegram теж прийде?
Так. Вебхук працює паралельно з поштою і Telegram. Команда бачить заявку в Telegram одразу, а картка з'являється в KeyCRM за мить.
Джерела
Перевірено 03.10.2026 за офіційною довідкою та публічними сторінками: Документація OpenAPI KeyCRM, Довідка KeyCRM: де отримати API-ключ, Make: застосунок HTTP, Документація n8n: HTTP Request node, Довідка Formgong про вебхуки.