Интеграция AlterCPA с Keitaro: API и постбэк
Как отправлять лиды в любую сеть на движке AlterCPA через push.json и настроить постбэк в Keitaro: токен, поля запроса, макрос stage, статусы и коды ошибок…

AlterCPA это не сеть, а движок, на котором работают многие партнёрки. Поэтому API у них одинаковый: лид отправляется POST-запросом на /api/wm/push.json?id=ТОКЕН домена вашей сети, subid Keitaro передаётся в поле subid, а статусы приходят постбэком с макросом {stage}.
Ниже типовая настройка для AlterCPA Pro, которую нужно сверить с API вашей сети: где взять токен и ID, рабочий api.php, постбэк в Keitaro, таблица статусов и расшифровка кодов ошибок. Всё сверено с базой знаний AlterCPA и справкой API сетей на 1 октября 2026 года.
- Как понять, что сеть на AlterCPA
- Что даёт интеграция по API
- Что взять в кабинете сети
- Поля запроса push.json
- Форма на лендинге
- Обработчик api.php для сетей на AlterCPA
- Постбэк AlterCPA в Keitaro
- Шаг 1. Партнёрская сеть в Keitaro
- Шаг 2. Постбэк в кабинете сети
- Статусы AlterCPA и Keitaro
- Коды ошибок push.json
- Частые вопросы
- Подойдёт ли этот код для любой сети на AlterCPA?
- Почему сеть отвечает access, хотя токен верный?
- В какое поле передавать subid Keitaro?
- Чем {cash} отличается от {paid}?
- Есть ли в Keitaro готовый шаблон для AlterCPA?
Как понять, что сеть на AlterCPA
У сетей на этом движке есть страница справки /help/api.php с разделами «Вебмастер», «Поставщик» и «Агентство». 1 октября 2026 года она открывалась, например, у CashFactories (cashfactories.com), OfferStore (offer.store), EnsoTraffic (leadcore.pro), Monolead (monolead.biz), ARKNET (arknet.group), ProfitPay (my.profitpay.one), eJex Network (ejex.club), Dimax (dimax-cpa.ru) и ManyMoney (manymoney.club). Текст раздела «Добавление лида» у всех совпадает, отличается только адрес запроса.
Адрес бывает разным. У Monolead это
https://monolead.biz/api/wm/push.json, у OfferStorehttps://api.offer.store/wm/push.json. Копируйте его из раздела API своей сети, а не из примеров.
Что даёт интеграция по API
- Можно лить на свой лендинг и отправлять лид в любую сеть на AlterCPA одним и тем же скриптом, меняя только константы.
- Сеть сразу отвечает кодом ошибки: дубль, чёрный список, закрытое ГЕО. Это видно в логе до того, как лид потеряется.
- Keitaro получает wait, hold, approve, cancel и trash по каждому клику.
Что взять в кабинете сети
| Что | Где | Комментарий |
|---|---|---|
| API-токен | раздел «Профиль» | передаётся в адресе: ?id=ТОКЕН |
| Доступ к отправке лидов | техподдержка или менеджер | по справке API функция отключена у новых пользователей и включается по запросу |
ID потока flow | раздел «Потоки» | поток создаётся из раздела «Офферы» |
ID оффера offer | список офферов | обязательное поле |
| Адрес API | справка API сети, раздел «Вебмастер» → «Добавление лида» | домен может отличаться от домена кабинета |
Поля запроса push.json
| Поле | Обязательное | Описание по справке API |
|---|---|---|
flow | да | ID потока, к которому привязывается заказ |
offer | да | ID оффера |
ip | да | IP-адрес покупателя |
phone | да | телефон в международном формате с кодом страны, например 79876543210 |
name, last | нет | имя и фамилия |
country | нет | ISO-код страны из двух букв, без него страна вычисляется по IP |
ua, email, comment | нет | User-Agent, почта, комментарий |
subid, uuid, sub1…sub5 | нет | метки до 255 символов только для трекеров, в статистике сети не видны |
utm_source и другие UTM | нет | метки до 255 символов для статистики |
Данные передаются обычным POST. JSON тоже принимается, но только с заголовком Content-type: application/json, иначе сеть ответит nooffer.
Форма на лендинге
В инструкции AlterCPA по трекерам для Keitaro предложено скрытое поле subid со значением {subid}. В лендинге, загруженном в Keitaro архивом, трекер подставит ID клика сам.
<form action="api.php" method="post">
<input type="text" name="name" placeholder="Nombre" required>
<input type="tel" name="phone" placeholder="+34 600 123 456" required>
<input type="hidden" name="subid" value="{subid}">
<button type="submit">Pedir</button>
</form>Если лендинг на своём хостинге, допишите к его адресу в Keitaro ?subid={subid} и выводите значение через htmlspecialchars($_GET['subid'] ?? '', ENT_QUOTES).
Обработчик api.php для сетей на AlterCPA
<?php
// api.php: принимает заявку с лендинга и отправляет её в сеть на AlterCPA
const API_URL = 'https://ДОМЕН_СЕТИ/api/wm/push.json'; // адрес из раздела API вашей сети
const TOKEN = 'ВАШ_API_ТОКЕН'; // токен из профиля
const FLOW = 0; // ID потока
const OFFER = 0; // ID оффера
const COUNTRY = 'ES'; // ISO-код страны оффера
const BEHIND_CF = false; // true, если домен за Cloudflare
const TIMEOUT = 3; // секунды: лимит Keitaro для локальных лендингов
const LOG_FILE = __DIR__ . '/alter-leads.log';
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
http_response_code(405);
exit;
}
$name = trim((string)($_POST['name'] ?? ''));
$phone = preg_replace('/\D+/', '', (string)($_POST['phone'] ?? ''));
$subid = preg_replace('/[^A-Za-z0-9_-]/', '', (string)($_POST['subid'] ?? ''));
if ($name === '' || strlen($phone) < 6 || strlen($phone) > 15) {
header('Location: error.php');
exit;
}
$ip = $_SERVER['REMOTE_ADDR'] ?? '';
if (BEHIND_CF && !empty($_SERVER['HTTP_CF_CONNECTING_IP'])) {
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
$lead = [
'flow' => FLOW,
'offer' => OFFER,
'ip' => $ip,
'name' => $name,
'phone' => $phone, // с кодом страны, только цифры
'country' => COUNTRY,
'ua' => (string)($_SERVER['HTTP_USER_AGENT'] ?? ''),
'subid' => $subid, // subid клика Keitaro
'sub1' => (string)($_POST['sub1'] ?? ''),
];
$ch = curl_init(API_URL . '?id=' . rawurlencode(TOKEN));
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($lead),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => TIMEOUT,
CURLOPT_TIMEOUT => TIMEOUT,
]);
$body = curl_exec($ch);
$code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
$resp = is_string($body) ? json_decode($body, true) : null;
// Успех: {"status":"ok","id":1234}, ошибка: {"status":"error","error":"код"}
$ok = is_array($resp) && ($resp['status'] ?? '') === 'ok';
file_put_contents(LOG_FILE, date('c') . " http=$code subid=$subid "
. substr((string)$body, 0, 300) . "\n", FILE_APPEND | LOCK_EX);
header('Location: ' . ($ok ? 'success.php' : 'error.php'));
exit;Не публикуйте журнал alter-leads.log: ответ сети может содержать данные клиента и служебные сведения. Держите его вне корня сайта и маскируйте чувствительные поля до записи. Флаг BEHIND_CF не заменяет проверку, что запрос пришёл от доверенного прокси Cloudflare.
Что важно в коде:
- Токен, поток и оффер лежат в PHP. В скрытых полях формы их увидит любой посетитель.
- Результат определяется по полю
status:okзначит лид создан,errorзначит ошибка с кодом в полеerror. HTTP-код при этом 200, мы проверили это на живом API с неверным токеном: ответ{"status":"error","error":"key"}. - Телефон очищается до цифр и проверяется по длине 6-15 символов, как требует справка API.
- IP берётся из
REMOTE_ADDR, заголовку Cloudflare скрипт верит только приBEHIND_CF = true. - Таймаут 3 секунды: лимит Keitaro для PHP-лендингов в трекере.
Если сеть отвечает duplicate слишком часто, проверьте свой трафик на повторы по инструкции из статьи про отсечение дублей лидов. Страницу благодарности можно взять готовую: «Спасибо за заказ» на нескольких языках.
Постбэк AlterCPA в Keitaro
Шаг 1. Партнёрская сеть в Keitaro
- «Партнерские сети» → «Создать», шаблон Altercpa.pro. Назовите сеть по имени партнёрки, чтобы не путать несколько сетей на одном движке.
- «Параметры для оффера»:
subid={subid}. - Проверьте Postback URL. И шаблон, и пример в справке AlterCPA пишут
reject_status=cancel,trash, а в документации Keitaro параметр называетсяrejected_status. Используйте вариант из документации трекера.

https://ВАШ_ТРЕКЕР/POSTBACK_KEY/postback?subid={subid}&tid={id}&payout={cash}¤cy={currency}&status={stage}&lead_status=wait,hold&sale_status=approve&rejected_status=cancel&trash_status=trash&from=altercpa{cash} передаёт сумму отчисления в любом статусе. Если нужна сумма только по апрувам, замените на {paid}. tid={id} с ID лида не даст двум заявкам с одного клика перезаписать друг друга.
Шаг 2. Постбэк в кабинете сети
- Откройте «Трафик» → «Постбек» (в некоторых сетях раздел лежит в «Потоках») и заполните глобальный постбэк.
- Отметьте статусы: Ожидает, Холд, Принят, Отмена, Треш.
- Сохраните. Основной постбэк может быть только один: если он указан в потоке, глобальный для этого потока игнорируется.

По справке AlterCPA о постбэках основной постбэк защищён от двойной отправки: если при смене статуса ссылка не изменилась, повтора не будет. Все отправки видны по кнопке «Журнал», там же можно повторить запрос, который не дошёл из-за недоступного трекера.
Статусы AlterCPA и Keitaro
{stage} | {phase} | Что значит | Тип в Keitaro |
|---|---|---|---|
| wait | 1 | лид в обработке | Lead |
| hold | 2 | холд | Lead |
| approve | 3 | лид принят | Sale |
| cancel | 4 | лид отменён | Rejected |
| trash | 5 | треш | Trash |
Причину отказа сеть отдаёт в макросе {reason} числом: 1 некорректный номер, 3 не заказывал, 5 неверное ГЕО, 7 дубль, 11 не удалось дозвониться, 12 подозрение на фрод и так далее. Её удобно писать в свободный параметр клика: &sub_id_20={reason}.
Коды ошибок push.json
| Код | Что значит | Что сделать |
|---|---|---|
| access | отправка лидов по API для вас не включена | попросить менеджера включить |
| key | неверный API-ключ | сверить токен с профилем |
| nooffer | не передан оффер, часто JSON без заголовка | проверить OFFER и формат запроса |
| noflow, badflow | поток не указан или указан неверно | создать поток и взять его ID |
| nophone, phone | телефона нет, он короче 6 или длиннее 15 цифр, либо не прошёл проверку | проверить маску и код страны |
| duplicate | такой заказ уже есть в CRM | искать повторы в трафике |
| ban | телефон или IP в чёрном списке, уточнение в поле info | смотреть info в логе |
| traffic | оффер или сайт вам недоступны | уточнить доступ у менеджера |
| data | нет обязательных полей, список в поле bad | дописать поля |
| db | внутренняя ошибка сети | повторить отправку |
Ошибки на стороне трекера (Click for subid REPLACE not found, Conversion type not found, Incorrect postback code) смотрите в «Обслуживание» → «Логи» → «Postbacks» и разбирайте по разделу Keitaro про устранение проблем с postback.
Частые вопросы
Подойдёт ли этот код для любой сети на AlterCPA?
Это типовой пример для AlterCPA Pro. Сверьте справку и версию API своей сети, прежде чем использовать его: Меняются адрес запроса, токен, поток и оффер.
Почему сеть отвечает access, хотя токен верный?
По справке API отправка лидов отключена для новых пользователей по умолчанию. Напишите менеджеру, чтобы её включили.
В какое поле передавать subid Keitaro?
В subid: так советует инструкция AlterCPA для Keitaro, и это поле не видно в статистике сети. Подойдут и sub1…sub5, если в постбэке стоит та же метка.
Чем {cash} отличается от {paid}?
{cash} показывает сумму в любом статусе, {paid} только в статусе approve, {holded} в статусах hold и approve.
Есть ли в Keitaro готовый шаблон для AlterCPA?
Да, шаблон называется Altercpa.pro. Перед сохранением замените в нём reject_status на rejected_status, как в документации Keitaro.



