Урок 6. Автозалив кампаний в MGID и Adskeeper через API
Готовый промт для ИИ плюс разбор, что происходит под капотом: создание кампании, целей и тизеров через API сразу в двух сетках, с двумя граблями, на которых всё ломается.
Заливка одной связки руками выглядит так: создать кампанию, выставить гео, язык, категорию, устройства, прицепить две цели конверсий, потом загрузить десять-двадцать тизеров — каждый с заголовком, описанием, картинкой, ссылкой и призывом. А потом повторить всё то же самое во второй сетке.
Полтора часа кликанья, из которых половина — копипаст одного и того же.
Всё это делается через API. Ниже сначала готовый промт — вставили свои ключи и поехали, — а потом разбор, что он делает, чтобы вы понимали, где агент может ошибиться.
Готовый промт
Заполните в нём только то, что в угловых скобках: ключи, гео, названия. Остальное трогать не нужно — там описан весь порядок действий и обе известные грабли.
Задача: завести рекламную кампанию с креативами в MGID и Adskeeper через API.
Мои данные (подставь мои):
- MGID: client ID
<MGID_CLIENT_ID>, токен<MGID_TOKEN> - Adskeeper: client ID
<AK_CLIENT_ID>, токен<AK_TOKEN> - Гео:
<КОД_СТРАНЫ, например jo>, язык объявлений:<КОД_ЯЗЫКА, например ar> - Название кампании:
<НАЗВАНИЕ>, имя рекламодателя:<БРЕНД, до 25 символов> - Ставка за клик в центах:
<СТАВКА, например 1> - Ссылка на кампанию в трекере:
<ССЫЛКА_ТРЕКЕРА> - Таблица с тизерами:
<ПУТЬ_К_ФАЙЛУ>— колонки: имя файла картинки, заголовок, описание - Картинки лежат по адресу:
<БАЗОВЫЙ_АДРЕС_ПАПКИ_С_КАРТИНКАМИ> - Текст кнопки:
<ПРИЗЫВ, например Заказать>
Про API. MGID и Adskeeper — один движок, пути совпадают до буквы: https://api.mgid.com/v1/goodhits/... и https://api.adskeeper.com/v1/goodhits/... Отличаются только хост, токен и client ID. Авторизация заголовками Authorization: Bearer <токен> и Accept: application/json.
Два обязательных правила, иначе всё сломается:
- Все запросы только через curl. Cloudflare перед API этих сеток банит user-agent стандартной питоновской библиотеки и отдаёт
403 Error 1010 browser_signature_banned. Повторять запрос бесполезно, в ответе так и написано. Логику можешь писать на питоне, но наружу ходи curl-ом. - Не передавай текст объявлений аргументом командной строки. Консоль Windows калечит не-ASCII символы, и арабские или азиатские заголовки приезжают в сетку как
????. Собирай тело запроса в файл в кодировке UTF-8 и отдавай его curl целиком.
Порядок действий. Делай по шагам, показывай прогресс.
1. Проверь доступ в обеих сетках, запрос ничего не меняет: GET {host}/v1/goodhits/clients/{client}/campaigns Если пришла ошибка доступа — остановись и скажи мне.
2. Возьми коды устройств. Они нигде не документированы. Прочитай любую мою уже настроенную кампанию из списка и вытащи из её targets все значения, оканчивающиеся на mobile. Это и будет osTargets.
3. Создай кампанию в каждой сетке: POST {host}/v1/goodhits/clients/{client}/campaigns, тело form-urlencoded: name, advertiserName, enabledGeoTargetingFlag=1, geoTargets={"method":"set","countries":["<гео>"]}, language, campaignType=product, categoryId, osTargets.
4. Сразу поставь обе кампании на паузу: PATCH {host}/v1/goodhits/clients/{client}/campaigns/{id} с телом whetherToBlockByClient=1. Запускать буду я сам, после модерации.
5. Прицепи две цели конверсий. Сначала посмотри список целей аккаунта: GET {host}/v1/goodhits/clients/{client}/conversions-targets Потом прицепи к кампании, тело JSON: POST {host}/v1/goodhits/campaigns/{id}/conversions {"stage":"buy","target_id":<id цели лида>,"price":0} {"stage":"decision","target_id":<id цели апрува>,"price":0} Цену ставь нулевую: реальная выплата приезжает макросом в постбеке, а не числом в настройках.
6. Залей тизеры из моей таблицы, в обе сетки сразу: POST {host}/v1/goodhits/clients/{client}/teasers, тело form-urlencoded: campaignId, title, advertText, imageLink (это ссылка на картинку, не файл), url (моя ссылка на кампанию в трекере), priceOfClick, callToAction, whetherShowGoodPrice=0.
Заливай по одному с паузой, а не залпом: у доменов есть лимит на новые тизеры, при залпе часть отвалится с ошибкой. Те, что отвалились, повтори позже.
7. Отчитайся: сколько тизеров принято и сколько отклонено в каждой сетке, какие ID у созданных кампаний, что стоит на паузе. Если что-то отвалилось — покажи текст ошибки, не глотай его.
Дальше — разбор того же самого словами, если хотите понимать, что происходит.
Где взять ключи
Нужны две вещи: ID API клиента и клиентский API-токен. У MGID и Adskeeper они свои — это два разных аккаунта.
В MGID. Жмём на аватарку в правом верхнем углу и выбираем Настройки.

Дальше вкладка API, раздел API V1. Там два поля: ID API клиента и клиентский API-токен. Рядом с каждым кнопка «Копировать».

В Adskeeper всё то же самое, только интерфейс тёмный: Настройки → API → API V1.

Про кнопку Regenerate. Она выдаёт новый токен и сразу отзывает старый, отменить это нельзя. Если на старом токене что-то уже работает — интеграция с трекером, чужой скрипт, — всё это отвалится молча. Не жмите её из любопытства.
Главное про API этих сеток
MGID и Adskeeper — один движок. Пути совпадают до буквы, даже внутреннее название одинаковое:
https://api.mgid.com/v1/goodhits/clients/{client_id}/...
https://api.adskeeper.com/v1/goodhits/clients/{client_id}/...
Различаются только три вещи: адрес, токен и ваш client ID. Это значит, что один раз написанный код работает в обеих сетках — меняете три переменные и заливаете параллельно.
Создание кампании
POST https://api.mgid.com/v1/goodhits/clients/ВАШ_CLIENT_ID/campaigns
Тело — обычная форма, не JSON. Параметры, которые нужны реально:
| Параметр | Что это |
|---|---|
name | Название, уникальное в пределах аккаунта, до 128 символов |
advertiserName | Имя рекламодателя, 1–25 символов |
enabledGeoTargetingFlag | 1 — включить таргет по гео |
geoTargets | JSON вида {"method":"set","countries":["jo"]} |
language | Код языка: ar, fr, es |
campaignType | Для нутры — product |
categoryId | Категория кампании |
osTargets | Список кодов устройств через запятую |
Про `osTargets` отдельно. Коды устройств нигде внятно не описаны, и выдумывать их бесполезно. Рабочий способ — прочитать любую свою уже настроенную кампанию и вытащить оттуда все значения, которые заканчиваются на mobile. Так вы получите ровно те коды, которые сетка понимает.
Сразу ставим на паузу
Кампания создаётся активной. Пока в ней нет тизеров, а цели не прицеплены, она вам в таком виде не нужна:
curl -s -X PATCH -H "Authorization: Bearer ВАШ_ТОКЕН" \
"https://api.mgid.com/v1/goodhits/clients/ВАШ_CLIENT_ID/campaigns/ID_КАМПАНИИ" \
--data "whetherToBlockByClient=1"
Включите её сами, когда тизеры пройдут модерацию.
Цели конверсий
Это тот самый механизм из урока 2, где мы разводим заявку и подтверждённый заказ по двум разным целям. Стадий три: interest, decision, buy.
Цену в цели ставим нулевую: реальная выплата приедет макросом в постбеке, а не фиксированным числом в настройках. Почему именно так — разобрано в уроке 2, там же про то, как сетка иначе начинает считать ваш доход впятеро больше реального.
Тизеры пачкой
Вот ради чего всё и затевалось.
| Параметр | Что это |
|---|---|
campaignId | В какую кампанию кладём |
title | Заголовок |
advertText | Описание |
imageLink | Ссылка на картинку, а не файл |
url | Ссылка на кампанию в трекере, с макросами |
priceOfClick | Ставка в центах |
callToAction | Текст кнопки |
Картинка передаётся ссылкой. Загружать файл не нужно: складываете тизеры в папку на своём домене и даёте сетке прямой адрес.
Ссылка на кампанию — с полным набором макросов сетки, чтобы трекер получил всё сразу:
https://ваш-трекер/click?key=КЛЮЧ_КАМПАНИИ
&click_id={click_id}&click_price={click_price}
&widget_id={widget_id}&teaser_id={teaser_id}
&campaign_id={campaign_id}&category_id={category_id}
&user_id={user_id}&geo={geo}
Сами тизеры удобно держать в обычной таблице: картинка, заголовок, описание. Скрипт проходит по строкам и заливает в обе сетки сразу. Двадцать креативов в два аккаунта уезжают за минуту.
Две грабли, на которых всё ломается
Обе я собрал лично, и обе стоят того, чтобы о них знать заранее. В промте выше они уже учтены.
Питон забанен, curl работает
Запрос из питона прилетает с ошибкой:
403 Error 1010: Access denied
"The site owner has blocked access based on your browser's signature"
Это не ваш токен и не ваши права. Cloudflare перед API сетки банит user-agent стандартной питоновской библиотеки целиком. Там же прямым текстом написано «не повторяйте запрос» — и это честный совет.
Лечится просто: все запросы слать через curl.
Windows ломает неевропейский текст
Запускаете залив арабских тизеров, а в кабинете вместо заголовков появляется ????.
Виновата консоль Windows: она калечит не-ASCII текст, когда он передаётся аргументом командной строки. Арабский, иврит, тайский — всё, что не влезает в однобайтовую кодировку.
Лечится так: собрать тело запроса в файл в кодировке UTF-8, а потом скормить файл curl целиком.
На латинице и кириллице вы эту грабли не встретите, поэтому она и выстреливает внезапно — на первом же арабском или азиатском гео.
Что остаётся руками
API не закрывает всё:
- Модерация. Тизеры уходят на проверку, и запускать кампанию вы будете сами.
- Картинки. Их всё равно надо подготовить и положить на домен.
- Тексты. Генерировать можно, но проверять — обязательно, особенно на арабских гео.
- Решение о запуске. Кампания создаётся на паузе, и это правильно.
И проверяйте за агентом
В том самом заливе, из которого вырос этот урок, агент сначала получил бан от Cloudflare, а потом испортил арабские заголовки. Оба раза он починил сам — но заметили это только потому, что открыли кабинет и посмотрели глазами.
Если бы не посмотрели, в сетке лежали бы двадцать тизеров с ???? вместо текста, прошли бы модерацию и начали откручивать бюджет.
Автоматизация экономит полтора часа кликанья. Она не экономит внимание.