late-sdk 0.0.930 → 0.0.931

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.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +0 -2
  3. data/docs/AdCampaignsApi.md +6 -10
  4. data/docs/AdCreative.md +0 -4
  5. data/docs/AdCreativesApi.md +1 -1
  6. data/docs/BoostPostRequest.md +1 -1
  7. data/docs/CreateAdCreative201Response.md +1 -5
  8. data/docs/CreateAdCreativeRequest.md +2 -2
  9. data/docs/CreateStandaloneAdRequest.md +2 -2
  10. data/docs/CreateStandaloneAdRequestCreativesInner.md +0 -2
  11. data/docs/UpdateAdRequestCreative.md +2 -2
  12. data/lib/zernio-sdk/api/ad_campaigns_api.rb +4 -7
  13. data/lib/zernio-sdk/api/ad_creatives_api.rb +2 -2
  14. data/lib/zernio-sdk/models/ad_creative.rb +1 -42
  15. data/lib/zernio-sdk/models/boost_post_request.rb +1 -1
  16. data/lib/zernio-sdk/models/create_ad_creative201_response.rb +4 -44
  17. data/lib/zernio-sdk/models/create_ad_creative_request.rb +3 -2
  18. data/lib/zernio-sdk/models/create_standalone_ad_request.rb +3 -2
  19. data/lib/zernio-sdk/models/create_standalone_ad_request_creatives_inner.rb +1 -11
  20. data/lib/zernio-sdk/models/update_ad_request_creative.rb +4 -3
  21. data/lib/zernio-sdk/version.rb +1 -1
  22. data/lib/zernio-sdk.rb +0 -2
  23. data/openapi.yaml +27 -71
  24. data/spec/api/ad_campaigns_api_spec.rb +2 -3
  25. data/spec/api/ad_creatives_api_spec.rb +1 -1
  26. data/spec/models/ad_creative_spec.rb +0 -12
  27. data/spec/models/create_ad_creative201_response_spec.rb +0 -12
  28. data/spec/models/create_standalone_ad_request_creatives_inner_spec.rb +0 -6
  29. data/zernio-sdk-0.0.931.gem +0 -0
  30. metadata +2 -10
  31. data/docs/MetaPromotion.md +0 -26
  32. data/docs/MetaPromotionStatus.md +0 -15
  33. data/lib/zernio-sdk/models/meta_promotion.rb +0 -275
  34. data/lib/zernio-sdk/models/meta_promotion_status.rb +0 -41
  35. data/spec/models/meta_promotion_spec.rb +0 -64
  36. data/spec/models/meta_promotion_status_spec.rb +0 -30
  37. data/zernio-sdk-0.0.930.gem +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2f1020934465a40b3d3b9dc7b7b4786998d988b2d2ce98aa64ff49d9a06c12a0
4
- data.tar.gz: 7a6497059af6badc53984f349f6d776a5f4bc69058aa6be8227a5fa852ec8a5e
3
+ metadata.gz: 81bb7c26bf2db4113a5a971d34a6b9328fb4e719b3524a1c243e4065c4fe8c7b
4
+ data.tar.gz: f6a4ed2d3dabde2d4d7926f0b78b80121b9f5c195beb913143c64c965dabf3f0
5
5
  SHA512:
6
- metadata.gz: 50aca6aa491c7549eae8db4eb5891915843056cd864a3f476e53417157d35e6f494a23c3ba781753ce5144012d597956c11aa0fdb118fcab94397cd144df4075
7
- data.tar.gz: ed3b210b3ac2c239d357afaee95d0157a75d1c19405ad873d85015087635ff8179445e1dedd30ef00197a0b68f9002088369fb279bbf47d701fc01bd833e1035
6
+ metadata.gz: 43edf702d34e1db0dd85c5e1532396ab557cdb061267948db4d7b9559b566cc5f8ce3e79b84573240015cd056981a7307ca613c04890a90acc95b3e51803ec2e
7
+ data.tar.gz: a671027d7a8770e94daf2f8a75a0d3c90662af19b9e4d460d17ed97349d4bfc64495e981cfcc9c18314c1d010af9dd10ec64ae61b375dbb64cfc2a9051662503
data/README.md CHANGED
@@ -2037,8 +2037,6 @@ Class | Method | HTTP request | Description
2037
2037
  - [Zernio::MetaInstagramIdentityRef](docs/MetaInstagramIdentityRef.md)
2038
2038
  - [Zernio::MetaLeadFormPlatformData](docs/MetaLeadFormPlatformData.md)
2039
2039
  - [Zernio::MetaLeadFormPlatformDataContextCard](docs/MetaLeadFormPlatformDataContextCard.md)
2040
- - [Zernio::MetaPromotion](docs/MetaPromotion.md)
2041
- - [Zernio::MetaPromotionStatus](docs/MetaPromotionStatus.md)
2042
2040
  - [Zernio::Money](docs/Money.md)
2043
2041
  - [Zernio::MoneyAmount](docs/MoneyAmount.md)
2044
2042
  - [Zernio::MoveAccountToProfile200Response](docs/MoveAccountToProfile200Response.md)
@@ -627,7 +627,7 @@ end
627
627
 
628
628
  Create standalone ad
629
629
 
630
- Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google's minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `promotion` and `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`. An item replaces the whole feature map; its `promotion` replaces the default offer, and `promotion: null` disables that default for the item. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a `promotion` receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect `ad.creative.promotionStatus` (or `ads[].creative.promotionStatus`). `not_returned` means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **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.
630
+ Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google's minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`; an item replaces the whole feature map. `promotion` is not supported on any shape and any object is rejected with 400. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **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.
631
631
 
632
632
  ### Examples
633
633
 
@@ -1130,11 +1130,11 @@ end
1130
1130
 
1131
1131
  ## get_ad
1132
1132
 
1133
- > <GetAd200Response> get_ad(ad_id, opts)
1133
+ > <GetAd200Response> get_ad(ad_id)
1134
1134
 
1135
1135
  Get ad details
1136
1136
 
1137
- Returns an ad with its creative, targeting, status, and performance metrics. Google Search ads include current creative.headlines, creative.descriptions and creative.finalUrls, preserving pinnedField. Top-level cachedAt and stale report cache freshness. Google mutations invalidate this read. RSA enrichment requires a stored advertisingChannelType of SEARCH. Ads with an unknown or other channel return their stored details without a Google read. If RSA enrichment fails, the stored ad is returned with HTTP 200 and without cache metadata. The `{adId}` path segment accepts any identifier dialect Zernio indexes for the ad: - the Zernio internal `_id` (24-char hex) - Meta's numeric `platformAdId` (the value shipped in `comment.received` webhooks as `comment.ad.id`) - the creative's `effective_object_story_id` (`{pageId}_{postId}` shape, Facebook side) - the creative's `effective_instagram_media_id` (Instagram side) Any of the four resolve to the same ad. Caller doesn't need a translation step. By default, creative.promotion and creative.creativeFeatures contain stored requested settings, which do not confirm platform application. With `refreshPromotion=true`, Meta promotion metadata is read live and exposed as `ad.creative.promotion` with `promotionStatus`. Only `applied` confirms an offer; `not_returned` means the creative read succeeded without promotion metadata, and `unavailable` means it failed.
1137
+ Returns an ad with its creative, targeting, status, and performance metrics. Google Search ads include current creative.headlines, creative.descriptions and creative.finalUrls, preserving pinnedField. Top-level cachedAt and stale report cache freshness. Google mutations invalidate this read. RSA enrichment requires a stored advertisingChannelType of SEARCH. Ads with an unknown or other channel return their stored details without a Google read. If RSA enrichment fails, the stored ad is returned with HTTP 200 and without cache metadata. The `{adId}` path segment accepts any identifier dialect Zernio indexes for the ad: - the Zernio internal `_id` (24-char hex) - Meta's numeric `platformAdId` (the value shipped in `comment.received` webhooks as `comment.ad.id`) - the creative's `effective_object_story_id` (`{pageId}_{postId}` shape, Facebook side) - the creative's `effective_instagram_media_id` (Instagram side) Any of the four resolve to the same ad. Caller doesn't need a translation step. `creative.creativeFeatures` holds the stored requested settings, which do not confirm platform application.
1138
1138
 
1139
1139
  ### Examples
1140
1140
 
@@ -1149,13 +1149,10 @@ end
1149
1149
 
1150
1150
  api_instance = Zernio::AdCampaignsApi.new
1151
1151
  ad_id = 'ad_id_example' # String | Zernio `_id` (hex), Meta `platformAdId` (numeric), or one of the creative's effective story/media IDs. See description for details.
1152
- opts = {
1153
- refresh_promotion: true # Boolean | Meta only. Read current promotion metadata from Meta and include promotionStatus. Omit for stored creative settings with no promotion-specific Graph call.
1154
- }
1155
1152
 
1156
1153
  begin
1157
1154
  # Get ad details
1158
- result = api_instance.get_ad(ad_id, opts)
1155
+ result = api_instance.get_ad(ad_id)
1159
1156
  p result
1160
1157
  rescue Zernio::ApiError => e
1161
1158
  puts "Error when calling AdCampaignsApi->get_ad: #{e}"
@@ -1166,12 +1163,12 @@ end
1166
1163
 
1167
1164
  This returns an Array which contains the response data, status code and headers.
1168
1165
 
1169
- > <Array(<GetAd200Response>, Integer, Hash)> get_ad_with_http_info(ad_id, opts)
1166
+ > <Array(<GetAd200Response>, Integer, Hash)> get_ad_with_http_info(ad_id)
1170
1167
 
1171
1168
  ```ruby
1172
1169
  begin
1173
1170
  # Get ad details
1174
- data, status_code, headers = api_instance.get_ad_with_http_info(ad_id, opts)
1171
+ data, status_code, headers = api_instance.get_ad_with_http_info(ad_id)
1175
1172
  p status_code # => 2xx
1176
1173
  p headers # => { ... }
1177
1174
  p data # => <GetAd200Response>
@@ -1185,7 +1182,6 @@ end
1185
1182
  | Name | Type | Description | Notes |
1186
1183
  | ---- | ---- | ----------- | ----- |
1187
1184
  | **ad_id** | **String** | Zernio &#x60;_id&#x60; (hex), Meta &#x60;platformAdId&#x60; (numeric), or one of the creative&#39;s effective story/media IDs. See description for details. | |
1188
- | **refresh_promotion** | **Boolean** | Meta only. Read current promotion metadata from Meta and include promotionStatus. Omit for stored creative settings with no promotion-specific Graph call. | [optional][default to false] |
1189
1185
 
1190
1186
  ### Return type
1191
1187
 
data/docs/AdCreative.md CHANGED
@@ -13,8 +13,6 @@
13
13
  | **image_url** | **String** | Alternative image URL | [optional] |
14
14
  | **video_id** | **String** | Meta video ID for VIDEO-type ads. Null for non-video ads. Callers that need an embeddable MP4 can call GET /{videoId}?fields&#x3D;source with the page access token. | [optional] |
15
15
  | **video_url** | **String** | Public Facebook watch URL for VIDEO-type ads (https://www.facebook.com/watch/?v&#x3D;{videoId}). Null for non-video ads. | [optional] |
16
- | **promotion** | [**MetaPromotion**](MetaPromotion.md) | Meta offer read from the live creative on creation or GET /v1/ads/{adId}. Null when metadata is not returned or cannot be read. Requested values are never echoed as applied. | [optional] |
17
- | **promotion_status** | [**MetaPromotionStatus**](MetaPromotionStatus.md) | | [optional] |
18
16
  | **creative_id** | **String** | Meta ad creative id backing this ad. Reusable via existingCreativeId on POST /v1/ads/create. | [optional] |
19
17
  | **object_type** | **String** | Meta creative object_type (e.g. SHARE, VIDEO, PRIVACY_CHECK_FAIL, POST_DELETED). Use this to render state-aware previews: when Meta moderation strips image/video fields, only thumbnailUrl at 64x64 is available. | [optional] |
20
18
  | **object_story_id** | **String** | Meta creative &#x60;object_story_id&#x60; (the SHARE reference). Frequently absent, because Meta omits it for SHARE creatives. Use effectiveObjectStoryId instead. | [optional] |
@@ -50,8 +48,6 @@ instance = Zernio::AdCreative.new(
50
48
  image_url: null,
51
49
  video_id: null,
52
50
  video_url: null,
53
- promotion: null,
54
- promotion_status: null,
55
51
  creative_id: null,
56
52
  object_type: null,
57
53
  object_story_id: null,
@@ -30,7 +30,7 @@ All URIs are relative to *https://zernio.com/api*
30
30
 
31
31
  Create a standalone creative
32
32
 
33
- Creates a creative in the library WITHOUT an ad, reusable on the create endpoints via `existingCreativeId`. Provide exactly one of `imageUrl` (uploaded server-side), `imageHash` (from POST /v1/ads/images or the library list), or `carouselCards` (2-10 hand-built cards). The Page (and linked Instagram account, when present) is resolved from `accountId` as the story actor. `promotion` configures an explicit offer separately from Advantage+ `creativeFeatures`. Only when `promotion` is supplied does the response read the creative back from Meta; `promotionStatus: not_returned` means Meta accepted creation but omitted promotion metadata, so the requested offer is not confirmed as applied.
33
+ Creates a creative in the library WITHOUT an ad, reusable on the create endpoints via `existingCreativeId`. Provide exactly one of `imageUrl` (uploaded server-side), `imageHash` (from POST /v1/ads/images or the library list), or `carouselCards` (2-10 hand-built cards). The Page (and linked Instagram account, when present) is resolved from `accountId` as the story actor. `creativeFeatures` configures Advantage+ enhancements. `promotion` is not supported and any object is rejected with 400.
34
34
 
35
35
  ### Examples
36
36
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  | Name | Type | Description | Notes |
6
6
  | ---- | ---- | ----------- | ----- |
7
- | **creative_features** | **Hash&lt;String, String&gt;** | Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT. auto_promotion_tag is an enhancement; use the separate promotion field for an explicit offer. The deprecated standard_enhancements bundle is rejected by Meta. | [optional] |
7
+ | **creative_features** | **Hash&lt;String, String&gt;** | Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT. auto_promotion_tag is an Advantage+ enhancement, not the Ads Manager Promotion setting. The deprecated standard_enhancements bundle is rejected by Meta. | [optional] |
8
8
  | **post_id** | **String** | Zernio post ID (provide this or platformPostId) | [optional] |
9
9
  | **platform_post_id** | **String** | Platform post ID (alternative to postId) | [optional] |
10
10
  | **account_id** | **String** | Account ID | |
@@ -6,8 +6,6 @@
6
6
  | ---- | ---- | ----------- | ----- |
7
7
  | **ad_account_id** | **String** | | [optional] |
8
8
  | **creative_id** | **String** | Platform creative id, reusable via existingCreativeId. | [optional] |
9
- | **promotion** | [**MetaPromotion**](MetaPromotion.md) | | [optional] |
10
- | **promotion_status** | [**MetaPromotionStatus**](MetaPromotionStatus.md) | | [optional] |
11
9
 
12
10
  ## Example
13
11
 
@@ -16,9 +14,7 @@ require 'zernio-sdk'
16
14
 
17
15
  instance = Zernio::CreateAdCreative201Response.new(
18
16
  ad_account_id: null,
19
- creative_id: null,
20
- promotion: null,
21
- promotion_status: null
17
+ creative_id: null
22
18
  )
23
19
  ```
24
20
 
@@ -15,8 +15,8 @@
15
15
  | **image_hash** | **String** | Existing library image hash (POST /v1/ads/images or GET /v1/ads/images). | [optional] |
16
16
  | **carousel_cards** | [**Array&lt;CreateAdCreativeRequestCarouselCardsInner&gt;**](CreateAdCreativeRequestCarouselCardsInner.md) | | [optional] |
17
17
  | **url_tags** | **String** | Appended to every outbound URL (e.g. utm_source&#x3D;fb). | [optional] |
18
- | **promotion** | [**MetaPromotion**](MetaPromotion.md) | | [optional] |
19
- | **creative_features** | **Hash&lt;String, String&gt;** | Meta only. Applied to each new creative, including standalone and attach shapes. With creatives[], these are defaults; an item replaces the whole feature map, including an empty map. auto_promotion_tag is an enhancement; an explicit offer uses promotion. | [optional] |
18
+ | **promotion** | [**Null**](Null.md) | Not supported. Meta validates creative_sourcing_spec.promotion_metadata_spec on the create call and then discards it, so a Promotion set through the Marketing API never reaches the creative. Any object is rejected with 400 invalid_field_value. Send null or omit the field, and set the Promotion on the ad in Ads Manager. Verified on 2026-09-11 across Graph v19.0 to v25.0 and every write path. | [optional] |
19
+ | **creative_features** | **Hash&lt;String, String&gt;** | Meta only. Applied to each new creative, including standalone and attach shapes. With creatives[], these are defaults; an item replaces the whole feature map, including an empty map. auto_promotion_tag is an Advantage+ enhancement, not the Ads Manager Promotion setting. | [optional] |
20
20
  | **multi_advertiser** | **String** | Meta only. Multi-advertiser ads: whether Meta may show this ad alongside other advertisers&#39; in one unit. Meta auto-enrols since Aug 2024, so send OPT_OUT to leave. It is a top-level creative field, NOT a &#x60;creativeFeatures&#x60; key, and Meta rejects it there. | [optional] |
21
21
 
22
22
  ## Example
@@ -16,8 +16,8 @@
16
16
  | **billing_event** | **String** | Meta only. Explicit ad-set &#x60;billing_event&#x60;. Defaults to &#x60;IMPRESSIONS&#x60;. Forwarded verbatim to Meta, which validates compatibility with the optimization goal. | [optional] |
17
17
  | **buying_type** | **String** | Meta only. Defaults to AUCTION and is explicitly sent on new campaigns, including validateOnly. Reusing existingCampaignId does not change the campaign. RESERVED &#x3D; Reach &amp; Frequency: requires &#x60;rfPredictionId&#x60; (a RESERVED prediction from /v1/ads/rf-predictions + /reserve). Budget, schedule and pricing come from the reservation, so budgetAmount/budgetType are not required and bid fields are ignored. Only the plain single-ad shape (no creatives[], adSetId, existingCampaignId or dynamicCreative). | [optional][default to &#39;AUCTION&#39;] |
18
18
  | **rf_prediction_id** | **String** | Meta only. The RESERVED prediction id the R&amp;F ad set runs on (reserving mints a new id, so pass that one). Requires buyingType RESERVED. | [optional] |
19
- | **promotion** | [**MetaPromotion**](MetaPromotion.md) | | [optional] |
20
- | **creative_features** | **Hash&lt;String, String&gt;** | Meta only. Applied to each new creative, including standalone and attach shapes. With creatives[], these are defaults; an item replaces the whole feature map, including an empty map. auto_promotion_tag is an enhancement; an explicit offer uses promotion. | [optional] |
19
+ | **promotion** | [**Null**](Null.md) | Not supported. Meta validates creative_sourcing_spec.promotion_metadata_spec on the create call and then discards it, so a Promotion set through the Marketing API never reaches the creative. Any object is rejected with 400 invalid_field_value. Send null or omit the field, and set the Promotion on the ad in Ads Manager. Verified on 2026-09-11 across Graph v19.0 to v25.0 and every write path. | [optional] |
20
+ | **creative_features** | **Hash&lt;String, String&gt;** | Meta only. Applied to each new creative, including standalone and attach shapes. With creatives[], these are defaults; an item replaces the whole feature map, including an empty map. auto_promotion_tag is an Advantage+ enhancement, not the Ads Manager Promotion setting. | [optional] |
21
21
  | **multi_advertiser** | **String** | Meta only. Multi-advertiser ads: whether Meta may show this ad alongside other advertisers&#39; in one unit. Meta auto-enrols since Aug 2024, so send OPT_OUT to leave. It is a top-level creative field, NOT a &#x60;creativeFeatures&#x60; key, and Meta rejects it there. | [optional] |
22
22
  | **validate_only** | **Boolean** | Google Performance Max validates the complete atomic campaign and asset group with no resource creation or local persistence. Google validation still downloads image URLs and consumes quota. On Meta, validates the complete inline campaign, ad set, creative and ad with execution_options validate_only. Nothing is uploaded or created, and validation bypasses Idempotency-Key storage. Supports a single image, all-image placementAssets with per-rule copy, existing video.id or existingCreativeId; other media pools, new video uploads, creatives[], adSetId and RESERVED buying return 400. Placement validation uses existing Instagram identities only. Existing campaign or creative nodes are marked skipped. Success returns 200 with per-node results; Meta rejection returns an error. | [optional] |
23
23
  | **budget_amount** | **Float** | Budget in WHOLE currency units (USD: 50 &#x3D; $50.00), NOT cents. Meta&#39;s own Marketing API takes this same number in minor units, so it is an easy and expensive mix-up. Required on legacy, multi-creative and Performance Max shapes. Inherited on attach. OpenAI Ads requires a $1 minimum (its budget is lifetime-only, see budgetType). | [optional] |
@@ -4,7 +4,6 @@
4
4
 
5
5
  | Name | Type | Description | Notes |
6
6
  | ---- | ---- | ----------- | ----- |
7
- | **promotion** | [**MetaPromotion**](MetaPromotion.md) | Overrides the top-level offer for this item. Omit to inherit; null disables the inherited offer. | [optional] |
8
7
  | **creative_features** | **Hash&lt;String, String&gt;** | Replaces the entire top-level creativeFeatures map for this item. Omit to inherit; an empty map clears these defaults. | [optional] |
9
8
  | **name** | **String** | Exact name for this ad. Falls back to &#x60;&lt;name&gt; #N&#x60; (N &#x3D; 1-based position). | [optional] |
10
9
  | **headline** | **String** | | |
@@ -21,7 +20,6 @@
21
20
  require 'zernio-sdk'
22
21
 
23
22
  instance = Zernio::CreateStandaloneAdRequestCreativesInner.new(
24
- promotion: null,
25
23
  creative_features: {auto_promotion_tag&#x3D;OPT_IN},
26
24
  name: null,
27
25
  headline: null,
@@ -4,8 +4,8 @@
4
4
 
5
5
  | Name | Type | Description | Notes |
6
6
  | ---- | ---- | ----------- | ----- |
7
- | **promotion** | [**MetaPromotion**](MetaPromotion.md) | | [optional] |
8
- | **creative_features** | **Hash&lt;String, String&gt;** | Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT. auto_promotion_tag is an enhancement; use the separate promotion field for an explicit offer. The deprecated standard_enhancements bundle is rejected by Meta. | [optional] |
7
+ | **promotion** | [**Null**](Null.md) | Not supported. Meta validates creative_sourcing_spec.promotion_metadata_spec on the create call and then discards it, so a Promotion set through the Marketing API never reaches the creative. Any object is rejected with 400 invalid_field_value. Send null or omit the field, and set the Promotion on the ad in Ads Manager. Verified on 2026-09-11 across Graph v19.0 to v25.0 and every write path. | [optional] |
8
+ | **creative_features** | **Hash&lt;String, String&gt;** | Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT. auto_promotion_tag is an Advantage+ enhancement, not the Ads Manager Promotion setting. The deprecated standard_enhancements bundle is rejected by Meta. | [optional] |
9
9
  | **headline** | **String** | Meta and LinkedIn (TikTok has no headline slot) | [optional] |
10
10
  | **long_headline** | **String** | Google Display only. Replaces the responsive display ad&#39;s long headline. | [optional] |
11
11
  | **business_name** | **String** | Google Display only. Replaces the responsive display ad&#39;s business name. | [optional] |
@@ -607,7 +607,7 @@ module Zernio
607
607
  end
608
608
 
609
609
  # Create standalone ad
610
- # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google's minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `promotion` and `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`. An item replaces the whole feature map; its `promotion` replaces the default offer, and `promotion: null` disables that default for the item. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a `promotion` receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect `ad.creative.promotionStatus` (or `ads[].creative.promotionStatus`). `not_returned` means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **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.
610
+ # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google's minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`; an item replaces the whole feature map. `promotion` is not supported on any shape and any object is rejected with 400. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **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.
611
611
  # @param create_standalone_ad_request [CreateStandaloneAdRequest]
612
612
  # @param [Hash] opts the optional parameters
613
613
  # @option opts [String] :idempotency_key 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.
@@ -618,7 +618,7 @@ module Zernio
618
618
  end
619
619
 
620
620
  # Create standalone ad
621
- # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set &#x60;campaignType: \&quot;pmax\&quot;&#x60; and supply &#x60;assetGroup&#x60; with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. &#x60;validateOnly: true&#x60; validates the complete request with Google without creating or persisting resources. Read assets with &#x60;GET /v1/ads/campaigns/{campaignId}/asset-groups&#x60;. The logo is required; video is optional via &#x60;assetGroup.youtubeVideoId&#x60;. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google&#39;s minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts &#x60;promotion&#x60; and &#x60;creativeFeatures&#x60; on the single and attach shapes and as defaults for &#x60;creatives[]&#x60;. An item replaces the whole feature map; its &#x60;promotion&#x60; replaces the default offer, and &#x60;promotion: null&#x60; disables that default for the item. Reusing &#x60;existingCreativeId&#x60; uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a &#x60;promotion&#x60; receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect &#x60;ad.creative.promotionStatus&#x60; (or &#x60;ads[].creative.promotionStatus&#x60;). &#x60;not_returned&#x60; means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \&quot;dark post\&quot; authored by a Company Page (see &#x60;organizationId&#x60;). Supported goals are engagement, traffic, awareness, and video_views (video ads use the &#x60;video&#x60; field; video_views requires a video), and traffic ads require &#x60;linkUrl&#x60;. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an &#x60;Idempotency-Key&#x60; 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 &#x60;Idempotent-Replayed: true&#x60;) 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.
621
+ # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set &#x60;campaignType: \&quot;pmax\&quot;&#x60; and supply &#x60;assetGroup&#x60; with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. &#x60;validateOnly: true&#x60; validates the complete request with Google without creating or persisting resources. Read assets with &#x60;GET /v1/ads/campaigns/{campaignId}/asset-groups&#x60;. The logo is required; video is optional via &#x60;assetGroup.youtubeVideoId&#x60;. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google&#39;s minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts &#x60;creativeFeatures&#x60; on the single and attach shapes and as defaults for &#x60;creatives[]&#x60;; an item replaces the whole feature map. &#x60;promotion&#x60; is not supported on any shape and any object is rejected with 400. Reusing &#x60;existingCreativeId&#x60; uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \&quot;dark post\&quot; authored by a Company Page (see &#x60;organizationId&#x60;). Supported goals are engagement, traffic, awareness, and video_views (video ads use the &#x60;video&#x60; field; video_views requires a video), and traffic ads require &#x60;linkUrl&#x60;. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an &#x60;Idempotency-Key&#x60; 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 &#x60;Idempotent-Replayed: true&#x60;) 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.
622
622
  # @param create_standalone_ad_request [CreateStandaloneAdRequest]
623
623
  # @param [Hash] opts the optional parameters
624
624
  # @option opts [String] :idempotency_key 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.
@@ -1121,10 +1121,9 @@ module Zernio
1121
1121
  end
1122
1122
 
1123
1123
  # Get ad details
1124
- # Returns an ad with its creative, targeting, status, and performance metrics. Google Search ads include current creative.headlines, creative.descriptions and creative.finalUrls, preserving pinnedField. Top-level cachedAt and stale report cache freshness. Google mutations invalidate this read. RSA enrichment requires a stored advertisingChannelType of SEARCH. Ads with an unknown or other channel return their stored details without a Google read. If RSA enrichment fails, the stored ad is returned with HTTP 200 and without cache metadata. The `{adId}` path segment accepts any identifier dialect Zernio indexes for the ad: - the Zernio internal `_id` (24-char hex) - Meta's numeric `platformAdId` (the value shipped in `comment.received` webhooks as `comment.ad.id`) - the creative's `effective_object_story_id` (`{pageId}_{postId}` shape, Facebook side) - the creative's `effective_instagram_media_id` (Instagram side) Any of the four resolve to the same ad. Caller doesn't need a translation step. By default, creative.promotion and creative.creativeFeatures contain stored requested settings, which do not confirm platform application. With `refreshPromotion=true`, Meta promotion metadata is read live and exposed as `ad.creative.promotion` with `promotionStatus`. Only `applied` confirms an offer; `not_returned` means the creative read succeeded without promotion metadata, and `unavailable` means it failed.
1124
+ # Returns an ad with its creative, targeting, status, and performance metrics. Google Search ads include current creative.headlines, creative.descriptions and creative.finalUrls, preserving pinnedField. Top-level cachedAt and stale report cache freshness. Google mutations invalidate this read. RSA enrichment requires a stored advertisingChannelType of SEARCH. Ads with an unknown or other channel return their stored details without a Google read. If RSA enrichment fails, the stored ad is returned with HTTP 200 and without cache metadata. The `{adId}` path segment accepts any identifier dialect Zernio indexes for the ad: - the Zernio internal `_id` (24-char hex) - Meta's numeric `platformAdId` (the value shipped in `comment.received` webhooks as `comment.ad.id`) - the creative's `effective_object_story_id` (`{pageId}_{postId}` shape, Facebook side) - the creative's `effective_instagram_media_id` (Instagram side) Any of the four resolve to the same ad. Caller doesn't need a translation step. `creative.creativeFeatures` holds the stored requested settings, which do not confirm platform application.
1125
1125
  # @param ad_id [String] Zernio &#x60;_id&#x60; (hex), Meta &#x60;platformAdId&#x60; (numeric), or one of the creative&#39;s effective story/media IDs. See description for details.
1126
1126
  # @param [Hash] opts the optional parameters
1127
- # @option opts [Boolean] :refresh_promotion Meta only. Read current promotion metadata from Meta and include promotionStatus. Omit for stored creative settings with no promotion-specific Graph call. (default to false)
1128
1127
  # @return [GetAd200Response]
1129
1128
  def get_ad(ad_id, opts = {})
1130
1129
  data, _status_code, _headers = get_ad_with_http_info(ad_id, opts)
@@ -1132,10 +1131,9 @@ module Zernio
1132
1131
  end
1133
1132
 
1134
1133
  # Get ad details
1135
- # Returns an ad with its creative, targeting, status, and performance metrics. Google Search ads include current creative.headlines, creative.descriptions and creative.finalUrls, preserving pinnedField. Top-level cachedAt and stale report cache freshness. Google mutations invalidate this read. RSA enrichment requires a stored advertisingChannelType of SEARCH. Ads with an unknown or other channel return their stored details without a Google read. If RSA enrichment fails, the stored ad is returned with HTTP 200 and without cache metadata. The &#x60;{adId}&#x60; path segment accepts any identifier dialect Zernio indexes for the ad: - the Zernio internal &#x60;_id&#x60; (24-char hex) - Meta&#39;s numeric &#x60;platformAdId&#x60; (the value shipped in &#x60;comment.received&#x60; webhooks as &#x60;comment.ad.id&#x60;) - the creative&#39;s &#x60;effective_object_story_id&#x60; (&#x60;{pageId}_{postId}&#x60; shape, Facebook side) - the creative&#39;s &#x60;effective_instagram_media_id&#x60; (Instagram side) Any of the four resolve to the same ad. Caller doesn&#39;t need a translation step. By default, creative.promotion and creative.creativeFeatures contain stored requested settings, which do not confirm platform application. With &#x60;refreshPromotion&#x3D;true&#x60;, Meta promotion metadata is read live and exposed as &#x60;ad.creative.promotion&#x60; with &#x60;promotionStatus&#x60;. Only &#x60;applied&#x60; confirms an offer; &#x60;not_returned&#x60; means the creative read succeeded without promotion metadata, and &#x60;unavailable&#x60; means it failed.
1134
+ # Returns an ad with its creative, targeting, status, and performance metrics. Google Search ads include current creative.headlines, creative.descriptions and creative.finalUrls, preserving pinnedField. Top-level cachedAt and stale report cache freshness. Google mutations invalidate this read. RSA enrichment requires a stored advertisingChannelType of SEARCH. Ads with an unknown or other channel return their stored details without a Google read. If RSA enrichment fails, the stored ad is returned with HTTP 200 and without cache metadata. The &#x60;{adId}&#x60; path segment accepts any identifier dialect Zernio indexes for the ad: - the Zernio internal &#x60;_id&#x60; (24-char hex) - Meta&#39;s numeric &#x60;platformAdId&#x60; (the value shipped in &#x60;comment.received&#x60; webhooks as &#x60;comment.ad.id&#x60;) - the creative&#39;s &#x60;effective_object_story_id&#x60; (&#x60;{pageId}_{postId}&#x60; shape, Facebook side) - the creative&#39;s &#x60;effective_instagram_media_id&#x60; (Instagram side) Any of the four resolve to the same ad. Caller doesn&#39;t need a translation step. &#x60;creative.creativeFeatures&#x60; holds the stored requested settings, which do not confirm platform application.
1136
1135
  # @param ad_id [String] Zernio &#x60;_id&#x60; (hex), Meta &#x60;platformAdId&#x60; (numeric), or one of the creative&#39;s effective story/media IDs. See description for details.
1137
1136
  # @param [Hash] opts the optional parameters
1138
- # @option opts [Boolean] :refresh_promotion Meta only. Read current promotion metadata from Meta and include promotionStatus. Omit for stored creative settings with no promotion-specific Graph call. (default to false)
1139
1137
  # @return [Array<(GetAd200Response, Integer, Hash)>] GetAd200Response data, response status code and response headers
1140
1138
  def get_ad_with_http_info(ad_id, opts = {})
1141
1139
  if @api_client.config.debugging
@@ -1150,7 +1148,6 @@ module Zernio
1150
1148
 
1151
1149
  # query parameters
1152
1150
  query_params = opts[:query_params] || {}
1153
- query_params[:'refreshPromotion'] = opts[:'refresh_promotion'] if !opts[:'refresh_promotion'].nil?
1154
1151
 
1155
1152
  # header parameters
1156
1153
  header_params = opts[:header_params] || {}
@@ -20,7 +20,7 @@ module Zernio
20
20
  @api_client = api_client
21
21
  end
22
22
  # Create a standalone creative
23
- # Creates a creative in the library WITHOUT an ad, reusable on the create endpoints via `existingCreativeId`. Provide exactly one of `imageUrl` (uploaded server-side), `imageHash` (from POST /v1/ads/images or the library list), or `carouselCards` (2-10 hand-built cards). The Page (and linked Instagram account, when present) is resolved from `accountId` as the story actor. `promotion` configures an explicit offer separately from Advantage+ `creativeFeatures`. Only when `promotion` is supplied does the response read the creative back from Meta; `promotionStatus: not_returned` means Meta accepted creation but omitted promotion metadata, so the requested offer is not confirmed as applied.
23
+ # Creates a creative in the library WITHOUT an ad, reusable on the create endpoints via `existingCreativeId`. Provide exactly one of `imageUrl` (uploaded server-side), `imageHash` (from POST /v1/ads/images or the library list), or `carouselCards` (2-10 hand-built cards). The Page (and linked Instagram account, when present) is resolved from `accountId` as the story actor. `creativeFeatures` configures Advantage+ enhancements. `promotion` is not supported and any object is rejected with 400.
24
24
  # @param create_ad_creative_request [CreateAdCreativeRequest]
25
25
  # @param [Hash] opts the optional parameters
26
26
  # @return [CreateAdCreative201Response]
@@ -30,7 +30,7 @@ module Zernio
30
30
  end
31
31
 
32
32
  # Create a standalone creative
33
- # Creates a creative in the library WITHOUT an ad, reusable on the create endpoints via &#x60;existingCreativeId&#x60;. Provide exactly one of &#x60;imageUrl&#x60; (uploaded server-side), &#x60;imageHash&#x60; (from POST /v1/ads/images or the library list), or &#x60;carouselCards&#x60; (2-10 hand-built cards). The Page (and linked Instagram account, when present) is resolved from &#x60;accountId&#x60; as the story actor. &#x60;promotion&#x60; configures an explicit offer separately from Advantage+ &#x60;creativeFeatures&#x60;. Only when &#x60;promotion&#x60; is supplied does the response read the creative back from Meta; &#x60;promotionStatus: not_returned&#x60; means Meta accepted creation but omitted promotion metadata, so the requested offer is not confirmed as applied.
33
+ # Creates a creative in the library WITHOUT an ad, reusable on the create endpoints via &#x60;existingCreativeId&#x60;. Provide exactly one of &#x60;imageUrl&#x60; (uploaded server-side), &#x60;imageHash&#x60; (from POST /v1/ads/images or the library list), or &#x60;carouselCards&#x60; (2-10 hand-built cards). The Page (and linked Instagram account, when present) is resolved from &#x60;accountId&#x60; as the story actor. &#x60;creativeFeatures&#x60; configures Advantage+ enhancements. &#x60;promotion&#x60; is not supported and any object is rejected with 400.
34
34
  # @param create_ad_creative_request [CreateAdCreativeRequest]
35
35
  # @param [Hash] opts the optional parameters
36
36
  # @return [Array<(CreateAdCreative201Response, Integer, Hash)>] CreateAdCreative201Response data, response status code and response headers
@@ -43,11 +43,6 @@ module Zernio
43
43
  # Public Facebook watch URL for VIDEO-type ads (https://www.facebook.com/watch/?v={videoId}). Null for non-video ads.
44
44
  attr_accessor :video_url
45
45
 
46
- # Meta offer read from the live creative on creation or GET /v1/ads/{adId}. Null when metadata is not returned or cannot be read. Requested values are never echoed as applied.
47
- attr_accessor :promotion
48
-
49
- attr_accessor :promotion_status
50
-
51
46
  # Meta ad creative id backing this ad. Reusable via existingCreativeId on POST /v1/ads/create.
52
47
  attr_accessor :creative_id
53
48
 
@@ -102,28 +97,6 @@ module Zernio
102
97
 
103
98
  attr_accessor :pinterest_description
104
99
 
105
- class EnumAttributeValidator
106
- attr_reader :datatype
107
- attr_reader :allowable_values
108
-
109
- def initialize(datatype, allowable_values)
110
- @allowable_values = allowable_values.map do |value|
111
- case datatype.to_s
112
- when /Integer/i
113
- value.to_i
114
- when /Float/i
115
- value.to_f
116
- else
117
- value
118
- end
119
- end
120
- end
121
-
122
- def valid?(value)
123
- !value || allowable_values.include?(value)
124
- end
125
- end
126
-
127
100
  # Attribute mapping from ruby-style variable name to JSON key.
128
101
  def self.attribute_map
129
102
  {
@@ -136,8 +109,6 @@ module Zernio
136
109
  :'image_url' => :'imageUrl',
137
110
  :'video_id' => :'videoId',
138
111
  :'video_url' => :'videoUrl',
139
- :'promotion' => :'promotion',
140
- :'promotion_status' => :'promotionStatus',
141
112
  :'creative_id' => :'creativeId',
142
113
  :'object_type' => :'objectType',
143
114
  :'object_story_id' => :'objectStoryId',
@@ -182,8 +153,6 @@ module Zernio
182
153
  :'image_url' => :'String',
183
154
  :'video_id' => :'String',
184
155
  :'video_url' => :'String',
185
- :'promotion' => :'MetaPromotion',
186
- :'promotion_status' => :'MetaPromotionStatus',
187
156
  :'creative_id' => :'String',
188
157
  :'object_type' => :'String',
189
158
  :'object_story_id' => :'String',
@@ -281,14 +250,6 @@ module Zernio
281
250
  self.video_url = attributes[:'video_url']
282
251
  end
283
252
 
284
- if attributes.key?(:'promotion')
285
- self.promotion = attributes[:'promotion']
286
- end
287
-
288
- if attributes.key?(:'promotion_status')
289
- self.promotion_status = attributes[:'promotion_status']
290
- end
291
-
292
253
  if attributes.key?(:'creative_id')
293
254
  self.creative_id = attributes[:'creative_id']
294
255
  end
@@ -474,8 +435,6 @@ module Zernio
474
435
  image_url == o.image_url &&
475
436
  video_id == o.video_id &&
476
437
  video_url == o.video_url &&
477
- promotion == o.promotion &&
478
- promotion_status == o.promotion_status &&
479
438
  creative_id == o.creative_id &&
480
439
  object_type == o.object_type &&
481
440
  object_story_id == o.object_story_id &&
@@ -506,7 +465,7 @@ module Zernio
506
465
  # Calculates hash code according to all attributes.
507
466
  # @return [Integer] Hash code
508
467
  def hash
509
- [asset_group, asset_group_resource_name, headlines, descriptions, final_urls, thumbnail_url, image_url, video_id, video_url, promotion, promotion_status, creative_id, object_type, object_story_id, effective_object_story_id, page_id, effective_instagram_media_id, instagram_user_id, instagram_permalink_url, media_urls, is_serving, serving_hold_reasons, body, google_headline, google_description, link_url, whatsapp_phone_number, pinterest_image_url, pinterest_title, pinterest_description].hash
468
+ [asset_group, asset_group_resource_name, headlines, descriptions, final_urls, thumbnail_url, image_url, video_id, video_url, creative_id, object_type, object_story_id, effective_object_story_id, page_id, effective_instagram_media_id, instagram_user_id, instagram_permalink_url, media_urls, is_serving, serving_hold_reasons, body, google_headline, google_description, link_url, whatsapp_phone_number, pinterest_image_url, pinterest_title, pinterest_description].hash
510
469
  end
511
470
 
512
471
  # Builds the object from hash
@@ -15,7 +15,7 @@ require 'time'
15
15
 
16
16
  module Zernio
17
17
  class BoostPostRequest < ApiModelBase
18
- # Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT. auto_promotion_tag is an enhancement; use the separate promotion field for an explicit offer. The deprecated standard_enhancements bundle is rejected by Meta.
18
+ # Meta Advantage+ creative enhancements. Map snake_case feature names to OPT_IN or OPT_OUT; Meta validates supported keys and unspecified features default to OPT_OUT. auto_promotion_tag is an Advantage+ enhancement, not the Ads Manager Promotion setting. The deprecated standard_enhancements bundle is rejected by Meta.
19
19
  attr_accessor :creative_features
20
20
 
21
21
  # Zernio post ID (provide this or platformPostId)
@@ -20,39 +20,11 @@ module Zernio
20
20
  # Platform creative id, reusable via existingCreativeId.
21
21
  attr_accessor :creative_id
22
22
 
23
- attr_accessor :promotion
24
-
25
- attr_accessor :promotion_status
26
-
27
- class EnumAttributeValidator
28
- attr_reader :datatype
29
- attr_reader :allowable_values
30
-
31
- def initialize(datatype, allowable_values)
32
- @allowable_values = allowable_values.map do |value|
33
- case datatype.to_s
34
- when /Integer/i
35
- value.to_i
36
- when /Float/i
37
- value.to_f
38
- else
39
- value
40
- end
41
- end
42
- end
43
-
44
- def valid?(value)
45
- !value || allowable_values.include?(value)
46
- end
47
- end
48
-
49
23
  # Attribute mapping from ruby-style variable name to JSON key.
50
24
  def self.attribute_map
51
25
  {
52
26
  :'ad_account_id' => :'adAccountId',
53
- :'creative_id' => :'creativeId',
54
- :'promotion' => :'promotion',
55
- :'promotion_status' => :'promotionStatus'
27
+ :'creative_id' => :'creativeId'
56
28
  }
57
29
  end
58
30
 
@@ -70,9 +42,7 @@ module Zernio
70
42
  def self.openapi_types
71
43
  {
72
44
  :'ad_account_id' => :'String',
73
- :'creative_id' => :'String',
74
- :'promotion' => :'MetaPromotion',
75
- :'promotion_status' => :'MetaPromotionStatus'
45
+ :'creative_id' => :'String'
76
46
  }
77
47
  end
78
48
 
@@ -105,14 +75,6 @@ module Zernio
105
75
  if attributes.key?(:'creative_id')
106
76
  self.creative_id = attributes[:'creative_id']
107
77
  end
108
-
109
- if attributes.key?(:'promotion')
110
- self.promotion = attributes[:'promotion']
111
- end
112
-
113
- if attributes.key?(:'promotion_status')
114
- self.promotion_status = attributes[:'promotion_status']
115
- end
116
78
  end
117
79
 
118
80
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -136,9 +98,7 @@ module Zernio
136
98
  return true if self.equal?(o)
137
99
  self.class == o.class &&
138
100
  ad_account_id == o.ad_account_id &&
139
- creative_id == o.creative_id &&
140
- promotion == o.promotion &&
141
- promotion_status == o.promotion_status
101
+ creative_id == o.creative_id
142
102
  end
143
103
 
144
104
  # @see the `==` method
@@ -150,7 +110,7 @@ module Zernio
150
110
  # Calculates hash code according to all attributes.
151
111
  # @return [Integer] Hash code
152
112
  def hash
153
- [ad_account_id, creative_id, promotion, promotion_status].hash
113
+ [ad_account_id, creative_id].hash
154
114
  end
155
115
 
156
116
  # Builds the object from hash
@@ -45,9 +45,10 @@ module Zernio
45
45
  # Appended to every outbound URL (e.g. utm_source=fb).
46
46
  attr_accessor :url_tags
47
47
 
48
+ # Not supported. Meta validates creative_sourcing_spec.promotion_metadata_spec on the create call and then discards it, so a Promotion set through the Marketing API never reaches the creative. Any object is rejected with 400 invalid_field_value. Send null or omit the field, and set the Promotion on the ad in Ads Manager. Verified on 2026-09-11 across Graph v19.0 to v25.0 and every write path.
48
49
  attr_accessor :promotion
49
50
 
50
- # Meta only. Applied to each new creative, including standalone and attach shapes. With creatives[], these are defaults; an item replaces the whole feature map, including an empty map. auto_promotion_tag is an enhancement; an explicit offer uses promotion.
51
+ # Meta only. Applied to each new creative, including standalone and attach shapes. With creatives[], these are defaults; an item replaces the whole feature map, including an empty map. auto_promotion_tag is an Advantage+ enhancement, not the Ads Manager Promotion setting.
51
52
  attr_accessor :creative_features
52
53
 
53
54
  # Meta only. Multi-advertiser ads: whether Meta may show this ad alongside other advertisers' in one unit. Meta auto-enrols since Aug 2024, so send OPT_OUT to leave. It is a top-level creative field, NOT a `creativeFeatures` key, and Meta rejects it there.
@@ -119,7 +120,7 @@ module Zernio
119
120
  :'image_hash' => :'String',
120
121
  :'carousel_cards' => :'Array<CreateAdCreativeRequestCarouselCardsInner>',
121
122
  :'url_tags' => :'String',
122
- :'promotion' => :'MetaPromotion',
123
+ :'promotion' => :'Null',
123
124
  :'creative_features' => :'Hash<String, String>',
124
125
  :'multi_advertiser' => :'String'
125
126
  }
@@ -47,9 +47,10 @@ module Zernio
47
47
  # Meta only. The RESERVED prediction id the R&F ad set runs on (reserving mints a new id, so pass that one). Requires buyingType RESERVED.
48
48
  attr_accessor :rf_prediction_id
49
49
 
50
+ # Not supported. Meta validates creative_sourcing_spec.promotion_metadata_spec on the create call and then discards it, so a Promotion set through the Marketing API never reaches the creative. Any object is rejected with 400 invalid_field_value. Send null or omit the field, and set the Promotion on the ad in Ads Manager. Verified on 2026-09-11 across Graph v19.0 to v25.0 and every write path.
50
51
  attr_accessor :promotion
51
52
 
52
- # Meta only. Applied to each new creative, including standalone and attach shapes. With creatives[], these are defaults; an item replaces the whole feature map, including an empty map. auto_promotion_tag is an enhancement; an explicit offer uses promotion.
53
+ # Meta only. Applied to each new creative, including standalone and attach shapes. With creatives[], these are defaults; an item replaces the whole feature map, including an empty map. auto_promotion_tag is an Advantage+ enhancement, not the Ads Manager Promotion setting.
53
54
  attr_accessor :creative_features
54
55
 
55
56
  # Meta only. Multi-advertiser ads: whether Meta may show this ad alongside other advertisers' in one unit. Meta auto-enrols since Aug 2024, so send OPT_OUT to leave. It is a top-level creative field, NOT a `creativeFeatures` key, and Meta rejects it there.
@@ -468,7 +469,7 @@ module Zernio
468
469
  :'billing_event' => :'String',
469
470
  :'buying_type' => :'String',
470
471
  :'rf_prediction_id' => :'String',
471
- :'promotion' => :'MetaPromotion',
472
+ :'promotion' => :'Null',
472
473
  :'creative_features' => :'Hash<String, String>',
473
474
  :'multi_advertiser' => :'String',
474
475
  :'validate_only' => :'Boolean',
@@ -16,9 +16,6 @@ require 'time'
16
16
  module Zernio
17
17
  # Each creative must supply EXACTLY ONE of `imageUrl` (image creative) or `video` (video creative).
18
18
  class CreateStandaloneAdRequestCreativesInner < ApiModelBase
19
- # Overrides the top-level offer for this item. Omit to inherit; null disables the inherited offer.
20
- attr_accessor :promotion
21
-
22
19
  # Replaces the entire top-level creativeFeatures map for this item. Omit to inherit; an empty map clears these defaults.
23
20
  attr_accessor :creative_features
24
21
 
@@ -66,7 +63,6 @@ module Zernio
66
63
  # Attribute mapping from ruby-style variable name to JSON key.
67
64
  def self.attribute_map
68
65
  {
69
- :'promotion' => :'promotion',
70
66
  :'creative_features' => :'creativeFeatures',
71
67
  :'name' => :'name',
72
68
  :'headline' => :'headline',
@@ -92,7 +88,6 @@ module Zernio
92
88
  # Attribute type mapping.
93
89
  def self.openapi_types
94
90
  {
95
- :'promotion' => :'MetaPromotion',
96
91
  :'creative_features' => :'Hash<String, String>',
97
92
  :'name' => :'String',
98
93
  :'headline' => :'String',
@@ -127,10 +122,6 @@ module Zernio
127
122
  h[k.to_sym] = v
128
123
  }
129
124
 
130
- if attributes.key?(:'promotion')
131
- self.promotion = attributes[:'promotion']
132
- end
133
-
134
125
  if attributes.key?(:'creative_features')
135
126
  if (value = attributes[:'creative_features']).is_a?(Hash)
136
127
  self.creative_features = value
@@ -307,7 +298,6 @@ module Zernio
307
298
  def ==(o)
308
299
  return true if self.equal?(o)
309
300
  self.class == o.class &&
310
- promotion == o.promotion &&
311
301
  creative_features == o.creative_features &&
312
302
  name == o.name &&
313
303
  headline == o.headline &&
@@ -328,7 +318,7 @@ module Zernio
328
318
  # Calculates hash code according to all attributes.
329
319
  # @return [Integer] Hash code
330
320
  def hash
331
- [promotion, creative_features, name, headline, body, description, image_url, video, link_url, call_to_action].hash
321
+ [creative_features, name, headline, body, description, image_url, video, link_url, call_to_action].hash
332
322
  end
333
323
 
334
324
  # Builds the object from hash