Prerequisite A Growi organization on the Growth plan or higher, a
connected Meta ad account with at least one campaign and ad set, and an
owner or admin who can create an API key.
How to automate Meta ad launches
The API under/api/public/v1/meta_ads, and Claude with the Growi MCP
server, let you turn creator social posts, TikTok Shop videos and content
submissions into Meta ads in ad sets you already have. A daily job usually
looks like this:
- List ad sources: new creator posts, TikTok Shop videos or approved submissions.
- Read the builder options: ad account, ad set, copy, CTA, UTMs and each creator’s tracking link, in one call.
- Create the ads in bulk, up to 50 per request, launched as soon as they publish.
- Poll the ads while Growi publishes them to Meta.
- Launch or pause individual ads when you need to.
Campaigns, ad sets, targeting, ad account sync, partnership requests, Meta
ad codes, copy templates, UTM params and naming are managed in the
dashboard under Meta Ads. The API reads your saved settings and builds
ads into the ad sets you set up there.
Before you start
An API key
- In the Growi dashboard, open Settings → Developer.
- Under API keys, choose Full access in the access level menu.
- Click Add API key and copy the key.
- Full access keys can create, launch and pause ads, as long as the key’s person is an owner or admin. If that person now has the viewer role, the key is read-only.
- View only keys can call the
GETendpoints but get403on bulk, launch and pause.
A connected Meta ad account with sync on
- Connect Meta in Settings → Integrations → Meta Ads.
- In Meta Ads → Settings → Ad Accounts, turn on auto-sync for every ad account you run creator ads from. The active account always syncs.
- Create the campaigns and ad sets you want to fill in the Meta Ads builder, or import them from Ads Manager.
Creators who are ready for partnership ads
To run an ad as the creator (a partnership ad, with the creator’s name on it), the creator must approve your partnership request on Instagram. Send requests and check who approved in Meta Ads → Partnerships. List ad sources shows each creator’s readiness inwhitelisting_status and gives you the approved
request in meta_partnership_ad_request_id.
Creators also need an active enrollment in the campaign that pays them for
Meta ads, so they have a Meta tracking link. See
How creators get credited and paid.
Authentication and base URL
organization_id=<brand id> to any request. Any other id returns 404.
1. List ad sources
List ad sources returns the content you can build ads from. Pick a source:
For a daily job, ask for content from the last day that is not in an ad yet:
campaign_id, campaign_affiliate_id, creator_id (Growi
user id), search, page and per_page (up to 100). Dates default to the
last 30 days and can span up to 366 days.
From each row you need:
creative_source: copy its keys into the ad’screativeas they are.meta_partnership_ad_request_id: send it to run the ad as the creator.creator.id: to get the creator’s Meta tracking link in step 2.
2. Read the builder options
Get builder options returns everything else you need in one call. Read it once at the start of a run and reuse it for every ad.
Pages, campaigns and ad sets are for one ad account: the active one, or the
one you pass as
meta_ad_account_id. Pass meta_campaign_id to see only the
ad sets of one campaign.
Meta allows 50 ads per ad set (150 with Advantage+ audience). If you build
more ads than one ad set can take, spread them across ad sets using
max_ads - ads_count, or add ad sets in the dashboard first.
3. Create ads in bulk
Create ads in bulk takes up to 50 ads. Each row is checked and created on its own, so one bad row does not stop the rest.name,meta_ad_account_idandmeta_ad_set_id(an existing ad set of that ad account).creativewithprimary_text,headline,call_to_action,link_urland the row’screative_sourcekeys.- Optionally
launch_state(pausedby default, oractive),meta_partnership_ad_request_idandcopy_template_id.
207 with one result per row:
meta_ad_id of every successful row: it is the Growi ad id you use
from now on.
4. Poll the ads
Growi publishes each ad to Meta in the background, usually within a few minutes. Ask for all of a run’s ads in one call with List ads, up to 200 ids:status is Meta’s own delivery status (ACTIVE, PAUSED, DELETED,
ARCHIVED). Get an ad returns the
same fields for one ad.
5. Launch or pause
- Launch turns the ad, its ad set and its campaign on. Spend starts. An ad that has not published yet launches as soon as it does (
deferred: true). - Pause pauses the ad on Meta.
launch_state on the bulk call instead.
Example: a daily job
This Python sketch builds partnership ads from yesterday’s Instagram posts with your default copy template, fills the ad sets of one campaign, launches them as they publish, and reports failures. It spaces requests 2 seconds apart and waits out429 responses.
per_page at or above the
number of ids you send.
How creators get credited and paid
Growi credits each ad to one creator enrollment when you create it, and the ad’scampaign_affiliate_id shows which one:
- An ad built from a creator’s social post is credited to the enrollment that post is attributed to.
- An ad built from a content submission is credited to the enrollment the submission came from.
- Otherwise, a
link_urlthat carries the creator’s Meta tag (a=meta_<tag>, fromcreator_linksin Get builder options) credits the creator the tag belongs to.
link_url, whatever the source. Growi
attributes purchases to the creator through that tag. It also attributes ads
made outside Growi when their URL has a=meta_<tag>, utm_source=meta and
utm_content={{ad.id}}.
What the creator earns depends on the campaign they are enrolled in:
A campaign can also require creators to deliver a number of posts before
their Meta commissions unlock.
Ad spend commission, sales and fees show up in the creator’s payouts like any
other earnings. If a creator is removed from a campaign, ads already credited
to that enrollment stay on it: re-add the creator to the same campaign to keep
treating those ads as active on that program.
Rate limits and batching
The Meta ads endpoints share your organization’s public API limits:- 2 seconds between requests from the same key.
- 40 requests per hour per key by default. Some organizations have a higher limit; the
X-RateLimit-Limit,X-RateLimit-RemainingandX-RateLimit-Resetheaders on each response show yours. - Over a limit you get
429with aRetry-Afterheader andretry_afterin the body. The hourly limit resets at the top of the hour.
- Send up to 50 ads per bulk request with
launch_state: "active", instead of one request per ad and a launch call per ad. - Read builder options once per run and reuse them.
- Poll List ads for up to 200 ids in one call, every few minutes.
- Use
per_page=100on sources.
Errors and troubleshooting
Rows in a bulk request fail with a
PREFLIGHT_* code before anything is
created; the full list is on
Create ads in bulk.
Ads that fail while publishing end in state: failed with error_message
and last_step.
PREFLIGHT_MISSING_FIELD on meta_ad_set_id
PREFLIGHT_MISSING_FIELD on meta_ad_set_id
meta_ad_set_id is missing, is not one of your ad sets, or belongs to a
different ad account than meta_ad_account_id. Use an id from
meta_ad_sets in builder options for the same ad account.PREFLIGHT_AD_SET_FULL
PREFLIGHT_AD_SET_FULL
The ad set already holds Meta’s maximum of 50 ads (150 with Advantage+
audience). Rows run in order and ads created by earlier rows in the same
request count, so the rows past the limit fail. Spread rows across ad sets
using
ads_count and max_ads from builder options, or add an ad set in
the dashboard.PREFLIGHT_INVALID_CTA
PREFLIGHT_INVALID_CTA
creative.call_to_action must be a Meta CTA type such as SHOP_NOW or
LEARN_MORE. allowed.call_to_actions in builder options lists every
value.PREFLIGHT_NO_INSTAGRAM_ACTOR
PREFLIGHT_NO_INSTAGRAM_ACTOR
Your organization has no active Instagram account for the ad. Check
instagram_accounts in builder options, or send
creative.require_instagram: false to run the ad from the Facebook page
only.PREFLIGHT_NO_PIXEL
PREFLIGHT_NO_PIXEL
The ad set optimizes for conversions and the ad account has no Meta pixel.
Install one, or pick an ad set with another goal.
PREFLIGHT_PARTNERSHIP_NOT_APPROVED
PREFLIGHT_PARTNERSHIP_NOT_APPROVED
The partnership request is not approved yet, or Meta says the creator’s
Instagram account is not eligible. Check Meta Ads → Partnerships, or
build the ad without
meta_partnership_ad_request_id to run it from your
page.PREFLIGHT_CAMPAIGN_ARCHIVED
PREFLIGHT_CAMPAIGN_ARCHIVED
The ad set’s campaign was archived or deleted in Ads Manager. Builder
options hides closed campaigns and ad sets, so read it again and pick
another ad set.
Sources return 422
Sources return 422
A
campaign_id, campaign_affiliate_id or creator_id that is not in
your organization, a bad date or range, or tik_tok_shop_videos when no
TikTok Shop is connected. The error field says which.An ad failed with 'We could not fetch this post's video'
An ad failed with 'We could not fetch this post's video'
Growi could not download the post’s video. Ask the creator for the file,
or build the ad from a content submission instead.
The creator gets no spend commission for an ad
The creator gets no spend commission for an ad
Check that the ad has the creator’s
campaign_affiliate_id (Get an ad),
that its ad account syncs, and that the creator’s campaign pays Meta ad
spend commission. Use the creator’s Meta link as link_url on new ads.Do the same with Claude
If you connected Claude to Growi, you can run the whole flow by asking, for example: “Build partnership ads from yesterday’s Instagram posts into the Broad US ad set, launch them, then tell me which ones failed.”create_meta_ads and manage_meta_ads need an owner or admin, connected with
their Growi login or with a full-access key they created. Both ask before they
change anything:
- Claude calls the tool without confirming. Nothing is created or changed:
create_meta_adschecks every ad and reports which ones would fail and which would start spend, andmanage_meta_adslists the ads that would change. - Claude shows you the plan.
- After you approve, Claude calls the tool again with the same arguments and the confirmation token from step 1. The token works once, only for those exact arguments, and expires after 10 minutes.
list_meta_ad_sources costs 5 units, create_meta_ads
and manage_meta_ads cost 3, and the other tools cost 1.