Документация
POST /api/v1/verify,
POST /api/v1/validate,
POST /api/v1/track,
GET /api/v1/widget/config,
POST /api/v1/widget/click,
POST /api/v1/threat/check и
GET /api/v1/threat/stats.
Публичные методы не требуют cookie и не принимают секретный ключ из браузера.
1. Как это работает
В личном кабинете создаётся ключ проверки. У ключа есть публичный
site_key для браузера и секретный secret_key только для вашего
сервера. Для каждого ключа отдельно выбирается тариф и указываются домены.
Один ключ может работать на нескольких доменах. Если домены не указаны,
ключ разрешён на всех доменах.
Браузер получает одноразовый токен через client.js. Ваш backend проверяет
этот токен методом POST /api/v1/validate с секретным ключом. Секретный
ключ нельзя вставлять в HTML, JavaScript или мобильное приложение.
Виджеты связи — отдельные сущности. У них нет ключей: в коде подключения используется
только публичный id/hash вида w_.... Формы и проекты отзывов
работают так же: публичный идентификатор cf_... или rv_...,
без секретного ключа в браузере.
Если месячный лимит проверок ключа исчерпан, проверки сверх лимита оплачиваются с баланса пользователя по условиям тарифа. Баланс и история операций доступны в личном кабинете. Пополнение баланса выполняет администратор: в истории такая операция отображается как «Пополнение от администрации» с комментарием.
2. Быстрый старт
- Зарегистрируйтесь по приглашению и войдите в личный кабинет.
- В разделе «Ключи проверки» создайте ключ, выберите его тариф и укажите домены сайта.
- Скопируйте
site_keyв код подключения, аsecret_keyсохраните в переменных окружения сервера. - Вставьте
client.jsна страницу с формой. - На сервере проверяйте поле
gf_tokenчерез/api/v1/validate. - При необходимости создайте форму, проект отзывов или виджет связи и вставьте его код.
3. Защита формы: client.js
Скрипт собирает только поведенческие счётчики, не отправляет значения полей и
добавляет в форму скрытое поле gf_token.
<form data-gateform action="/send" method="post">
<input name="email" type="email" required>
<textarea name="message"></textarea>
<button type="submit">Отправить</button>
</form>
<script src="https://gateform.ru/client.js"
data-site-key="gf_site_..."
data-form="form[data-gateform]"
defer></script>
Необязательные атрибуты: data-token-name (по умолчанию
gf_token), data-api (другой origin API),
data-timeout (мс) и data-block-message.
При сетевой ошибке или ответе 5xx скрипт отправляет форму без токена (fail-open). Решение, принимать такую заявку или нет, остаётся за вашим backend.
4. Серверная проверка на PHP
Секретный ключ храните в переменной окружения. Не передавайте его в HTML или клиентский JavaScript.
<?php
$token = $_POST['gf_token'] ?? '';
$secret = getenv('GATEFORM_SECRET_KEY');
$siteKey = getenv('GATEFORM_SITE_KEY');
if ($token === '' || $secret === false) {
http_response_code(400);
exit('Не удалось проверить форму.');
}
$payload = json_encode([
'secret_key' => $secret,
'site_key' => $siteKey,
'token' => $token,
], JSON_UNESCAPED_UNICODE);
$ch = curl_init('https://gateform.ru/api/v1/validate');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 3,
CURLOPT_TIMEOUT => 5,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$result = json_decode((string) $body, true);
if ($status !== 200 || empty($result['valid'])) {
http_response_code(400);
exit('Проверка не пройдена.');
}
// Токен принят: обрабатываем заявку.
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$message = trim((string) ($_POST['message'] ?? ''));
Токен одноразовый. Повторная проверка того же токена вернёт
TOKEN_ALREADY_USED, поэтому сохраняйте результат проверки в рамках
обработки одной заявки.
5. Серверная проверка на Node.js
const secretKey = process.env.GATEFORM_SECRET_KEY;
const siteKey = process.env.GATEFORM_SITE_KEY;
async function validateCaptcha(token) {
if (!token || !secretKey) return false;
const response = await fetch('https://gateform.ru/api/v1/validate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
secret_key: secretKey,
site_key: siteKey,
token
})
});
const result = await response.json().catch(() => ({}));
return response.ok && result.valid === true;
}
// Express/Fastify: token приходит из поля gf_token
app.post('/send', async (req, res) => {
const ok = await validateCaptcha(req.body.gf_token);
if (!ok) return res.status(400).send('Проверка не пройдена');
// ... обработка заявки
});
Для Python, Go, Ruby и других языков достаточно отправить JSON с полями
secret_key, site_key и token на
/api/v1/validate и проверить valid === true.
6. Публичный API
POST /api/v1/verify
Вызывается браузером через client.js. Публичный site_key
не является секретом. Домен проверяется по заголовкам Origin или
Referer и списку доменов ключа.
{
"site_key": "gf_site_...",
"form_id": "contact",
"page_url": "https://example.ru/contacts",
"telemetry": {
"elapsed_ms": 4200,
"mouse_moves": 12,
"pointer_distance": 380,
"key_events": 8,
"focus_events": 2,
"form_interactions": 4,
"form_fields_filled": 2,
"touch": false,
"honeypot": false,
"webdriver": false,
"plugins": 3
}
}
Ответ при разрешении:
{
"success": true,
"action": "allow",
"score": 0.95,
"token": "<подписанный токен>",
"expires_in": 600,
"fail_open": false
}
Ответ при блокировке: { "success": false, "action": "block", "score": 0, "reason": "honeypot" }.
Honeypot и navigator.webdriver дают жёсткую блокировку. Остальные
сигналы влияют на score. Порог разрешения зависит от уровня защиты тарифа:
базовая — 0.35, расширенная — 0.5, максимальная — 0.65.
POST /api/v1/validate
Вызывается только с сервера клиента. Секретный ключ обязателен. Токен живёт 10 минут и одноразовый.
{
"secret_key": "gf_sec_...",
"site_key": "gf_site_...",
"token": "<токен из формы>"
}
Успешный ответ:
{
"success": true,
"valid": true,
"action": "allow",
"score": 0.95,
"fail_open": false,
"expires_at": "2026-10-20T12:10:00.000Z"
}
Невалидный или повторно использованный токен возвращает HTTP 200 с
{ "success": false, "valid": false, "code": "..." }. Неверный
секретный ключ — 401 INVALID_CREDENTIALS.
7. Виджет связи: widget.js
Виджет изолирован в Shadow DOM, не использует внешние шрифты и картинки. У него нет ключей: только публичный id/hash. В кабинете настраиваются тема, акцентный цвет, фон и цвет иконок, кнопка «только иконка» или «иконка с текстом», скругление, максимальная ширина, отступы, ссылки и режим показа. Заголовка у виджета нет. У формы настроек есть живое превью.
Виджет не привязан к домену: один и тот же код можно вставить на любой сайт, а статистика будет общей по виджету. Для каждой ссылки сохраняется URL на момент перехода, поэтому статистика не смешивается после изменения адреса.
<script src="https://gateform.ru/widget.js"
data-widget-id="w_..."
defer></script>
Плавающая кнопка
Режим floating (по умолчанию) показывает кнопку в выбранном углу.
По нажатию раскрывается столбец иконок-ссылок без заголовка и панели: вверх
для нижних углов и вниз для верхних. Кнопка может быть круглой иконкой или
кнопкой с текстом; отступы задаются отдельно для ПК, планшета и мобильного.
Встроенный блок
Режим inline выводит ряд иконок-ссылок сразу, без плавающей
кнопки и модального окна. Поставьте скрипт в нужное место страницы. Если нужен
конкретный контейнер, добавьте необязательный data-target:
<div id="contacts-widget"></div>
<script src="https://gateform.ru/widget.js"
data-widget-id="w_..."
data-target="#contacts-widget"
defer></script>
Без data-target встроенный блок добавляется сразу после скрипта.
Если скрипт подключён в <head>, выбирайте контейнер в
<body> через data-target.
Конфигурация загружается через GET /api/v1/widget/config?id=w_....
Endpoint возвращает только безопасные поля: режим, тему, цвета, кнопку,
отступы и ссылки. Комментарий виджета является внутренним и публично
не отдаётся.
{
"success": true,
"name": "Поддержка на сайте",
"widget": {
"position": "bottom-right",
"color": "#4A6CF7",
"theme": "light",
"panel_color": null,
"text_color": null,
"button_style": "pill",
"button_text": "Связаться",
"border_radius": 16,
"max_width": 360,
"display_mode": "floating",
"offsets": {
"desktop": { "x": 20, "y": 20 },
"tablet": { "x": 16, "y": 16 },
"mobile": { "x": 12, "y": 12 }
},
"links": [
{ "id": "telegram", "type": "telegram", "label": "Telegram", "value": "https://t.me/example" }
]
}
}
panel_color и text_color могут быть
null — тогда используются цвета выбранной темы. Переходы по
каждой ссылке учитываются автоматически и видны в кабинете. На один аккаунт
можно создать до 10 виджетов; тариф на виджеты не влияет.
8. Формы и отзывы
Форма — самостоятельная страница с капчей, согласием и уведомлением в Telegram. В конструкторе можно собрать свои поля: текст, email, телефон, многострочный текст, число, дату, выпадающий список, чекбокс и скрытое поле. Проект отзывов — один сайт и набор товаров; отзыв привязывается к названию товара, артикулу и авторизованному пользователю. В обоих случаях используется публичный идентификатор, а не секретный ключ.
<!-- Встроенная форма -->
<script src="https://gateform.ru/callback-embed.js"
data-callback-form="cf_..."
defer></script>
<!-- Форма в модальном окне по кнопке -->
<button type="button" id="open-form">Оставить заявку</button>
<script src="https://gateform.ru/callback-embed.js"
data-callback-form="cf_..."
data-mode="modal"
data-trigger="#open-form"
defer></script>
<!-- Отзывы -->
<script src="https://gateform.ru/review-embed.js"
data-gateform-reviews="rv_..."
defer></script>
В настройках формы можно выбрать встроенный режим или модальное окно
и указать CSS-селектор кнопки (#open-form, .open-form).
Атрибуты data-mode и data-trigger в коде вставки
переопределяют настройки для конкретного сайта.
На платном тарифе поля могут автоматически брать данные со страницы:
параметр URL, URL страницы, заголовок, Referrer, UTM-метки, ID и название
товара. Значения подставляются в форму при загрузке и сохраняются в заявке.
На бесплатном тарифе запрос с источником данных отклоняется с
403 PAGE_DATA_REQUIRES_SUBSCRIPTION.
Капча включена для всех форм: заявок, отзывов, входа и восстановления пароля. Отключить её можно только глобально в настройках платформы. По каждой форме видна статистика капчи за 30 дней: показы, успешные прохождения, блокировки и конверсия в отправленную заявку.
Прямые адреса: https://gateform.ru/f/cf_... и
https://gateform.ru/r/rv_.... Для CSP разрешите
script-src https://gateform.ru и
frame-src https://gateform.ru.
Брендинг GateForm показывается только нижней подписью. Снять её можно на
платном тарифе аккаунта или любого ключа с ценой выше 0; на бесплатном тарифе
запрос с show_branding=false отклоняется, а публичная выдача
оставляет подпись включённой.
В настройках формы и проекта отзывов можно указать свою ссылку на политику обработки персональных данных и текст этой ссылки. Если ссылка не задана, используется политика GateForm.
9. База репутации IP
В общую базу попадают только события форм и капчи: блокировки проверки,
провалы капчи и явный спам (honeypot, превышение частоты). IP хранится
только как HMAC-хеш. Тела запросов, cookies и Authorization
не сохраняются.
API: POST /api/v1/threat/check — проверка IP по HTTPS;
GET /api/v1/threat/stats — сводка без IP. Автоматическая блокировка
в общей базе включается только при высоком score и нескольких независимых
источниках; ручная блокировка администратора имеет приоритет.
Открытая страница репутации IP показывает агрегированную статистику и результат проверки, а не список сырых адресов.
10. Статистика трафика
Подключите tracker.js на все страницы сайта. Он собирает
переходы, источники и поведение посетителей, не сохраняя IP-адреса.
<script src="https://gateform.ru/tracker.js"
data-site-key="gf_site_..."
defer></script>
Что попадает в статистику:
- путь и заголовок страницы;
- referrer, поисковая система и поисковый запрос;
- UTM-метки: source, medium, campaign, term, content;
- источник: поиск, прямой заход, соцсети, переходы с сайтов, реклама, email;
- новый или вернувшийся посетитель;
- устройство, браузер, ОС, язык и разрешение экрана;
- время на странице и глубина визита.
Посетитель определяется случайным visitor_id в
localStorage и first-party cookie. Сессия живёт 30 минут
без активности. IP-адрес не отправляется и не сохраняется. Трекер
уважает Do Not Track, не работает для известных ботов и
хранит сырые события 180 дней.
Для SPA переходы pushState и replaceState
отслеживаются автоматически. При необходимости вызовите
window.GateFormTracker.pageview() вручную.
Данные кабинета: GET /api/traffic/summary?days=30&key_id=1
с cookie-сессией пользователя. Без key_id статистика
суммируется по всем ключам.
11. Готовые модули и сниппеты
Модули используют публичные ключи и поддерживают формы, отзывы и виджет связи. Секретный ключ в шаблоны не вставляется.
- Универсальный HTML/JS — для любого сайта без PHP: форма, защита формы, отзывы, виджет.
- Конструкторы сайтов — Tilda, Wix, Webflow, Squarespace, Craftum, uKit, Nethouse, Flexbe, LPgenerator, Readymag.
- 1С-Битрикс — модуль с настройками и серверной проверкой токена.
- Joomla 4/5 — системный плагин.
- MODX Revolution — плагин и хук FormIt.
- Drupal 10/11 — модуль с настройками.
- WordPress / WooCommerce — шорткоды
[gateform_callback],[gateform_form],[gateform_reviews],[gateform_widget]. - OpenCart 3 — форма, отзывы и виджет связи.
- OpenCart 4 — namespace-модуль с теми же возможностями.
- Yii2 —
CallbackWidget,ReviewsWidget,ContactWidget. - Yii3 —
Callback,Reviews,Contact.
Для конструкторов без серверного хука полную защиту даёт форма GateForm
в iframe. Подключение client.js к native-форме фильтрует
простых ботов, но не заменяет серверную проверку токена.
Модальную форму можно открыть программно:
window.GateFormCallback.open() и закрыть:
window.GateFormCallback.close(). Кнопка может быть
добавлена на страницу позже — делегирование событий найдёт её
автоматически. Формы, добавленные после загрузки страницы, подключаются
к client.js автоматически; вручную можно вызвать
window.GateForm.attach().
После установки проверьте вывод на мобильном и десктопе, CSP, работу iframe и
отсутствие секретов в HTML. Для OpenCart-архивов не должно быть лишней папки
integrations; WordPress-архив содержит папку gateform/,
Bitrix-архив — папку gateform/ с install/index.php.
12. Ошибки публичного API
403 INVALID_SITE_KEY— публичный ключ не найден, отключён или не одобрен;403 DOMAIN_NOT_ALLOWED— запрос пришёл с домена, которого нет в ключе;403 ACCOUNT_BLOCKED— аккаунт владельца ключа заблокирован;429 QUOTA_EXCEEDED— месячный лимит проверок ключа исчерпан;402 BALANCE_INSUFFICIENT— лимит исчерпан, на балансе недостаточно средств для оплаты сверх лимита;401 INVALID_CREDENTIALS— неверный секретный ключ в validate;403 THREAT_INTEL_BLOCKED— адрес заблокирован общей базой репутации;TOKEN_EXPIRED,INVALID_TOKEN,TOKEN_ALREADY_USED— токен не принят;THREAT_INTEL_DISABLED,THREAT_INTEL_UNAVAILABLE— база репутации IP отключена или недоступна;403 BRANDING_REQUIRES_SUBSCRIPTION— снятие брендинга недоступно на бесплатном тарифе;503 VERIFICATION_UNAVAILABLE— временная ошибка; client.js работает fail-open;- внутренняя ошибка расчёта score — токен всё равно выдаётся с
fail_open: true.
13. Безопасность
- Пароли хранятся только в виде bcrypt-хешей.
- Сессия — HttpOnly cookie, SameSite=Lax; в production включается Secure после настройки HTTPS.
- Сырые IP-адреса не пишутся в логи; для rate limit используется HMAC-хеш.
- Публичный API не использует cookie и не принимает секретные ключи из браузера.
- Внешние CDN, шрифты, карты, аналитика и внешние JS/CSS не подключаются.
- Скрипты и стили отдаются только с домена GateForm.
- Список доменов ключа ограничивает использование публичного ключа на чужих сайтах.