late-sdk 0.0.637 → 0.0.639

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5ebe1bb31790fb37d31bde9137c5b05e86f723cd3c08c4c9f027aef7bcaaa7cb
4
- data.tar.gz: db336ffe0bdee07a42159925a5285a2813ba8fe7f707ca60fbf5ff3b7d485a14
3
+ metadata.gz: 8a1e52f2fc494ac1d77f85382297c83612bcd8e957b9dc2186d9d35a2cc2ad92
4
+ data.tar.gz: dd09be0c5c864e3fa64571f2386a49c0c373c0446f25507823ed09612606d17b
5
5
  SHA512:
6
- metadata.gz: 9309a47c51d5eeb83953a2c718919e047a3d035d39323a7183ae15d93fcd72a13b6e17a0c3d8580fb536b0d10584b174a4012073b858acaabc5ae337e4e9b3a1
7
- data.tar.gz: 292b6e3da3e3cad95bf85a84ba74021525a16b1bbdd824705b43884e8004d9ab1f2a642800e203743322bcfb3ec089570f25889a0ed761b760a6e88a929899b9
6
+ metadata.gz: 7d127baaef1e5725924e3e0b3b185c9c0461c02c43029ea224cfb3b615e0b064ef0aede0588bafd82638e695b65002a105baf755ec78591037413e8fdf59192d
7
+ data.tar.gz: 75c1561d78e50d3d7c64b9240e3601cc90206509180771f5f01efdd8ebc2b62e15187f5130c1b31e499ba72f9048a265a8ba0e41687aaffac809a760ab55cd33
data/docs/Ad.md CHANGED
@@ -22,11 +22,13 @@
22
22
  | **campaign_name** | **String** | | [optional] |
23
23
  | **ad_set_name** | **String** | | [optional] |
24
24
  | **platform_objective** | **String** | Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC). Only present for Meta ads. | [optional] |
25
- | **optimization_goal** | **String** | Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS). Only present for Meta ads. | [optional] |
25
+ | **optimization_goal** | **String** | What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: - Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS). - LinkedIn: the campaign's EFFECTIVE `optimizationTargetType`, refreshed from LinkedIn on every sync rather than echoing what was passed on create. `NONE` means manual bidding, and it is a real value, not missing data. Auto-bid values are MAX_IMPRESSION / MAX_CLICK / MAX_CONVERSION / MAX_VIDEO_VIEW / MAX_LEAD / MAX_REACH; target-cost values are TARGET_COST_PER_CLICK / TARGET_COST_PER_IMPRESSION / TARGET_COST_PER_VIDEO_VIEW; cost-cap values are the CAP_COST_AND_MAXIMIZE_* family. | [optional] |
26
+ | **cost_type** | **String** | LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. One of `CPM` (cost per thousand impressions), `CPC` (cost per click) or `CPV` (cost per video view). On LinkedIn this is the axis that pairs with `bidAmount`; there is no `bidStrategy`. For campaign type SPONSORED_INMAILS, `CPM` bills as cost-per-send x 1000. `null` for non-LinkedIn ads. | [optional] |
27
+ | **serving_statuses** | **Array<String>** | LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array is what says so. - `[]` means no serving data: a non-LinkedIn ad, or a LinkedIn ad not yet re-synced. - `[\"RUNNABLE\"]` means the campaign is eligible to serve. - Anything else is a hold. Known values include ACCOUNT_SERVING_HOLD, ACCOUNT_TOTAL_BUDGET_HOLD, ACCOUNT_END_DATE_HOLD, CAMPAIGN_START_DATE_HOLD, CAMPAIGN_END_DATE_HOLD, CAMPAIGN_TOTAL_BUDGET_HOLD, CAMPAIGN_AUDIENCE_COUNT_HOLD, CAMPAIGN_GROUP_START_DATE_HOLD, CAMPAIGN_GROUP_END_DATE_HOLD, CAMPAIGN_GROUP_TOTAL_BUDGET_HOLD, CAMPAIGN_GROUP_STATUS_HOLD and STOPPED. The list is open on purpose, so treat unrecognized values as holds rather than errors. The end-date and total-budget holds are terminal and surface as `status: completed`; the rest surface as `status: paused`. Note that a hold is not the only cause of zero delivery: with manual, target-cost or cost-cap bidding, a `bidAmount` of 0 stops delivery while `servingStatuses` still reads `[\"RUNNABLE\"]`. Check `costType` / `bidAmount` / `optimizationGoal` as well. | [optional] |
26
28
  | **platform_ad_account_name** | **String** | Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle. `null` when the platform doesn't return a name or the sync hasn't run yet. | [optional] |
27
29
  | **platform_created_at** | **Time** | Platform-reported creation timestamp (Meta `created_time`, TikTok `create_time`). Distinct from `createdAt` which reflects when Zernio first synced the doc — for sort/filter by \"when the ad was actually created on the platform\", read this field. `null` for legacy ads synced before this field was added; aggregations fall back to `createdAt` in that case. | [optional] |
28
30
  | **bid_strategy** | [**BidStrategy**](BidStrategy.md) | | [optional] |
29
- | **bid_amount** | **Float** | Bid cap in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Populated when bidStrategy is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`. `null` for auto-bid (`LOWEST_COST_WITHOUT_CAP`). - Meta source: `bid_amount` on the ad set (smallest-denomination int, decoded here). - TikTok source: priority order `bid_price` -> `conversion_bid_price` -> `deep_cpa_bid` (whichever is set on the ad group). TikTok stores all three in whole currency units. Source: facebook-business-sdk-codegen api_specs/specs/AdSet.json (`bid_amount`). | [optional] |
31
+ | **bid_amount** | **Float** | Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). - Meta source: `bid_amount` on the ad set (smallest-denomination int, decoded here). Populated when bidStrategy is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`; `null` for auto-bid (`LOWEST_COST_WITHOUT_CAP`). - TikTok source: priority order `bid_price` -> `conversion_bid_price` -> `deep_cpa_bid` (whichever is set on the ad group). TikTok stores all three in whole currency units. - LinkedIn source: the campaign's EFFECTIVE `unitCost`, refreshed on every sync rather than echoing what was passed on create. Its meaning depends on the bidding mode implied by `optimizationGoal`: bid amount (manual), target cost, or cost cap. It pairs with `costType`, NOT with `bidStrategy`, which LinkedIn does not have. A value of `0` is a real, delivery- stopping configuration and not \"unset\", so do not gate this field on `bidStrategy` for LinkedIn ads. Source: facebook-business-sdk-codegen api_specs/specs/AdSet.json (`bid_amount`). | [optional] |
30
32
  | **roas_average_floor** | **Float** | Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`. - Meta source: decoded from `bid_constraints.roas_average_floor` (Meta stores as fixed-point int × 10000; we return the decimal). - TikTok source: `roas_bid` on the ad group (already a decimal). Source: facebook-business-sdk-codegen api_specs/specs/AdCampaignBidConstraint.json. | [optional] |
31
33
  | **promoted_object** | [**AdPromotedObject**](AdPromotedObject.md) | | [optional] |
32
34
  | **creative** | [**AdCreative**](AdCreative.md) | | [optional] |
@@ -61,6 +63,8 @@ instance = Zernio::Ad.new(
61
63
  ad_set_name: null,
62
64
  platform_objective: OUTCOME_SALES,
63
65
  optimization_goal: OFFSITE_CONVERSIONS,
66
+ cost_type: CPC,
67
+ serving_statuses: [ACCOUNT_TOTAL_BUDGET_HOLD],
64
68
  platform_ad_account_name: Zernio - previously Late,
65
69
  platform_created_at: null,
66
70
  bid_strategy: null,
data/docs/AdCampaign.md CHANGED
@@ -24,9 +24,9 @@
24
24
  | **profile_id** | **String** | | [optional] |
25
25
  | **advertising_channel_type** | **String** | Google-only. Raw campaign.advertising_channel_type. See AdTreeCampaign.advertisingChannelType. | [optional] |
26
26
  | **platform_objective** | **String** | Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC) | [optional] |
27
- | **optimization_goal** | **String** | Meta optimization goal shared across ad sets, or comma-separated values when ad sets differ (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION) | [optional] |
27
+ | **optimization_goal** | **String** | Optimization goal shared across ad sets, or comma-separated values when ad sets differ. Meta: e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION. LinkedIn: the campaign optimizationTargetType (e.g. MAX_CLICK, MAX_IMPRESSION, NONE); `NONE` with a manual costType is a campaign LinkedIn will not deliver. | [optional] |
28
28
  | **bid_strategy** | [**BidStrategy**](BidStrategy.md) | | [optional] |
29
- | **bid_amount** | **Float** | Representative bid cap from the top-spending ad set (whole currency units). Populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. | [optional] |
29
+ | **bid_amount** | **Float** | Representative bid from the top-spending ad set (whole currency units). Meta: populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. LinkedIn: the campaign unitCost, ungated, where 0 is a real delivery-stopping value. | [optional] |
30
30
  | **roas_average_floor** | **Float** | Representative ROAS floor from the top-spending ad set. Decimal multiplier (2.0 = 2.0x). | [optional] |
31
31
  | **promoted_object** | [**AdTreeCampaignPromotedObject**](AdTreeCampaignPromotedObject.md) | | [optional] |
32
32
  | **earliest_ad** | **Time** | | [optional] |
data/docs/AdCreative.md CHANGED
@@ -16,6 +16,8 @@
16
16
  | **instagram_user_id** | **String** | Meta `instagram_user_id` — the Instagram-scoped business ID that owns the boosted media. | [optional] |
17
17
  | **instagram_permalink_url** | **String** | Meta `instagram_permalink_url` — public Instagram post URL of the boosted media. | [optional] |
18
18
  | **media_urls** | **Array<String>** | All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts). | [optional] |
19
+ | **is_serving** | **Boolean** | LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign. | [optional] |
20
+ | **serving_hold_reasons** | **Array<String>** | LinkedIn only. Why this specific creative is not being served. Empty when it is serving. A superset of the ad-level `servingStatuses`: it repeats the inherited campaign, campaign group and account holds AND adds creative-only causes such as UNDER_REVIEW, REJECTED, PROCESSING, PROCESSING_FAILED, FORM_HOLD (lead-gen-form creatives), REFERRED_CONTENT_QUALITY_HOLD, JOB_POSTING_ON_HOLD and JOB_POSTING_INVALID (job ads). Some values are format-specific and will never appear on other ad formats. The list is open, so treat unrecognized values as holds rather than errors. | [optional] |
19
21
  | **body** | **String** | Ad copy/text | [optional] |
20
22
  | **google_headline** | **String** | Google Ads headline | [optional] |
21
23
  | **google_description** | **String** | Google Ads description | [optional] |
@@ -42,6 +44,8 @@ instance = Zernio::AdCreative.new(
42
44
  instagram_user_id: null,
43
45
  instagram_permalink_url: null,
44
46
  media_urls: null,
47
+ is_serving: null,
48
+ serving_hold_reasons: [UNDER_REVIEW],
45
49
  body: null,
46
50
  google_headline: null,
47
51
  google_description: null,
data/docs/AdTreeAdSet.md CHANGED
@@ -11,10 +11,12 @@
11
11
  | **budget** | [**AdTreeAdSetBudget**](AdTreeAdSetBudget.md) | | [optional] |
12
12
  | **ad_set_budget** | [**AdTreeAdSetAdSetBudget**](AdTreeAdSetAdSetBudget.md) | | [optional] |
13
13
  | **metrics** | [**AdMetrics**](AdMetrics.md) | | [optional] |
14
- | **optimization_goal** | **String** | Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION) | [optional] |
14
+ | **optimization_goal** | **String** | What the delivery system optimizes for. Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION), or on LinkedIn the campaign's effective optimizationTargetType (NONE means manual bidding). See the `optimizationGoal` field on `Ad` for the full value spaces. | [optional] |
15
15
  | **bid_strategy** | [**BidStrategy**](BidStrategy.md) | | [optional] |
16
- | **bid_amount** | **Float** | Bid cap in whole currency units. Populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. | [optional] |
16
+ | **bid_amount** | **Float** | Bid amount in whole currency units. On Meta/TikTok populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP; on LinkedIn it is the campaign's effective unitCost and pairs with `costType`, where 0 is a real, delivery-stopping value. | [optional] |
17
17
  | **roas_average_floor** | **Float** | Minimum ROAS as a decimal multiplier (2.0 = 2.0x). Populated when bidStrategy is LOWEST_COST_WITH_MIN_ROAS. | [optional] |
18
+ | **cost_type** | **String** | LinkedIn only. Effective cost model (billing event) of the LinkedIn campaign backing this ad set: CPM, CPC or CPV. Null for non-LinkedIn ad sets. | [optional] |
19
+ | **serving_statuses** | **Array<String>** | LinkedIn only. Why the LinkedIn campaign backing this ad set is (or is not) delivering. A LinkedIn Campaign maps to this ad-set node, so this is the level where LinkedIn's holds actually apply. Empty means no serving data, [\"RUNNABLE\"] means eligible to serve, anything else is a hold. See the `servingStatuses` field on `Ad` for the known values. | [optional] |
18
20
  | **promoted_object** | [**AdTreeAdSetPromotedObject**](AdTreeAdSetPromotedObject.md) | | [optional] |
19
21
  | **ads** | [**Array<Ad>**](Ad.md) | Individual ads within this ad set (capped at 100). Returns a subset of Ad fields from the aggregation (core fields like _id, name, platform, status, budget, metrics, creative, goal are included; targeting and schedule may be absent). When `timeIncrement=1&dailyLevel=ad`, each entry also carries a `daily[]` array of `AdDailyMetrics`. | [optional] |
20
22
  | **daily** | [**Array<AdDailyMetrics>**](AdDailyMetrics.md) | Per-day metric series for this ad set. Present only when `GET /v1/ads/tree` is called with `timeIncrement=1` and `dailyLevel` is `adset` or `ad`. | [optional] |
@@ -36,6 +38,8 @@ instance = Zernio::AdTreeAdSet.new(
36
38
  bid_strategy: null,
37
39
  bid_amount: null,
38
40
  roas_average_floor: null,
41
+ cost_type: null,
42
+ serving_statuses: [RUNNABLE],
39
43
  promoted_object: null,
40
44
  ads: null,
41
45
  daily: null
@@ -25,9 +25,9 @@
25
25
  | **profile_id** | **String** | | [optional] |
26
26
  | **advertising_channel_type** | **String** | Google-only. Raw campaign.advertising_channel_type (SEARCH, PERFORMANCE_MAX, VIDEO, DEMAND_GEN, DISPLAY, SHOPPING, ...). Serving surface, distinct from platformObjective (advertiser intent). Null/absent for non-Google platforms. | [optional] |
27
27
  | **platform_objective** | **String** | Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC) | [optional] |
28
- | **optimization_goal** | **String** | Meta optimization goal shared across ad sets, or comma-separated values when ad sets differ (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION) | [optional] |
28
+ | **optimization_goal** | **String** | Optimization goal shared across ad sets, or comma-separated values when ad sets differ. Meta: e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION. LinkedIn: the campaign optimizationTargetType (e.g. MAX_CLICK, MAX_IMPRESSION, NONE); `NONE` with a manual costType is a campaign LinkedIn will not deliver. | [optional] |
29
29
  | **bid_strategy** | [**BidStrategy**](BidStrategy.md) | | [optional] |
30
- | **bid_amount** | **Float** | Representative bid cap for the campaign bubbled up from the top-spending ad set's `bid_amount` (whole currency units). Populated when the ad-set bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. | [optional] |
30
+ | **bid_amount** | **Float** | Representative bid for the campaign, bubbled up from the top-spending ad set (whole currency units). Meta: populated when the ad-set bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. LinkedIn: the campaign unitCost, which has no bidStrategy gate and where 0 is a real, delivery-stopping value rather than unset. | [optional] |
31
31
  | **roas_average_floor** | **Float** | Representative ROAS floor for the campaign — bubbled up from the top-spending ad set. Decimal multiplier (2.0 = 2.0x). | [optional] |
32
32
  | **promoted_object** | [**AdTreeCampaignPromotedObject**](AdTreeCampaignPromotedObject.md) | | [optional] |
33
33
  | **ad_sets** | [**Array<AdTreeAdSet>**](AdTreeAdSet.md) | | [optional] |
@@ -15,6 +15,7 @@
15
15
  | **follows** | **Integer** | Instagram feed posts and stories only: organic accounts that started following from this post. 0 for reels and other platforms. | [optional] |
16
16
  | **ig_reels_avg_watch_time** | **Integer** | Instagram Reels only: average watch time per play, in milliseconds. 0 for non-Reels media and other platforms. | [optional] |
17
17
  | **ig_reels_video_view_total_time** | **Integer** | Instagram Reels only: total watch time including replays, in milliseconds. 0 for non-Reels media and other platforms. | [optional] |
18
+ | **video_duration_seconds** | **Integer** | Video length in seconds. Currently Instagram Reels only; combine with igReelsAvgWatchTime (ms) to estimate retention. Null when unknown (other platforms, non-video media, or when Instagram does not expose the media URL, e.g. reels with copyrighted audio). | [optional] |
18
19
  | **engagement_rate** | **Float** | | [optional] |
19
20
  | **last_updated** | **Time** | | [optional] |
20
21
 
@@ -35,6 +36,7 @@ instance = Zernio::PostAnalytics.new(
35
36
  follows: 0,
36
37
  ig_reels_avg_watch_time: 0,
37
38
  ig_reels_video_view_total_time: 0,
39
+ video_duration_seconds: 30,
38
40
  engagement_rate: 0,
39
41
  last_updated: null
40
42
  )
@@ -57,9 +57,15 @@ module Zernio
57
57
  # Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC). Only present for Meta ads.
58
58
  attr_accessor :platform_objective
59
59
 
60
- # Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS). Only present for Meta ads.
60
+ # What the delivery system optimizes for, at ad-set level. The value space depends on `platform`: - Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS). - LinkedIn: the campaign's EFFECTIVE `optimizationTargetType`, refreshed from LinkedIn on every sync rather than echoing what was passed on create. `NONE` means manual bidding, and it is a real value, not missing data. Auto-bid values are MAX_IMPRESSION / MAX_CLICK / MAX_CONVERSION / MAX_VIDEO_VIEW / MAX_LEAD / MAX_REACH; target-cost values are TARGET_COST_PER_CLICK / TARGET_COST_PER_IMPRESSION / TARGET_COST_PER_VIDEO_VIEW; cost-cap values are the CAP_COST_AND_MAXIMIZE_* family.
61
61
  attr_accessor :optimization_goal
62
62
 
63
+ # LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn, refreshed on every sync rather than echoing what was passed on create. One of `CPM` (cost per thousand impressions), `CPC` (cost per click) or `CPV` (cost per video view). On LinkedIn this is the axis that pairs with `bidAmount`; there is no `bidStrategy`. For campaign type SPONSORED_INMAILS, `CPM` bills as cost-per-send x 1000. `null` for non-LinkedIn ads.
64
+ attr_accessor :cost_type
65
+
66
+ # LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn. A campaign can report `status: ACTIVE` and still serve nothing; this array is what says so. - `[]` means no serving data: a non-LinkedIn ad, or a LinkedIn ad not yet re-synced. - `[\"RUNNABLE\"]` means the campaign is eligible to serve. - Anything else is a hold. Known values include ACCOUNT_SERVING_HOLD, ACCOUNT_TOTAL_BUDGET_HOLD, ACCOUNT_END_DATE_HOLD, CAMPAIGN_START_DATE_HOLD, CAMPAIGN_END_DATE_HOLD, CAMPAIGN_TOTAL_BUDGET_HOLD, CAMPAIGN_AUDIENCE_COUNT_HOLD, CAMPAIGN_GROUP_START_DATE_HOLD, CAMPAIGN_GROUP_END_DATE_HOLD, CAMPAIGN_GROUP_TOTAL_BUDGET_HOLD, CAMPAIGN_GROUP_STATUS_HOLD and STOPPED. The list is open on purpose, so treat unrecognized values as holds rather than errors. The end-date and total-budget holds are terminal and surface as `status: completed`; the rest surface as `status: paused`. Note that a hold is not the only cause of zero delivery: with manual, target-cost or cost-cap bidding, a `bidAmount` of 0 stops delivery while `servingStatuses` still reads `[\"RUNNABLE\"]`. Check `costType` / `bidAmount` / `optimizationGoal` as well.
67
+ attr_accessor :serving_statuses
68
+
63
69
  # Human-readable advertiser/account name (Meta `AdAccount.name`, TikTok `advertiser_name`, LinkedIn / X / Pinterest equivalents). Refreshed every sync so platform-side renames propagate within one cycle. `null` when the platform doesn't return a name or the sync hasn't run yet.
64
70
  attr_accessor :platform_ad_account_name
65
71
 
@@ -68,7 +74,7 @@ module Zernio
68
74
 
69
75
  attr_accessor :bid_strategy
70
76
 
71
- # Bid cap in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). Populated when bidStrategy is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`. `null` for auto-bid (`LOWEST_COST_WITHOUT_CAP`). - Meta source: `bid_amount` on the ad set (smallest-denomination int, decoded here). - TikTok source: priority order `bid_price` -> `conversion_bid_price` -> `deep_cpa_bid` (whichever is set on the ad group). TikTok stores all three in whole currency units. Source: facebook-business-sdk-codegen api_specs/specs/AdSet.json (`bid_amount`).
77
+ # Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100). - Meta source: `bid_amount` on the ad set (smallest-denomination int, decoded here). Populated when bidStrategy is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`; `null` for auto-bid (`LOWEST_COST_WITHOUT_CAP`). - TikTok source: priority order `bid_price` -> `conversion_bid_price` -> `deep_cpa_bid` (whichever is set on the ad group). TikTok stores all three in whole currency units. - LinkedIn source: the campaign's EFFECTIVE `unitCost`, refreshed on every sync rather than echoing what was passed on create. Its meaning depends on the bidding mode implied by `optimizationGoal`: bid amount (manual), target cost, or cost cap. It pairs with `costType`, NOT with `bidStrategy`, which LinkedIn does not have. A value of `0` is a real, delivery- stopping configuration and not \"unset\", so do not gate this field on `bidStrategy` for LinkedIn ads. Source: facebook-business-sdk-codegen api_specs/specs/AdSet.json (`bid_amount`).
72
78
  attr_accessor :bid_amount
73
79
 
74
80
  # Minimum ROAS as a decimal multiplier (2.0 = 2.0x ROAS). Populated when bidStrategy is `LOWEST_COST_WITH_MIN_ROAS`. - Meta source: decoded from `bid_constraints.roas_average_floor` (Meta stores as fixed-point int × 10000; we return the decimal). - TikTok source: `roas_bid` on the ad group (already a decimal). Source: facebook-business-sdk-codegen api_specs/specs/AdCampaignBidConstraint.json.
@@ -133,6 +139,8 @@ module Zernio
133
139
  :'ad_set_name' => :'adSetName',
134
140
  :'platform_objective' => :'platformObjective',
135
141
  :'optimization_goal' => :'optimizationGoal',
142
+ :'cost_type' => :'costType',
143
+ :'serving_statuses' => :'servingStatuses',
136
144
  :'platform_ad_account_name' => :'platformAdAccountName',
137
145
  :'platform_created_at' => :'platformCreatedAt',
138
146
  :'bid_strategy' => :'bidStrategy',
@@ -180,6 +188,8 @@ module Zernio
180
188
  :'ad_set_name' => :'String',
181
189
  :'platform_objective' => :'String',
182
190
  :'optimization_goal' => :'String',
191
+ :'cost_type' => :'String',
192
+ :'serving_statuses' => :'Array<String>',
183
193
  :'platform_ad_account_name' => :'String',
184
194
  :'platform_created_at' => :'Time',
185
195
  :'bid_strategy' => :'BidStrategy',
@@ -202,6 +212,7 @@ module Zernio
202
212
  :'metrics',
203
213
  :'platform_objective',
204
214
  :'optimization_goal',
215
+ :'cost_type',
205
216
  :'platform_ad_account_name',
206
217
  :'platform_created_at',
207
218
  :'bid_strategy',
@@ -302,6 +313,16 @@ module Zernio
302
313
  self.optimization_goal = attributes[:'optimization_goal']
303
314
  end
304
315
 
316
+ if attributes.key?(:'cost_type')
317
+ self.cost_type = attributes[:'cost_type']
318
+ end
319
+
320
+ if attributes.key?(:'serving_statuses')
321
+ if (value = attributes[:'serving_statuses']).is_a?(Array)
322
+ self.serving_statuses = value
323
+ end
324
+ end
325
+
305
326
  if attributes.key?(:'platform_ad_account_name')
306
327
  self.platform_ad_account_name = attributes[:'platform_ad_account_name']
307
328
  end
@@ -426,6 +447,8 @@ module Zernio
426
447
  ad_set_name == o.ad_set_name &&
427
448
  platform_objective == o.platform_objective &&
428
449
  optimization_goal == o.optimization_goal &&
450
+ cost_type == o.cost_type &&
451
+ serving_statuses == o.serving_statuses &&
429
452
  platform_ad_account_name == o.platform_ad_account_name &&
430
453
  platform_created_at == o.platform_created_at &&
431
454
  bid_strategy == o.bid_strategy &&
@@ -449,7 +472,7 @@ module Zernio
449
472
  # Calculates hash code according to all attributes.
450
473
  # @return [Integer] Hash code
451
474
  def hash
452
- [_id, name, platform, status, configured_status, review_status, ad_type, goal, is_external, budget, metrics, platform_ad_id, platform_ad_account_id, platform_campaign_id, platform_ad_set_id, campaign_name, ad_set_name, platform_objective, optimization_goal, platform_ad_account_name, platform_created_at, bid_strategy, bid_amount, roas_average_floor, promoted_object, creative, targeting, schedule, rejection_reason, created_at, updated_at].hash
475
+ [_id, name, platform, status, configured_status, review_status, ad_type, goal, is_external, budget, metrics, platform_ad_id, platform_ad_account_id, platform_campaign_id, platform_ad_set_id, campaign_name, ad_set_name, platform_objective, optimization_goal, cost_type, serving_statuses, platform_ad_account_name, platform_created_at, bid_strategy, bid_amount, roas_average_floor, promoted_object, creative, targeting, schedule, rejection_reason, created_at, updated_at].hash
453
476
  end
454
477
 
455
478
  # Builds the object from hash
@@ -64,12 +64,12 @@ module Zernio
64
64
  # Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC)
65
65
  attr_accessor :platform_objective
66
66
 
67
- # Meta optimization goal shared across ad sets, or comma-separated values when ad sets differ (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION)
67
+ # Optimization goal shared across ad sets, or comma-separated values when ad sets differ. Meta: e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION. LinkedIn: the campaign optimizationTargetType (e.g. MAX_CLICK, MAX_IMPRESSION, NONE); `NONE` with a manual costType is a campaign LinkedIn will not deliver.
68
68
  attr_accessor :optimization_goal
69
69
 
70
70
  attr_accessor :bid_strategy
71
71
 
72
- # Representative bid cap from the top-spending ad set (whole currency units). Populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.
72
+ # Representative bid from the top-spending ad set (whole currency units). Meta: populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. LinkedIn: the campaign unitCost, ungated, where 0 is a real delivery-stopping value.
73
73
  attr_accessor :bid_amount
74
74
 
75
75
  # Representative ROAS floor from the top-spending ad set. Decimal multiplier (2.0 = 2.0x).
@@ -52,6 +52,12 @@ module Zernio
52
52
  # All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).
53
53
  attr_accessor :media_urls
54
54
 
55
+ # LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign.
56
+ attr_accessor :is_serving
57
+
58
+ # LinkedIn only. Why this specific creative is not being served. Empty when it is serving. A superset of the ad-level `servingStatuses`: it repeats the inherited campaign, campaign group and account holds AND adds creative-only causes such as UNDER_REVIEW, REJECTED, PROCESSING, PROCESSING_FAILED, FORM_HOLD (lead-gen-form creatives), REFERRED_CONTENT_QUALITY_HOLD, JOB_POSTING_ON_HOLD and JOB_POSTING_INVALID (job ads). Some values are format-specific and will never appear on other ad formats. The list is open, so treat unrecognized values as holds rather than errors.
59
+ attr_accessor :serving_hold_reasons
60
+
55
61
  # Ad copy/text
56
62
  attr_accessor :body
57
63
 
@@ -85,6 +91,8 @@ module Zernio
85
91
  :'instagram_user_id' => :'instagramUserId',
86
92
  :'instagram_permalink_url' => :'instagramPermalinkUrl',
87
93
  :'media_urls' => :'mediaUrls',
94
+ :'is_serving' => :'isServing',
95
+ :'serving_hold_reasons' => :'servingHoldReasons',
88
96
  :'body' => :'body',
89
97
  :'google_headline' => :'googleHeadline',
90
98
  :'google_description' => :'googleDescription',
@@ -120,6 +128,8 @@ module Zernio
120
128
  :'instagram_user_id' => :'String',
121
129
  :'instagram_permalink_url' => :'String',
122
130
  :'media_urls' => :'Array<String>',
131
+ :'is_serving' => :'Boolean',
132
+ :'serving_hold_reasons' => :'Array<String>',
123
133
  :'body' => :'String',
124
134
  :'google_headline' => :'String',
125
135
  :'google_description' => :'String',
@@ -141,6 +151,7 @@ module Zernio
141
151
  :'effective_instagram_media_id',
142
152
  :'instagram_user_id',
143
153
  :'instagram_permalink_url',
154
+ :'is_serving',
144
155
  ])
145
156
  end
146
157
 
@@ -210,6 +221,16 @@ module Zernio
210
221
  end
211
222
  end
212
223
 
224
+ if attributes.key?(:'is_serving')
225
+ self.is_serving = attributes[:'is_serving']
226
+ end
227
+
228
+ if attributes.key?(:'serving_hold_reasons')
229
+ if (value = attributes[:'serving_hold_reasons']).is_a?(Array)
230
+ self.serving_hold_reasons = value
231
+ end
232
+ end
233
+
213
234
  if attributes.key?(:'body')
214
235
  self.body = attributes[:'body']
215
236
  end
@@ -271,6 +292,8 @@ module Zernio
271
292
  instagram_user_id == o.instagram_user_id &&
272
293
  instagram_permalink_url == o.instagram_permalink_url &&
273
294
  media_urls == o.media_urls &&
295
+ is_serving == o.is_serving &&
296
+ serving_hold_reasons == o.serving_hold_reasons &&
274
297
  body == o.body &&
275
298
  google_headline == o.google_headline &&
276
299
  google_description == o.google_description &&
@@ -289,7 +312,7 @@ module Zernio
289
312
  # Calculates hash code according to all attributes.
290
313
  # @return [Integer] Hash code
291
314
  def hash
292
- [thumbnail_url, image_url, video_id, video_url, object_type, object_story_id, effective_object_story_id, page_id, effective_instagram_media_id, instagram_user_id, instagram_permalink_url, media_urls, body, google_headline, google_description, link_url, pinterest_image_url, pinterest_title, pinterest_description].hash
315
+ [thumbnail_url, image_url, video_id, video_url, 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, pinterest_image_url, pinterest_title, pinterest_description].hash
293
316
  end
294
317
 
295
318
  # Builds the object from hash
@@ -31,17 +31,23 @@ module Zernio
31
31
 
32
32
  attr_accessor :metrics
33
33
 
34
- # Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION)
34
+ # What the delivery system optimizes for. Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION), or on LinkedIn the campaign's effective optimizationTargetType (NONE means manual bidding). See the `optimizationGoal` field on `Ad` for the full value spaces.
35
35
  attr_accessor :optimization_goal
36
36
 
37
37
  attr_accessor :bid_strategy
38
38
 
39
- # Bid cap in whole currency units. Populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.
39
+ # Bid amount in whole currency units. On Meta/TikTok populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP; on LinkedIn it is the campaign's effective unitCost and pairs with `costType`, where 0 is a real, delivery-stopping value.
40
40
  attr_accessor :bid_amount
41
41
 
42
42
  # Minimum ROAS as a decimal multiplier (2.0 = 2.0x). Populated when bidStrategy is LOWEST_COST_WITH_MIN_ROAS.
43
43
  attr_accessor :roas_average_floor
44
44
 
45
+ # LinkedIn only. Effective cost model (billing event) of the LinkedIn campaign backing this ad set: CPM, CPC or CPV. Null for non-LinkedIn ad sets.
46
+ attr_accessor :cost_type
47
+
48
+ # LinkedIn only. Why the LinkedIn campaign backing this ad set is (or is not) delivering. A LinkedIn Campaign maps to this ad-set node, so this is the level where LinkedIn's holds actually apply. Empty means no serving data, [\"RUNNABLE\"] means eligible to serve, anything else is a hold. See the `servingStatuses` field on `Ad` for the known values.
49
+ attr_accessor :serving_statuses
50
+
45
51
  attr_accessor :promoted_object
46
52
 
47
53
  # Individual ads within this ad set (capped at 100). Returns a subset of Ad fields from the aggregation (core fields like _id, name, platform, status, budget, metrics, creative, goal are included; targeting and schedule may be absent). When `timeIncrement=1&dailyLevel=ad`, each entry also carries a `daily[]` array of `AdDailyMetrics`.
@@ -86,6 +92,8 @@ module Zernio
86
92
  :'bid_strategy' => :'bidStrategy',
87
93
  :'bid_amount' => :'bidAmount',
88
94
  :'roas_average_floor' => :'roasAverageFloor',
95
+ :'cost_type' => :'costType',
96
+ :'serving_statuses' => :'servingStatuses',
89
97
  :'promoted_object' => :'promotedObject',
90
98
  :'ads' => :'ads',
91
99
  :'daily' => :'daily'
@@ -116,6 +124,8 @@ module Zernio
116
124
  :'bid_strategy' => :'BidStrategy',
117
125
  :'bid_amount' => :'Float',
118
126
  :'roas_average_floor' => :'Float',
127
+ :'cost_type' => :'String',
128
+ :'serving_statuses' => :'Array<String>',
119
129
  :'promoted_object' => :'AdTreeAdSetPromotedObject',
120
130
  :'ads' => :'Array<Ad>',
121
131
  :'daily' => :'Array<AdDailyMetrics>'
@@ -129,6 +139,7 @@ module Zernio
129
139
  :'bid_strategy',
130
140
  :'bid_amount',
131
141
  :'roas_average_floor',
142
+ :'cost_type',
132
143
  ])
133
144
  end
134
145
 
@@ -192,6 +203,16 @@ module Zernio
192
203
  self.roas_average_floor = attributes[:'roas_average_floor']
193
204
  end
194
205
 
206
+ if attributes.key?(:'cost_type')
207
+ self.cost_type = attributes[:'cost_type']
208
+ end
209
+
210
+ if attributes.key?(:'serving_statuses')
211
+ if (value = attributes[:'serving_statuses']).is_a?(Array)
212
+ self.serving_statuses = value
213
+ end
214
+ end
215
+
195
216
  if attributes.key?(:'promoted_object')
196
217
  self.promoted_object = attributes[:'promoted_object']
197
218
  end
@@ -240,6 +261,8 @@ module Zernio
240
261
  bid_strategy == o.bid_strategy &&
241
262
  bid_amount == o.bid_amount &&
242
263
  roas_average_floor == o.roas_average_floor &&
264
+ cost_type == o.cost_type &&
265
+ serving_statuses == o.serving_statuses &&
243
266
  promoted_object == o.promoted_object &&
244
267
  ads == o.ads &&
245
268
  daily == o.daily
@@ -254,7 +277,7 @@ module Zernio
254
277
  # Calculates hash code according to all attributes.
255
278
  # @return [Integer] Hash code
256
279
  def hash
257
- [platform_ad_set_id, ad_set_name, status, ad_count, budget, ad_set_budget, metrics, optimization_goal, bid_strategy, bid_amount, roas_average_floor, promoted_object, ads, daily].hash
280
+ [platform_ad_set_id, ad_set_name, status, ad_count, budget, ad_set_budget, metrics, optimization_goal, bid_strategy, bid_amount, roas_average_floor, cost_type, serving_statuses, promoted_object, ads, daily].hash
258
281
  end
259
282
 
260
283
  # Builds the object from hash
@@ -68,12 +68,12 @@ module Zernio
68
68
  # Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC)
69
69
  attr_accessor :platform_objective
70
70
 
71
- # Meta optimization goal shared across ad sets, or comma-separated values when ad sets differ (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION)
71
+ # Optimization goal shared across ad sets, or comma-separated values when ad sets differ. Meta: e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION. LinkedIn: the campaign optimizationTargetType (e.g. MAX_CLICK, MAX_IMPRESSION, NONE); `NONE` with a manual costType is a campaign LinkedIn will not deliver.
72
72
  attr_accessor :optimization_goal
73
73
 
74
74
  attr_accessor :bid_strategy
75
75
 
76
- # Representative bid cap for the campaign bubbled up from the top-spending ad set's `bid_amount` (whole currency units). Populated when the ad-set bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP.
76
+ # Representative bid for the campaign, bubbled up from the top-spending ad set (whole currency units). Meta: populated when the ad-set bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. LinkedIn: the campaign unitCost, which has no bidStrategy gate and where 0 is a real, delivery-stopping value rather than unset.
77
77
  attr_accessor :bid_amount
78
78
 
79
79
  # Representative ROAS floor for the campaign — bubbled up from the top-spending ad set. Decimal multiplier (2.0 = 2.0x).
@@ -41,6 +41,9 @@ module Zernio
41
41
  # Instagram Reels only: total watch time including replays, in milliseconds. 0 for non-Reels media and other platforms.
42
42
  attr_accessor :ig_reels_video_view_total_time
43
43
 
44
+ # Video length in seconds. Currently Instagram Reels only; combine with igReelsAvgWatchTime (ms) to estimate retention. Null when unknown (other platforms, non-video media, or when Instagram does not expose the media URL, e.g. reels with copyrighted audio).
45
+ attr_accessor :video_duration_seconds
46
+
44
47
  attr_accessor :engagement_rate
45
48
 
46
49
  attr_accessor :last_updated
@@ -59,6 +62,7 @@ module Zernio
59
62
  :'follows' => :'follows',
60
63
  :'ig_reels_avg_watch_time' => :'igReelsAvgWatchTime',
61
64
  :'ig_reels_video_view_total_time' => :'igReelsVideoViewTotalTime',
65
+ :'video_duration_seconds' => :'videoDurationSeconds',
62
66
  :'engagement_rate' => :'engagementRate',
63
67
  :'last_updated' => :'lastUpdated'
64
68
  }
@@ -88,6 +92,7 @@ module Zernio
88
92
  :'follows' => :'Integer',
89
93
  :'ig_reels_avg_watch_time' => :'Integer',
90
94
  :'ig_reels_video_view_total_time' => :'Integer',
95
+ :'video_duration_seconds' => :'Integer',
91
96
  :'engagement_rate' => :'Float',
92
97
  :'last_updated' => :'Time'
93
98
  }
@@ -96,6 +101,7 @@ module Zernio
96
101
  # List of attributes with nullable: true
97
102
  def self.openapi_nullable
98
103
  Set.new([
104
+ :'video_duration_seconds',
99
105
  ])
100
106
  end
101
107
 
@@ -159,6 +165,10 @@ module Zernio
159
165
  self.ig_reels_video_view_total_time = attributes[:'ig_reels_video_view_total_time']
160
166
  end
161
167
 
168
+ if attributes.key?(:'video_duration_seconds')
169
+ self.video_duration_seconds = attributes[:'video_duration_seconds']
170
+ end
171
+
162
172
  if attributes.key?(:'engagement_rate')
163
173
  self.engagement_rate = attributes[:'engagement_rate']
164
174
  end
@@ -199,6 +209,7 @@ module Zernio
199
209
  follows == o.follows &&
200
210
  ig_reels_avg_watch_time == o.ig_reels_avg_watch_time &&
201
211
  ig_reels_video_view_total_time == o.ig_reels_video_view_total_time &&
212
+ video_duration_seconds == o.video_duration_seconds &&
202
213
  engagement_rate == o.engagement_rate &&
203
214
  last_updated == o.last_updated
204
215
  end
@@ -212,7 +223,7 @@ module Zernio
212
223
  # Calculates hash code according to all attributes.
213
224
  # @return [Integer] Hash code
214
225
  def hash
215
- [impressions, reach, likes, comments, shares, saves, clicks, views, follows, ig_reels_avg_watch_time, ig_reels_video_view_total_time, engagement_rate, last_updated].hash
226
+ [impressions, reach, likes, comments, shares, saves, clicks, views, follows, ig_reels_avg_watch_time, ig_reels_video_view_total_time, video_duration_seconds, engagement_rate, last_updated].hash
216
227
  end
217
228
 
218
229
  # Builds the object from hash
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Zernio
14
- VERSION = '0.0.637'
14
+ VERSION = '0.0.639'
15
15
  end
data/openapi.yaml CHANGED
@@ -6093,6 +6093,7 @@ components:
6093
6093
  follows: { type: integer, example: 0, description: 'Instagram feed posts and stories only: organic accounts that started following from this post. 0 for reels and other platforms.' }
6094
6094
  igReelsAvgWatchTime: { type: integer, example: 0, description: 'Instagram Reels only: average watch time per play, in milliseconds. 0 for non-Reels media and other platforms.' }
6095
6095
  igReelsVideoViewTotalTime: { type: integer, example: 0, description: 'Instagram Reels only: total watch time including replays, in milliseconds. 0 for non-Reels media and other platforms.' }
6096
+ videoDurationSeconds: { type: [integer, "null"], example: 30, description: 'Video length in seconds. Currently Instagram Reels only; combine with igReelsAvgWatchTime (ms) to estimate retention. Null when unknown (other platforms, non-video media, or when Instagram does not expose the media URL, e.g. reels with copyrighted audio).' }
6096
6097
  engagementRate: { type: number, example: 0 }
6097
6098
  lastUpdated: { type: string, format: date-time }
6098
6099
  PlatformAnalytics:
@@ -6855,8 +6856,47 @@ components:
6855
6856
  example: OUTCOME_SALES
6856
6857
  optimizationGoal:
6857
6858
  type: [string, "null"]
6858
- description: "Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS). Only present for Meta ads."
6859
+ description: |
6860
+ What the delivery system optimizes for, at ad-set level. The value space depends on `platform`:
6861
+
6862
+ - Meta: ad set `optimization_goal` (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION, LINK_CLICKS).
6863
+ - LinkedIn: the campaign's EFFECTIVE `optimizationTargetType`, refreshed from LinkedIn on every
6864
+ sync rather than echoing what was passed on create. `NONE` means manual bidding, and it is a
6865
+ real value, not missing data. Auto-bid values are MAX_IMPRESSION / MAX_CLICK / MAX_CONVERSION /
6866
+ MAX_VIDEO_VIEW / MAX_LEAD / MAX_REACH; target-cost values are TARGET_COST_PER_CLICK /
6867
+ TARGET_COST_PER_IMPRESSION / TARGET_COST_PER_VIDEO_VIEW; cost-cap values are the
6868
+ CAP_COST_AND_MAXIMIZE_* family.
6859
6869
  example: OFFSITE_CONVERSIONS
6870
+ costType:
6871
+ type: [string, "null"]
6872
+ description: |
6873
+ LinkedIn only. The campaign's EFFECTIVE cost model (billing event) as applied by LinkedIn,
6874
+ refreshed on every sync rather than echoing what was passed on create. One of `CPM` (cost per
6875
+ thousand impressions), `CPC` (cost per click) or `CPV` (cost per video view). On LinkedIn this is
6876
+ the axis that pairs with `bidAmount`; there is no `bidStrategy`. For campaign type
6877
+ SPONSORED_INMAILS, `CPM` bills as cost-per-send x 1000. `null` for non-LinkedIn ads.
6878
+ example: CPC
6879
+ servingStatuses:
6880
+ type: array
6881
+ items: { type: string }
6882
+ description: |
6883
+ LinkedIn only. Why the parent campaign is (or is not) delivering, verbatim from LinkedIn.
6884
+ A campaign can report `status: ACTIVE` and still serve nothing; this array is what says so.
6885
+
6886
+ - `[]` means no serving data: a non-LinkedIn ad, or a LinkedIn ad not yet re-synced.
6887
+ - `["RUNNABLE"]` means the campaign is eligible to serve.
6888
+ - Anything else is a hold. Known values include ACCOUNT_SERVING_HOLD, ACCOUNT_TOTAL_BUDGET_HOLD,
6889
+ ACCOUNT_END_DATE_HOLD, CAMPAIGN_START_DATE_HOLD, CAMPAIGN_END_DATE_HOLD,
6890
+ CAMPAIGN_TOTAL_BUDGET_HOLD, CAMPAIGN_AUDIENCE_COUNT_HOLD, CAMPAIGN_GROUP_START_DATE_HOLD,
6891
+ CAMPAIGN_GROUP_END_DATE_HOLD, CAMPAIGN_GROUP_TOTAL_BUDGET_HOLD, CAMPAIGN_GROUP_STATUS_HOLD and
6892
+ STOPPED. The list is open on purpose, so treat unrecognized values as holds rather than errors.
6893
+
6894
+ The end-date and total-budget holds are terminal and surface as `status: completed`; the rest
6895
+ surface as `status: paused`. Note that a hold is not the only cause of zero delivery: with
6896
+ manual, target-cost or cost-cap bidding, a `bidAmount` of 0 stops delivery while
6897
+ `servingStatuses` still reads `["RUNNABLE"]`. Check `costType` / `bidAmount` /
6898
+ `optimizationGoal` as well.
6899
+ example: ["ACCOUNT_TOTAL_BUDGET_HOLD"]
6860
6900
  platformAdAccountName:
6861
6901
  type: [string, "null"]
6862
6902
  description: |
@@ -6888,13 +6928,19 @@ components:
6888
6928
  bidAmount:
6889
6929
  type: [number, "null"]
6890
6930
  description: |
6891
- Bid cap in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100).
6892
- Populated when bidStrategy is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`. `null` for
6893
- auto-bid (`LOWEST_COST_WITHOUT_CAP`).
6931
+ Bid amount in WHOLE currency units of the ad account (USD: 5 = $5.00; JPY: 100 = ¥100).
6894
6932
 
6895
- - Meta source: `bid_amount` on the ad set (smallest-denomination int, decoded here).
6933
+ - Meta source: `bid_amount` on the ad set (smallest-denomination int, decoded here). Populated
6934
+ when bidStrategy is `LOWEST_COST_WITH_BID_CAP` or `COST_CAP`; `null` for auto-bid
6935
+ (`LOWEST_COST_WITHOUT_CAP`).
6896
6936
  - TikTok source: priority order `bid_price` -> `conversion_bid_price` -> `deep_cpa_bid`
6897
6937
  (whichever is set on the ad group). TikTok stores all three in whole currency units.
6938
+ - LinkedIn source: the campaign's EFFECTIVE `unitCost`, refreshed on every sync rather than
6939
+ echoing what was passed on create. Its meaning depends on the bidding mode implied by
6940
+ `optimizationGoal`: bid amount (manual), target cost, or cost cap. It pairs with `costType`,
6941
+ NOT with `bidStrategy`, which LinkedIn does not have. A value of `0` is a real, delivery-
6942
+ stopping configuration and not "unset", so do not gate this field on `bidStrategy` for
6943
+ LinkedIn ads.
6898
6944
 
6899
6945
  Source: facebook-business-sdk-codegen api_specs/specs/AdSet.json (`bid_amount`).
6900
6946
  example: 5
@@ -6938,6 +6984,19 @@ components:
6938
6984
  type: array
6939
6985
  items: { type: string }
6940
6986
  description: All media URLs for this ad (carousel images, multiple assets). Populated for Meta (carousel child_attachments), Google Ads (responsive display marketing_images), and LinkedIn (multi-image posts).
6987
+ isServing: { type: [boolean, "null"], description: "LinkedIn only. Whether LinkedIn is currently serving this specific creative. Complements the ad-level `servingStatuses`, which describes the parent campaign." }
6988
+ servingHoldReasons:
6989
+ type: array
6990
+ items: { type: string }
6991
+ description: |
6992
+ LinkedIn only. Why this specific creative is not being served. Empty when it is serving.
6993
+ A superset of the ad-level `servingStatuses`: it repeats the inherited campaign, campaign
6994
+ group and account holds AND adds creative-only causes such as UNDER_REVIEW, REJECTED,
6995
+ PROCESSING, PROCESSING_FAILED, FORM_HOLD (lead-gen-form creatives),
6996
+ REFERRED_CONTENT_QUALITY_HOLD, JOB_POSTING_ON_HOLD and JOB_POSTING_INVALID (job ads).
6997
+ Some values are format-specific and will never appear on other ad formats. The list is
6998
+ open, so treat unrecognized values as holds rather than errors.
6999
+ example: ["UNDER_REVIEW"]
6941
7000
  body: { type: string, description: Ad copy/text }
6942
7001
  googleHeadline: { type: string, description: Google Ads headline }
6943
7002
  googleDescription: { type: string, description: Google Ads description }
@@ -6983,14 +7042,20 @@ components:
6983
7042
  amount: { type: number }
6984
7043
  type: { type: string, enum: [daily, lifetime] }
6985
7044
  metrics: { $ref: '#/components/schemas/AdMetrics' }
6986
- optimizationGoal: { type: [string, "null"], description: "Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION)" }
7045
+ optimizationGoal: { type: [string, "null"], description: "What the delivery system optimizes for. Meta ad set optimization goal (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION), or on LinkedIn the campaign's effective optimizationTargetType (NONE means manual bidding). See the `optimizationGoal` field on `Ad` for the full value spaces." }
6987
7046
  bidStrategy:
6988
7047
  anyOf:
6989
7048
  - $ref: '#/components/schemas/BidStrategy'
6990
7049
  - type: "null"
6991
- description: "Bid strategy for this ad set (overrides campaign level when set)"
6992
- bidAmount: { type: [number, "null"], description: "Bid cap in whole currency units. Populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP." }
7050
+ description: "Bid strategy for this ad set (overrides campaign level when set). Meta and TikTok only; LinkedIn uses `costType` instead."
7051
+ bidAmount: { type: [number, "null"], description: "Bid amount in whole currency units. On Meta/TikTok populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP; on LinkedIn it is the campaign's effective unitCost and pairs with `costType`, where 0 is a real, delivery-stopping value." }
6993
7052
  roasAverageFloor: { type: [number, "null"], description: "Minimum ROAS as a decimal multiplier (2.0 = 2.0x). Populated when bidStrategy is LOWEST_COST_WITH_MIN_ROAS." }
7053
+ costType: { type: [string, "null"], description: "LinkedIn only. Effective cost model (billing event) of the LinkedIn campaign backing this ad set: CPM, CPC or CPV. Null for non-LinkedIn ad sets." }
7054
+ servingStatuses:
7055
+ type: array
7056
+ items: { type: string }
7057
+ description: "LinkedIn only. Why the LinkedIn campaign backing this ad set is (or is not) delivering. A LinkedIn Campaign maps to this ad-set node, so this is the level where LinkedIn's holds actually apply. Empty means no serving data, [\"RUNNABLE\"] means eligible to serve, anything else is a hold. See the `servingStatuses` field on `Ad` for the known values."
7058
+ example: ["RUNNABLE"]
6994
7059
  promotedObject:
6995
7060
  type: [object, "null"]
6996
7061
  description: "Meta promoted object for this ad set (conversion event details)"
@@ -7069,13 +7134,13 @@ components:
7069
7134
  platformObjective: { type: [string, "null"], description: "Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC)" }
7070
7135
  optimizationGoal:
7071
7136
  type: [string, "null"]
7072
- description: "Meta optimization goal shared across ad sets, or comma-separated values when ad sets differ (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION)"
7137
+ description: "Optimization goal shared across ad sets, or comma-separated values when ad sets differ. Meta: e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION. LinkedIn: the campaign optimizationTargetType (e.g. MAX_CLICK, MAX_IMPRESSION, NONE); `NONE` with a manual costType is a campaign LinkedIn will not deliver."
7073
7138
  bidStrategy:
7074
7139
  anyOf:
7075
7140
  - $ref: '#/components/schemas/BidStrategy'
7076
7141
  - type: "null"
7077
7142
  description: "Campaign-level bid strategy. Ad sets inherit this unless they override."
7078
- bidAmount: { type: [number, "null"], description: "Representative bid cap for the campaign bubbled up from the top-spending ad set's `bid_amount` (whole currency units). Populated when the ad-set bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP." }
7143
+ bidAmount: { type: [number, "null"], description: "Representative bid for the campaign, bubbled up from the top-spending ad set (whole currency units). Meta: populated when the ad-set bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. LinkedIn: the campaign unitCost, which has no bidStrategy gate and where 0 is a real, delivery-stopping value rather than unset." }
7079
7144
  roasAverageFloor: { type: [number, "null"], description: "Representative ROAS floor for the campaign — bubbled up from the top-spending ad set. Decimal multiplier (2.0 = 2.0x)." }
7080
7145
  promotedObject:
7081
7146
  type: [object, "null"]
@@ -7146,13 +7211,13 @@ components:
7146
7211
  platformObjective: { type: [string, "null"], description: "Raw Meta campaign objective (e.g. OUTCOME_SALES, OUTCOME_LEADS, OUTCOME_TRAFFIC)" }
7147
7212
  optimizationGoal:
7148
7213
  type: [string, "null"]
7149
- description: "Meta optimization goal shared across ad sets, or comma-separated values when ad sets differ (e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION)"
7214
+ description: "Optimization goal shared across ad sets, or comma-separated values when ad sets differ. Meta: e.g. OFFSITE_CONVERSIONS, VALUE, LEAD_GENERATION. LinkedIn: the campaign optimizationTargetType (e.g. MAX_CLICK, MAX_IMPRESSION, NONE); `NONE` with a manual costType is a campaign LinkedIn will not deliver."
7150
7215
  bidStrategy:
7151
7216
  anyOf:
7152
7217
  - $ref: '#/components/schemas/BidStrategy'
7153
7218
  - type: "null"
7154
7219
  description: "Campaign-level bid strategy. Ad sets inherit this unless they override."
7155
- bidAmount: { type: [number, "null"], description: "Representative bid cap from the top-spending ad set (whole currency units). Populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP." }
7220
+ bidAmount: { type: [number, "null"], description: "Representative bid from the top-spending ad set (whole currency units). Meta: populated when bidStrategy is LOWEST_COST_WITH_BID_CAP or COST_CAP. LinkedIn: the campaign unitCost, ungated, where 0 is a real delivery-stopping value." }
7156
7221
  roasAverageFloor: { type: [number, "null"], description: "Representative ROAS floor from the top-spending ad set. Decimal multiplier (2.0 = 2.0x)." }
7157
7222
  promotedObject:
7158
7223
  type: [object, "null"]
@@ -99,6 +99,18 @@ describe Zernio::AdCreative do
99
99
  end
100
100
  end
101
101
 
102
+ describe 'test attribute "is_serving"' do
103
+ it 'should work' do
104
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
105
+ end
106
+ end
107
+
108
+ describe 'test attribute "serving_hold_reasons"' do
109
+ it 'should work' do
110
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
111
+ end
112
+ end
113
+
102
114
  describe 'test attribute "body"' do
103
115
  it 'should work' do
104
116
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
@@ -153,6 +153,18 @@ describe Zernio::Ad do
153
153
  end
154
154
  end
155
155
 
156
+ describe 'test attribute "cost_type"' do
157
+ it 'should work' do
158
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
159
+ end
160
+ end
161
+
162
+ describe 'test attribute "serving_statuses"' do
163
+ it 'should work' do
164
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
165
+ end
166
+ end
167
+
156
168
  describe 'test attribute "platform_ad_account_name"' do
157
169
  it 'should work' do
158
170
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
@@ -93,6 +93,18 @@ describe Zernio::AdTreeAdSet do
93
93
  end
94
94
  end
95
95
 
96
+ describe 'test attribute "cost_type"' do
97
+ it 'should work' do
98
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
99
+ end
100
+ end
101
+
102
+ describe 'test attribute "serving_statuses"' do
103
+ it 'should work' do
104
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
105
+ end
106
+ end
107
+
96
108
  describe 'test attribute "promoted_object"' do
97
109
  it 'should work' do
98
110
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
@@ -93,6 +93,12 @@ describe Zernio::PostAnalytics do
93
93
  end
94
94
  end
95
95
 
96
+ describe 'test attribute "video_duration_seconds"' do
97
+ it 'should work' do
98
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
99
+ end
100
+ end
101
+
96
102
  describe 'test attribute "engagement_rate"' do
97
103
  it 'should work' do
98
104
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: late-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.637
4
+ version: 0.0.639
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenAPI-Generator
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-08-01 00:00:00.000000000 Z
11
+ date: 2026-08-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: typhoeus
@@ -4919,7 +4919,7 @@ files:
4919
4919
  - spec/models/you_tube_video_retention_response_retention_curve_inner_spec.rb
4920
4920
  - spec/models/you_tube_video_retention_response_spec.rb
4921
4921
  - spec/spec_helper.rb
4922
- - zernio-sdk-0.0.637.gem
4922
+ - zernio-sdk-0.0.639.gem
4923
4923
  - zernio-sdk.gemspec
4924
4924
  homepage: https://openapi-generator.tech
4925
4925
  licenses:
Binary file