Справочник Python SDK для Meta Marketing API
Клиент Ads в Python SDK Socialift работает с Meta Marketing API: рекламные кабинеты, поиск таргетинга и оценка охвата, кампании, группы объявлений, креативы и объявления, пользовательские и похожие аудитории, статистика. Кампании, группы и объявления создаются в статусе PAUSED — деньги не тратятся, пока вы не вызовете set_status(..., "ACTIVE"). Все методы асинхронные и принимают пользовательский access token.
from socialift import AdsМетодов: 35по версии socialift 1.3.0Обновлено:
Как создать клиент Ads?
Ads принимает секрет приложения Meta в app_secret; с ним к каждому запросу добавляется appsecret_proof. Ads.from_env() читает его из FACEBOOK_APP_SECRET (ту же переменную использует Facebook.from_env()), а версию API — из META_GRAPH_VERSION. В отличие от других клиентов, отсутствие секрета не вызывает ошибку: он останется пустым, и запросы уйдут без appsecret_proof. Лицензионный ключ берётся из SOCIALIFT_LICENSE_KEY.
Методы принимают пользовательский access token (не токен страницы): для чтения нужно разрешение ads_read, для создания и изменения — ads_management. Для продакшена Meta требует App Review по обоим разрешениям.
Безопасность бюджета: кампании, группы объявлений, объявления и объекты boost_post() создаются в PAUSED, а delivery_estimate() ничего не тратит. Бюджетные аргументы с суффиксом _major задаются в валюте рекламного кабинета и перед отправкой умножаются на CURRENCY_OFFSET (100). Для части валют (JPY, KRW, IDR, VND, HUF и др.) Meta использует offset 1 — для таких кабинетов сначала разделите сумму на 100. UZS нет в списке валют рекламных кабинетов Meta.
Версия API по умолчанию — DEFAULT_GRAPH_VERSION (v26.0). Meta поддерживает каждую версию минимум два года с момента выпуска, а после выхода следующей срок старой истекает ещё через два года; вызовы к истёкшей версии автоматически перенаправляются на самую старую из поддерживаемых. Если нужна другая версия, передайте её в graph_version= и сверьте дату на странице версий Meta.
import asyncio
import os
from socialift import Ads
# Из окружения: ads = Ads.from_env()
# (FACEBOOK_APP_SECRET, META_GRAPH_VERSION)
ads = Ads(
app_secret=os.environ["FACEBOOK_APP_SECRET"],
graph_version="v26.0", # сверьтесь со страницей версий Meta
)
async def main():
# ваша собственная переменная: токен пользователя с ads_read
user_token = os.environ["META_USER_TOKEN"]
async with ads:
for account in await ads.ad_accounts(user_token):
print(account.id, account.name, account.currency, account.is_active)
asyncio.run(main())Клиент и ключи
Создание клиента и чтение секрета приложения Meta из переменных окружения.
from_env
classmethodСоздаёт клиент из переменных окружения: FACEBOOK_APP_SECRET (для appsecret_proof) и META_GRAPH_VERSION. Дополнительные аргументы (timeout, retry, session, license_key) передаются в конструктор.
Ads.from_env(**kwargs) -> Ads- В отличие от других клиентов, пустой ключ не вызывает ошибку: без
FACEBOOK_APP_SECRETполеapp_secretостанется пустым иappsecret_proofк запросам добавляться не будет. Если в настройках приложения Meta секрет обязателен, такие запросы будут отклонены. - Без
META_GRAPH_VERSIONиспользуется версия SDK по умолчанию; нужную можно передать сразу:Ads.from_env(graph_version="..."). - Access token отсюда не читается — он передаётся аргументом в каждый метод.
Рекламные кабинеты и пиксели
Выбор рекламного кабинета и подключённых к нему пикселей.
ad_accounts
asyncВозвращает рекламные кабинеты, доступные токену пользователя, списком AdAccount с id, name, currency и статусом. Обычно это первый вызов: большинству методов нужен ad_account_id.
await ads.ad_accounts(token: str) -> list[socialift.ads.AdAccount]- Нужны пользовательский access token (не токен страницы) и
ads_read. - Возвращается одна страница — до 50 кабинетов.
is_activeравенTrue, когдаaccount_statusв Meta равен 1.- Бюджеты — в валюте кабинета (
currency); UZS нет в списке валют рекламных кабинетов Meta.
Нужные разрешения:ads_read
for account in await ads.ad_accounts(user_token):
print(account.id, account.currency)pixels
asyncВозвращает пиксели Meta, подключённые к рекламному кабинету, с last_fired_time. ID пикселя нужен для групп объявлений на конверсии (promoted_object) и аудиторий сайта.
await ads.pixels(token: str, *, ad_account_id: str) -> list[dict]- Одна страница, до 50 пикселей; нужен
ads_read.
Нужные разрешения:ads_read
pixels = await ads.pixels(user_token, ad_account_id="act_123")Таргетинг и оценка охвата
Поиск вариантов таргетинга, сборка спецификации и оценка охвата — без расходов.
build_targetingdelivery_estimatesearch_interestssearch_localessearch_locationssearch_targetingtargeting_suggestionsvalidate_targeting
build_targeting
staticmethodСобирает спецификацию таргетинга Meta (dict) из простых аргументов: география, возраст, пол, языки, интересы, поведение, пользовательские аудитории, плейсменты. Чистая функция: без сетевых запросов и без токена.
Ads.build_targeting(
*,
countries: Optional[list[str]] = None,
regions: Optional[list[Any]] = None,
cities: Optional[list[Any]] = None,
zips: Optional[list[Any]] = None,
excluded_countries: Optional[list[str]] = None,
excluded_cities: Optional[list[Any]] = None,
age_min: Optional[int] = None,
age_max: Optional[int] = None,
genders: Optional[list[Any]] = None,
locales: Optional[list[int]] = None,
interests: Optional[list[Any]] = None,
behaviors: Optional[list[Any]] = None,
demographics: Optional[list[Any]] = None,
life_events: Optional[list[Any]] = None,
excluded_interests: Optional[list[Any]] = None,
custom_audiences: Optional[list[str]] = None,
excluded_custom_audiences: Optional[list[str]] = None,
platforms: Optional[list[str]] = None,
facebook_positions: Optional[list[str]] = None,
instagram_positions: Optional[list[str]] = None,
devices: Optional[list[str]] = None,
connections: Optional[list[str]] = None,
excluded_connections: Optional[list[str]] = None,
flexible_spec: Optional[list[dict]] = None,
advantage_audience: bool = True,
) -> dict[str, Any]- Элементы внутри
interestsобъединяются через ИЛИ; для «И» используйтеflexible_spec— каждый его элемент является отдельным условием И. gendersпринимает1/2или"male"/"female"; чтобы охватить всех, не передавайте его вовсе. Возраст приводится к диапазону 13–65.advantage_audienceпо умолчаниюTrue. При включённой Advantage+ audience Meta фиксируетage_maxна 65 и принимаетage_minтолько от 18 до 25 — для жёстких возрастных рамок передайтеadvantage_audience=False.- Meta требует географию в таргетинге группы объявлений; хелпер это не проверяет, поэтому передайте
countries,regions,citiesилиzips.
targeting = ads.build_targeting(countries=["UZ"], age_min=18, age_max=45, interests=[{"id": "6003107902433"}], advantage_audience=False)delivery_estimate
asyncОценивает размер аудитории для спецификации таргетинга и цели оптимизации, ничего не создавая и не тратя деньги. Чтобы до создания группы объявлений поймать слишком маленькую или слишком широкую аудиторию.
await ads.delivery_estimate(
token: str,
*,
ad_account_id: str,
targeting: dict[str, Any],
optimization_goal: str = 'REACH',
promoted_object: Optional[dict] = None,
) -> dict- Только чтение: ничего не создаётся и ничего не списывается.
- Возвращает первую строку оценки из ответа Meta как dict (или пустой dict).
optimization_goalпо умолчаниюREACH; укажите цель, которую планируете для группы объявлений.- Нужен
ads_read.
Нужные разрешения:ads_read
estimate = await ads.delivery_estimate(user_token, ad_account_id="act_123", targeting=targeting)search_interests
asyncИщет варианты таргетинга по интересам Meta по названию: возвращает id, name, границы размера аудитории и path. Используйте ID в build_targeting(interests=...).
await ads.search_interests(token: str, query: str, *, limit: int = 25) -> list[dict]limitпо умолчанию 25; нуженads_read.- Meta со временем выводит интересы из использования — проверяйте сохранённые ID через
validate_targeting().
Нужные разрешения:ads_read
interests = await ads.search_interests(user_token, "fitness", limit=25)
cities = await ads.search_locations(user_token, "Tosh", country_code="UZ")search_locales
asyncИщет варианты таргетинга Meta по языку (locale) и возвращает числовые ключи для build_targeting(locales=...). Используйте, когда аудиторию нужно разделить по языку, а не по географии.
await ads.search_locales(token: str, query: str, *, limit: int = 25) -> list[dict]search_locations
asyncИщет локации Meta (страны, регионы, города) по названию; key из ответа — идентификатор, который ждёт таргетинг. Сужайте выдачу через country_code.
await ads.search_locations(
token: str,
query: str,
*,
location_types: tuple[str, ...] = ('city', 'region', 'country'),
country_code: Optional[str] = None,
limit: int = 25,
) -> list[dict]location_typesпо умолчанию:city,region,country; для почтовых индексов добавьтеzip.- Городу можно задать радиус:
{"key": "...", "radius": 25, "distance_unit": "kilometer"}; Meta принимает 17–80 км (10–50 миль). - Нужен
ads_read.
Нужные разрешения:ads_read
interests = await ads.search_interests(user_token, "fitness", limit=25)
cities = await ads.search_locations(user_token, "Tosh", country_code="UZ")search_targeting
asyncПеречисляет или ищет категории таргетинга одного класса: behaviors, demographics, life_events, industries, income и другие. Без query возвращается весь класс — например, чтобы построить список для выбора.
await ads.search_targeting(
token: str,
*,
target_class: str = 'interests',
query: Optional[str] = None,
limit: int = 50,
) -> list[dict]target_classдолжен быть изTARGETING_CLASSES, иначе ещё до запроса выбрасываетсяConfigurationError.
Предлагает варианты таргетинга, похожие на переданные (например, близкие интересы). Быстрый способ расширить слишком узкую аудиторию.
await ads.targeting_suggestions(
token: str,
*,
ad_account_id: str,
targeting_list: list[dict],
limit: int = 25,
) -> list[dict]- Формат
targeting_list:[{"type": "interests", "id": "..."}]; нуженads_read.
Нужные разрешения:ads_read
similar = await ads.targeting_suggestions(user_token, ad_account_id="act_123", targeting_list=[{"type": "interests", "id": "6003107902433"}])validate_targeting
asyncПроверяет, действительны ли ещё сохранённые элементы таргетинга (ID интересов и т. п.) для этого кабинета. Вызывайте перед повторным использованием старого таргетинга в новой группе объявлений.
await ads.validate_targeting(
token: str,
*,
ad_account_id: str,
targeting_list: list[dict],
) -> list[dict]- Meta со временем выводит варианты таргетинга из использования, поэтому ID, сохранённые месяцы назад, могут перестать работать.
- Нужен
ads_read.
Нужные разрешения:ads_read
result = await ads.validate_targeting(user_token, ad_account_id="act_123", targeting_list=[{"type": "interests", "id": "6003107902433"}])Кампании, группы объявлений и объявления
Создание и управление тремя уровнями. По умолчанию всё создаётся в PAUSED.
adsadsetadsetsboost_postcampaigncampaignscreate_adcreate_adsetcreate_campaigndeleteset_statusupdate_budgetupdate_targeting
ads
asyncВозвращает объявления с креативом, статусом и ссылкой на предпросмотр — по одной группе объявлений, одной кампании или всему кабинету.
await ads.ads(
token: str,
*,
ad_account_id: Optional[str] = None,
adset_id: Optional[str] = None,
campaign_id: Optional[str] = None,
limit: int = 100,
) -> list[dict]- Приоритет:
adset_id, затемcampaign_id, затемad_account_id; если нет ни одного —ConfigurationError. - Одна страница до
limitэлементов; нуженads_read.
Нужные разрешения:ads_read
items = await ads.ads(user_token, adset_id="120200000000001")adset
asyncПолучает одну группу объявлений по ID с таргетингом, бюджетами, ставкой, целью оптимизации и расписанием.
await ads.adset(token: str, adset_id: str) -> dictadsets
asyncВозвращает группы объявлений кампании (campaign_id) или всего рекламного кабинета (ad_account_id) с полями таргетинга, бюджета и оптимизации.
await ads.adsets(
token: str,
*,
ad_account_id: Optional[str] = None,
campaign_id: Optional[str] = None,
limit: int = 100,
) -> list[dict]- Если переданы оба, приоритет у
campaign_id; если ни одного —ConfigurationError. - Одна страница до
limit(по умолчанию 100) элементов; нуженads_read.
Нужные разрешения:ads_read
adsets = await ads.adsets(user_token, campaign_id="120200000000000")boost_post
asyncПревращает существующий пост Instagram в рекламу за один вызов: создаёт кампанию, группу объявлений, креатив из поста и объявление — всё в PAUSED. Возвращает их ID; деньги не тратятся, пока не вызван set_status(..., "ACTIVE").
await ads.boost_post(
token: str,
*,
ad_account_id: str,
ig_user_id: str,
media_id: str,
name: str,
daily_budget_major: float,
goal: str = 'traffic',
page_id: Optional[str] = None,
link: Optional[str] = None,
targeting: Optional[dict[str, Any]] = None,
currency: Optional[str] = None,
cleanup_on_error: bool = True,
) -> dict[str, str]goal:traffic,engagement,reachилиmessages(сопоставляется с цельюOUTCOME_*и оптимизацией); дляmessagesобязателенpage_id. Кампания создаётся с пустымspecial_ad_categories— не используйте метод для рекламы жилья, вакансий, финансов или политики.daily_budget_major— в валюте кабинета, умножается наCURRENCY_OFFSET(100); для валют с offset 1 в Meta (JPY, KRW, IDR, VND, HUF …) сначала разделите сумму на 100.- Без
targetingиспользуетсяdefault_targeting(): UZ, возраст 18–55, плейсменты Instagram, Advantage+ audience включена. - Четыре объекта создаются по очереди: если следующий шаг падает, предыдущие остаются в кабинете (PAUSED) — удалите их. Посты с музыкой, защищённой авторским правом, или интерактивными элементами вроде фильтров продвигать нельзя.
Нужные разрешения:ads_managementinstagram_basic
result = await ads.boost_post(user_token, ad_account_id="act_123", ig_user_id="1784...", media_id="1790...", name="Reels boost", daily_budget_major=10, goal="traffic")campaign
asyncПолучает одну кампанию по ID с теми же полями, что и campaigns(): цель, статус, бюджеты, стратегия ставок, особые категории рекламы.
await ads.campaign(token: str, campaign_id: str) -> dictcampaigns
asyncВозвращает кампании рекламного кабинета с полями бюджета, цели и статуса. Фильтруйте через statuses, например ["ACTIVE", "PAUSED"].
await ads.campaigns(
token: str,
*,
ad_account_id: str,
statuses: Optional[list[str]] = None,
limit: int = 100,
) -> list[dict]statusesотправляется в Meta как фильтрeffective_status.- Возвращается одна страница до
limit(по умолчанию 100) элементов, без автопагинации. - Нужен
ads_read.
Нужные разрешения:ads_read
campaigns = await ads.campaigns(user_token, ad_account_id="act_123", statuses=["ACTIVE", "PAUSED"])create_ad
asyncСоздаёт объявление в группе из готового creative_id или встроенной спецификации creative. По умолчанию в PAUSED.
await ads.create_ad(
token: str,
*,
ad_account_id: str,
name: str,
adset_id: str,
creative_id: Optional[str] = None,
creative: Optional[dict] = None,
status: str = 'PAUSED',
**extra: Any,
) -> dict- Нужен
creative_idилиcreative; если переданы оба, используетсяcreative_id. - Дополнительные поля Meta передаются через
**extraстроками или числами (dict сериализуйте в JSON сами).
Нужные разрешения:ads_management
ad = await ads.create_ad(user_token, ad_account_id="act_123", name="Banner A", adset_id="120200000000001", creative_id="120200000000002")create_adset
asyncСоздаёт группу объявлений: кто видит рекламу (таргетинг), как идёт оптимизация и — если у кампании нет бюджета — сколько тратится. По умолчанию создаётся в PAUSED.
await ads.create_adset(
token: str,
*,
ad_account_id: str,
name: str,
campaign_id: str,
targeting: dict[str, Any],
optimization_goal: str = 'LINK_CLICKS',
billing_event: str = 'IMPRESSIONS',
status: str = 'PAUSED',
daily_budget_major: Optional[float] = None,
lifetime_budget_major: Optional[float] = None,
bid_amount_major: Optional[float] = None,
start_time: Optional[str] = None,
end_time: Optional[str] = None,
promoted_object: Optional[dict] = None,
destination_type: Optional[str] = None,
currency: Optional[str] = None,
**extra: Any,
) -> dicttargetingне может быть пустым — собирайте его черезbuild_targeting()илиdefault_targeting().optimization_goalиbilling_eventпроверяются поOPTIMIZATION_GOALSиBILLING_EVENTS.daily_budget_major,lifetime_budget_majorиbid_amount_majorумножаются наCURRENCY_OFFSET(100); для валют с offset 1 (JPY, KRW, IDR, VND, HUF …) сначала разделите на 100.- С
lifetime_budget_majorобязателенend_time. При создании Meta принимает только статусACTIVEилиPAUSED. - Для некоторых целей нужен
promoted_object, например{"pixel_id": "...", "custom_event_type": "PURCHASE"}для конверсий.
Нужные разрешения:ads_management
adset = await ads.create_adset(user_token, ad_account_id="act_123", name="Toshkent 18-45", campaign_id="120200000000000", targeting=targeting, daily_budget_major=15)create_campaign
asyncСоздаёт кампанию — верхний уровень, который задаёт цель и, при необходимости, бюджет кампании. По умолчанию создаётся в PAUSED.
await ads.create_campaign(
token: str,
*,
ad_account_id: str,
name: str,
objective: str = 'OUTCOME_TRAFFIC',
status: str = 'PAUSED',
daily_budget_major: Optional[float] = None,
lifetime_budget_major: Optional[float] = None,
bid_strategy: Optional[str] = None,
special_ad_categories: Optional[list[str]] = None,
special_ad_category_country: Optional[list[str]] = None,
is_adset_budget_sharing_enabled: Optional[bool] = None,
currency: Optional[str] = None,
**extra: Any,
) -> dictobjectiveдолжен быть одним из значенийOUTCOME_*изOBJECTIVES; старые названия даютConfigurationError.special_ad_categoriesотправляется всегда (по умолчанию пустой список): Meta требует от каждой кампании указать категорию, напримерHOUSING,EMPLOYMENT,FINANCIAL_PRODUCTS_SERVICES,ISSUES_ELECTIONS_POLITICS.- Бюджет задаётся либо здесь (
daily_budget_majorилиlifetime_budget_major, что-то одно), либо в группах объявлений, но не там и там. Сумма умножается наCURRENCY_OFFSET(100) — для валют с offset 1, таких как JPY и KRW, сначала разделите на 100. - Начиная с Marketing API v24.0 кампания без собственного бюджета требует
is_adset_budget_sharing_enabled; передайте его через**extraстрокой ("false"или"true").
Нужные разрешения:ads_management
campaign = await ads.create_campaign(user_token, ad_account_id="act_123", name="Kuz aksiyasi", objective="OUTCOME_TRAFFIC", daily_budget_major=20)delete
asyncУдаляет кампанию, группу объявлений, объявление или другой объект Marketing API по ID HTTP-запросом DELETE. Чтобы остановить расход, но сохранить объект, используйте set_status(..., "PAUSED").
await ads.delete(token: str, node_id: str) -> bool- Возвращает флаг
successот Meta; нуженads_management.
Нужные разрешения:ads_management
await ads.delete(user_token, node_id)set_status
asyncМеняет статус кампании, группы объявлений или объявления. ACTIVE запускает расход; PAUSED останавливает показы и является безопасным способом выключить рекламу.
await ads.set_status(token: str, node_id: str, status: str) -> bool- Допустимые значения:
ACTIVE,PAUSED,ARCHIVED,DELETED; любое другое —ConfigurationError. - Если кампания или группа на паузе, эффективный статус объявлений в ней —
CAMPAIGN_PAUSEDилиADSET_PAUSED. - Нужен
ads_management.
Нужные разрешения:ads_management
await ads.set_status(user_token, campaign_id, "ACTIVE")update_budget
asyncУстанавливает группе объявлений новый дневной бюджет. Влияет на уже работающую рекламу, поэтому перепроверьте сумму.
await ads.update_budget(
token: str,
adset_id: str,
daily_budget_major: float,
*,
currency: Optional[str] = None,
ad_account_id: Optional[str] = None,
) -> booldaily_budget_majorдолжен быть больше нуля и умножается наCURRENCY_OFFSET(100); для валют с offset 1 сначала разделите на 100.- Нужен
ads_management.
Нужные разрешения:ads_management
await ads.update_budget(user_token, adset_id, daily_budget_major=25)update_targeting
asyncЗаменяет таргетинг существующей группы объявлений переданной спецификацией. Передавайте полную новую спецификацию, а не только изменения.
await ads.update_targeting(token: str, adset_id: str, targeting: dict[str, Any]) -> bool- Пустой
targetingдаётConfigurationError; нуженads_management. - Возрастные правила Advantage+ audience действуют и здесь (см.
build_targeting()).
Нужные разрешения:ads_management
await ads.update_targeting(user_token, adset_id, targeting)Креативы и изображения
Как выглядит объявление: загрузка изображений, креативы, предпросмотр.
create_creativepreviewupload_image
create_creative
asyncСоздаёт креатив объявления со ссылкой из страницы, URL, текста и загруженного изображения (image_hash) или видео (video_id). Используйте, когда нужен отдельный рекламный креатив, а не существующий пост (boost_post()).
await ads.create_creative(
token: str,
*,
ad_account_id: str,
name: str,
page_id: str,
link: str,
message: Optional[str] = None,
headline: Optional[str] = None,
description: Optional[str] = None,
image_hash: Optional[str] = None,
video_id: Optional[str] = None,
call_to_action: str = 'LEARN_MORE',
instagram_user_id: Optional[str] = None,
**extra: Any,
) -> dict- SDK собирает
object_story_spec.link_data:headlineпопадает вname,call_to_action(по умолчаниюLEARN_MORE) — вtype. - Чтобы объявление показывалось от имени аккаунта Instagram, передайте
instagram_user_id;page_idобязателен всегда. image_hashберите изupload_image(). Нуженads_management.
Нужные разрешения:ads_management
creative = await ads.create_creative(user_token, ad_account_id="act_123", name="Kuz", page_id="1111", link="https://siz.uz", message="Chegirma 30%", image_hash=image_hash)preview
asyncВозвращает HTML (iframe в body), показывающий, как объявление будет выглядеть в выбранном плейсменте. Чтобы показать его человеку перед запуском.
await ads.preview(
token: str,
ad_id: str,
*,
ad_format: str = 'MOBILE_FEED_STANDARD',
) -> list[dict]ad_formatпо умолчаниюMOBILE_FEED_STANDARD;DESKTOP_FEED_STANDARDи другие форматы описаны в документации Meta по предпросмотру.- Нужен
ads_read.
Нужные разрешения:ads_read
previews = await ads.preview(user_token, ad_id, ad_format="INSTAGRAM_STANDARD")upload_image
asyncЗагружает байты изображения в библиотеку изображений рекламного кабинета и возвращает {"hash", "url", "raw"}. Креативы ссылаются на изображение именно по этому hash.
await ads.upload_image(
token: str,
*,
ad_account_id: str,
image: bytes,
filename: str = 'ad.jpg',
) -> dictimage— сырыеbytes, а не путь;filename— только имя файла при загрузке.- Нужен
ads_management.
Нужные разрешения:ads_management
with open("banner.jpg", "rb") as f:
image = await ads.upload_image(user_token, ad_account_id="act_123", image=f.read(), filename="banner.jpg")Аудитории
Пользовательские, похожие и сохранённые аудитории.
add_audience_userscreate_custom_audiencecreate_lookalikecustom_audiencessaved_audiences
add_audience_users
asyncДобавляет людей в аудиторию-список клиентов по email и/или телефону. Значения нормализуются и хешируются SHA-256 на вашем сервере — открытые контактные данные его не покидают.
await ads.add_audience_users(
token: str,
audience_id: str,
*,
emails: Optional[list[str]] = None,
phones: Optional[list[str]] = None,
phone_country: Optional[str] = None,
batch_size: int = 10000,
) -> dict- Нормализация: email очищается от пробелов и приводится к нижнему регистру; в телефоне остаются только цифры. Ведущие нули не удаляются, код страны не добавляется — передавайте номер в международном формате, например
+998901234567. - Meta принимает до 10 000 записей за запрос; большие списки делите на несколько вызовов.
- Если переданы оба списка, они склеиваются построчно как один человек: длина и порядок должны совпадать (лишние элементы отбрасываются).
- Нужен
ads_management.
Нужные разрешения:ads_management
await ads.add_audience_users(user_token, audience_id, emails=["ali@example.com"], phones=["+998901234567"])Создаёт пустую пользовательскую аудиторию — по умолчанию список клиентов (subtype="CUSTOM"), который затем заполняется через add_audience_users().
await ads.create_custom_audience(
token: str,
*,
ad_account_id: str,
name: str,
subtype: str = 'CUSTOM',
description: Optional[str] = None,
customer_file_source: str = 'USER_PROVIDED_ONLY',
rule: Optional[dict] = None,
**extra: Any,
) -> dict- Для списка клиентов кабинет должен принять условия Custom Audience Terms Meta, иначе Meta вернёт ошибку о непринятых условиях.
customer_file_sourceуказывает источник данных:USER_PROVIDED_ONLY(по умолчанию),PARTNER_PROVIDED_ONLYилиBOTH_USER_AND_PARTNER_PROVIDED.ruleотправляется в JSON; прочие поля Meta — через**extra. Нуженads_management.
Нужные разрешения:ads_management
audience = await ads.create_custom_audience(user_token, ad_account_id="act_123", name="Mijozlar")create_lookalike
asyncСоздаёт похожую (lookalike) аудиторию в одной стране на основе исходной. Чем меньше ratio, тем выше сходство и тем меньше аудитория.
await ads.create_lookalike(
token: str,
*,
ad_account_id: str,
name: str,
origin_audience_id: str,
country: str = 'UZ',
ratio: float = 0.01,
) -> dictratio— от 0.01 до 0.20 (самые похожие 1–20% страны); по умолчанию 0.01,countryпо умолчаниюUZ.- В исходной аудитории должно быть не меньше 100 человек из одной страны.
- Заполнение lookalike занимает 1–6 часов; группы объявлений с ней можно создавать уже в это время.
- Нужен
ads_management.
Нужные разрешения:ads_management
lookalike = await ads.create_lookalike(user_token, ad_account_id="act_123", name="1% UZ", origin_audience_id="1202...", country="UZ", ratio=0.01)custom_audiences
asyncВозвращает пользовательские аудитории кабинета с типом (subtype), примерными границами размера и статусами доставки и обработки.
await ads.custom_audiences(
token: str,
*,
ad_account_id: str,
limit: int = 100,
) -> list[dict]- Одна страница до
limit(по умолчанию 100) элементов; нуженads_read.
Нужные разрешения:ads_read
custom = await ads.custom_audiences(user_token, ad_account_id="act_123")
saved = await ads.saved_audiences(user_token, ad_account_id="act_123")saved_audiences
asyncВозвращает сохранённые в Ads Manager аудитории (шаблоны таргетинга) со спецификацией таргетинга и примерным размером.
await ads.saved_audiences(
token: str,
*,
ad_account_id: str,
limit: int = 100,
) -> list[dict]- Одна страница до
limitэлементов; нуженads_read.
Нужные разрешения:ads_read
custom = await ads.custom_audiences(user_token, ad_account_id="act_123")
saved = await ads.saved_audiences(user_token, ad_account_id="act_123")Статистика
Расходы и результаты: итогом или в разрезах.
insights
asyncВозвращает расходы и результаты по кампании, группе объявлений, объявлению или кабинету как AdInsights (spend, impressions, reach, clicks, link_clicks, cpc, ctr, frequency). Для быстрой карточки с итогами.
await ads.insights(
token: str,
node_id: str,
*,
since: Optional[str] = None,
until: Optional[str] = None,
) -> socialift.ads.AdInsights- Передавайте и
since, иuntil(YYYY-MM-DD); иначе берётся весь период (date_preset=maximum). - Читается только первая строка; для разрезов используйте
insights_rows(). - Нужен
ads_read.
insights_rows
asyncВозвращает сырые строки статистики на выбранном level с необязательными breakdowns (age, gender, country, publisher_platform и т. п.). Чтобы найти сегмент, где результат дешевле.
await ads.insights_rows(
token: str,
node_id: str,
*,
level: str = 'campaign',
date_preset: Optional[str] = 'last_30d',
since: Optional[str] = None,
until: Optional[str] = None,
breakdowns: Optional[list[str]] = None,
action_breakdowns: Optional[list[str]] = None,
fields: Optional[str] = None,
limit: int = 200,
) -> list[dict]- Meta поддерживает только часть комбинаций разрезов:
age+genderработает,age+country— нет. - Если переданы
since+until, они используются вместоdate_preset(по умолчаниюlast_30d). - Одна страница до
limit(по умолчанию 200) строк; нуженads_read.
Нужные разрешения:ads_read
rows = await ads.insights_rows(user_token, "act_123", level="campaign", date_preset="last_7d", breakdowns=["age", "gender"])Низкоуровневые вызовы
Прямой доступ к путям Marketing API без обёртки в SDK.
call
asyncВызывает любой путь Marketing API с подписью SDK (access_token, appsecret_proof), повторами и классификацией ошибок. Для эндпоинтов без обёртки, например правил автоматизации.
await ads.call(token: str, path: str, *, method: str = 'GET', **params: Any) -> Any- Порядок аргументов —
token, path;methodпо умолчаниюGET. Всё, кромеGET/DELETE, отправляется какPOSTи меняет реальные объекты. - Значения
dict/listсериализуются в JSON автоматически; булевы значения передавайте строками ("true"/"false").
Нужные разрешения:ads_read
data = await ads.call(user_token, "act_123/adcreatives", method="GET", fields="id,name")Общие методы всех клиентов
У каждого HTTP-клиента (Telegram, Facebook, Instagram, LinkedIn, TikTok, Ads) есть эти низкоуровневые методы: чтобы вызвать эндпоинт, для которого в SDK ещё нет обёртки, или читать данные постранично. По завершении блока async with соединение закрывается автоматически.
request
asyncОтправляет произвольный HTTP-запрос и возвращает JSON-ответ — для эндпоинта, у которого в SDK пока нет отдельного метода. Токен и параметры подписи (access_token, для Meta — appsecret_proof через socialift.crypto.appsecret_proof) вы передаёте сами в params или headers.
await ads.request(
method: str,
url: str,
*,
params: Optional[Mapping[str, Any]] = None,
data: Optional[Any] = None,
json: Optional[Any] = None,
headers: Optional[Mapping[str, str]] = None,
) -> Any- Значения
Noneвparamsне отправляются. - При лимите (
RateLimitError) и временных ошибках сервера (HTTP 429, 500, 502, 503, 504) запрос повторяется поRetryPolicy; если есть заголовокRetry-After, SDK ждёт указанное время. Обрыв сети выбрасывается какTransportError.
get
asyncКороткая форма request("GET", ...).
await ads.get(url: str, **kw) -> Anypost
asyncКороткая форма request("POST", ...).
await ads.post(url: str, **kw) -> Anydelete
asyncКороткая форма request("DELETE", ...).
await ads.delete(url: str, **kw) -> Anypaginate
asyncПроходит по курсорной пагинации Meta (paging.next) и возвращает все элементы data одним списком.
await ads.paginate(
url: str,
*,
params: Optional[Mapping[str, Any]] = None,
max_items: int = 500,
page_size: int = 100,
) -> list[dict]max_items(по умолчанию 500) — защитный предел: у крупного аккаунта могут быть десятки тысяч записей.page_size—limitодного запроса.
close
asyncЗакрывает HTTP-сессию, созданную самим SDK (переданную извне сессию не трогает). При использовании async with Client(...) вызывается автоматически.
await ads.close() -> NoneЧастые вопросы
Тратятся ли деньги, если создать кампанию через SDK?
Сами по себе — нет. create_campaign, create_adset и create_ad по умолчанию используют status="PAUSED", а boost_post() создаёт все четыре объекта на паузе. Если кампания или группа объявлений на паузе, эффективный статус объявления — CAMPAIGN_PAUSED или ADSET_PAUSED, поэтому переведите кампанию, группу и объявление в ACTIVE через set_status().
В какой валюте задаётся бюджет рекламы Meta?
В валюте рекламного кабинета (AdAccount.currency). Аргументы с суффиксом _major перед отправкой умножаются на CURRENCY_OFFSET (100). Для части валют (JPY, KRW, IDR, VND, HUF и др.) Meta использует offset 1 — для таких кабинетов сначала разделите сумму на 100. UZS в списке валют рекламных кабинетов Meta нет.
Какие разрешения нужны для Meta Marketing API?
Пользовательский access token: ads_read — чтобы читать кабинеты, таргетинг и статистику, ads_management — чтобы создавать и менять кампании и аудитории. Для boost_post() дополнительно указан instagram_basic. Для продакшена Meta требует App Review по этим разрешениям.
Как узнать размер аудитории до запуска рекламы в Facebook?
Соберите спецификацию через build_targeting() и передайте её в delivery_estimate(). Это только чтение: ничего не создаётся и ничего не списывается. В optimization_goal укажите ту же цель, что планируете для группы объявлений.
Уходят ли данные клиентов в Meta в открытом виде при загрузке аудитории?
Нет. add_audience_users() нормализует email и телефоны и хеширует их SHA-256 на вашем сервере до отправки запроса. Meta принимает до 10 000 записей за запрос, поэтому большие списки делите на несколько вызовов.