late-sdk 0.0.917 → 0.0.919

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: a2e2abc4e0d2a3a3ae3834d34c3df0cb0e6132c8833acc68e77fd070d9c1bb8a
4
- data.tar.gz: 79442e8b80568ed9fc7d3e57d919f4cd1ff26c9c994c8b47b591529135ae0742
3
+ metadata.gz: 50ae8ba4aad6e3d8b95e5ef53cdc8ea55d5092a6a780568fd117eada60f70688
4
+ data.tar.gz: ffd64b43fd0a11878b8b8411bdf17735ae575306cf4f5cc5541ccc750a7c1e3b
5
5
  SHA512:
6
- metadata.gz: 105850d51e71d95900c5ed568f12d3bb195c1d38774dc8f412b6126b66b49e96b3592a77392d115e562e91d044fcfdc0c221fc2674c180bf268695c9e348398b
7
- data.tar.gz: 531ed2631d928f4022a4393b39c3321bfc15c23866c4a0eb5ea32f58e830b8da320fec99a9139c4b15e7c6fed43b670c27ff195699d93b8fc5cb628102f7d641
6
+ metadata.gz: f53206f81e1f7bc71b66ef9443ebc7d57e72a1533ae75a843810f182e310b34418f3b9b7fb40cbf78fc9f2a1c3061bdaf59324a5d17e332adfb17414a34002ab
7
+ data.tar.gz: b82e884b8f21e53ebf22d34c53a38c405f1ff201a040cf8bec51bb91201c9df21b3ee4ec0e9b488903eabb0fa7f8ac798959a4c0b63b90bd4e05b79f88bfa992
@@ -627,7 +627,7 @@ end
627
627
 
628
628
  Create standalone ad
629
629
 
630
- Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `promotion` and `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`. An item replaces the whole feature map; its `promotion` replaces the default offer, and `promotion: null` disables that default for the item. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a `promotion` receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect `ad.creative.promotionStatus` (or `ads[].creative.promotionStatus`). `not_returned` means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an `Idempotency-Key` header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with `Idempotent-Replayed: true`) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
630
+ Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google's minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `promotion` and `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`. An item replaces the whole feature map; its `promotion` replaces the default offer, and `promotion: null` disables that default for the item. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a `promotion` receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect `ad.creative.promotionStatus` (or `ads[].creative.promotionStatus`). `not_returned` means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an `Idempotency-Key` header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with `Idempotent-Replayed: true`) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
631
631
 
632
632
  ### Examples
633
633
 
data/docs/AnalyticsApi.md CHANGED
@@ -62,7 +62,7 @@ opts = {
62
62
  to_date: Date.parse('2013-10-20'), # Date | Inclusive upper bound (YYYY-MM-DD). Defaults to today if omitted.
63
63
  limit: 56, # Integer | Page size (default 50)
64
64
  page: 56, # Integer | Page number (default 1)
65
- sort_by: 'date', # String | Sort by date, engagement, or a specific metric. Instagram-only metrics (follows, reposts, reels_skip_rate, ig_reels_*) sort a null value as 0.
65
+ sort_by: 'date', # String | Sort by date, engagement, or a specific metric. Platform-specific metrics (follows, reposts, reels_skip_rate, ig_reels_*, completion_rate, profile_views) sort a null value as 0.
66
66
  order: 'asc' # String | Sort order
67
67
  }
68
68
 
@@ -106,7 +106,7 @@ end
106
106
  | **to_date** | **Date** | Inclusive upper bound (YYYY-MM-DD). Defaults to today if omitted. | [optional] |
107
107
  | **limit** | **Integer** | Page size (default 50) | [optional][default to 50] |
108
108
  | **page** | **Integer** | Page number (default 1) | [optional][default to 1] |
109
- | **sort_by** | **String** | Sort by date, engagement, or a specific metric. Instagram-only metrics (follows, reposts, reels_skip_rate, ig_reels_*) sort a null value as 0. | [optional][default to 'date'] |
109
+ | **sort_by** | **String** | Sort by date, engagement, or a specific metric. Platform-specific metrics (follows, reposts, reels_skip_rate, ig_reels_*, completion_rate, profile_views) sort a null value as 0. | [optional][default to 'date'] |
110
110
  | **order** | **String** | Sort order | [optional][default to 'desc'] |
111
111
 
112
112
  ### Return type
@@ -18,6 +18,8 @@
18
18
  | **ig_reels_video_view_total_time** | **Integer** | Instagram Reels total watch time, in milliseconds | |
19
19
  | **reposts** | **Integer** | | |
20
20
  | **reels_skip_rate** | **Float** | Instagram Reels skip rate, 0 to 1 | |
21
+ | **completion_rate** | **Float** | TikTok business lane: share of viewers who watched to the end, 0 to 1 | |
22
+ | **profile_views** | **Integer** | TikTok business lane: profile views attributed to the post | |
21
23
 
22
24
  ## Example
23
25
 
@@ -38,7 +40,9 @@ instance = Zernio::AnalyticsDeltaEntryMetrics.new(
38
40
  ig_reels_avg_watch_time: null,
39
41
  ig_reels_video_view_total_time: null,
40
42
  reposts: null,
41
- reels_skip_rate: null
43
+ reels_skip_rate: null,
44
+ completion_rate: null,
45
+ profile_views: null
42
46
  )
43
47
  ```
44
48
 
@@ -16,6 +16,8 @@
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
18
  | **reels_skip_rate** | **Float** | Instagram Reels only: percentage (0-100) of initial views that skipped the reel within its first 3 seconds, as reported by Meta. Meta labels the metric estimated and in development, so it can move between syncs. 0 for non-Reels media and other platforms. When a post is published to several accounts, the aggregate is weighted by views. | [optional] |
19
+ | **completion_rate** | **Float** | TikTok accounts connected through the TikTok for Business app only: share of viewers who watched the video to the end, 0 to 1, as TikTok reports it (T+24-48h, only for posts active in the last 7 days). 0 for other platforms. When a post is published to several accounts, the aggregate is weighted by views. | [optional] |
20
+ | **profile_views** | **Integer** | TikTok accounts connected through the TikTok for Business app only: profile views from users who reached the profile through this post (T+24-48h). 0 for other platforms. | [optional] |
19
21
  | **reposts** | **Integer** | Instagram accounts connected with Facebook Login only: reposts of the media by other users, minus deleted reposts, on feed posts, reels and stories. Meta does not expose this metric for accounts connected with Instagram Login, so those always report 0. 0 for other platforms, including Threads, where reposts are counted in shares instead. | [optional] |
20
22
  | **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] |
21
23
  | **engagement_rate** | **Float** | Percentage, rounded to 2 decimals: (likes + comments + shares + saves) / (impressions or reach or views) * 100. Clicks and follows are never counted. The denominator is the FIRST of impressions, reach, views that is non-zero, so it is not the same basis on every post: a post with impressions divides by impressions, one without falls back to reach, then to views. If you need a single consistent basis (e.g. interactions / reach), compute it from the raw fields above. The engagementRate on the LinkedIn account endpoints is a different formula. | [optional] |
@@ -39,6 +41,8 @@ instance = Zernio::PostAnalytics.new(
39
41
  ig_reels_avg_watch_time: 0,
40
42
  ig_reels_video_view_total_time: 0,
41
43
  reels_skip_rate: 48.8,
44
+ completion_rate: 0,
45
+ profile_views: 0,
42
46
  reposts: 0,
43
47
  video_duration_seconds: 30,
44
48
  engagement_rate: 6.59,
@@ -607,7 +607,7 @@ module Zernio
607
607
  end
608
608
 
609
609
  # Create standalone ad
610
- # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `promotion` and `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`. An item replaces the whole feature map; its `promotion` replaces the default offer, and `promotion: null` disables that default for the item. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a `promotion` receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect `ad.creative.promotionStatus` (or `ads[].creative.promotionStatus`). `not_returned` means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an `Idempotency-Key` header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with `Idempotent-Replayed: true`) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
610
+ # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google's minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `promotion` and `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`. An item replaces the whole feature map; its `promotion` replaces the default offer, and `promotion: null` disables that default for the item. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a `promotion` receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect `ad.creative.promotionStatus` (or `ads[].creative.promotionStatus`). `not_returned` means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an `Idempotency-Key` header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with `Idempotent-Replayed: true`) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
611
611
  # @param create_standalone_ad_request [CreateStandaloneAdRequest]
612
612
  # @param [Hash] opts the optional parameters
613
613
  # @option opts [String] :idempotency_key Optional client-generated unique key (e.g. a UUID) that makes retries safe. Same key + same body replays the original response; same key + different body → 422; key still processing → 409.
@@ -618,7 +618,7 @@ module Zernio
618
618
  end
619
619
 
620
620
  # Create standalone ad
621
- # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `promotion` and `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`. An item replaces the whole feature map; its `promotion` replaces the default offer, and `promotion: null` disables that default for the item. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a `promotion` receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect `ad.creative.promotionStatus` (or `ads[].creative.promotionStatus`). `not_returned` means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an `Idempotency-Key` header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with `Idempotent-Replayed: true`) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
621
+ # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set `campaignType: \"pmax\"` and supply `assetGroup` with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. `validateOnly: true` validates the complete request with Google without creating or persisting resources. Read assets with `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google's minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts `promotion` and `creativeFeatures` on the single and attach shapes and as defaults for `creatives[]`. An item replaces the whole feature map; its `promotion` replaces the default offer, and `promotion: null` disables that default for the item. Reusing `existingCreativeId` uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a `promotion` receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect `ad.creative.promotionStatus` (or `ads[].creative.promotionStatus`). `not_returned` means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \"dark post\" authored by a Company Page (see `organizationId`). Supported goals are engagement, traffic, awareness, and video_views (video ads use the `video` field; video_views requires a video), and traffic ads require `linkUrl`. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an `Idempotency-Key` header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with `Idempotent-Replayed: true`) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
622
622
  # @param create_standalone_ad_request [CreateStandaloneAdRequest]
623
623
  # @param [Hash] opts the optional parameters
624
624
  # @option opts [String] :idempotency_key Optional client-generated unique key (e.g. a UUID) that makes retries safe. Same key + same body replays the original response; same key + different body → 422; key still processing → 409.
@@ -31,7 +31,7 @@ module Zernio
31
31
  # @option opts [Date] :to_date Inclusive upper bound (YYYY-MM-DD). Defaults to today if omitted.
32
32
  # @option opts [Integer] :limit Page size (default 50) (default to 50)
33
33
  # @option opts [Integer] :page Page number (default 1) (default to 1)
34
- # @option opts [String] :sort_by Sort by date, engagement, or a specific metric. Instagram-only metrics (follows, reposts, reels_skip_rate, ig_reels_*) sort a null value as 0. (default to 'date')
34
+ # @option opts [String] :sort_by Sort by date, engagement, or a specific metric. Platform-specific metrics (follows, reposts, reels_skip_rate, ig_reels_*, completion_rate, profile_views) sort a null value as 0. (default to 'date')
35
35
  # @option opts [String] :order Sort order (default to 'desc')
36
36
  # @return [GetAnalytics200Response]
37
37
  def get_analytics(opts = {})
@@ -51,7 +51,7 @@ module Zernio
51
51
  # @option opts [Date] :to_date Inclusive upper bound (YYYY-MM-DD). Defaults to today if omitted.
52
52
  # @option opts [Integer] :limit Page size (default 50) (default to 50)
53
53
  # @option opts [Integer] :page Page number (default 1) (default to 1)
54
- # @option opts [String] :sort_by Sort by date, engagement, or a specific metric. Instagram-only metrics (follows, reposts, reels_skip_rate, ig_reels_*) sort a null value as 0. (default to 'date')
54
+ # @option opts [String] :sort_by Sort by date, engagement, or a specific metric. Platform-specific metrics (follows, reposts, reels_skip_rate, ig_reels_*, completion_rate, profile_views) sort a null value as 0. (default to 'date')
55
55
  # @option opts [String] :order Sort order (default to 'desc')
56
56
  # @return [Array<(GetAnalytics200Response, Integer, Hash)>] GetAnalytics200Response data, response status code and response headers
57
57
  def get_analytics_with_http_info(opts = {})
@@ -74,7 +74,7 @@ module Zernio
74
74
  fail ArgumentError, 'invalid value for "opts[:"page"]" when calling AnalyticsApi.get_analytics, must be greater than or equal to 1.'
75
75
  end
76
76
 
77
- allowable_values = ["date", "engagement", "impressions", "reach", "likes", "comments", "shares", "saves", "clicks", "views", "follows", "ig_reels_avg_watch_time", "ig_reels_video_view_total_time", "reposts", "reels_skip_rate"]
77
+ allowable_values = ["date", "engagement", "impressions", "reach", "likes", "comments", "shares", "saves", "clicks", "views", "follows", "ig_reels_avg_watch_time", "ig_reels_video_view_total_time", "reposts", "reels_skip_rate", "completion_rate", "profile_views"]
78
78
  if @api_client.config.client_side_validation && opts[:'sort_by'] && !allowable_values.include?(opts[:'sort_by'])
79
79
  fail ArgumentError, "invalid value for \"sort_by\", must be one of #{allowable_values}"
80
80
  end
@@ -48,6 +48,12 @@ module Zernio
48
48
  # Instagram Reels skip rate, 0 to 1
49
49
  attr_accessor :reels_skip_rate
50
50
 
51
+ # TikTok business lane: share of viewers who watched to the end, 0 to 1
52
+ attr_accessor :completion_rate
53
+
54
+ # TikTok business lane: profile views attributed to the post
55
+ attr_accessor :profile_views
56
+
51
57
  # Attribute mapping from ruby-style variable name to JSON key.
52
58
  def self.attribute_map
53
59
  {
@@ -64,7 +70,9 @@ module Zernio
64
70
  :'ig_reels_avg_watch_time' => :'igReelsAvgWatchTime',
65
71
  :'ig_reels_video_view_total_time' => :'igReelsVideoViewTotalTime',
66
72
  :'reposts' => :'reposts',
67
- :'reels_skip_rate' => :'reelsSkipRate'
73
+ :'reels_skip_rate' => :'reelsSkipRate',
74
+ :'completion_rate' => :'completionRate',
75
+ :'profile_views' => :'profileViews'
68
76
  }
69
77
  end
70
78
 
@@ -94,7 +102,9 @@ module Zernio
94
102
  :'ig_reels_avg_watch_time' => :'Integer',
95
103
  :'ig_reels_video_view_total_time' => :'Integer',
96
104
  :'reposts' => :'Integer',
97
- :'reels_skip_rate' => :'Float'
105
+ :'reels_skip_rate' => :'Float',
106
+ :'completion_rate' => :'Float',
107
+ :'profile_views' => :'Integer'
98
108
  }
99
109
  end
100
110
 
@@ -203,6 +213,18 @@ module Zernio
203
213
  else
204
214
  self.reels_skip_rate = nil
205
215
  end
216
+
217
+ if attributes.key?(:'completion_rate')
218
+ self.completion_rate = attributes[:'completion_rate']
219
+ else
220
+ self.completion_rate = nil
221
+ end
222
+
223
+ if attributes.key?(:'profile_views')
224
+ self.profile_views = attributes[:'profile_views']
225
+ else
226
+ self.profile_views = nil
227
+ end
206
228
  end
207
229
 
208
230
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -266,6 +288,14 @@ module Zernio
266
288
  invalid_properties.push('invalid value for "reels_skip_rate", reels_skip_rate cannot be nil.')
267
289
  end
268
290
 
291
+ if @completion_rate.nil?
292
+ invalid_properties.push('invalid value for "completion_rate", completion_rate cannot be nil.')
293
+ end
294
+
295
+ if @profile_views.nil?
296
+ invalid_properties.push('invalid value for "profile_views", profile_views cannot be nil.')
297
+ end
298
+
269
299
  invalid_properties
270
300
  end
271
301
 
@@ -287,6 +317,8 @@ module Zernio
287
317
  return false if @ig_reels_video_view_total_time.nil?
288
318
  return false if @reposts.nil?
289
319
  return false if @reels_skip_rate.nil?
320
+ return false if @completion_rate.nil?
321
+ return false if @profile_views.nil?
290
322
  true
291
323
  end
292
324
 
@@ -430,6 +462,26 @@ module Zernio
430
462
  @reels_skip_rate = reels_skip_rate
431
463
  end
432
464
 
465
+ # Custom attribute writer method with validation
466
+ # @param [Object] completion_rate Value to be assigned
467
+ def completion_rate=(completion_rate)
468
+ if completion_rate.nil?
469
+ fail ArgumentError, 'completion_rate cannot be nil'
470
+ end
471
+
472
+ @completion_rate = completion_rate
473
+ end
474
+
475
+ # Custom attribute writer method with validation
476
+ # @param [Object] profile_views Value to be assigned
477
+ def profile_views=(profile_views)
478
+ if profile_views.nil?
479
+ fail ArgumentError, 'profile_views cannot be nil'
480
+ end
481
+
482
+ @profile_views = profile_views
483
+ end
484
+
433
485
  # Checks equality by comparing each attribute.
434
486
  # @param [Object] Object to be compared
435
487
  def ==(o)
@@ -448,7 +500,9 @@ module Zernio
448
500
  ig_reels_avg_watch_time == o.ig_reels_avg_watch_time &&
449
501
  ig_reels_video_view_total_time == o.ig_reels_video_view_total_time &&
450
502
  reposts == o.reposts &&
451
- reels_skip_rate == o.reels_skip_rate
503
+ reels_skip_rate == o.reels_skip_rate &&
504
+ completion_rate == o.completion_rate &&
505
+ profile_views == o.profile_views
452
506
  end
453
507
 
454
508
  # @see the `==` method
@@ -460,7 +514,7 @@ module Zernio
460
514
  # Calculates hash code according to all attributes.
461
515
  # @return [Integer] Hash code
462
516
  def hash
463
- [impressions, reach, likes, comments, shares, saves, sends, clicks, views, follows, ig_reels_avg_watch_time, ig_reels_video_view_total_time, reposts, reels_skip_rate].hash
517
+ [impressions, reach, likes, comments, shares, saves, sends, clicks, views, follows, ig_reels_avg_watch_time, ig_reels_video_view_total_time, reposts, reels_skip_rate, completion_rate, profile_views].hash
464
518
  end
465
519
 
466
520
  # Builds the object from hash
@@ -44,6 +44,12 @@ module Zernio
44
44
  # Instagram Reels only: percentage (0-100) of initial views that skipped the reel within its first 3 seconds, as reported by Meta. Meta labels the metric estimated and in development, so it can move between syncs. 0 for non-Reels media and other platforms. When a post is published to several accounts, the aggregate is weighted by views.
45
45
  attr_accessor :reels_skip_rate
46
46
 
47
+ # TikTok accounts connected through the TikTok for Business app only: share of viewers who watched the video to the end, 0 to 1, as TikTok reports it (T+24-48h, only for posts active in the last 7 days). 0 for other platforms. When a post is published to several accounts, the aggregate is weighted by views.
48
+ attr_accessor :completion_rate
49
+
50
+ # TikTok accounts connected through the TikTok for Business app only: profile views from users who reached the profile through this post (T+24-48h). 0 for other platforms.
51
+ attr_accessor :profile_views
52
+
47
53
  # Instagram accounts connected with Facebook Login only: reposts of the media by other users, minus deleted reposts, on feed posts, reels and stories. Meta does not expose this metric for accounts connected with Instagram Login, so those always report 0. 0 for other platforms, including Threads, where reposts are counted in shares instead.
48
54
  attr_accessor :reposts
49
55
 
@@ -70,6 +76,8 @@ module Zernio
70
76
  :'ig_reels_avg_watch_time' => :'igReelsAvgWatchTime',
71
77
  :'ig_reels_video_view_total_time' => :'igReelsVideoViewTotalTime',
72
78
  :'reels_skip_rate' => :'reelsSkipRate',
79
+ :'completion_rate' => :'completionRate',
80
+ :'profile_views' => :'profileViews',
73
81
  :'reposts' => :'reposts',
74
82
  :'video_duration_seconds' => :'videoDurationSeconds',
75
83
  :'engagement_rate' => :'engagementRate',
@@ -102,6 +110,8 @@ module Zernio
102
110
  :'ig_reels_avg_watch_time' => :'Integer',
103
111
  :'ig_reels_video_view_total_time' => :'Integer',
104
112
  :'reels_skip_rate' => :'Float',
113
+ :'completion_rate' => :'Float',
114
+ :'profile_views' => :'Integer',
105
115
  :'reposts' => :'Integer',
106
116
  :'video_duration_seconds' => :'Integer',
107
117
  :'engagement_rate' => :'Float',
@@ -181,6 +191,14 @@ module Zernio
181
191
  self.reels_skip_rate = attributes[:'reels_skip_rate']
182
192
  end
183
193
 
194
+ if attributes.key?(:'completion_rate')
195
+ self.completion_rate = attributes[:'completion_rate']
196
+ end
197
+
198
+ if attributes.key?(:'profile_views')
199
+ self.profile_views = attributes[:'profile_views']
200
+ end
201
+
184
202
  if attributes.key?(:'reposts')
185
203
  self.reposts = attributes[:'reposts']
186
204
  end
@@ -230,6 +248,8 @@ module Zernio
230
248
  ig_reels_avg_watch_time == o.ig_reels_avg_watch_time &&
231
249
  ig_reels_video_view_total_time == o.ig_reels_video_view_total_time &&
232
250
  reels_skip_rate == o.reels_skip_rate &&
251
+ completion_rate == o.completion_rate &&
252
+ profile_views == o.profile_views &&
233
253
  reposts == o.reposts &&
234
254
  video_duration_seconds == o.video_duration_seconds &&
235
255
  engagement_rate == o.engagement_rate &&
@@ -245,7 +265,7 @@ module Zernio
245
265
  # Calculates hash code according to all attributes.
246
266
  # @return [Integer] Hash code
247
267
  def hash
248
- [impressions, reach, likes, comments, shares, saves, clicks, views, follows, ig_reels_avg_watch_time, ig_reels_video_view_total_time, reels_skip_rate, reposts, video_duration_seconds, engagement_rate, last_updated].hash
268
+ [impressions, reach, likes, comments, shares, saves, clicks, views, follows, ig_reels_avg_watch_time, ig_reels_video_view_total_time, reels_skip_rate, completion_rate, profile_views, reposts, video_duration_seconds, engagement_rate, last_updated].hash
249
269
  end
250
270
 
251
271
  # 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.917'
14
+ VERSION = '0.0.919'
15
15
  end
data/openapi.yaml CHANGED
@@ -7781,6 +7781,8 @@ components:
7781
7781
  igReelsAvgWatchTime: { type: integer, example: 0, description: 'Instagram Reels only: average watch time per play, in milliseconds. 0 for non-Reels media and other platforms.' }
7782
7782
  igReelsVideoViewTotalTime: { type: integer, example: 0, description: 'Instagram Reels only: total watch time including replays, in milliseconds. 0 for non-Reels media and other platforms.' }
7783
7783
  reelsSkipRate: { type: number, example: 48.8, description: 'Instagram Reels only: percentage (0-100) of initial views that skipped the reel within its first 3 seconds, as reported by Meta. Meta labels the metric estimated and in development, so it can move between syncs. 0 for non-Reels media and other platforms. When a post is published to several accounts, the aggregate is weighted by views.' }
7784
+ completionRate: { type: number, example: 0, description: 'TikTok accounts connected through the TikTok for Business app only: share of viewers who watched the video to the end, 0 to 1, as TikTok reports it (T+24-48h, only for posts active in the last 7 days). 0 for other platforms. When a post is published to several accounts, the aggregate is weighted by views.' }
7785
+ profileViews: { type: integer, example: 0, description: 'TikTok accounts connected through the TikTok for Business app only: profile views from users who reached the profile through this post (T+24-48h). 0 for other platforms.' }
7784
7786
  reposts: { type: integer, example: 0, description: 'Instagram accounts connected with Facebook Login only: reposts of the media by other users, minus deleted reposts, on feed posts, reels and stories. Meta does not expose this metric for accounts connected with Instagram Login, so those always report 0. 0 for other platforms, including Threads, where reposts are counted in shares instead.' }
7785
7787
  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).' }
7786
7788
  engagementRate: { type: number, example: 6.59, description: 'Percentage, rounded to 2 decimals: (likes + comments + shares + saves) / (impressions or reach or views) * 100. Clicks and follows are never counted. The denominator is the FIRST of impressions, reach, views that is non-zero, so it is not the same basis on every post: a post with impressions divides by impressions, one without falls back to reach, then to views. If you need a single consistent basis (e.g. interactions / reach), compute it from the raw fields above. The engagementRate on the LinkedIn account endpoints is a different formula.' }
@@ -7976,7 +7978,7 @@ components:
7976
7978
  metrics:
7977
7979
  type: object
7978
7980
  description: 'Metrics a platform does not report are 0, not absent.'
7979
- required: [impressions, reach, likes, comments, shares, saves, sends, clicks, views, follows, igReelsAvgWatchTime, igReelsVideoViewTotalTime, reposts, reelsSkipRate]
7981
+ required: [impressions, reach, likes, comments, shares, saves, sends, clicks, views, follows, igReelsAvgWatchTime, igReelsVideoViewTotalTime, reposts, reelsSkipRate, completionRate, profileViews]
7980
7982
  properties:
7981
7983
  impressions: { type: integer }
7982
7984
  reach: { type: integer }
@@ -7992,6 +7994,8 @@ components:
7992
7994
  igReelsVideoViewTotalTime: { type: integer, description: 'Instagram Reels total watch time, in milliseconds' }
7993
7995
  reposts: { type: integer }
7994
7996
  reelsSkipRate: { type: number, description: 'Instagram Reels skip rate, 0 to 1' }
7997
+ completionRate: { type: number, description: 'TikTok business lane: share of viewers who watched to the end, 0 to 1' }
7998
+ profileViews: { type: integer, description: 'TikTok business lane: profile views attributed to the post' }
7995
7999
  AnalyticsDeltaResponse:
7996
8000
  type: object
7997
8001
  required: [data, nextCursor, hasMore]
@@ -12187,8 +12191,8 @@ paths:
12187
12191
  description: Page number (default 1)
12188
12192
  - name: sortBy
12189
12193
  in: query
12190
- schema: { type: string, enum: [date, engagement, impressions, reach, likes, comments, shares, saves, clicks, views, follows, ig_reels_avg_watch_time, ig_reels_video_view_total_time, reposts, reels_skip_rate], default: date }
12191
- description: 'Sort by date, engagement, or a specific metric. Instagram-only metrics (follows, reposts, reels_skip_rate, ig_reels_*) sort a null value as 0.'
12194
+ schema: { type: string, enum: [date, engagement, impressions, reach, likes, comments, shares, saves, clicks, views, follows, ig_reels_avg_watch_time, ig_reels_video_view_total_time, reposts, reels_skip_rate, completion_rate, profile_views], default: date }
12195
+ description: 'Sort by date, engagement, or a specific metric. Platform-specific metrics (follows, reposts, reels_skip_rate, ig_reels_*, completion_rate, profile_views) sort a null value as 0.'
12192
12196
  - name: order
12193
12197
  in: query
12194
12198
  schema: { type: string, enum: [asc, desc], default: desc }
@@ -12498,6 +12502,8 @@ paths:
12498
12502
  igReelsVideoViewTotalTime: 0
12499
12503
  reposts: 0
12500
12504
  reelsSkipRate: 0
12505
+ completionRate: 0
12506
+ profileViews: 0
12501
12507
  nextCursor: "v1.WyIyMDI2LTA5LTAxIDE3OjEyOjA0IiwiNjVmMWMwYTllMmI1YWYwMDEyYWIzNGNkIl0"
12502
12508
  hasMore: true
12503
12509
  '400': { $ref: '#/components/responses/BadRequest' }
@@ -50917,6 +50923,7 @@ paths:
50917
50923
  request with Google without creating or persisting resources. Read assets with
50918
50924
  `GET /v1/ads/campaigns/{campaignId}/asset-groups`. The logo is required; video is
50919
50925
  optional via `assetGroup.youtubeVideoId`. Brand guidelines are disabled at creation.
50926
+ All supplied asset links are validated together against Google's minimum asset requirements.
50920
50927
  PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields
50921
50928
  and attach shapes. Geo and language targeting are supported; omitted geo targets
50922
50929
  all locations. PMax does not require top-level goal, headline, body or linkUrl.
@@ -135,7 +135,7 @@ describe 'AdCampaignsApi' do
135
135
 
136
136
  # unit tests for create_standalone_ad
137
137
  # Create standalone ad
138
- # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set &#x60;campaignType: \&quot;pmax\&quot;&#x60; and supply &#x60;assetGroup&#x60; with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. &#x60;validateOnly: true&#x60; validates the complete request with Google without creating or persisting resources. Read assets with &#x60;GET /v1/ads/campaigns/{campaignId}/asset-groups&#x60;. The logo is required; video is optional via &#x60;assetGroup.youtubeVideoId&#x60;. Brand guidelines are disabled at creation. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts &#x60;promotion&#x60; and &#x60;creativeFeatures&#x60; on the single and attach shapes and as defaults for &#x60;creatives[]&#x60;. An item replaces the whole feature map; its &#x60;promotion&#x60; replaces the default offer, and &#x60;promotion: null&#x60; disables that default for the item. Reusing &#x60;existingCreativeId&#x60; uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a &#x60;promotion&#x60; receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect &#x60;ad.creative.promotionStatus&#x60; (or &#x60;ads[].creative.promotionStatus&#x60;). &#x60;not_returned&#x60; means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \&quot;dark post\&quot; authored by a Company Page (see &#x60;organizationId&#x60;). Supported goals are engagement, traffic, awareness, and video_views (video ads use the &#x60;video&#x60; field; video_views requires a video), and traffic ads require &#x60;linkUrl&#x60;. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an &#x60;Idempotency-Key&#x60; header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with &#x60;Idempotent-Replayed: true&#x60;) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
138
+ # Create a paid ad with custom creative across Meta, Google Ads, Pinterest, TikTok, X, LinkedIn, and OpenAI Ads (ChatGPT Ads). Google Performance Max: set &#x60;campaignType: \&quot;pmax\&quot;&#x60; and supply &#x60;assetGroup&#x60; with text, images by role, business name and finalUrl. Creates a daily budget, PAUSED campaign and asset group atomically. &#x60;validateOnly: true&#x60; validates the complete request with Google without creating or persisting resources. Read assets with &#x60;GET /v1/ads/campaigns/{campaignId}/asset-groups&#x60;. The logo is required; video is optional via &#x60;assetGroup.youtubeVideoId&#x60;. Brand guidelines are disabled at creation. All supplied asset links are validated together against Google&#39;s minimum asset requirements. PMax rejects ACTIVE creation, portfolio bidding, bid caps, legacy creative fields and attach shapes. Geo and language targeting are supported; omitted geo targets all locations. PMax does not require top-level goal, headline, body or linkUrl. Supported bidding: omitted or LOWEST_COST_WITHOUT_CAP for Maximize Conversions, COST_CAP plus bidAmount for target CPA, LOWEST_COST_WITH_MIN_ROAS plus roasAverageFloor for Maximize Conversion Value with target ROAS. Other mutually-exclusive request shapes are selected by the body: - Legacy single-creative shape (all platforms, the default). - Meta-only multi-creative shape via the creatives array: one ad set with N ads sharing budget and targeting. - Attach shape via adSetId: adds one new ad to an existing ad set, inheriting its budget, targeting, and schedule (Meta, Google Ads, TikTok, and LinkedIn). On LinkedIn adSetId is the existing Campaign id, and the budget, schedule, targeting and bidding fields must be omitted. Meta accepts &#x60;promotion&#x60; and &#x60;creativeFeatures&#x60; on the single and attach shapes and as defaults for &#x60;creatives[]&#x60;. An item replaces the whole feature map; its &#x60;promotion&#x60; replaces the default offer, and &#x60;promotion: null&#x60; disables that default for the item. Reusing &#x60;existingCreativeId&#x60; uses the existing creative settings instead of new settings. Requested settings are persisted for lists, exports, and default ad-detail reads. Only ads supplied a &#x60;promotion&#x60; receive live readback; multi-create batches those reads in groups of up to 50 IDs without per-ad fallback. Inspect &#x60;ad.creative.promotionStatus&#x60; (or &#x60;ads[].creative.promotionStatus&#x60;). &#x60;not_returned&#x60; means Meta omitted the metadata; successful creation does not by itself prove the offer was applied or will display. Per-platform required fields, budget minimums, and video-ad rules are documented on each property below. LinkedIn creates a Single Image or Single Video Ad backed by a Direct Sponsored Content \&quot;dark post\&quot; authored by a Company Page (see &#x60;organizationId&#x60;). Supported goals are engagement, traffic, awareness, and video_views (video ads use the &#x60;video&#x60; field; video_views requires a video), and traffic ads require &#x60;linkUrl&#x60;. **Idempotency:** this endpoint is not idempotent at the platform level (a blind retry creates a second campaign/ad set/ad). Send an &#x60;Idempotency-Key&#x60; header to make retries safe: the first request with a given key creates the ad and we store the response; a retry with the same key replays that exact response (with &#x60;Idempotent-Replayed: true&#x60;) instead of creating duplicates. Reusing a key with a different body returns 422; a key whose first request is still in flight returns 409 (retry after a short backoff). Keys are scoped to your credential and expire after 24h.
139
139
  # @param create_standalone_ad_request
140
140
  # @param [Hash] opts the optional parameters
141
141
  # @option opts [String] :idempotency_key Optional client-generated unique key (e.g. a UUID) that makes retries safe. Same key + same body replays the original response; same key + different body → 422; key still processing → 409.
@@ -45,7 +45,7 @@ describe 'AnalyticsApi' do
45
45
  # @option opts [Date] :to_date Inclusive upper bound (YYYY-MM-DD). Defaults to today if omitted.
46
46
  # @option opts [Integer] :limit Page size (default 50)
47
47
  # @option opts [Integer] :page Page number (default 1)
48
- # @option opts [String] :sort_by Sort by date, engagement, or a specific metric. Instagram-only metrics (follows, reposts, reels_skip_rate, ig_reels_*) sort a null value as 0.
48
+ # @option opts [String] :sort_by Sort by date, engagement, or a specific metric. Platform-specific metrics (follows, reposts, reels_skip_rate, ig_reels_*, completion_rate, profile_views) sort a null value as 0.
49
49
  # @option opts [String] :order Sort order
50
50
  # @return [GetAnalytics200Response]
51
51
  describe 'get_analytics test' do
@@ -111,4 +111,16 @@ describe Zernio::AnalyticsDeltaEntryMetrics do
111
111
  end
112
112
  end
113
113
 
114
+ describe 'test attribute "completion_rate"' do
115
+ it 'should work' do
116
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
117
+ end
118
+ end
119
+
120
+ describe 'test attribute "profile_views"' do
121
+ it 'should work' do
122
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
123
+ end
124
+ end
125
+
114
126
  end
@@ -99,6 +99,18 @@ describe Zernio::PostAnalytics do
99
99
  end
100
100
  end
101
101
 
102
+ describe 'test attribute "completion_rate"' 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 "profile_views"' 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 "reposts"' do
103
115
  it 'should work' do
104
116
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: late-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.917
4
+ version: 0.0.919
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenAPI-Generator
@@ -6355,7 +6355,7 @@ files:
6355
6355
  - spec/models/you_tube_video_retention_response_retention_curve_inner_spec.rb
6356
6356
  - spec/models/you_tube_video_retention_response_spec.rb
6357
6357
  - spec/spec_helper.rb
6358
- - zernio-sdk-0.0.917.gem
6358
+ - zernio-sdk-0.0.919.gem
6359
6359
  - zernio-sdk.gemspec
6360
6360
  homepage: https://openapi-generator.tech
6361
6361
  licenses:
Binary file