@getlatedev/node 0.2.237 → 0.2.239

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -18646,6 +18646,10 @@ type CreateStandaloneAdData = {
18646
18646
  * Required on legacy + attach shapes. For X/Twitter this is the tweet text (max 280 chars including a ~24-char URL when `linkUrl` is set). On LinkedIn this is the post commentary (the intro text shown above the ad). Max: Google=90, Pinterest=500.
18647
18647
  */
18648
18648
  body?: string;
18649
+ /**
18650
+ * Meta only (facebook/instagram). Link description — the secondary text shown below the headline (Meta's link_data.description; on video creatives mapped to video_data.link_description). When omitted, Meta auto-pulls the destination URL's OpenGraph description. Applies on legacy, attach, and placementAssets shapes; for multi-creative use creatives[].description (this field is the shared fallback). For multi-text variations use dynamicCreative.descriptions instead.
18651
+ */
18652
+ description?: string;
18649
18653
  /**
18650
18654
  * Required on legacy + attach shapes for Meta. Honoured on TikTok (passes through to the Spark Ad creative's `call_to_action`) and on LinkedIn (the CTA button on the ad; defaults to LEARN_MORE when `linkUrl` is set). LinkedIn accepts: LEARN_MORE, SIGN_UP, DOWNLOAD, SUBSCRIBE, REGISTER, JOIN, ATTEND, REQUEST_DEMO, VIEW_QUOTE, APPLY, SEE_MORE, SHOP_NOW, BUY_NOW. Ignored by Google, Pinterest, and X/Twitter.
18651
18655
  */
@@ -18655,7 +18659,7 @@ type CreateStandaloneAdData = {
18655
18659
  */
18656
18660
  linkUrl?: string;
18657
18661
  /**
18658
- * Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`; ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` entry plus your text variations to get Meta's "Multiple Text Options" behavior on a lead ad.
18662
+ * Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`, and on every ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` entry plus your text variations to get Meta's "Multiple Text Options" behavior on a lead ad.
18659
18663
  */
18660
18664
  leadGenFormId?: string;
18661
18665
  /**
@@ -18684,7 +18688,7 @@ type CreateStandaloneAdData = {
18684
18688
  */
18685
18689
  url: string;
18686
18690
  /**
18687
- * Public URL of a still-image thumbnail for the video. Required by Meta on every video creative (uploaded as an ad image and referenced in object_story_spec.video_data). Ignored by LinkedIn (auto-generated poster frame).
18691
+ * Public URL of a still-image thumbnail for the video. OPTIONAL: when omitted on Meta, the poster is auto-generated from Meta's own preferred video thumbnail (the same candidates Ads Manager shows), so video ads publish without supplying one. Provide it to control the poster frame exactly (uploaded as an ad image and referenced in object_story_spec.video_data). Ignored by LinkedIn (auto-generated poster frame).
18688
18692
  */
18689
18693
  thumbnailUrl?: string;
18690
18694
  };
@@ -18702,16 +18706,20 @@ type CreateStandaloneAdData = {
18702
18706
  name?: string;
18703
18707
  headline: string;
18704
18708
  body: string;
18709
+ /**
18710
+ * Link description for this ad (link_data.description; video creatives: video_data.link_description). Falls back to the top-level `description`; when both are omitted Meta scrapes the destination URL's OG description.
18711
+ */
18712
+ description?: string;
18705
18713
  /**
18706
18714
  * Image creative. Mutually exclusive with `video`.
18707
18715
  */
18708
18716
  imageUrl?: string;
18709
18717
  /**
18710
- * Video creative for this entry. Mutually exclusive with `imageUrl`.
18718
+ * Video creative for this entry. Mutually exclusive with `imageUrl`. thumbnailUrl is optional — when omitted, the poster is auto-generated from Meta's preferred video thumbnail.
18711
18719
  */
18712
18720
  video?: {
18713
18721
  url: string;
18714
- thumbnailUrl: string;
18722
+ thumbnailUrl?: string;
18715
18723
  };
18716
18724
  linkUrl: string;
18717
18725
  callToAction: 'LEARN_MORE' | 'SHOP_NOW' | 'SIGN_UP' | 'BOOK_TRAVEL' | 'CONTACT_US' | 'DOWNLOAD' | 'GET_OFFER' | 'GET_QUOTE' | 'SUBSCRIBE' | 'WATCH_MORE';
@@ -18725,6 +18733,16 @@ type CreateStandaloneAdData = {
18725
18733
  * bid, use `PUT /v1/ads/ad-sets/{adSetId}`. Mutually exclusive
18726
18734
  * with `creatives[]`.
18727
18735
  *
18736
+ * The attached ad takes the full single-creative surface:
18737
+ * `headline`/`body`/`description`/`callToAction` plus either
18738
+ * `imageUrl`/`video` OR `placementAssets` (its own per-placement
18739
+ * Feed/Story assets), and `leadGenFormId` when the target is a
18740
+ * lead ad set (the parent must be ON_AD — true for ad sets
18741
+ * created via goal `lead_generation`; Meta rejects a formless ad
18742
+ * there, so pass the form on EVERY attached ad). This is the way
18743
+ * to build N full ads sharing one ad set: create the first ad
18744
+ * via the normal shape, then attach the rest one call each.
18745
+ *
18728
18746
  * Supported on Meta (facebook, instagram) and TikTok. On TikTok
18729
18747
  * the `adSetId` is the ad group ID; the new ad inherits the
18730
18748
  * ad group's bid + budget + targeting.
@@ -18949,8 +18967,11 @@ type CreateStandaloneAdData = {
18949
18967
  * each placement group on a SINGLE ad (e.g. a 9:16 on Stories/Reels and a 4:5 on Feed).
18950
18968
  * The same thing Meta Ads Manager produces with "different creative per placement",
18951
18969
  * mapped to the creative's `asset_feed_spec` + `asset_customization_rules`. Deterministic
18952
- * pinning, NOT the auto-optimizing pool of `dynamicCreative` (mutually exclusive, and it
18953
- * cannot be combined with `creatives[]` or `adSetId`). Shared copy (headline, body, link,
18970
+ * pinning, NOT the auto-optimizing pool of `dynamicCreative` (mutually exclusive). Works
18971
+ * on the legacy single shape AND the attach shape (`adSetId` + placementAssets adds one
18972
+ * placement-customized ad to an existing ad set — the way to build N per-placement ads
18973
+ * sharing one ad set: create the first normally, attach the rest). Cannot be combined
18974
+ * with `creatives[]`. Shared copy (headline, body, link,
18954
18975
  * CTA) comes from the top-level single-creative fields since only the asset varies by
18955
18976
  * placement. Each rule's `placements` accepts the same fields as the top-level
18956
18977
  * `placements` object; Meta enforces co-selection rules and returns an actionable error.
package/dist/index.d.ts CHANGED
@@ -18646,6 +18646,10 @@ type CreateStandaloneAdData = {
18646
18646
  * Required on legacy + attach shapes. For X/Twitter this is the tweet text (max 280 chars including a ~24-char URL when `linkUrl` is set). On LinkedIn this is the post commentary (the intro text shown above the ad). Max: Google=90, Pinterest=500.
18647
18647
  */
18648
18648
  body?: string;
18649
+ /**
18650
+ * Meta only (facebook/instagram). Link description — the secondary text shown below the headline (Meta's link_data.description; on video creatives mapped to video_data.link_description). When omitted, Meta auto-pulls the destination URL's OpenGraph description. Applies on legacy, attach, and placementAssets shapes; for multi-creative use creatives[].description (this field is the shared fallback). For multi-text variations use dynamicCreative.descriptions instead.
18651
+ */
18652
+ description?: string;
18649
18653
  /**
18650
18654
  * Required on legacy + attach shapes for Meta. Honoured on TikTok (passes through to the Spark Ad creative's `call_to_action`) and on LinkedIn (the CTA button on the ad; defaults to LEARN_MORE when `linkUrl` is set). LinkedIn accepts: LEARN_MORE, SIGN_UP, DOWNLOAD, SUBSCRIBE, REGISTER, JOIN, ATTEND, REQUEST_DEMO, VIEW_QUOTE, APPLY, SEE_MORE, SHOP_NOW, BUY_NOW. Ignored by Google, Pinterest, and X/Twitter.
18651
18655
  */
@@ -18655,7 +18659,7 @@ type CreateStandaloneAdData = {
18655
18659
  */
18656
18660
  linkUrl?: string;
18657
18661
  /**
18658
- * Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`; ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` entry plus your text variations to get Meta's "Multiple Text Options" behavior on a lead ad.
18662
+ * Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`, and on every ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` entry plus your text variations to get Meta's "Multiple Text Options" behavior on a lead ad.
18659
18663
  */
18660
18664
  leadGenFormId?: string;
18661
18665
  /**
@@ -18684,7 +18688,7 @@ type CreateStandaloneAdData = {
18684
18688
  */
18685
18689
  url: string;
18686
18690
  /**
18687
- * Public URL of a still-image thumbnail for the video. Required by Meta on every video creative (uploaded as an ad image and referenced in object_story_spec.video_data). Ignored by LinkedIn (auto-generated poster frame).
18691
+ * Public URL of a still-image thumbnail for the video. OPTIONAL: when omitted on Meta, the poster is auto-generated from Meta's own preferred video thumbnail (the same candidates Ads Manager shows), so video ads publish without supplying one. Provide it to control the poster frame exactly (uploaded as an ad image and referenced in object_story_spec.video_data). Ignored by LinkedIn (auto-generated poster frame).
18688
18692
  */
18689
18693
  thumbnailUrl?: string;
18690
18694
  };
@@ -18702,16 +18706,20 @@ type CreateStandaloneAdData = {
18702
18706
  name?: string;
18703
18707
  headline: string;
18704
18708
  body: string;
18709
+ /**
18710
+ * Link description for this ad (link_data.description; video creatives: video_data.link_description). Falls back to the top-level `description`; when both are omitted Meta scrapes the destination URL's OG description.
18711
+ */
18712
+ description?: string;
18705
18713
  /**
18706
18714
  * Image creative. Mutually exclusive with `video`.
18707
18715
  */
18708
18716
  imageUrl?: string;
18709
18717
  /**
18710
- * Video creative for this entry. Mutually exclusive with `imageUrl`.
18718
+ * Video creative for this entry. Mutually exclusive with `imageUrl`. thumbnailUrl is optional — when omitted, the poster is auto-generated from Meta's preferred video thumbnail.
18711
18719
  */
18712
18720
  video?: {
18713
18721
  url: string;
18714
- thumbnailUrl: string;
18722
+ thumbnailUrl?: string;
18715
18723
  };
18716
18724
  linkUrl: string;
18717
18725
  callToAction: 'LEARN_MORE' | 'SHOP_NOW' | 'SIGN_UP' | 'BOOK_TRAVEL' | 'CONTACT_US' | 'DOWNLOAD' | 'GET_OFFER' | 'GET_QUOTE' | 'SUBSCRIBE' | 'WATCH_MORE';
@@ -18725,6 +18733,16 @@ type CreateStandaloneAdData = {
18725
18733
  * bid, use `PUT /v1/ads/ad-sets/{adSetId}`. Mutually exclusive
18726
18734
  * with `creatives[]`.
18727
18735
  *
18736
+ * The attached ad takes the full single-creative surface:
18737
+ * `headline`/`body`/`description`/`callToAction` plus either
18738
+ * `imageUrl`/`video` OR `placementAssets` (its own per-placement
18739
+ * Feed/Story assets), and `leadGenFormId` when the target is a
18740
+ * lead ad set (the parent must be ON_AD — true for ad sets
18741
+ * created via goal `lead_generation`; Meta rejects a formless ad
18742
+ * there, so pass the form on EVERY attached ad). This is the way
18743
+ * to build N full ads sharing one ad set: create the first ad
18744
+ * via the normal shape, then attach the rest one call each.
18745
+ *
18728
18746
  * Supported on Meta (facebook, instagram) and TikTok. On TikTok
18729
18747
  * the `adSetId` is the ad group ID; the new ad inherits the
18730
18748
  * ad group's bid + budget + targeting.
@@ -18949,8 +18967,11 @@ type CreateStandaloneAdData = {
18949
18967
  * each placement group on a SINGLE ad (e.g. a 9:16 on Stories/Reels and a 4:5 on Feed).
18950
18968
  * The same thing Meta Ads Manager produces with "different creative per placement",
18951
18969
  * mapped to the creative's `asset_feed_spec` + `asset_customization_rules`. Deterministic
18952
- * pinning, NOT the auto-optimizing pool of `dynamicCreative` (mutually exclusive, and it
18953
- * cannot be combined with `creatives[]` or `adSetId`). Shared copy (headline, body, link,
18970
+ * pinning, NOT the auto-optimizing pool of `dynamicCreative` (mutually exclusive). Works
18971
+ * on the legacy single shape AND the attach shape (`adSetId` + placementAssets adds one
18972
+ * placement-customized ad to an existing ad set — the way to build N per-placement ads
18973
+ * sharing one ad set: create the first normally, attach the rest). Cannot be combined
18974
+ * with `creatives[]`. Shared copy (headline, body, link,
18954
18975
  * CTA) comes from the top-level single-creative fields since only the asset varies by
18955
18976
  * placement. Each rule's `placements` accepts the same fields as the top-level
18956
18977
  * `placements` object; Meta enforces co-selection rules and returns an actionable error.
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(index_exports);
36
36
  // package.json
37
37
  var package_default = {
38
38
  name: "@getlatedev/node",
39
- version: "0.2.237",
39
+ version: "0.2.239",
40
40
  description: "The official Node.js library for the Zernio API",
41
41
  main: "dist/index.js",
42
42
  module: "dist/index.mjs",
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5
5
  // package.json
6
6
  var package_default = {
7
7
  name: "@getlatedev/node",
8
- version: "0.2.237",
8
+ version: "0.2.239",
9
9
  description: "The official Node.js library for the Zernio API",
10
10
  main: "dist/index.js",
11
11
  module: "dist/index.mjs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getlatedev/node",
3
- "version": "0.2.237",
3
+ "version": "0.2.239",
4
4
  "description": "The official Node.js library for the Zernio API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -19139,6 +19139,10 @@ export type CreateStandaloneAdData = {
19139
19139
  * Required on legacy + attach shapes. For X/Twitter this is the tweet text (max 280 chars including a ~24-char URL when `linkUrl` is set). On LinkedIn this is the post commentary (the intro text shown above the ad). Max: Google=90, Pinterest=500.
19140
19140
  */
19141
19141
  body?: string;
19142
+ /**
19143
+ * Meta only (facebook/instagram). Link description — the secondary text shown below the headline (Meta's link_data.description; on video creatives mapped to video_data.link_description). When omitted, Meta auto-pulls the destination URL's OpenGraph description. Applies on legacy, attach, and placementAssets shapes; for multi-creative use creatives[].description (this field is the shared fallback). For multi-text variations use dynamicCreative.descriptions instead.
19144
+ */
19145
+ description?: string;
19142
19146
  /**
19143
19147
  * Required on legacy + attach shapes for Meta. Honoured on TikTok (passes through to the Spark Ad creative's `call_to_action`) and on LinkedIn (the CTA button on the ad; defaults to LEARN_MORE when `linkUrl` is set). LinkedIn accepts: LEARN_MORE, SIGN_UP, DOWNLOAD, SUBSCRIBE, REGISTER, JOIN, ATTEND, REQUEST_DEMO, VIEW_QUOTE, APPLY, SEE_MORE, SHOP_NOW, BUY_NOW. Ignored by Google, Pinterest, and X/Twitter.
19144
19148
  */
@@ -19148,7 +19152,7 @@ export type CreateStandaloneAdData = {
19148
19152
  */
19149
19153
  linkUrl?: string;
19150
19154
  /**
19151
- * Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`; ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` entry plus your text variations to get Meta's "Multiple Text Options" behavior on a lead ad.
19155
+ * Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`, and on every ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` entry plus your text variations to get Meta's "Multiple Text Options" behavior on a lead ad.
19152
19156
  */
19153
19157
  leadGenFormId?: string;
19154
19158
  /**
@@ -19177,7 +19181,7 @@ export type CreateStandaloneAdData = {
19177
19181
  */
19178
19182
  url: string;
19179
19183
  /**
19180
- * Public URL of a still-image thumbnail for the video. Required by Meta on every video creative (uploaded as an ad image and referenced in object_story_spec.video_data). Ignored by LinkedIn (auto-generated poster frame).
19184
+ * Public URL of a still-image thumbnail for the video. OPTIONAL: when omitted on Meta, the poster is auto-generated from Meta's own preferred video thumbnail (the same candidates Ads Manager shows), so video ads publish without supplying one. Provide it to control the poster frame exactly (uploaded as an ad image and referenced in object_story_spec.video_data). Ignored by LinkedIn (auto-generated poster frame).
19181
19185
  */
19182
19186
  thumbnailUrl?: string;
19183
19187
  };
@@ -19195,16 +19199,20 @@ export type CreateStandaloneAdData = {
19195
19199
  name?: string;
19196
19200
  headline: string;
19197
19201
  body: string;
19202
+ /**
19203
+ * Link description for this ad (link_data.description; video creatives: video_data.link_description). Falls back to the top-level `description`; when both are omitted Meta scrapes the destination URL's OG description.
19204
+ */
19205
+ description?: string;
19198
19206
  /**
19199
19207
  * Image creative. Mutually exclusive with `video`.
19200
19208
  */
19201
19209
  imageUrl?: string;
19202
19210
  /**
19203
- * Video creative for this entry. Mutually exclusive with `imageUrl`.
19211
+ * Video creative for this entry. Mutually exclusive with `imageUrl`. thumbnailUrl is optional — when omitted, the poster is auto-generated from Meta's preferred video thumbnail.
19204
19212
  */
19205
19213
  video?: {
19206
19214
  url: string;
19207
- thumbnailUrl: string;
19215
+ thumbnailUrl?: string;
19208
19216
  };
19209
19217
  linkUrl: string;
19210
19218
  callToAction: 'LEARN_MORE' | 'SHOP_NOW' | 'SIGN_UP' | 'BOOK_TRAVEL' | 'CONTACT_US' | 'DOWNLOAD' | 'GET_OFFER' | 'GET_QUOTE' | 'SUBSCRIBE' | 'WATCH_MORE';
@@ -19218,6 +19226,16 @@ export type CreateStandaloneAdData = {
19218
19226
  * bid, use `PUT /v1/ads/ad-sets/{adSetId}`. Mutually exclusive
19219
19227
  * with `creatives[]`.
19220
19228
  *
19229
+ * The attached ad takes the full single-creative surface:
19230
+ * `headline`/`body`/`description`/`callToAction` plus either
19231
+ * `imageUrl`/`video` OR `placementAssets` (its own per-placement
19232
+ * Feed/Story assets), and `leadGenFormId` when the target is a
19233
+ * lead ad set (the parent must be ON_AD — true for ad sets
19234
+ * created via goal `lead_generation`; Meta rejects a formless ad
19235
+ * there, so pass the form on EVERY attached ad). This is the way
19236
+ * to build N full ads sharing one ad set: create the first ad
19237
+ * via the normal shape, then attach the rest one call each.
19238
+ *
19221
19239
  * Supported on Meta (facebook, instagram) and TikTok. On TikTok
19222
19240
  * the `adSetId` is the ad group ID; the new ad inherits the
19223
19241
  * ad group's bid + budget + targeting.
@@ -19442,8 +19460,11 @@ export type CreateStandaloneAdData = {
19442
19460
  * each placement group on a SINGLE ad (e.g. a 9:16 on Stories/Reels and a 4:5 on Feed).
19443
19461
  * The same thing Meta Ads Manager produces with "different creative per placement",
19444
19462
  * mapped to the creative's `asset_feed_spec` + `asset_customization_rules`. Deterministic
19445
- * pinning, NOT the auto-optimizing pool of `dynamicCreative` (mutually exclusive, and it
19446
- * cannot be combined with `creatives[]` or `adSetId`). Shared copy (headline, body, link,
19463
+ * pinning, NOT the auto-optimizing pool of `dynamicCreative` (mutually exclusive). Works
19464
+ * on the legacy single shape AND the attach shape (`adSetId` + placementAssets adds one
19465
+ * placement-customized ad to an existing ad set — the way to build N per-placement ads
19466
+ * sharing one ad set: create the first normally, attach the rest). Cannot be combined
19467
+ * with `creatives[]`. Shared copy (headline, body, link,
19447
19468
  * CTA) comes from the top-level single-creative fields since only the asset varies by
19448
19469
  * placement. Each rule's `placements` accepts the same fields as the top-level
19449
19470
  * `placements` object; Meta enforces co-selection rules and returns an actionable error.