Create messaging ad
Creates a click-to-message ad; destination selects where the tapped ad opens a conversation: WhatsApp, the Page's Messenger inbox or the linked Instagram account's Direct inbox. destinations puts two or three of them on one ad set and lets Meta pick the app per viewer. The ad set is created with the matching destination_type and CONVERSATIONS optimization; the campaign objective defaults to OUTCOME_ENGAGEMENT. Supports single-creative and multi-creative shapes. Supersedes POST /v1/ads/ctwa (deprecated, equivalent to destination: whatsapp). Existing posts and reels are supported through platformPostId (alias existingPostId) or objectStoryId, either per creative or at the top level. Omit fresh media and copy for that creative. Optional whatsappPhoneNumber selects a number already paired with the Page (WhatsApp destination only). accountId is a Facebook, Instagram or Meta ads (business login) connection; pageId picks the Page when that connection was granted several.
Idempotency: this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an Idempotency-Key header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with Idempotent-Replayed: true) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
Headers
Optional client-generated unique key (e.g. a UUID) that makes retries safe. Same key + same body replays the original response; same key + different body → 422; key still processing → 409.
Request body
Example request
{
"creativeFeatures": {
"auto_promotion_tag": "OPT_IN"
},
"creatives": [
{
"creativeFeatures": {
"auto_promotion_tag": "OPT_IN"
}
}
]
}Response
Ad(s) created and submitted for review. The route shares its handler with POST /v1/ads/ctwa, so the body is the same tagged union discriminated by adType: single carries { adType, ad, message }, and multi carries { adType, ads, platformCampaignId, platformAdSetId, message }.
Changes
Changed in 17 of the 56 revisions of this API.57
- ○
added the new optional
headerrequest parameterIdempotency-Keynew-optional-request-parameter
- ○
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
This revision also has 2 changes that name no endpoint, such as unreferenced schemas being removed. See the revision's changelog
- ○
- ○
added the new optional request property
//////new-optional-request-property
- ○
added the new optional request property
////new-optional-request-property
- ○
added the new optional request property
/new-optional-request-property
- ○
the request property
/became optionalrequest-property-became-optional
- ○
request property
//////deprecatedrequest-property-deprecated
- ○
request property
////deprecatedrequest-property-deprecated
- ○
- ○
added the new optional request property
////new-optional-request-property
- ○
added the new optional request property
////new-optional-request-property
- ○
added the new optional request property
////new-optional-request-property
- ○
- ○
added the new optional request property
/////new-optional-request-property
- ○
the request property
/////became optionalrequest-property-became-optional
- ○
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
added the optional property
/to the response with the statusresponse-optional-property-added
- ○
- ○
added the new optional request property
////new-optional-request-property
- ○
- ○
added the media type
application/jsonfor the response with the statusresponse-media-type-added
- ○
added the non-success response with the status
response-non-success-status-added
- ○
- ○
added the new optional request property
////new-optional-request-property
- ○
added the new optional request property
//////new-optional-request-property
- ○
added the new optional request property
//////new-optional-request-property
- ○
added the new optional request property
//////new-optional-request-property
- ○
added the new optional request property
////new-optional-request-property
- ○
added the new optional request property
////new-optional-request-property
- ○
added the new optional request property
////new-optional-request-property
- ○
added the new optional request property
////new-optional-request-property
- ○
the request property
//////became optionalrequest-property-became-optional
- ○
the request property
//////became optionalrequest-property-became-optional
- ○
added the media type
application/jsonfor the response with the statusresponse-media-type-added
- ○