Start a mutation
Starts a change on a live advertiser and answers immediately.
The change does not happen during this request. The answer carries a workflowId. Poll GET /mutations/{id} with it to find out how the change ended. A Mutation is durable, so the id stays valid across retries and restarts.
A request that is refused here starts nothing. A body that does not match, an advertiser that is not yours, and an advertiser connected without write access are all refused before a Mutation exists, so a failed call leaves no row in the history.
This operation checks the credential first and the body second. A missing or unusable credential answers 401 even when the body is wrong as well. A body that does not match then answers 400 with error of invalid_request, and issues names each field.
A create never starts delivery: a campaign, an ad set and an ad all arrive paused. This API also cannot delete, so meta_set_status with ARCHIVED is how an object is retired.
/mutationsAuthorizationBearer token · headerrequiredSend Authorization: Bearer <credential>.
Use an API key (acr_…), from the AdCrunch console under Settings → API keys.
The credential names the organization, and no operation takes an organization parameter.
See https://docs.adcrunch.dev/api/authentication.
application/jsonactionobjectrequiredWhat to do. The kind field selects the action, and each kind takes its own fields.
Show propertiesHide properties
idstringrequiredThe Meta id of the object to change. It is the native id, not an AdCrunch id.
kindstringrequiredmeta_set_statuslevelstringrequiredWhich object the id refers to.
campaignadsetadstatusstringrequiredThe status to set. ACTIVE starts delivery and starts spend. PAUSED stops delivery and can be reversed. ARCHIVED retires the object, and on Meta it is close to one-way: you cannot make an archived object active again from this API. Archive is the only way to retire an object, because this API never deletes one.
ACTIVEPAUSEDARCHIVEDdailyBudgetnumberThe amount to spend each day. The amount is in whole units of the ad account currency: 10.5 is 10.50. Meta refuses more decimals than the currency has, and it counts some currencies, such as JPY and HUF, with none. Give a daily budget or a lifetime budget, not both.
idstringrequiredThe Meta id of the campaign or ad set to change. It is the native id, not an AdCrunch id.
kindstringrequiredmeta_update_budgetlevelstringrequiredWhich object the id refers to. An ad has no budget of its own.
campaignadsetlifetimeBudgetnumberThe amount to spend across the whole schedule. The amount is in whole units of the ad account currency: 10.5 is 10.50. Meta refuses more decimals than the currency has, and it counts some currencies, such as JPY and HUF, with none. A lifetime budget needs an end time on the ad set.
dailyBudgetnumberThe amount the campaign spends each day, shared across its ad sets. The amount is in whole units of the ad account currency: 10.5 is 10.50. Meta refuses more decimals than the currency has, and it counts some currencies, such as JPY and HUF, with none. Give one of the two budgets. Meta refuses a campaign with neither, and AdCrunch cannot yet create a campaign whose ad sets carry their own budgets.
kindstringrequiredmeta_create_campaignlifetimeBudgetnumberThe amount the campaign spends across its whole schedule, shared across its ad sets. The amount is in whole units of the ad account currency: 10.5 is 10.50. Meta refuses more decimals than the currency has, and it counts some currencies, such as JPY and HUF, with none. Give one of the two budgets. Meta refuses a campaign with neither, and AdCrunch cannot yet create a campaign whose ad sets carry their own budgets.
namestringrequiredThe campaign name. It is visible in Meta Ads Manager.
objectivestringrequiredThe result the campaign optimizes for. It cannot be changed after the campaign is created, and it limits which optimization goals the ad sets below it can use.
OUTCOME_AWARENESSOUTCOME_ENGAGEMENTOUTCOME_LEADSOUTCOME_SALESOUTCOME_TRAFFICOUTCOME_APP_PROMOTIONspecialAdCategoriesstring[]requiredDeclare a regulated category when the campaign advertises one: EMPLOYMENT, HOUSING, CREDIT, ISSUES_ELECTIONS_POLITICS, ONLINE_GAMBLING_AND_GAMING, or FINANCIAL_PRODUCTS_SERVICES. Meta restricts targeting for each of them, and a wrong declaration breaks the advertiser policy agreement. Send an empty array or NONE when none applies. Do not guess: ask the advertiser.
ageMaxintegerThe oldest age to target, from 13 to 65. Omit it to target every age above the minimum. 65 and above is one group on Meta.
ageMinintegerrequiredThe youngest age to target, from 13 to 65. This field is required, and it is the one targeting field with no default. Many advertisers must not show ads to people under 18, and a default would spend their money on an audience they cannot legally address. State the age deliberately: send 18 to exclude minors.
campaignIdstringrequiredThe Meta id of the campaign this ad set belongs to. Create the campaign first and use the id it returns.
countriesstring[]requiredThe countries to target, as two-letter ISO 3166-1 alpha-2 codes, for example US or GB. Give at least one.
customEventTypestringThe conversion the pixel reports, for example PURCHASE. Required with a conversion optimization goal, and it must be sent together with pixelId.
PURCHASELEADCOMPLETE_REGISTRATIONADD_TO_CARTINITIATED_CHECKOUTADD_PAYMENT_INFOVIEW_CONTENTSEARCHSUBSCRIBESTART_TRIALCONTACTOTHERdailyBudgetnumberThe amount this ad set spends each day. The amount is in whole units of the ad account currency: 10.5 is 10.50. Meta refuses more decimals than the currency has, and it counts some currencies, such as JPY and HUF, with none. Omit both budgets when the campaign carries one, which is the usual case: a campaign created here always carries a budget, and it is shared across its ad sets.
endTimestringWhen delivery stops, as an ISO 8601 timestamp. Required with a lifetime budget.
gendersstringrequiredWhich genders to target. The default targets everybody.
allmenwomenkindstringrequiredmeta_create_adsetlifetimeBudgetnumberThe amount this ad set spends across its whole schedule. The amount is in whole units of the ad account currency: 10.5 is 10.50. Meta refuses more decimals than the currency has, and it counts some currencies, such as JPY and HUF, with none. It needs an end time.
namestringrequiredThe ad set name. It is visible in Meta Ads Manager.
optimizationGoalstringrequiredWhat Meta optimizes delivery for. The campaign objective limits which goals are valid. A conversion goal also needs pixelId and customEventType. The billing event follows from this goal, so there is no separate field for it.
IMPRESSIONSREACHLINK_CLICKSLANDING_PAGE_VIEWSOFFSITE_CONVERSIONSPOST_ENGAGEMENTTHRUPLAYLEAD_GENERATIONVALUEpixelIdstringThe Meta pixel that reports conversions. Required with a conversion optimization goal. AdCrunch can list the pixels this ad account can use.
startTimestringWhen delivery starts, as an ISO 8601 timestamp. Omit it to start when the ad set becomes active. The ad set is created paused either way.
adsetIdstringrequiredThe Meta id of the ad set this ad runs in. Create the ad set first and use the id it returns.
creativeIdstringrequiredThe Meta id of the creative this ad shows. Create the creative first with meta_create_creative and use the id it returns. One creative can be used by more than one ad.
kindstringrequiredmeta_create_adnamestringrequiredThe ad name. It is visible in Meta Ads Manager.
assetIdstringrequiredThe AdCrunch Asset to build the creative from, as the ast_ id that Asset registration returned. The Asset must already be registered to this advertiser. Do not send a Meta image hash or video id. Whether the creative becomes an image or a video follows from the Asset.
callToActionstringrequiredThe label on the button, for example SHOP_NOW.
LEARN_MORESHOP_NOWSIGN_UPBOOK_TRAVELDOWNLOADGET_OFFERGET_QUOTECONTACT_USSUBSCRIBEAPPLY_NOWNO_BUTTONdescriptionstringThe text below the headline. Meta can truncate it.
headlinestringrequiredThe short bold line next to the button.
kindstringrequiredmeta_create_creativelinkstring<uri>requiredThe page the ad opens when somebody clicks it.
messagestringrequiredThe main body text, shown above the media.
namestringrequiredThe creative name. It is visible in Meta Ads Manager, and it is not shown to a person who sees the ad.
pageIdstringrequiredThe Facebook Page the ad is published from. AdCrunch can list the Pages this ad account can publish from.
advertiserIdstringrequiredThe advertiser to act on, as an AdCrunch acc_ id. It must belong to your organization and be connected with write access.
The Mutation started. Poll it for the outcome.
workflowIdstringrequiredThe id of the Mutation. Poll GET /mutations/{id} with it to find out whether the change succeeded.
The request does not match the schema of this operation: a field is missing or has the wrong type, or the body is not valid JSON. error is invalid_request, and issues names each field. Nothing was changed.
issuesobject[]requiredOne entry for each field that does not match.
Show propertiesHide properties
objectinstringrequiredThe part of the request that holds the field.
bodycookieheadersparamsquerymessagestringrequiredA sentence to show a person. Written to say what to do next. Reworded whenever it can be said better, so never branch on it.
pathstringrequiredA JSON Pointer into that part of the request, such as /filename. An empty string is the whole part.
errorstringrequiredA stable code for the failure. This is the field to branch on. It does not change for a given failure.
invalid_requestmessagestringrequiredA sentence to show a person. Written to say what to do next. Reworded whenever it can be said better, so never branch on it.
No API key, or one that does not resolve. See the security scheme. error is unauthorized.
errorstringrequiredA stable code for the failure. This is the field to branch on. It does not change for a given failure.
unauthorizedmessagestringrequiredA sentence to show a person. Written to say what to do next. Reworded whenever it can be said better, so never branch on it.
The caller does not hold mutation:write, or the advertiser is connected without write access. In the second case error is missing_write_access and message says how to fix it. Nothing was started.
errorstringrequiredA stable code for the failure. This is the field to branch on. It does not change for a given failure.
forbiddenmessagestringrequiredA sentence to show a person. Written to say what to do next. Reworded whenever it can be said better, so never branch on it.
errorstringrequiredA stable code for the failure. This is the field to branch on. It does not change for a given failure.
missing_write_accessmessagestringrequiredA sentence to show a person. Written to say what to do next. Reworded whenever it can be said better, so never branch on it.
The advertiser does not exist, or it belongs to another organization. Both answer the same way on purpose, so a caller cannot learn which. error is not_found. Nothing was started.
errorstringrequiredA stable code for the failure. This is the field to branch on. It does not change for a given failure.
not_foundmessagestringrequiredA sentence to show a person. Written to say what to do next. Reworded whenever it can be said better, so never branch on it.