Zernio
APIFor you
Zernio
APIFor you
Platforms

Meta Ads

Overview

Set up

Connect

Build

CampaignsAd setsCreativesCreative libraryPreviewsBoost a postLead Gen Forms

Target

TargetingCustom Audiences

Ad types

Creative testingConversion campaignsCatalog adsMessaging & call adsClick-to-WhatsApp adsReach & frequency

Measure

InsightsMeta PixelsConversions APIAd URL tracking tags

Operate

Duplicate & lifecycleAccount & ops readsAd LibraryAd comments

Reference

Enums, limits & error codes
Dashboard
OverviewPlatformsAPI ReferenceResources
Meta Ads

Conversion campaigns

Optimize a Meta campaign toward a pixel event, an instant form or an app install by adding a promotedObject to the create request.


Optimize toward a conversion by sending a goal from the table below plus a promotedObject on POST /v1/ads/create.

The promoted object names the thing being optimized against: a pixel and its event, a Page, an app, or a product set.

The promoted object

Without it, Meta rejects the ad set with subcode 1815430. Zernio checks first and returns a 400 with param: "promotedObject".

goalMeta objective and optimizationRequired promotedObject fields
conversionsSales, OFFSITE_CONVERSIONSpixelId and customEventType, with a commerce event such as PURCHASE, ADD_TO_CART or START_TRIAL
lead_conversionLeads, OFFSITE_CONVERSIONSpixelId and customEventType, with a leads event such as LEAD, SUBMIT_APPLICATION, SCHEDULE or CONTACT
lead_generationLeads, LEAD_GENERATION on an instant formpageId, auto-filled from the connected Page when omitted (lead forms)
app_promotionApp promotion, APP_INSTALLSapplicationId and objectStoreUrl
catalog_salesSales, catalog template creativeproductSetId, pixelId and customEventType (catalog ads)

Meta gates which events are valid per objective.

conversions runs the Sales objective, so a leads event such as LEAD is rejected there. Website pixel lead optimization is lead_conversion.

lead_generation is the Leads objective too, but it optimizes for an instant form rather than a pixel event.

customEventType takes Meta's standard event names:

PURCHASE, LEAD, COMPLETE_REGISTRATION, ADD_TO_CART, INITIATE_CHECKOUT, ADD_PAYMENT_INFO,
SUBSCRIBE, START_TRIAL, VIEW_CONTENT, SEARCH, CONTACT, SUBMIT_APPLICATION, SCHEDULE

For a pixel event you named yourself, or for a Custom Conversion, see the samples below.

For iOS app promotion, follow the SKAdNetwork campaign fields.

App promotion discovery lists promotable apps and reads an app's iOS 14 campaign limits before creation.

Create a purchase-optimized ad

import Zernio from '@zernio/node';

const zernio = new Zernio();

const { data: created } = await zernio.adcampaigns.createStandaloneAd({
  body: {
    accountId: '66b2e19d8c3f5a7e9d0b1c2d',
    adAccountId: 'act_1234567890',
    name: 'Spring sale, purchases',
    goal: 'conversions',
    budgetAmount: 75,
    budgetType: 'daily',
    headline: 'Spring sale, 30% off',
    body: 'Limited time. Upgrade today.',
    imageUrl: 'https://cdn.example.com/spring.jpg',
    callToAction: 'SHOP_NOW',
    linkUrl: 'https://example.com/spring',
    countries: ['US'],
    promotedObject: { pixelId: '1729525464415281', customEventType: 'PURCHASE' }
  }
});

Response (201), trimmed:

{
  "ad": {
    "_id": "66d4a1b2c3e4f5a6b7c8d9e5",
    "status": "pending_review",
    "goal": "conversions",
    "platformObjective": "OUTCOME_SALES",
    "optimizationGoal": "OFFSITE_CONVERSIONS",
    "promotedObject": { "pixelId": "1729525464415281", "customEventType": "PURCHASE" }
  }
}

To find a pixelId, list the pixels the connected ad account can see with GET /v1/accounts/{accountId}/tracking-tags, or create one there.

GET /v1/accounts/{accountId}/conversion-destinations returns the same set in the shape the Conversions API uses.

Custom events and custom conversions

For a pixel event you named yourself, send OTHER with the name exactly as Events Manager shows it.

The two fields travel together. OTHER without customEventStr is a 400, and so is customEventStr with any other event type.

{
  "promotedObject": {
    "pixelId": "1729525464415281",
    "customEventType": "OTHER",
    "customEventStr": "trial_activated"
  }
}

To optimize against a Custom Conversion instead, send its id alone. It replaces the pixel and event pair rather than joining it:

{
  "promotedObject": { "customConversionId": "1234567890123456" }
}

The id comes from GET /v1/accounts/{accountId}/custom-conversions with adAccountId. It lists the ad account's Custom Conversions, archived ones included.

POST on the same path provisions one, so a flow does not have to send the user to Ads Manager first. It takes:

  • a name
  • a pixelId
  • a customEventType
  • Meta's own rule grammar, for example {"url": {"i_contains": "thank-you"}}

It returns customConversionId, ready for promotedObject.

It reuses a non-archived conversion with the same name on the same pixel rather than minting a duplicate. That reply is a 200 with reused: true instead of a 201.

Everything else in the create request stays as it is above.

Every promoted object key

promotedObject accepts exactly these keys, on create and on the post-launch edit:

FieldWhen to send it
pixelIdThe pixel to optimize against. Meta rejects a promoted object with a pixel and no customEventType (subcode 1885014).
customEventTypeThe standard event, or OTHER with customEventStr.
customEventStrThe custom pixel event name, case-sensitive. Requires customEventType: "OTHER", and OTHER requires it.
pageIdThe Page for goal: "lead_generation".
applicationId, objectStoreUrlThe app and its store listing, for goal: "app_promotion".
customConversionIdA Custom Conversion instead of a standard event. Accepted on its own.
productCatalogId, productSetIdCatalog and Advantage+ shopping campaigns.
offlineConversionDataSetIdAn offline event set. Post-merger these are datasets, so the id is the dataset id (the pixel id for pixel-backed datasets).
whatsappPhoneNumberThe WhatsApp number on a messaging-destination ad set.

promotedObject is strict. An unknown or misspelled key returns a 400 naming it instead of being dropped.

A dropped key used to change what the ad set optimized toward with no warning.

Override the optimization goal

The ad set's optimization_goal is derived from goal (traffic gives LINK_CLICKS).

Send the top-level optimizationGoal to set it yourself, for example LANDING_PAGE_VIEWS, REACH, IMPRESSIONS, OFFSITE_CONVERSIONS or THRUPLAY.

It is forwarded verbatim, and Meta rejects a combination its objective does not allow.

billingEvent works the same way and defaults to IMPRESSIONS.

If it fails

A 400 before the request reaches Meta means the promoted object is missing:

{
  "error": "promotedObject is required for goal conversions",
  "type": "invalid_request_error",
  "param": "promotedObject"
}

Add pixelId and customEventType, or customConversionId.

If the request does reach Meta, the subcodes are:

  • 1815430: the same problem
  • 1885014: a pixel sent without an event

The reference lists both.

Related

  • Campaigns: the base create request and the bid strategy.
  • Pixels: create and share the pixel these goals point at.
  • Conversions: send the events server-side.
  • Ad sets: change the promoted object after launch.
  • Create standalone ad: every field.
Was this page helpful?

Creative testing

Test Meta creative variations by creating N ads inside one ad set with the creatives[] shape on POST /v1/ads/create.

Catalog ads

Run Advantage+ catalog ads from a Meta product catalog with goal catalog_sales, and find the catalog and product set to promote.

On this page

The promoted objectCreate a purchase-optimized adCustom events and custom conversionsEvery promoted object keyOverride the optimization goalIf it failsRelated