Интеграция Meta CPA с Keitaro: API и постбэк
Как подключить Meta CPA к Keitaro: лиды на metacpa.ru/create с хешем API-потока, subid в sub5, постбэк со status_text, таблица статусов и разбор ошибок…

Meta CPA принимает лиды по API запросом на https://metacpa.ru/create: нужны хеш API-потока, числовой ID страны, имя, телефон и IP покупателя. Subid клика Keitaro передаётся в метке sub5, а статусы возвращаются постбэком с макросом {status_text}.
Сеть работает: на metacpa.ru и metacpa.com она называет себя международной нутра-сетью с 2013 года и прямым рекламодателем с эксклюзивными офферами. Ниже настройка на октябрь 2026 года, сверенная с кабинетом Meta CPA и документацией Keitaro.
- Что даёт интеграция по API
- Что взять в кабинете Meta CPA
- Форма на лендинге
- Обработчик api.php для Meta CPA
- Постбэк Meta CPA в Keitaro
- Шаг 1. Партнёрская сеть в Keitaro
- Шаг 2. Постбэк в кабинете Meta CPA
- Статусы Meta CPA и Keitaro
- Ошибки и где их искать
- Частые вопросы
- Где взять хеш потока для API?
- Что передавать в geo?
- Почему в постбэке лучше {status_text}, а не {status}?
- Можно ли передать subid не в sub5?
- Почему тестовый постбэк не создаёт конверсию?
Что даёт интеграция по API
- Лид уходит в сеть с вашего лендинга, промо можно переводить, переверстывать и тестировать без кабинета сети.
- Keitaro получает новый лид, холд, апрув, отказ и треш по каждому клику, поэтому ROI видно по связке, а не по офферу.
- Мусорные заявки можно отсеять до отправки: пустые имена, короткие номера, повторы.
Что взять в кабинете Meta CPA
| Поле API | Что это | Где взять |
|---|---|---|
flow_id | хеш потока | создайте поток с типом «API»: кабинет сгенерирует только хеш, по которому принимаются лиды с ваших лендингов |
geo | числовой ID страны | справочник ГЕО в разделе помощи кабинета |
name, phone, ip | данные покупателя | форма лендинга и сервер |
sub1…sub5 | пользовательские метки | заполняете сами, sub5 под subid Keitaro |
Набор обязательных полей совпадает с инструкцией сервиса WebJack по отправке заявок в metacpa.ru. Генератор кода страны metacpa.ru/city/helper из старых инструкций сейчас отдаёт 404, поэтому ID страны берите в кабинете или у менеджера.
Сервер сам подсказывает, чего не хватает. При проверке 1 октября 2026 года запрос без хеша вернул HTTP 422 и {"errors":{"flow_hash":["The flow hash field is required."]}}, а с неверным хешем "The flow hash not found". В ответе поле называется flow_hash, но значение из flow_id сервер принимает.
Форма на лендинге
Если лендинг загружен в Keitaro архивом, трекер подставит ID клика вместо {subid}, так работает локальный лендинг. Поле sub3 в примере хранит имя баера, его можно убрать.
<form action="api.php" method="post">
<input type="text" name="name" placeholder="Nombre" required>
<input type="tel" name="phone" placeholder="Teléfono" required>
<input type="hidden" name="subid" value="{subid}">
<input type="hidden" name="sub3" value="buyer1">
<button type="submit">Pedir</button>
</form>Для лендинга на своём хостинге допишите к его адресу в Keitaro ?subid={subid} и выводите значение через htmlspecialchars($_GET['subid'] ?? '', ENT_QUOTES) в index.php.
Обработчик api.php для Meta CPA
<?php
// api.php: принимает заявку с лендинга и отправляет её в Meta CPA
const API_URL = 'https://metacpa.ru/create';
const FLOW_ID = 'ХЕШ_ПОТОКА'; // хеш API-потока из кабинета Meta CPA
const GEO_ID = 0; // числовой ID страны из справочника ГЕО в кабинете
const BEHIND_CF = false; // true, если домен лендинга за Cloudflare
const TIMEOUT = 3; // секунды: лимит Keitaro для локальных лендингов
const LOG_FILE = __DIR__ . '/meta-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) < 7) {
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_id' => FLOW_ID,
'geo' => GEO_ID,
'name' => $name,
'phone' => $phone,
'ip' => $ip,
'sub5' => $subid, // subid клика Keitaro, вернётся в постбэке как {sub5}
'sub3' => (string)($_POST['sub3'] ?? ''),
];
$ch = curl_init(API_URL);
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;
// Ошибки валидации приходят с кодом 422: {"errors":{"поле":["текст"]}}
$ok = $code >= 200 && $code < 300 && is_array($resp)
&& !isset($resp['errors']) && !isset($resp['error']);
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;До рабочего запуска подтвердите позитивный ответ API и ID заказа по документации кабинета: исправленное условие отклоняет некорректный JSON, но отсутствие errors само по себе ещё не подтверждает создание заказа. Журнал храните вне публичной папки и удаляйте из ответа персональные данные и секреты до записи. Заголовку Cloudflare доверяйте только при запросе от доверенного прокси.
Что важно в коде:
- Хеш потока и ID страны лежат в PHP, а не в скрытых полях формы. Иначе любой посетитель увидит хеш в исходнике и сможет слать лиды в ваш поток.
- subid клика уходит в
sub5: так же устроен шаблон Meta CPA в Keitaro, и в постбэке значение вернётся как{sub5}. - Ответ 422 с ключом
errorsсчитается ошибкой, тело ответа пишется вmeta-leads.log. Формат успешного ответа сеть публично не описывает, поэтому пример использует упрощённое условие: любой код 2xx безerrorsиerror. - IP берётся из
REMOTE_ADDR, заголовку Cloudflare скрипт верит только приBEHIND_CF = true. - Таймаут 3 секунды соответствует лимиту Keitaro для PHP-лендингов в трекере.
В старом варианте этого скрипта была опечатка curl_close($ch) вместо curl_close($process) и цикл, который копировал в запрос все поля из $_POST. Новый код отправляет только нужные поля.
Для success.php подойдёт готовая мультиязычная страница «Спасибо за заказ», для error.php страница ошибки на нескольких языках.
Постбэк Meta CPA в Keitaro
Шаг 1. Партнёрская сеть в Keitaro
- «Партнерские сети» → «Создать», шаблон Metacpa.ru.
- «Параметры для оффера»:
sub5={subid}. Поле работает для офферов в потоке редиректом, при API-отправке subid передаётapi.php. - Postback URL шаблона построен на числовом
{status}(0, 1, 3). Мы советуем заменить его на текстовый{status_text}: так холд и треш не смешаются с новыми лидами и отказами.

https://ВАШ_ТРЕКЕР/POSTBACK_KEY/postback?subid={sub5}&status={status_text}&payout={payout}¤cy={currency}&tid={id}&lead_status=new,hold&sale_status=approve&rejected_status=reject&trash_status=trash&from=metacpaОбучение статусов (lead_status, sale_status и другие) описано в документации Keitaro по postback. ID оффера и лендинга можно сохранить в клик, дописав &sub_id_21={offer_id}&sub_id_22={landing_id}: берите номера sub_id, которые не заняты в кампании.
Шаг 2. Постбэк в кабинете Meta CPA
- Глобальный постбэк задаётся в профиле, свой постбэк можно указать в настройках потока.
- В кабинете отдельные поля для событий: новый лид, принят или холд, отклонён, апселл и частичная заявка. Вставьте одну и ту же ссылку в поля нового, принятого и отклонённого лида: статус различит
{status_text}. - Если в форме есть выбор метода, ставьте GET: параметры останутся в ссылке и будут видны в логе Keitaro.
- Сохраните настройки.

Макросы Meta CPA: {id} (номер лида), {sub1}…{sub5}, {ip}, {status}, {status_text}, {price} (ставка по офферу), {payout} (фактическая выплата), {currency}, {offer_id}, {landing_id}, {prelanding_id}, {flow_id}, {datetime_create}, {create_timestamp}, {upsell_payout} и {click_id}.
Статусы Meta CPA и Keitaro
{status_text} | {status} | Что значит | Тип в Keitaro |
|---|---|---|---|
| new | 0 | новый лид | Lead |
| hold | не указано | принят, выплата в холде | Lead |
| approve | 1 | принят | Sale |
| reject | 3 | отклонён | Rejected |
| trash | не указано | треш | Trash |
Если холд должен сразу считаться продажей, перенесите hold в sale_status. Как апрув и холд влияют на итоговый ROI, разобрано в статье про метрики арбитража.
Ошибки и где их искать
| Где видно | Сообщение | Что сделать |
|---|---|---|
| meta-leads.log | 422, The flow hash field is required | хеш не передан: заполните FLOW_ID |
| meta-leads.log | 422, The flow hash not found | хеш неверный или поток не API-типа: скопируйте хеш заново |
| meta-leads.log | http=0 | запрос не дошёл или превысил таймаут, проверьте исходящие соединения хостинга |
| Keitaro, логи постбэков | Click for subid REPLACE not found | метка в ссылке не совпадает с той, куда api.php кладёт subid |
| Keitaro, логи постбэков | Conversion type not found | пришёл статус без обучения, например hold: добавьте его в lead_status |
| Keitaro, логи постбэков | Incorrect postback code | ключ в ссылке устарел, возьмите его в «Настройки» → «Postback URL» |
Лог входящих постбэков в Keitaro находится в «Обслуживание» → «Логи» → «Postbacks», расшифровка ошибок в разделе устранение проблем с postback.
Частые вопросы
Где взять хеш потока для API?
Создайте в кабинете поток с типом «API». Для такого потока Meta CPA генерирует только хеш, который и передаётся в flow_id.
Что передавать в geo?
Числовой ID страны из справочника ГЕО Meta CPA, а не ISO-код. Если не нашли справочник, запросите ID у менеджера.
Почему в постбэке лучше {status_text}, а не {status}?
Числовой статус различает только новый, принятый и отклонённый лид. Текстовый дополнительно передаёт hold и trash, и Keitaro разложит их по нужным типам конверсий.
Можно ли передать subid не в sub5?
Можно в любую из меток sub1…sub5, если в постбэке стоит та же метка. sub5 удобна тем, что её использует шаблон Keitaro.
Почему тестовый постбэк не создаёт конверсию?
В тестовых постбэках сети не передают реальный subid клика, это отдельно отмечено в документации Keitaro. Проверяйте связку настоящей заявкой по ссылке кампании.



