late-sdk 0.0.894 → 0.0.896

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 (109) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +26 -3
  3. data/docs/AdAccountsApi.md +446 -0
  4. data/docs/AdAnalyticsResponse.md +1 -1
  5. data/docs/AdAnalyticsResponseAnalytics.md +22 -0
  6. data/docs/AdCampaign.md +1 -1
  7. data/docs/AdCampaignBudget.md +11 -3
  8. data/docs/AdCampaignsApi.md +149 -3
  9. data/docs/AdInsightsApi.md +1 -1
  10. data/docs/AdNegativeKeywordList.md +26 -0
  11. data/docs/AdNegativeKeywordListKeyword.md +22 -0
  12. data/docs/BoostPostRequest.md +6 -4
  13. data/docs/CampaignAnalyticsResponseAnalytics.md +3 -1
  14. data/docs/CampaignAnalyticsResponseAnalyticsImpressionShareCache.md +20 -0
  15. data/docs/CampaignAnalyticsResponseAnalyticsSummary.md +96 -0
  16. data/docs/CampaignAnalyticsResponseCampaign.md +2 -0
  17. data/docs/CreateAdNegativeKeywordList201Response.md +24 -0
  18. data/docs/CreateAdNegativeKeywordListRequest.md +26 -0
  19. data/docs/CreateCallAdRequest.md +8 -2
  20. data/docs/CreateMessagingAdRequest.md +8 -2
  21. data/docs/CtwaAdRequestBody.md +8 -2
  22. data/docs/CtwaAdRequestBodyCreativesInner.md +7 -3
  23. data/docs/DeleteAdNegativeKeywordList200Response.md +20 -0
  24. data/docs/GetAdAnalytics202Response.md +1 -1
  25. data/docs/GetAdNegativeKeywordList200Response.md +24 -0
  26. data/docs/GetAdNegativeKeywordList200ResponseList.md +28 -0
  27. data/docs/ListAdNegativeKeywordLists200Response.md +24 -0
  28. data/docs/MediaItem.md +1 -1
  29. data/docs/MessagingAdsApi.md +10 -10
  30. data/docs/ReplaceAdNegativeKeywordListKeywords200Response.md +22 -0
  31. data/docs/ReplaceAdNegativeKeywordListKeywordsRequest.md +24 -0
  32. data/docs/ReplaceCampaignNegativeKeywordListsRequest.md +20 -0
  33. data/docs/UpdateAdCampaign200Response.md +1 -1
  34. data/docs/UpdateAdCampaignRequest.md +2 -0
  35. data/docs/UpdateAdNegativeKeywordList200Response.md +20 -0
  36. data/docs/UpdateAdNegativeKeywordListRequest.md +24 -0
  37. data/lib/zernio-sdk/api/ad_accounts_api.rb +500 -0
  38. data/lib/zernio-sdk/api/ad_campaigns_api.rb +160 -6
  39. data/lib/zernio-sdk/api/ad_insights_api.rb +2 -2
  40. data/lib/zernio-sdk/api/messaging_ads_api.rb +8 -8
  41. data/lib/zernio-sdk/models/ad_analytics_response.rb +1 -1
  42. data/lib/zernio-sdk/models/ad_analytics_response_analytics.rb +169 -0
  43. data/lib/zernio-sdk/models/ad_campaign.rb +3 -1
  44. data/lib/zernio-sdk/models/ad_campaign_budget.rb +99 -5
  45. data/lib/zernio-sdk/models/ad_negative_keyword_list.rb +209 -0
  46. data/lib/zernio-sdk/models/ad_negative_keyword_list_keyword.rb +222 -0
  47. data/lib/zernio-sdk/models/boost_post_request.rb +38 -7
  48. data/lib/zernio-sdk/models/campaign_analytics_response_analytics.rb +11 -2
  49. data/lib/zernio-sdk/models/campaign_analytics_response_analytics_impression_share_cache.rb +158 -0
  50. data/lib/zernio-sdk/models/campaign_analytics_response_analytics_summary.rb +550 -0
  51. data/lib/zernio-sdk/models/campaign_analytics_response_campaign.rb +11 -1
  52. data/lib/zernio-sdk/models/create_ad_negative_keyword_list201_response.rb +220 -0
  53. data/lib/zernio-sdk/models/create_ad_negative_keyword_list_request.rb +327 -0
  54. data/lib/zernio-sdk/models/create_call_ad_request.rb +94 -3
  55. data/lib/zernio-sdk/models/create_messaging_ad_request.rb +94 -3
  56. data/lib/zernio-sdk/models/ctwa_ad_request_body.rb +95 -4
  57. data/lib/zernio-sdk/models/ctwa_ad_request_body_creatives_inner.rb +67 -21
  58. data/lib/zernio-sdk/models/ctwa_ad_request_body_creatives_inner_video.rb +1 -1
  59. data/lib/zernio-sdk/models/ctwa_ad_request_body_video.rb +1 -1
  60. data/lib/zernio-sdk/models/{ad_campaign_campaign_budget.rb → delete_ad_negative_keyword_list200_response.rb} +35 -48
  61. data/lib/zernio-sdk/models/get_ad_analytics202_response.rb +1 -1
  62. data/lib/zernio-sdk/models/get_ad_negative_keyword_list200_response.rb +199 -0
  63. data/lib/zernio-sdk/models/get_ad_negative_keyword_list200_response_list.rb +227 -0
  64. data/lib/zernio-sdk/models/list_ad_negative_keyword_lists200_response.rb +201 -0
  65. data/lib/zernio-sdk/models/media_item.rb +1 -0
  66. data/lib/zernio-sdk/models/replace_ad_negative_keyword_list_keywords200_response.rb +189 -0
  67. data/lib/zernio-sdk/models/replace_ad_negative_keyword_list_keywords_request.rb +289 -0
  68. data/lib/zernio-sdk/models/replace_campaign_negative_keyword_lists_request.rb +219 -0
  69. data/lib/zernio-sdk/models/update_ad_campaign200_response.rb +1 -1
  70. data/lib/zernio-sdk/models/update_ad_campaign_request.rb +13 -1
  71. data/lib/zernio-sdk/models/update_ad_campaign_request_budget.rb +1 -1
  72. data/lib/zernio-sdk/models/update_ad_negative_keyword_list200_response.rb +178 -0
  73. data/lib/zernio-sdk/models/update_ad_negative_keyword_list_request.rb +296 -0
  74. data/lib/zernio-sdk/version.rb +1 -1
  75. data/lib/zernio-sdk.rb +16 -1
  76. data/openapi.yaml +981 -43
  77. data/spec/api/ad_accounts_api_spec.rb +82 -0
  78. data/spec/api/ad_campaigns_api_spec.rb +29 -3
  79. data/spec/api/ad_insights_api_spec.rb +1 -1
  80. data/spec/api/messaging_ads_api_spec.rb +4 -4
  81. data/spec/models/ad_analytics_response_analytics_spec.rb +48 -0
  82. data/spec/models/ad_campaign_budget_spec.rb +24 -0
  83. data/spec/models/ad_negative_keyword_list_keyword_spec.rb +52 -0
  84. data/spec/models/ad_negative_keyword_list_spec.rb +60 -0
  85. data/spec/models/boost_post_request_spec.rb +7 -1
  86. data/spec/models/campaign_analytics_response_analytics_impression_share_cache_spec.rb +42 -0
  87. data/spec/models/campaign_analytics_response_analytics_spec.rb +6 -0
  88. data/spec/models/campaign_analytics_response_analytics_summary_spec.rb +270 -0
  89. data/spec/models/campaign_analytics_response_campaign_spec.rb +6 -0
  90. data/spec/models/create_ad_negative_keyword_list201_response_spec.rb +54 -0
  91. data/spec/models/create_ad_negative_keyword_list_request_spec.rb +64 -0
  92. data/spec/models/create_call_ad_request_spec.rb +18 -0
  93. data/spec/models/create_messaging_ad_request_spec.rb +18 -0
  94. data/spec/models/ctwa_ad_request_body_creatives_inner_spec.rb +12 -0
  95. data/spec/models/ctwa_ad_request_body_spec.rb +18 -0
  96. data/spec/models/delete_ad_negative_keyword_list200_response_spec.rb +42 -0
  97. data/spec/models/get_ad_negative_keyword_list200_response_list_spec.rb +66 -0
  98. data/spec/models/get_ad_negative_keyword_list200_response_spec.rb +54 -0
  99. data/spec/models/list_ad_negative_keyword_lists200_response_spec.rb +54 -0
  100. data/spec/models/replace_ad_negative_keyword_list_keywords200_response_spec.rb +48 -0
  101. data/spec/models/replace_ad_negative_keyword_list_keywords_request_spec.rb +58 -0
  102. data/spec/models/{ad_campaign_campaign_budget_spec.rb → replace_campaign_negative_keyword_lists_request_spec.rb} +12 -12
  103. data/spec/models/update_ad_campaign_request_spec.rb +6 -0
  104. data/spec/models/update_ad_negative_keyword_list200_response_spec.rb +42 -0
  105. data/spec/models/update_ad_negative_keyword_list_request_spec.rb +58 -0
  106. data/zernio-sdk-0.0.896.gem +0 -0
  107. metadata +66 -6
  108. data/docs/AdCampaignCampaignBudget.md +0 -20
  109. data/zernio-sdk-0.0.894.gem +0 -0
@@ -6,7 +6,7 @@
6
6
  | ---- | ---- | ----------- | ----- |
7
7
  | **backfill_pending** | **Boolean** | Present and true while historical data is being backfilled. | [optional] |
8
8
  | **ad** | [**AdAnalyticsResponseAd**](AdAnalyticsResponseAd.md) | | [optional] |
9
- | **analytics** | [**CampaignAnalyticsResponseAnalytics**](CampaignAnalyticsResponseAnalytics.md) | | [optional] |
9
+ | **analytics** | [**AdAnalyticsResponseAnalytics**](AdAnalyticsResponseAnalytics.md) | | [optional] |
10
10
 
11
11
  ## Example
12
12
 
@@ -0,0 +1,22 @@
1
+ # Zernio::AdAnalyticsResponseAnalytics
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **summary** | [**AdMetrics**](AdMetrics.md) | | [optional] |
8
+ | **daily** | [**Array<CampaignAnalyticsResponseAnalyticsDailyInner>**](CampaignAnalyticsResponseAnalyticsDailyInner.md) | | [optional] |
9
+ | **breakdowns** | **Hash<String, Array<Object>>** | | [optional] |
10
+
11
+ ## Example
12
+
13
+ ```ruby
14
+ require 'zernio-sdk'
15
+
16
+ instance = Zernio::AdAnalyticsResponseAnalytics.new(
17
+ summary: null,
18
+ daily: null,
19
+ breakdowns: null
20
+ )
21
+ ```
22
+
data/docs/AdCampaign.md CHANGED
@@ -13,7 +13,7 @@
13
13
  | **campaign_issues_info** | **Array<Object>** | Platform-reported campaign issues (Meta `issues_info[]`). | [optional] |
14
14
  | **ad_count** | **Integer** | | [optional] |
15
15
  | **budget** | [**AdCampaignBudget**](AdCampaignBudget.md) | | [optional] |
16
- | **campaign_budget** | [**AdCampaignCampaignBudget**](AdCampaignCampaignBudget.md) | | [optional] |
16
+ | **campaign_budget** | [**AdCampaignBudget**](AdCampaignBudget.md) | | [optional] |
17
17
  | **budget_level** | **String** | Canonical CBO/ABO indicator. See AdTreeCampaign.budgetLevel. | [optional] |
18
18
  | **is_budget_schedule_enabled** | **Boolean** | Meta-only. Mirrors Campaign.is_budget_schedule_enabled. | [optional][default to false] |
19
19
  | **currency** | **String** | ISO 4217 currency code for all budget amounts. Budgets are NOT normalized to USD. | [optional] |
@@ -4,8 +4,12 @@
4
4
 
5
5
  | Name | Type | Description | Notes |
6
6
  | ---- | ---- | ----------- | ----- |
7
- | **amount** | **Float** | | [optional] |
8
- | **type** | **String** | | [optional] |
7
+ | **amount** | **Float** | | |
8
+ | **type** | **String** | | |
9
+ | **amount_micros** | **String** | Google only. Exact decimal micros; DAILY uses amount_micros and CUSTOM_PERIOD uses total_amount_micros. | [optional] |
10
+ | **explicitly_shared** | **Boolean** | Google only. True for a shared budget; null when unavailable. Shared writes require allowSharedBudgetUpdate=true; unknown sharing status cannot be overridden. | [optional] |
11
+ | **resource_name** | **String** | Google only. campaign_budget.resource_name, or null when unavailable. | [optional] |
12
+ | **delivery_method** | **String** | Google only. campaign_budget.delivery_method, typically STANDARD, or null when unavailable. | [optional] |
9
13
 
10
14
  ## Example
11
15
 
@@ -14,7 +18,11 @@ require 'zernio-sdk'
14
18
 
15
19
  instance = Zernio::AdCampaignBudget.new(
16
20
  amount: null,
17
- type: null
21
+ type: null,
22
+ amount_micros: null,
23
+ explicitly_shared: null,
24
+ resource_name: null,
25
+ delivery_method: null
18
26
  )
19
27
  ```
20
28
 
@@ -29,8 +29,10 @@ All URIs are relative to *https://zernio.com/api*
29
29
  | [**list_ad_sets**](AdCampaignsApi.md#list_ad_sets) | **GET** /v1/ads/ad-sets | List ad sets |
30
30
  | [**list_ads**](AdCampaignsApi.md#list_ads) | **GET** /v1/ads | List ads |
31
31
  | [**list_bid_strategies**](AdCampaignsApi.md#list_bid_strategies) | **GET** /v1/ads/bid-strategies | List Google Ads portfolio bid strategies |
32
+ | [**list_campaign_negative_keyword_lists**](AdCampaignsApi.md#list_campaign_negative_keyword_lists) | **GET** /v1/ads/campaigns/{campaignId}/negative-keyword-lists | List campaign negative lists |
32
33
  | [**list_campaign_negative_keywords**](AdCampaignsApi.md#list_campaign_negative_keywords) | **GET** /v1/ads/campaigns/{campaignId}/negative-keywords | List campaign-level negative keywords |
33
34
  | [**remove_ad_keyword**](AdCampaignsApi.md#remove_ad_keyword) | **DELETE** /v1/ads/keywords/{keywordId} | Remove a Search keyword |
35
+ | [**replace_campaign_negative_keyword_lists**](AdCampaignsApi.md#replace_campaign_negative_keyword_lists) | **PUT** /v1/ads/campaigns/{campaignId}/negative-keyword-lists | Replace campaign negative lists |
34
36
  | [**replace_campaign_negative_keywords**](AdCampaignsApi.md#replace_campaign_negative_keywords) | **PUT** /v1/ads/campaigns/{campaignId}/negative-keywords | Replace campaign-level negative keywords |
35
37
  | [**update_ad**](AdCampaignsApi.md#update_ad) | **PUT** /v1/ads/{adId} | Update ad |
36
38
  | [**update_ad_campaign**](AdCampaignsApi.md#update_ad_campaign) | **PUT** /v1/ads/campaigns/{campaignId} | Update a campaign |
@@ -189,7 +191,7 @@ end
189
191
 
190
192
  Boost post as ad
191
193
 
192
- Creates a paid ad from an existing published post, keeping the post's engagement. By default it provisions the whole hierarchy (campaign, ad set, ad). **Attach shape (Meta).** Send `adSetId` to put the ad under an EXISTING ad set instead, so that ad set keeps its learning phase. It then owns `budget`, `schedule` and `targeting`, and sending any of those alongside `adSetId` is a 400 rather than a silent drop. `budget` is required only without `adSetId`. `instagramAccountId`, `destinationType` and `adSetId` are Meta-only and return 400 on other platforms. **Retries.** Boosts are NOT idempotent and can take minutes when Meta requires re-hosting an Instagram video, so do not retry on client timeout. Send an Idempotency-Key header to make retries safe: same key and body replays the original 201, and distinct keys always create distinct ads. Without the header, an identical request is treated as a retry: while one is in flight it returns 409, and within 10 minutes of a completed boost it returns the already-created ad instead of creating another. To intentionally duplicate an ad, send distinct Idempotency-Keys (or vary the body, e.g. the name).
194
+ Creates a paid ad from an existing published post, keeping the post's engagement. By default it provisions the whole hierarchy (campaign, ad set, ad). **Attach shape (Meta).** Send `adSetId` to put the ad under an EXISTING ad set instead, so that ad set keeps its learning phase. It then owns `budget`, `schedule` and `targeting`, and sending any of those alongside `adSetId` is a 400 rather than a silent drop. `budget` is required only without `adSetId`. `instagramAccountId`, `destinationType`, `whatsappPhoneNumber` and `adSetId` are Meta-only and return 400 on other platforms. **Messaging boosts (Meta).** Use `goal: engagement` with `callToAction: WHATSAPP_MESSAGE`, `MESSAGE_PAGE`, or `INSTAGRAM_MESSAGE`. The CTA implies WHATSAPP, MESSENGER, or INSTAGRAM_DIRECT respectively; `destinationType` alone also selects the matching CTA. Omit `linkUrl`. The campaign uses OUTCOME_ENGAGEMENT and the ad set uses CONVERSATIONS with the promoted Page. Optional `whatsappPhoneNumber` selects a number already paired with that Page. Conflicting CTA/destination, instant form, goal, or optimizationGoal inputs return 400. Attach requires the target ad set destination to match. Existing post references preserve social proof; an Instagram reel rejected by Meta is not re-uploaded as a new post for a messaging boost. **Retries.** Boosts are NOT idempotent and can take minutes when Meta requires re-hosting an Instagram video, so do not retry on client timeout. Send an Idempotency-Key header to make retries safe: same key and body replays the original 201, and distinct keys always create distinct ads. Without the header, an identical request is treated as a retry: while one is in flight it returns 409, and within 10 minutes of a completed boost it returns the already-created ad instead of creating another. To intentionally duplicate an ad, send distinct Idempotency-Keys (or vary the body, e.g. the name).
193
195
 
194
196
  ### Examples
195
197
 
@@ -1529,7 +1531,7 @@ end
1529
1531
 
1530
1532
  List campaigns
1531
1533
 
1532
- Returns campaigns as virtual aggregations over ad documents grouped by platform campaign ID. Metrics (spend, impressions, clicks, etc.) are summed across all ads in each campaign. Campaign status is derived from child ad statuses (active > pending_review > paused > error > completed > cancelled > rejected).
1534
+ Returns campaigns as virtual aggregations over ad documents grouped by platform campaign ID. Metrics (spend, impressions, clicks, etc.) are summed across all ads in each campaign. Campaign status is derived from child ad statuses (active > pending_review > paused > error > completed > cancelled > rejected). Google campaign budgets include amountMicros, explicitlyShared, resourceName and deliveryMethod after the next successful sync. This endpoint does not fetch Google live.
1533
1535
 
1534
1536
  ### Examples
1535
1537
 
@@ -1964,6 +1966,79 @@ end
1964
1966
  - **Accept**: application/json
1965
1967
 
1966
1968
 
1969
+ ## list_campaign_negative_keyword_lists
1970
+
1971
+ > <ListAdNegativeKeywordLists200Response> list_campaign_negative_keyword_lists(campaign_id, opts)
1972
+
1973
+ List campaign negative lists
1974
+
1975
+ Returns shared negative keyword lists attached to the campaign, separate from campaign-level negative keywords. Google Ads shared negative keyword lists (shared_set type NEGATIVE_KEYWORDS). Reads are cached for 10 minutes; quota exhaustion may return the last successful result for up to 7 days with stale=true. Customer selection is limited to this connection and its account scope.
1976
+
1977
+ ### Examples
1978
+
1979
+ ```ruby
1980
+ require 'time'
1981
+ require 'zernio-sdk'
1982
+ # setup authorization
1983
+ Zernio.configure do |config|
1984
+ # Configure Bearer authorization (JWT): bearerAuth
1985
+ config.access_token = 'YOUR_BEARER_TOKEN'
1986
+ end
1987
+
1988
+ api_instance = Zernio::AdCampaignsApi.new
1989
+ campaign_id = 'campaign_id_example' # String |
1990
+ opts = {
1991
+ platform: 'facebook' # String |
1992
+ }
1993
+
1994
+ begin
1995
+ # List campaign negative lists
1996
+ result = api_instance.list_campaign_negative_keyword_lists(campaign_id, opts)
1997
+ p result
1998
+ rescue Zernio::ApiError => e
1999
+ puts "Error when calling AdCampaignsApi->list_campaign_negative_keyword_lists: #{e}"
2000
+ end
2001
+ ```
2002
+
2003
+ #### Using the list_campaign_negative_keyword_lists_with_http_info variant
2004
+
2005
+ This returns an Array which contains the response data, status code and headers.
2006
+
2007
+ > <Array(<ListAdNegativeKeywordLists200Response>, Integer, Hash)> list_campaign_negative_keyword_lists_with_http_info(campaign_id, opts)
2008
+
2009
+ ```ruby
2010
+ begin
2011
+ # List campaign negative lists
2012
+ data, status_code, headers = api_instance.list_campaign_negative_keyword_lists_with_http_info(campaign_id, opts)
2013
+ p status_code # => 2xx
2014
+ p headers # => { ... }
2015
+ p data # => <ListAdNegativeKeywordLists200Response>
2016
+ rescue Zernio::ApiError => e
2017
+ puts "Error when calling AdCampaignsApi->list_campaign_negative_keyword_lists_with_http_info: #{e}"
2018
+ end
2019
+ ```
2020
+
2021
+ ### Parameters
2022
+
2023
+ | Name | Type | Description | Notes |
2024
+ | ---- | ---- | ----------- | ----- |
2025
+ | **campaign_id** | **String** | | |
2026
+ | **platform** | **String** | | [optional] |
2027
+
2028
+ ### Return type
2029
+
2030
+ [**ListAdNegativeKeywordLists200Response**](ListAdNegativeKeywordLists200Response.md)
2031
+
2032
+ ### Authorization
2033
+
2034
+ [bearerAuth](../README.md#bearerAuth)
2035
+
2036
+ ### HTTP request headers
2037
+
2038
+ - **Content-Type**: Not defined
2039
+ - **Accept**: application/json
2040
+
2041
+
1967
2042
  ## list_campaign_negative_keywords
1968
2043
 
1969
2044
  > <ListCampaignNegativeKeywords200Response> list_campaign_negative_keywords(campaign_id, opts)
@@ -2106,6 +2181,77 @@ end
2106
2181
  - **Accept**: application/json
2107
2182
 
2108
2183
 
2184
+ ## replace_campaign_negative_keyword_lists
2185
+
2186
+ > <ReplaceAdNegativeKeywordListKeywords200Response> replace_campaign_negative_keyword_lists(campaign_id, replace_campaign_negative_keyword_lists_request)
2187
+
2188
+ Replace campaign negative lists
2189
+
2190
+ Sets the full desired set of shared negative keyword list associations on this campaign. Send listIds=[] to detach all negative keyword lists. Only campaign_shared_set links are changed; the lists and their keywords are preserved. Every list must belong to the campaign customer and have type NEGATIVE_KEYWORDS.
2191
+
2192
+ ### Examples
2193
+
2194
+ ```ruby
2195
+ require 'time'
2196
+ require 'zernio-sdk'
2197
+ # setup authorization
2198
+ Zernio.configure do |config|
2199
+ # Configure Bearer authorization (JWT): bearerAuth
2200
+ config.access_token = 'YOUR_BEARER_TOKEN'
2201
+ end
2202
+
2203
+ api_instance = Zernio::AdCampaignsApi.new
2204
+ campaign_id = 'campaign_id_example' # String |
2205
+ replace_campaign_negative_keyword_lists_request = Zernio::ReplaceCampaignNegativeKeywordListsRequest.new({list_ids: ['list_ids_example']}) # ReplaceCampaignNegativeKeywordListsRequest |
2206
+
2207
+ begin
2208
+ # Replace campaign negative lists
2209
+ result = api_instance.replace_campaign_negative_keyword_lists(campaign_id, replace_campaign_negative_keyword_lists_request)
2210
+ p result
2211
+ rescue Zernio::ApiError => e
2212
+ puts "Error when calling AdCampaignsApi->replace_campaign_negative_keyword_lists: #{e}"
2213
+ end
2214
+ ```
2215
+
2216
+ #### Using the replace_campaign_negative_keyword_lists_with_http_info variant
2217
+
2218
+ This returns an Array which contains the response data, status code and headers.
2219
+
2220
+ > <Array(<ReplaceAdNegativeKeywordListKeywords200Response>, Integer, Hash)> replace_campaign_negative_keyword_lists_with_http_info(campaign_id, replace_campaign_negative_keyword_lists_request)
2221
+
2222
+ ```ruby
2223
+ begin
2224
+ # Replace campaign negative lists
2225
+ data, status_code, headers = api_instance.replace_campaign_negative_keyword_lists_with_http_info(campaign_id, replace_campaign_negative_keyword_lists_request)
2226
+ p status_code # => 2xx
2227
+ p headers # => { ... }
2228
+ p data # => <ReplaceAdNegativeKeywordListKeywords200Response>
2229
+ rescue Zernio::ApiError => e
2230
+ puts "Error when calling AdCampaignsApi->replace_campaign_negative_keyword_lists_with_http_info: #{e}"
2231
+ end
2232
+ ```
2233
+
2234
+ ### Parameters
2235
+
2236
+ | Name | Type | Description | Notes |
2237
+ | ---- | ---- | ----------- | ----- |
2238
+ | **campaign_id** | **String** | | |
2239
+ | **replace_campaign_negative_keyword_lists_request** | [**ReplaceCampaignNegativeKeywordListsRequest**](ReplaceCampaignNegativeKeywordListsRequest.md) | | |
2240
+
2241
+ ### Return type
2242
+
2243
+ [**ReplaceAdNegativeKeywordListKeywords200Response**](ReplaceAdNegativeKeywordListKeywords200Response.md)
2244
+
2245
+ ### Authorization
2246
+
2247
+ [bearerAuth](../README.md#bearerAuth)
2248
+
2249
+ ### HTTP request headers
2250
+
2251
+ - **Content-Type**: application/json
2252
+ - **Accept**: application/json
2253
+
2254
+
2109
2255
  ## replace_campaign_negative_keywords
2110
2256
 
2111
2257
  > <ReplaceCampaignNegativeKeywords200Response> replace_campaign_negative_keywords(campaign_id, replace_campaign_negative_keywords_request)
@@ -2254,7 +2400,7 @@ end
2254
2400
 
2255
2401
  Update a campaign
2256
2402
 
2257
- Campaign-level edits. Send at least one of `budget`, `bidStrategy`, `portfolioBidStrategyId`, `name` or `platformSpecificData`. An unsupported field is always an error, never a silent drop. | Body field | Meta | Google | Others | |---|---|---|---| | `bidStrategy` | Yes | Yes | 501 | | `bidAmount`, `roasAverageFloor` | 400 (ad-set level) | Yes | 400 | | `portfolioBidStrategyId` | 400 | Yes | 400 | | `budget` (CBO; ABO returns 409) | Yes | 501 | 501 | | `name` | Yes | 501 | 501 | | `platformSpecificData.spendCap` | Yes | 400 | 400 | | `accountId` (empty campaigns) | Yes | - | - | On Google: `LOWEST_COST_WITHOUT_CAP` = Maximize Conversions, `COST_CAP` + `bidAmount` = Target CPA, `LOWEST_COST_WITH_MIN_ROAS` + `roasAverageFloor` = Target ROAS, `LOWEST_COST_WITH_BID_CAP` + `bidAmount` = Maximize Clicks with a CPC ceiling; `portfolioBidStrategyId` attaches a portfolio strategy instead (exclusive with `bidStrategy`). Setting the standard triplet on a campaign that is currently on a PORTFOLIO strategy is rejected: detach it in Google Ads first, since it is shared across campaigns. `accountId` forwards the update straight to Meta for a campaign with zero ads, which would otherwise 404; the response then carries `updated: 0`.
2403
+ Campaign-level edits. Send at least one of `budget`, `bidStrategy`, `portfolioBidStrategyId`, `name` or `platformSpecificData`. An unsupported field is always an error, never a silent drop. | Body field | Meta | Google | Others | |---|---|---|---| | `bidStrategy` | Yes | Yes | 501 | | `bidAmount`, `roasAverageFloor` | 400 (ad-set level) | Yes | 400 | | `portfolioBidStrategyId` | 400 | Yes | 400 | | `budget` (CBO; ABO returns 409) | Yes | Daily only | 501 | | `name` | Yes | 501 | 501 | | `platformSpecificData.spendCap` | Yes | 400 | 400 | | `accountId` (empty campaigns) | Yes | - | - | On Google: `LOWEST_COST_WITHOUT_CAP` = Maximize Conversions, `COST_CAP` + `bidAmount` = Target CPA, `LOWEST_COST_WITH_MIN_ROAS` + `roasAverageFloor` = Target ROAS, `LOWEST_COST_WITH_BID_CAP` + `bidAmount` = Maximize Clicks with a CPC ceiling; `portfolioBidStrategyId` attaches a portfolio strategy instead (exclusive with `bidStrategy`). Setting the standard triplet on a campaign that is currently on a PORTFOLIO strategy is rejected: detach it in Google Ads first, since it is shared across campaigns. Google budget updates read the current budget before mutation. Shared budgets return 409 unless allowSharedBudgetUpdate=true is explicitly supplied, because the change affects every campaign using that budget. Unknown sharing state also returns 409. `accountId` forwards the update straight to Meta for a campaign with zero ads, which would otherwise 404; the response then carries `updated: 0`.
2258
2404
 
2259
2405
  ### Examples
2260
2406
 
@@ -466,7 +466,7 @@ end
466
466
 
467
467
  Get campaign analytics
468
468
 
469
- Returns performance analytics for a whole campaign in one call: summary metrics, a daily timeline over the requested date range (summed across the campaign's ads), and optional demographic breakdowns. Breakdowns are fetched live from Meta at the campaign level (one call per dimension, no per-ad fan-out), so an agency dashboard gets campaign-level age/gender/etc. without summing thousands of per-ad reads. `campaignId` is the platform campaign id; pass `platform` when a campaign id could be ambiguous across platforms. If no date range is provided, defaults to the last 90 days. Date range is capped at 730 days max.
469
+ Returns performance analytics for a whole campaign in one call: summary metrics, a daily timeline over the requested date range (summed across the campaign's ads), and optional demographic breakdowns. Breakdowns are fetched live from Meta at the campaign level (one call per dimension, no per-ad fan-out), so an agency dashboard gets campaign-level age/gender/etc. without summing thousands of per-ad reads. `campaignId` is the platform campaign id; pass `platform` when a campaign id could be ambiguous across platforms. If no date range is provided, defaults to the last 90 days. Date range is capped at 730 days max. Google adds searchImpressionShare, searchBudgetLostImpressionShare, searchRankLostImpressionShare, searchTopImpressionShare and searchAbsoluteTopImpressionShare under analytics.summary for the requested inclusive range. These ratios are queried together without daily segmentation and cached for 10 minutes. Unavailable values are null. analytics.impressionShareCache reports cachedAt and stale independently of synced metrics.
470
470
 
471
471
  ### Examples
472
472
 
@@ -0,0 +1,26 @@
1
+ # Zernio::AdNegativeKeywordList
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **id** | **String** | Google shared set id. | [optional] |
8
+ | **resource_name** | **String** | Google shared set resource name. | [optional] |
9
+ | **name** | **String** | List name. | [optional] |
10
+ | **member_count** | **Integer** | Number of keywords in the list. | [optional] |
11
+ | **reference_count** | **Integer** | Number of resources referencing the list. | [optional] |
12
+
13
+ ## Example
14
+
15
+ ```ruby
16
+ require 'zernio-sdk'
17
+
18
+ instance = Zernio::AdNegativeKeywordList.new(
19
+ id: null,
20
+ resource_name: null,
21
+ name: null,
22
+ member_count: null,
23
+ reference_count: null
24
+ )
25
+ ```
26
+
@@ -0,0 +1,22 @@
1
+ # Zernio::AdNegativeKeywordListKeyword
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **criterion_id** | **String** | Google shared criterion id. | [optional] |
8
+ | **text** | **String** | Keyword text. | [optional] |
9
+ | **match_type** | **String** | | [optional] |
10
+
11
+ ## Example
12
+
13
+ ```ruby
14
+ require 'zernio-sdk'
15
+
16
+ instance = Zernio::AdNegativeKeywordListKeyword.new(
17
+ criterion_id: null,
18
+ text: null,
19
+ match_type: null
20
+ )
21
+ ```
22
+
@@ -13,7 +13,8 @@
13
13
  | **ad_set_id** | **String** | Meta only. Attach the boosted post to this existing ad set instead of creating a campaign. The ad set then owns budget, schedule and targeting; sending those too is a 400. | [optional] |
14
14
  | **budget** | [**BoostPostRequestBudget**](BoostPostRequestBudget.md) | | [optional] |
15
15
  | **instagram_account_id** | **String** | Meta only. Instagram identity the ad runs AS (creative.instagram_user_id), overriding the account linked to the Page. Live-verified against a Page-post creative. | [optional] |
16
- | **destination_type** | **String** | Meta only. Ad-set destination_type: where the click LANDS, as opposed to instagramAccountId which is who the ad runs as. Lead ads force ON_AD and ignore this. | [optional] |
16
+ | **destination_type** | **String** | Meta only. Ad-set destination_type: where the click LANDS, as opposed to instagramAccountId which is who the ad runs as. Messaging destinations imply their matching CTA and require goal engagement. Lead ads use ON_AD; combining an instant form with a messaging destination is rejected. | [optional] |
17
+ | **whatsapp_phone_number** | **String** | Meta WhatsApp only. E.164 number already paired with the Page. Omit to use the default pairing. Requires WHATSAPP destinationType or WHATSAPP_MESSAGE callToAction. | [optional] |
17
18
  | **currency** | **String** | ISO 4217 currency code matching the ad account&#39;s currency. Meta only. Optional: Zernio resolves it from the ad account when omitted. The value selects the minor-unit exponent Zernio converts budget/bid amounts by before calling Meta (most currencies are cents; zero-decimal currencies like JPY/KRW are sent as-is). | [optional] |
18
19
  | **schedule** | [**BoostPostRequestSchedule**](BoostPostRequestSchedule.md) | | [optional] |
19
20
  | **targeting** | [**BoostPostRequestTargeting**](BoostPostRequestTargeting.md) | | [optional] |
@@ -27,14 +28,14 @@
27
28
  | **special_ad_category_country** | **Array&lt;String&gt;** | Meta (metaads) only. 2-letter ISO country codes the special ad category applies to. Requires specialAdCategories to be set (400 otherwise). | [optional] |
28
29
  | **regional_regulated_categories** | **Array&lt;String&gt;** | Meta only. Regional regulation categories required when the ad set targets certain countries (e.g. BRAZIL_REGULATION, SINGAPORE_UNIVERSAL, TAIWAN_UNIVERSAL, THAILAND_UNIVERSAL, AUSTRALIA_FINSERV, INDIA_FINSERV, TAIWAN_FINSERV). Forwarded to the ad set. | [optional] |
29
30
  | **regional_regulation_identities** | **Hash&lt;String, Integer&gt;** | Meta only. Beneficiary/payer entity IDs for regionalRegulatedCategories. Values are numeric IDs from Meta verification. Keys vary by category (e.g. universal_beneficiary / universal_payer for BRAZIL_REGULATION and THAILAND_UNIVERSAL). If omitted, Meta uses Ads Manager defaults when configured. | [optional] |
30
- | **link_url** | **String** | Destination URL for the CTA button. Send it together with &#x60;callToAction&#x60;. **Meta**: adds a top-level &#x60;call_to_action&#x60; to the post-reference creative. This is what gives a &#x60;traffic&#x60; boost a clickable destination without replacing the creative and losing the post&#39;s social proof. Ignored when &#x60;leadGenFormId&#x60; is set, which supplies its own destination. Live-verified against a Page-post creative. **TikTok**: maps to &#x60;landing_page_url&#x60; on the Spark Ad creative (&#x60;AdcreateCreatives.landing_page_url&#x60;); Spark Ads have no clickable destination without it. Ignored on LinkedIn / Pinterest / X / Google, which infer the destination from the boosted post. | [optional] |
31
- | **call_to_action** | **String** | CTA button label. Send it together with &#x60;linkUrl&#x60;: a CTA without a destination produces a button that goes nowhere, so sending one alone is a 400. **Meta**: the CTA enum of POST /v1/ads/create plus &#x60;VIEW_INSTAGRAM_PROFILE&#x60;, which is accepted on boost only. For that value &#x60;linkUrl&#x60; is typically the Instagram profile URL. **TikTok**: pass-through to &#x60;call_to_action&#x60; on the Spark Ad creative; the platform validates the value. See TikTok&#39;s \&quot;Enumeration - Call-to-Action\&quot;. | [optional] |
31
+ | **link_url** | **String** | Website URL for non-messaging CTA buttons. Send it with &#x60;callToAction&#x60;. Omit for messaging boosts. **Meta**: adds a top-level &#x60;call_to_action&#x60; to the post-reference creative. This is what gives a &#x60;traffic&#x60; boost a clickable destination without replacing the creative and losing the post&#39;s social proof. Ignored when &#x60;leadGenFormId&#x60; is set, which supplies its own destination. Live-verified against a Page-post creative. **TikTok**: maps to &#x60;landing_page_url&#x60; on the Spark Ad creative (&#x60;AdcreateCreatives.landing_page_url&#x60;); Spark Ads have no clickable destination without it. Ignored on LinkedIn / Pinterest / X / Google, which infer the destination from the boosted post. | [optional] |
32
+ | **call_to_action** | **String** | CTA button label. Non-messaging CTAs require &#x60;linkUrl&#x60;. WHATSAPP_MESSAGE, MESSAGE_PAGE, and INSTAGRAM_MESSAGE do not require a URL and reject linkUrl. **Meta**: the CTA enum of POST /v1/ads/create plus &#x60;VIEW_INSTAGRAM_PROFILE&#x60;, &#x60;WHATSAPP_MESSAGE&#x60;, &#x60;MESSAGE_PAGE&#x60;, and &#x60;INSTAGRAM_MESSAGE&#x60;. VIEW_INSTAGRAM_PROFILE requires linkUrl; the messaging CTAs select their destination automatically. **TikTok**: pass-through to &#x60;call_to_action&#x60; on the Spark Ad creative; the platform validates the value. See TikTok&#39;s \&quot;Enumeration - Call-to-Action\&quot;. | [optional] |
32
33
  | **spark_auth_code** | **String** | TikTok-only. Spark Code (creator&#39;s &#x60;auth_code&#x60;) authorizing cross-creator Spark Ads: the advertiser can boost a video owned by a DIFFERENT TikTok account. Without this, boosts are limited to videos owned by the same account running the ads (same-BC creators only). The creator generates the code in their TikTok app&#39;s Promote settings and shares it with the advertiser. Maps to &#x60;auth_code&#x60; on the creative entry of /v2/ad/create/. | [optional] |
33
34
  | **dsa_beneficiary** | **String** | Legal entity that benefits from the ad. Required when targeting EU users (EU DSA, Article 26). Optional if the ad account has a default beneficiary: set it once via &#x60;PATCH /v1/ads/accounts&#x60; or in Meta Ads Manager, and Meta fills it in whenever the field is omitted. | [optional] |
34
35
  | **dsa_payor** | **String** | Legal entity that pays for the ad. Can differ from &#x60;dsaBeneficiary&#x60; (for example, an agency paying for a client&#39;s ads). Same rules as &#x60;dsaBeneficiary&#x60;: required for EU targeting unless the ad account has a default payor. | [optional] |
35
36
  | **lead_gen_form_id** | **String** | Lead Gen form ID to attach to the boosted ad&#39;s creative. REQUIRED when &#x60;goal&#x60; is &#x60;lead_generation&#x60;. On Meta this is the leadgen_forms ID (create one via POST /v1/ads/lead-forms). On LinkedIn this is the adForm ID (create one via POST /v1/ads/lead-forms with a LinkedIn account); the creative&#39;s &#x60;leadgenCallToAction.destination&#x60; is set to &#x60;urn:li:adForm:{id}&#x60;. Ignored for other goals. | [optional] |
36
37
  | **status** | **String** | Meta, TikTok, and LinkedIn. Publish state of the created entities. Omitted or ACTIVE publishes live (default); PAUSED creates them paused so you can review before they spend. On LinkedIn the whole campaign group, campaign, and creative hierarchy stays PAUSED (intendedStatus PAUSED on each). | [optional] |
37
- | **optimization_goal** | **String** | Meta only. Explicit ad-set &#x60;optimization_goal&#x60; override. When omitted, defaults to the value derived from &#x60;goal&#x60;. The value must be compatible with the objective Meta derives from &#x60;goal&#x60;, not with the objective used by &#x60;POST /v1/ads/create&#x60; for the same &#x60;goal&#x60; name: boost maps &#x60;goal: \&quot;engagement\&quot;&#x60; to objective &#x60;OUTCOME_AWARENESS&#x60;, which accepts &#x60;REACH&#x60;, &#x60;IMPRESSIONS&#x60;, &#x60;AD_RECALL_LIFT&#x60;, or THRUPLAY-class values, and rejects &#x60;POST_ENGAGEMENT&#x60; (that value is only valid under &#x60;OUTCOME_ENGAGEMENT&#x60;, which create uses for the same goal name). | [optional] |
38
+ | **optimization_goal** | **String** | Meta only. Explicit ad-set &#x60;optimization_goal&#x60; override. When omitted, defaults to the value derived from &#x60;goal&#x60;. Messaging boosts always use CONVERSATIONS and reject another optimizationGoal. Otherwise the value must be compatible with the objective Meta derives from &#x60;goal&#x60;, not with the objective used by &#x60;POST /v1/ads/create&#x60; for the same &#x60;goal&#x60; name: boost maps &#x60;goal: \&quot;engagement\&quot;&#x60; to objective &#x60;OUTCOME_AWARENESS&#x60;, which accepts &#x60;REACH&#x60;, &#x60;IMPRESSIONS&#x60;, &#x60;AD_RECALL_LIFT&#x60;, or THRUPLAY-class values, and rejects &#x60;POST_ENGAGEMENT&#x60; (that value is only valid under &#x60;OUTCOME_ENGAGEMENT&#x60;, which create uses for the same goal name). | [optional] |
38
39
 
39
40
  ## Example
40
41
 
@@ -52,6 +53,7 @@ instance = Zernio::BoostPostRequest.new(
52
53
  budget: null,
53
54
  instagram_account_id: null,
54
55
  destination_type: null,
56
+ whatsapp_phone_number: null,
55
57
  currency: USD,
56
58
  schedule: null,
57
59
  targeting: null,
@@ -4,7 +4,8 @@
4
4
 
5
5
  | Name | Type | Description | Notes |
6
6
  | ---- | ---- | ----------- | ----- |
7
- | **summary** | [**AdMetrics**](AdMetrics.md) | | [optional] |
7
+ | **summary** | [**CampaignAnalyticsResponseAnalyticsSummary**](CampaignAnalyticsResponseAnalyticsSummary.md) | | [optional] |
8
+ | **impression_share_cache** | [**CampaignAnalyticsResponseAnalyticsImpressionShareCache**](CampaignAnalyticsResponseAnalyticsImpressionShareCache.md) | | [optional] |
8
9
  | **daily** | [**Array&lt;CampaignAnalyticsResponseAnalyticsDailyInner&gt;**](CampaignAnalyticsResponseAnalyticsDailyInner.md) | | [optional] |
9
10
  | **breakdowns** | **Hash&lt;String, Array&lt;Object&gt;&gt;** | | [optional] |
10
11
 
@@ -15,6 +16,7 @@ require 'zernio-sdk'
15
16
 
16
17
  instance = Zernio::CampaignAnalyticsResponseAnalytics.new(
17
18
  summary: null,
19
+ impression_share_cache: null,
18
20
  daily: null,
19
21
  breakdowns: null
20
22
  )
@@ -0,0 +1,20 @@
1
+ # Zernio::CampaignAnalyticsResponseAnalyticsImpressionShareCache
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **cached_at** | **Time** | | [optional] |
8
+ | **stale** | **Boolean** | | [optional] |
9
+
10
+ ## Example
11
+
12
+ ```ruby
13
+ require 'zernio-sdk'
14
+
15
+ instance = Zernio::CampaignAnalyticsResponseAnalyticsImpressionShareCache.new(
16
+ cached_at: null,
17
+ stale: null
18
+ )
19
+ ```
20
+
@@ -0,0 +1,96 @@
1
+ # Zernio::CampaignAnalyticsResponseAnalyticsSummary
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **spend** | **Float** | | [optional] |
8
+ | **impressions** | **Integer** | | [optional] |
9
+ | **reach** | **Integer** | Unique people reached in the requested date range. Meta (facebook/instagram) and TikTok: the platform&#39;s own de-duplicated reach for the exact range, fetched live and cached up to ~1 hour (may lag recent delivery; on a transient platform error the value temporarily falls back to a sum of per-day reach, which overcounts people reached on multiple days or by multiple child ads). Because it is de-duplicated, reach is NOT additive on these platforms: neither daily values nor child nodes sum to the range total. Google, LinkedIn, X, Pinterest and OpenAI report 0 (reach not synced). Frequency (impressions / reach) is only meaningful for Meta and TikTok. | [optional] |
10
+ | **clicks** | **Integer** | | [optional] |
11
+ | **ctr** | **Float** | Click-through rate (%) | [optional] |
12
+ | **cpc** | **Float** | Cost per click | [optional] |
13
+ | **cpm** | **Float** | Cost per 1000 impressions | [optional] |
14
+ | **engagement** | **Integer** | | [optional] |
15
+ | **conversions** | **Float** | Count of conversion events over the requested date range. FRACTIONAL: attribution splits one conversion across touchpoints and Google additionally reports modeled conversions, so values like 0.347 are normal. Meta: events matching the campaign&#39;s promoted_object.custom_event_type (PURCHASE, LEAD, etc.). Google: the account&#39;s tracked conversions. X and LinkedIn: their reported website/lead conversions (added 2026-07). 0 for non-conversion campaigns or when no events have fired. | [optional] |
16
+ | **all_conversions** | **Float** | All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept. | [optional] |
17
+ | **cost_per_conversion** | **Float** | Derived spend / conversions in the same currency as spend. 0 when conversions is 0. | [optional] |
18
+ | **actions** | **Hash&lt;String, Integer&gt;** | Per-action-type counts summed over the date range, keyed by the platform&#39;s action-type names. Meta: raw Insights action_type keys (link_click, offsite_conversion.fb_pixel_purchase, onsite_conversion.lead_grouped, ...), covering both engagement and conversion events. TikTok: pixel conversions (purchase, add_to_cart, initiate_checkout, view_content, complete_payment, lead) plus the paid-engagement family (follow, post_reaction for paid likes, comment, share). Follow is how FOLLOWERS-goal campaigns report their result. X: conversion types (purchase, sign_up, site_visit, download, custom). LinkedIn: conversion types (post_click, post_view, lead_gen). Google returns {} (its per-action names aren&#39;t synced per ad). Empty object when no actions are reported. NOTE: keys differ by platform, so branch on the ad&#39;s platform when interpreting them. | [optional] |
19
+ | **action_values** | **Hash&lt;String, Float&gt;** | Monetary mirror of &#x60;actions&#x60;, from Meta&#39;s Insights &#x60;action_values[]&#x60; array. Same keying: values are the revenue attributed to each action_type, in ad-account native currency (same unit as &#x60;spend&#x60;; see the campaign node&#39;s &#x60;currency&#x60; field). Use this to compute revenue-per-event (e.g. avg purchase value). Meta-only; other platforms return {}. | [optional] |
20
+ | **purchase_value** | **Float** | Convenience sum of purchase-type action values, picked from &#x60;actionValues&#x60; via the same priority list as &#x60;conversions&#x60; so both fields describe the same events. In ad-account native currency. 0 when the campaign has no purchase event configured. Meta-only. | [optional] |
21
+ | **roas** | **Float** | Return on ad spend, derived as &#x60;purchaseValue / spend&#x60;. 0 when &#x60;spend&#x60; is 0. Equivalent to Meta&#39;s &#x60;purchase_roas&#x60; under default attribution. At ad-set and campaign levels this is recomputed from summed purchaseValue + spend (NOT averaged across children) so it&#39;s mathematically correct at every rollup level. | [optional] |
22
+ | **cost_per_action** | **Hash&lt;String, Float&gt;** | Derived &#x60;spend / actions[type]&#x60; for every action type with a non-zero count, in ad-account native currency. Same keys as &#x60;actions&#x60;. Rounded to 4 decimals because cheap actions cost well under a cent. Recomputed from summed spend + counts at every rollup level. Empty object when spend is 0 or no actions are reported. | [optional] |
23
+ | **outbound_clicks** | **Integer** | Clicks leading off Meta&#39;s surfaces to the advertiser&#39;s destination. Meta-only; other platforms report 0. | [optional] |
24
+ | **outbound_clicks_ctr** | **Float** | Derived &#x60;outboundClicks / impressions * 100&#x60;, recomputed from sums at every rollup level. | [optional] |
25
+ | **inline_link_clicks** | **Integer** | In-session link clicks. Differs from the attributed &#x60;link_click&#x60; count in &#x60;actions&#x60;/&#x60;engagementBreakdown.linkClicks&#x60;, which uses the attribution window. Meta-only. | [optional] |
26
+ | **inline_link_click_ctr** | **Float** | Derived &#x60;inlineLinkClicks / impressions * 100&#x60;, recomputed from sums at every rollup level. | [optional] |
27
+ | **unique_clicks** | **Integer** | People who clicked at least once. NOT additive: summed across days/children it overcounts people who clicked on multiple days or ads, so treat rollups as an upper bound (same caveat as &#x60;reach&#x60;). Meta-only. | [optional] |
28
+ | **unique_ctr** | **Float** | Derived &#x60;uniqueClicks / impressions * 100&#x60; (NOT Meta&#39;s reach-based unique_ctr). Inherits the non-additivity caveat of &#x60;uniqueClicks&#x60;. | [optional] |
29
+ | **video_play_actions** | **Integer** | Number of times the video started playing, summed over the date range and across children at ad-set/campaign level. 0 for non-video ads. Sources: Meta &#x60;video_play_actions&#x60;, TikTok &#x60;video_play_actions&#x60;. | [optional] |
30
+ | **video30_sec_watched_actions** | **Integer** | Views of at least 30 seconds (or to the end, for shorter videos). Sources: Meta &#x60;video_30_sec_watched_actions&#x60; (Meta only). | [optional] |
31
+ | **video_thruplay_watched_actions** | **Integer** | ThruPlays (watched to completion, or at least 15 seconds). Sources: Meta &#x60;video_thruplay_watched_actions&#x60; (Meta only). | [optional] |
32
+ | **video_p25_watched_actions** | **Integer** | Views reaching 25% of the video&#39;s length. With the other percentile fields, powers hook/hold/drop-off analysis (e.g. hook rate &#x3D; videoP25WatchedActions / videoPlayActions). Sources: Meta &#x60;video_p25_watched_actions&#x60;, TikTok &#x60;video_views_p25&#x60;. | [optional] |
33
+ | **video_p50_watched_actions** | **Integer** | Views reaching 50% of the video&#39;s length. Sources: Meta &#x60;video_p50_watched_actions&#x60;, TikTok &#x60;video_views_p50&#x60;. | [optional] |
34
+ | **video_p75_watched_actions** | **Integer** | Views reaching 75% of the video&#39;s length. Sources: Meta &#x60;video_p75_watched_actions&#x60;, TikTok &#x60;video_views_p75&#x60;. | [optional] |
35
+ | **video_p95_watched_actions** | **Integer** | Views reaching 95% of the video&#39;s length. Sources: Meta &#x60;video_p95_watched_actions&#x60; (Meta only). | [optional] |
36
+ | **video_p100_watched_actions** | **Integer** | Views reaching 100% of the video&#39;s length. Sources: Meta &#x60;video_p100_watched_actions&#x60;, TikTok &#x60;video_views_p100&#x60;. | [optional] |
37
+ | **video_avg_time_watched_actions** | **Float** | Average seconds watched per play. Aggregated over date ranges and across children as a play-weighted average (total watch time / total plays), never a plain average of averages. Sources: Meta &#x60;video_avg_time_watched_actions&#x60;, TikTok &#x60;average_video_play&#x60;. | [optional] |
38
+ | **cost_per_thruplay** | **Float** | Derived &#x60;spend / videoThruplayWatchedActions&#x60;, in ad-account native currency. Rounded to 4 decimals rather than the usual 2 because a ThruPlay routinely costs well under a cent. 0 when the ad has no ThruPlays (ThruPlay is Meta-only). | [optional] |
39
+ | **funnel** | [**AdFunnelCounts**](AdFunnelCounts.md) | | [optional] |
40
+ | **engagement_breakdown** | [**AdEngagementCounts**](AdEngagementCounts.md) | | [optional] |
41
+ | **last_synced_at** | **Time** | Present on individual ads only, not on campaign aggregations | [optional] |
42
+ | **search_impression_share** | **Float** | Google only. Date-range ratio, not a percentage. Null when unavailable; Google&#39;s threshold sentinel values are preserved. | [optional] |
43
+ | **search_budget_lost_impression_share** | **Float** | Google only. Date-range ratio, not a percentage. Null when unavailable; Google&#39;s threshold sentinel values are preserved. | [optional] |
44
+ | **search_rank_lost_impression_share** | **Float** | Google only. Date-range ratio, not a percentage. Null when unavailable; Google&#39;s threshold sentinel values are preserved. | [optional] |
45
+ | **search_top_impression_share** | **Float** | Google only. Date-range ratio, not a percentage. Null when unavailable; Google&#39;s threshold sentinel values are preserved. | [optional] |
46
+ | **search_absolute_top_impression_share** | **Float** | Google only. Date-range ratio, not a percentage. Null when unavailable; Google&#39;s threshold sentinel values are preserved. | [optional] |
47
+
48
+ ## Example
49
+
50
+ ```ruby
51
+ require 'zernio-sdk'
52
+
53
+ instance = Zernio::CampaignAnalyticsResponseAnalyticsSummary.new(
54
+ spend: null,
55
+ impressions: null,
56
+ reach: null,
57
+ clicks: null,
58
+ ctr: null,
59
+ cpc: null,
60
+ cpm: null,
61
+ engagement: null,
62
+ conversions: null,
63
+ all_conversions: null,
64
+ cost_per_conversion: null,
65
+ actions: {link_click&#x3D;160, post_engagement&#x3D;300, offsite_conversion.fb_pixel_purchase&#x3D;42},
66
+ action_values: {offsite_conversion.fb_pixel_purchase&#x3D;2456.78, offsite_conversion.fb_pixel_add_to_cart&#x3D;980.5},
67
+ purchase_value: null,
68
+ roas: null,
69
+ cost_per_action: {link_click&#x3D;0.1052, offsite_conversion.fb_pixel_purchase&#x3D;4.0114},
70
+ outbound_clicks: null,
71
+ outbound_clicks_ctr: null,
72
+ inline_link_clicks: null,
73
+ inline_link_click_ctr: null,
74
+ unique_clicks: null,
75
+ unique_ctr: null,
76
+ video_play_actions: null,
77
+ video30_sec_watched_actions: null,
78
+ video_thruplay_watched_actions: null,
79
+ video_p25_watched_actions: null,
80
+ video_p50_watched_actions: null,
81
+ video_p75_watched_actions: null,
82
+ video_p95_watched_actions: null,
83
+ video_p100_watched_actions: null,
84
+ video_avg_time_watched_actions: null,
85
+ cost_per_thruplay: null,
86
+ funnel: null,
87
+ engagement_breakdown: null,
88
+ last_synced_at: null,
89
+ search_impression_share: null,
90
+ search_budget_lost_impression_share: null,
91
+ search_rank_lost_impression_share: null,
92
+ search_top_impression_share: null,
93
+ search_absolute_top_impression_share: null
94
+ )
95
+ ```
96
+
@@ -8,6 +8,7 @@
8
8
  | **name** | **String** | | [optional] |
9
9
  | **platform** | **String** | | [optional] |
10
10
  | **status** | **String** | Effective campaign status (ACTIVE when any child ad is active). | [optional] |
11
+ | **budget** | [**AdCampaignBudget**](AdCampaignBudget.md) | | [optional] |
11
12
  | **currency** | **String** | ISO 4217 code of the ad account (e.g. USD, THB). All money values in &#x60;summary&#x60; and &#x60;daily&#x60; are in this currency. | [optional] |
12
13
 
13
14
  ## Example
@@ -20,6 +21,7 @@ instance = Zernio::CampaignAnalyticsResponseCampaign.new(
20
21
  name: null,
21
22
  platform: null,
22
23
  status: null,
24
+ budget: null,
23
25
  currency: null
24
26
  )
25
27
  ```
@@ -0,0 +1,24 @@
1
+ # Zernio::CreateAdNegativeKeywordList201Response
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **id** | **String** | New shared set id. | [optional] |
8
+ | **resource_name** | **String** | New shared set resource name. | [optional] |
9
+ | **created** | **Integer** | Number of initial keyword criteria created. | [optional] |
10
+ | **customer_id** | **String** | Resolved Google Ads customer id. | [optional] |
11
+
12
+ ## Example
13
+
14
+ ```ruby
15
+ require 'zernio-sdk'
16
+
17
+ instance = Zernio::CreateAdNegativeKeywordList201Response.new(
18
+ id: null,
19
+ resource_name: null,
20
+ created: null,
21
+ customer_id: null
22
+ )
23
+ ```
24
+
@@ -0,0 +1,26 @@
1
+ # Zernio::CreateAdNegativeKeywordListRequest
2
+
3
+ ## Properties
4
+
5
+ | Name | Type | Description | Notes |
6
+ | ---- | ---- | ----------- | ----- |
7
+ | **account_id** | **String** | Zernio SocialAccount id. | |
8
+ | **customer_id** | **String** | Connected Google Ads customer id, without dashes. Required when the connection has multiple customers. | [optional] |
9
+ | **platform** | **String** | Optional courtesy field. The resolved account or campaign determines support; other platforms return 501. | [optional] |
10
+ | **name** | **String** | Nonempty list name, trimmed before use. | |
11
+ | **keywords** | [**Array&lt;KeywordEntry&gt;**](KeywordEntry.md) | Full desired keyword set. Bare strings use broad match. Send [] to clear the list. | [optional] |
12
+
13
+ ## Example
14
+
15
+ ```ruby
16
+ require 'zernio-sdk'
17
+
18
+ instance = Zernio::CreateAdNegativeKeywordListRequest.new(
19
+ account_id: null,
20
+ customer_id: null,
21
+ platform: null,
22
+ name: null,
23
+ keywords: null
24
+ )
25
+ ```
26
+
@@ -7,12 +7,15 @@
7
7
  | **account_id** | **String** | Facebook or Instagram SocialAccount ID. | |
8
8
  | **ad_account_id** | **String** | Meta ad account ID, e.g. &#x60;act_123456789&#x60;. | |
9
9
  | **name** | **String** | Ad display name. Used to derive campaign / ad set names. On the multi-creative shape, each ad&#39;s Meta name gets a \&quot; #N\&quot; suffix (1-indexed) so Ads Manager shows them as a numbered batch. | |
10
+ | **existing_post_id** | **String** | Messaging and CTWA only. Platform post or reel ID, resolved like boost platformPostId. Facebook IDs become object_story_id; Instagram IDs become source_instagram_media_id using the connected Instagram identity. Mutually exclusive with objectStoryId and fresh creative fields. | [optional] |
11
+ | **object_story_id** | **String** | Messaging and CTWA only. Raw Facebook pageId_postId reference, used as object_story_id even with an Instagram account. Mutually exclusive with existingPostId and fresh creative fields. | [optional] |
12
+ | **whatsapp_phone_number** | **String** | WhatsApp only. Optional E.164 number already paired with the Facebook Page. Omit to let Meta select the paired number. Sent to the creative CTA and, when creating a new ad set, its promoted_object. Attach requests do not change the existing ad set. | [optional] |
10
13
  | **headline** | **String** | Single-creative shape only. Mutually exclusive with &#x60;creatives[]&#x60;. | [optional] |
11
14
  | **body** | **String** | Primary text shown above the image / video. Single-creative shape only. Mutually exclusive with &#x60;creatives[]&#x60;. | [optional] |
12
- | **image_url** | **String** | Image asset for single-creative shape. Mutually exclusive with &#x60;video&#x60; and with &#x60;creatives[]&#x60;. Required on the single-creative shape if &#x60;video&#x60; is not supplied. | [optional] |
15
+ | **image_url** | **String** | Image asset for single-creative shape. Mutually exclusive with &#x60;video&#x60; and with &#x60;creatives[]&#x60;. Required on the single-creative shape if neither &#x60;video&#x60; nor an existing post reference is supplied. | [optional] |
13
16
  | **video** | [**CtwaAdRequestBodyVideo**](CtwaAdRequestBodyVideo.md) | | [optional] |
14
17
  | **welcome_message** | [**CtwaAdRequestBodyWelcomeMessage**](CtwaAdRequestBodyWelcomeMessage.md) | | [optional] |
15
- | **creatives** | [**Array&lt;CtwaAdRequestBodyCreativesInner&gt;**](CtwaAdRequestBodyCreativesInner.md) | Multi-creative shape: N CTWA ads under one campaign + one ad set, sharing budget and targeting. Mutually exclusive with the top-level single-creative fields (&#x60;headline&#x60; / &#x60;body&#x60; / &#x60;imageUrl&#x60; / &#x60;video&#x60;): setting both is a 400, unlike &#x60;POST /v1/ads/create&#x60; where the top-level fields are silently ignored in multi-creative mode. Each entry must supply its own headline, body, and exactly one of &#x60;imageUrl&#x60; / &#x60;video&#x60;. | [optional] |
18
+ | **creatives** | [**Array&lt;CtwaAdRequestBodyCreativesInner&gt;**](CtwaAdRequestBodyCreativesInner.md) | Multi-creative shape: N CTWA ads under one campaign + one ad set, sharing budget and targeting. Mutually exclusive with the top-level single-creative fields (&#x60;headline&#x60; / &#x60;body&#x60; / &#x60;imageUrl&#x60; / &#x60;video&#x60;): setting both is a 400, unlike &#x60;POST /v1/ads/create&#x60; where the top-level fields are silently ignored in multi-creative mode. Each entry supplies headline, body, and image/video, or an existingPostId or objectStoryId reference. Fresh and existing creatives can be mixed. | [optional] |
16
19
  | **ad_set_id** | **String** | Attach the creatives to this EXISTING messaging ad set instead of building a campaign, so the ad set keeps its learning phase. It then owns budget, targeting and schedule, so &#x60;budgetAmount&#x60;, &#x60;budgetType&#x60;, &#x60;endDate&#x60;, &#x60;objective&#x60;, &#x60;countries&#x60;, &#x60;interests&#x60;, &#x60;audienceId&#x60; and &#x60;campaignStatus&#x60; are rejected with a 400 alongside it. Its &#x60;destination_type&#x60; must match the ad&#39;s destination. | [optional] |
17
20
  | **budget_amount** | **Float** | Budget amount in the ad account&#39;s currency major units (e.g. dollars for USD, not cents). Must be &gt; 0. Required unless &#x60;adSetId&#x60; is set, where the ad set owns it. | [optional] |
18
21
  | **budget_type** | **String** | Required unless &#x60;adSetId&#x60; is set. | [optional] |
@@ -52,6 +55,9 @@ instance = Zernio::CreateCallAdRequest.new(
52
55
  account_id: null,
53
56
  ad_account_id: null,
54
57
  name: null,
58
+ existing_post_id: null,
59
+ object_story_id: null,
60
+ whatsapp_phone_number: null,
55
61
  headline: null,
56
62
  body: null,
57
63
  image_url: null,