Criar campanhas pela API
Do cliente ao anúncio publicado (pausado) — seleção, consultas, especificação, validação e envio.
1. Descubra a seleção (Etapa 0)
# clientes ativos
curl -s $BASE/clients -H "Authorization: Bearer $KEY"
# BMs e ativos do cliente (id ou nome exato)
curl -s $BASE/clients/<client_id>/businesses -H "Authorization: Bearer $KEY"De cada BM use id como business_manager_id e um assets.ad_accounts[].id como ad_account_id. Página, Instagram, pixel e WhatsApp são opcionais: sem eles, o servidor usa os padrões da BM. Só contas utilizáveis aparecem; mandar outra conta resulta em 403.
"selection": { "business_manager_id": "6f1c…", "ad_account_id": "1234567890" }2. Consulte o que precisar
| Necessidade | Chamada |
|---|---|
| Interesses | POST /meta/audiences/search { selection, search_type: "interests", query: "marketing" } |
| Localizações | POST /meta/audiences/search { selection, search_type: "geo", query: "Goiânia", location_types: ["city"] } — a Meta pode devolver também subcidades e bairros; filtre por type |
| Sugestões de interesses | POST /meta/audiences/search { selection, search_type: "interest_suggestions", interest_list: ["Residência médica"] } |
| Públicos personalizados | POST /meta/audiences/search { selection, search_type: "audiences" } — use só os usable: true; públicos salvos só com include_saved: true |
| Campanhas existentes | POST /meta/campaigns/search { selection, effective_status: ["ACTIVE", "PAUSED"] } |
| Formulário de cadastro | POST /meta/leadforms/search { selection } |
| Publicações do Instagram | POST /meta/posts/search { selection, action: "search", query: "…" } |
| Modelos de segmentação | GET /targeting-templates |
Repasse os objetos devolvidos (interesses, localizações) como vierem — eles já estão no formato que a criação espera.
Públicos personalizados e campanhas existentes são paginados: 50 itens por página por padrão (limit, até 100). Quando paging.has_more for true, envie paging.after de volta como after para buscar a próxima página.
O job_id devolvido por uma consulta só agrupa os logs daquela chamada (GET /executions/{id}/logs); não é uma execução de campanha.
3. Monte a especificação
{
"selection": { "business_manager_id": "6f1c…", "ad_account_id": "1234567890" },
"mode": "new_campaign",
"campaign": {
"name": "ACME | Tráfego | Nov",
"objective": "OUTCOME_TRAFFIC",
"budget_level": "CBO",
"budget_type": "daily_budget",
"budget": 80,
"isolate_creatives": true
},
"adsets": [
{
"conversion_objective": "website_traffic",
"start_time": "2026-11-10T08:00",
"targeting": {
"age_min": 25,
"age_max": 45,
"locations": [{ "key": "2430536", "name": "São Paulo", "type": "city", "country_code": "BR" }]
}
}
],
"ads": {
"source": "drive",
"folder_url": "https://drive.google.com/drive/folders/…",
"copy": "Texto principal",
"headline": "Título",
"cta_type": "LEARN_MORE",
"link_url": "https://acme.com.br"
}
}Campanha e conjuntos
objective:OUTCOME_AWARENESS,OUTCOME_TRAFFIC,OUTCOME_ENGAGEMENT,OUTCOME_LEADS,OUTCOME_SALES.budget_level:CBO(orçamento na campanha,campaign.budget) ouABO(orçamento em cada conjunto,adsets[].budget).conversion_objectiveecustom_event_type(evento do pixel) têm padrões por objetivo; valores fora do permitido são recusados.start_timepadrão = agora;end_timeé obrigatório para orçamento vitalício.targeting_template_idaplica um modelo salvo; os campos detargetingenviados sobrepõem o modelo.- Nomes de conjuntos e anúncios seguem a nomenclatura automática da interface, a menos que você envie
name.
isolate_creatives
isolate_creativestrue(padrão, exceto comads.source: "media_urls", em que o padrão éfalse): envie um conjunto modelo; ele é duplicado para cada criativo (1 criativo = 1 conjunto). Umnameno modelo vira a base de todas as cópias, com sufixo sequencial (00_SP_25-45→00_SP_25-45_01,_02…); sem ele, vale a nomenclatura automática.false: todos os criativos vão para todos os conjuntos informados.
Origem dos anúncios (ads.source)
ads.source)source | Campos | Observações |
|---|---|---|
drive | folder_url ou feed_folder_url + stories_folder_url; copy, headline, description, cta_type, link_url, phone_number, url_tags, advantage_creative | Mesmas regras da pasta usada na interface: subpasta CARROSSEL/ vira carrossel; pastas FEED/STORIES ativam a personalização por posicionamento (placement_customization força ligar/desligar). Vídeos são preparados automaticamente. |
existing_posts | post_ids, link_url, phone_number, url_tags | Cada publicação vira um anúncio em todos os conjuntos. |
media_urls | items[] com creative_type (image/video/carousel), image_url/video_url/thumb_url/cards, textos e link_url | Não aceita isolate_creatives: true (o padrão para esta origem é false). URLs devem ser públicas (https). |
UTMsTodo anúncio leva o padrão Infotráfego em
url_tags. Se olink_urljá tiver UTMs ou você mudarurl_tags, envieconfirm_custom_url_tags: true— senão a validação recusa (mesma confirmação da interface).
Estender o que já existe
{ "mode": "extend_campaign", "existing_campaign_id": "120210…", "selection": {…}, "adsets": [{…}], "ads": {…} }
{ "mode": "extend_adset", "existing_campaign_id": "120210…", "existing_adset_id": "120211…", "selection": {…}, "ads": {…} }Em extend_campaign o servidor espelha a otimização dos conjuntos existentes e continua a numeração; em extend_adset nenhum conjunto é criado.
4. Valide antes (recomendado)
curl -s -X POST $BASE/campaigns/validate -H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" -d @campanha.json{ "valid": false, "errors": { "ad_0_0_cta_type": "Botão (CTA) não disponível para o objetivo de conversão" }, "preview": null }Quando a especificação é válida, preview mostra o que será criado exatamente como o servidor resolveu (padrões, modelos e nomes aplicados): orçamento da campanha (CBO) e, para cada conjunto, nome, objetivo e evento de conversão, orçamento (ABO), datas, segmentação (idades, gêneros, localizações, interesses, públicos), posicionamentos, limite de frequência e os anúncios com CTA, link e UTMs.
5. Crie a campanha
curl -s -X POST $BASE/campaigns -H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" -d @campanha.json
# 202 → { "job_id": "…", "status": "queued", "status_url": "/api/v1/executions/…" }A criação roda no servidor, em segundo plano. Guarde o job_id e siga em Acompanhar e reexecutar.
Updated about 23 hours ago

