late-sdk 0.0.854 → 0.0.856

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/docs/AdCampaignsApi.md +1 -1
  3. data/docs/AdDailyMetrics.md +2 -0
  4. data/docs/AdMetrics.md +2 -0
  5. data/docs/AdsTimelineResponseRowsInner.md +2 -0
  6. data/docs/CampaignAnalyticsResponseAnalyticsDailyInner.md +2 -0
  7. data/docs/ConnectApi.md +2 -2
  8. data/docs/CreatePostRequest.md +6 -6
  9. data/docs/CreateTrackingTagRequest.md +3 -1
  10. data/docs/PostsApi.md +1 -1
  11. data/docs/TrackingTagsApi.md +1 -1
  12. data/docs/WebhooksApi.md +2 -2
  13. data/lib/zernio-sdk/api/ad_campaigns_api.rb +2 -2
  14. data/lib/zernio-sdk/api/connect_api.rb +2 -2
  15. data/lib/zernio-sdk/api/posts_api.rb +2 -2
  16. data/lib/zernio-sdk/api/tracking_tags_api.rb +2 -2
  17. data/lib/zernio-sdk/api/webhooks_api.rb +4 -4
  18. data/lib/zernio-sdk/models/ad_daily_metrics.rb +11 -1
  19. data/lib/zernio-sdk/models/ad_metrics.rb +11 -1
  20. data/lib/zernio-sdk/models/ads_timeline_response_rows_inner.rb +11 -1
  21. data/lib/zernio-sdk/models/campaign_analytics_response_analytics_daily_inner.rb +11 -1
  22. data/lib/zernio-sdk/models/create_post_request.rb +6 -0
  23. data/lib/zernio-sdk/models/create_tracking_tag_request.rb +48 -4
  24. data/lib/zernio-sdk/version.rb +1 -1
  25. data/openapi.yaml +62 -11
  26. data/spec/api/ad_campaigns_api_spec.rb +1 -1
  27. data/spec/api/connect_api_spec.rb +1 -1
  28. data/spec/api/posts_api_spec.rb +1 -1
  29. data/spec/api/tracking_tags_api_spec.rb +1 -1
  30. data/spec/api/webhooks_api_spec.rb +2 -2
  31. data/spec/models/ad_daily_metrics_spec.rb +6 -0
  32. data/spec/models/ad_metrics_spec.rb +6 -0
  33. data/spec/models/ads_timeline_response_rows_inner_spec.rb +6 -0
  34. data/spec/models/campaign_analytics_response_analytics_daily_inner_spec.rb +6 -0
  35. data/spec/models/create_tracking_tag_request_spec.rb +10 -0
  36. data/zernio-sdk-0.0.856.gem +0 -0
  37. metadata +2 -2
  38. data/zernio-sdk-0.0.854.gem +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c541aaaa8448460a57e09acf9fe79b03e95d7b887d43446b44610c7318bbefca
4
- data.tar.gz: b03c4ea167008348ed01fc8cbdb664045dfff9f901ed6642f50d7f7a25c52370
3
+ metadata.gz: 8de27aa225cf1072a71925bdd11e8c2060b5ce9d26491a2368a7e2b5b4014504
4
+ data.tar.gz: 36d212d52cf7bf9eb6f3f1b204861b10910d8205204b54bea22e266bab5e2ec4
5
5
  SHA512:
6
- metadata.gz: 456cf510447ea7fada96c77e7c5fee370f3b716b33643d34fce10af7b72d2140f51b80c333e40d5a8206bff30430cc07a2edd25a8b545419718a11a0e6f43071
7
- data.tar.gz: '0925de744e040767d2adb50be47404a637c64e87679499700eb9942cdc86a5a2653a07f0aecc90d3d3f59976359367b812889966a816e66327c32b655d6215cf'
6
+ metadata.gz: bcdc77dec797fcd7934afd3cd797092f0f4fe51c6917f821aae3192bcb8024480483a54427ae5d3914f0401c16dd15b7a250491ab9967804311d396bcf5ee472
7
+ data.tar.gz: 9169d3d94cf271c2dc58a862f8ac6bdff90479448511a6c7ac6d0d14a7f025e5b3cc42cedc9b8d4a046c832a0d4aff1771ebe1670d0c7fcfc658409ff576958e
@@ -1076,7 +1076,7 @@ end
1076
1076
 
1077
1077
  Get daily account metrics
1078
1078
 
1079
- Returns daily aggregate metrics across all ads in a SocialAccount as a single time series — one row per calendar day in the requested range. Use this for dashboards that draw a daily-spend or daily-conversions chart, instead of calling `/v1/ads/tree` once per day. `accountId` is required. The lookup is sibling-expanded so passing the `metaads` ID also includes ads under the linked `facebook` / `instagram` posting account (and vice-versa) — same convention as `/v1/ads/tree` and `/v1/ads`. Date range defaults to the last 90 days. Capped at 730 days. Ranges older than the ingested history return a `202` immediately with the covered part and `backfillPending: true` while the rest is backfilled in the background; repeat the request shortly until it returns 200 with full data.
1079
+ Returns daily aggregate metrics across all ads in a SocialAccount as a single time series — one row per calendar day in the requested range. Use this for dashboards that draw a daily-spend or daily-conversions chart, instead of calling `/v1/ads/tree` once per day. `accountId` is required. The lookup is sibling-expanded so passing the `metaads` ID also includes ads under the linked `facebook` / `instagram` posting account (and vice-versa) — same convention as `/v1/ads/tree` and `/v1/ads`. Date range defaults to the last 90 days. Capped at 730 days. Ranges older than the ingested history return a `202` immediately with the covered part and `backfillPending: true` while the rest is backfilled in the background; repeat the request shortly until it returns 200 with full data. With adAccountId set to a Google customer id this is the customer-level performance report (clicks, cost, impressions, conversions, all conversions per day).
1080
1080
 
1081
1081
  ### Examples
1082
1082
 
@@ -13,6 +13,7 @@
13
13
  | **cpm** | **Float** | Cost per 1000 impressions | [optional] |
14
14
  | **engagement** | **Integer** | | [optional] |
15
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's promoted_object.custom_event_type (PURCHASE, LEAD, etc.). Google: the account'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] |
16
17
  | **cost_per_conversion** | **Float** | Derived spend / conversions in the same currency as spend. 0 when conversions is 0. | [optional] |
17
18
  | **actions** | **Hash<String, Integer>** | Per-action-type counts summed over the date range, keyed by the platform's action-type names. Meta: raw Insights action_type keys (link_click, offsite_conversion.fb_pixel_purchase, onsite_conversion.lead_grouped, ...) — 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't synced per ad). Empty object when no actions are reported. NOTE: keys differ by platform, so branch on the ad's platform when interpreting them. | [optional] |
18
19
  | **action_values** | **Hash<String, Float>** | Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Same keying — values are the revenue attributed to each action_type, in ad-account native currency (same unit as `spend`; see the campaign node's `currency` field). Use this to compute revenue-per-event (e.g. avg purchase value). Meta-only; other platforms return {}. | [optional] |
@@ -55,6 +56,7 @@ instance = Zernio::AdDailyMetrics.new(
55
56
  cpm: null,
56
57
  engagement: null,
57
58
  conversions: null,
59
+ all_conversions: null,
58
60
  cost_per_conversion: null,
59
61
  actions: {link_click=160, post_engagement=300, offsite_conversion.fb_pixel_purchase=42},
60
62
  action_values: {offsite_conversion.fb_pixel_purchase=2456.78, offsite_conversion.fb_pixel_add_to_cart=980.5},
data/docs/AdMetrics.md CHANGED
@@ -13,6 +13,7 @@
13
13
  | **cpm** | **Float** | Cost per 1000 impressions | [optional] |
14
14
  | **engagement** | **Integer** | | [optional] |
15
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's promoted_object.custom_event_type (PURCHASE, LEAD, etc.). Google: the account'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] |
16
17
  | **cost_per_conversion** | **Float** | Derived spend / conversions in the same currency as spend. 0 when conversions is 0. | [optional] |
17
18
  | **actions** | **Hash<String, Integer>** | Per-action-type counts summed over the date range, keyed by the platform's action-type names. Meta: raw Insights action_type keys (link_click, offsite_conversion.fb_pixel_purchase, onsite_conversion.lead_grouped, ...) — 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't synced per ad). Empty object when no actions are reported. NOTE: keys differ by platform, so branch on the ad's platform when interpreting them. | [optional] |
18
19
  | **action_values** | **Hash<String, Float>** | Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Same keying — values are the revenue attributed to each action_type, in ad-account native currency (same unit as `spend`; see the campaign node's `currency` field). Use this to compute revenue-per-event (e.g. avg purchase value). Meta-only; other platforms return {}. | [optional] |
@@ -54,6 +55,7 @@ instance = Zernio::AdMetrics.new(
54
55
  cpm: null,
55
56
  engagement: null,
56
57
  conversions: null,
58
+ all_conversions: null,
57
59
  cost_per_conversion: null,
58
60
  actions: {link_click=160, post_engagement=300, offsite_conversion.fb_pixel_purchase=42},
59
61
  action_values: {offsite_conversion.fb_pixel_purchase=2456.78, offsite_conversion.fb_pixel_add_to_cart=980.5},
@@ -14,6 +14,7 @@
14
14
  | **cpc** | **Float** | Cost per click in native currency. | [optional] |
15
15
  | **cpm** | **Float** | Cost per 1000 impressions in native currency. | [optional] |
16
16
  | **conversions** | **Float** | Sum of conversion events over the range. Fractional values are normal (attribution splitting + Google modeled conversions). Meta: events matching the campaign optimization goal. Google: tracked conversions. X / LinkedIn: reported website/lead conversions (added 2026-07). | [optional] |
17
+ | **all_conversions** | **Float** | All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept. | [optional] |
17
18
  | **cost_per_conversion** | **Float** | | [optional] |
18
19
  | **actions** | **Hash<String, Float>** | Per-action-type counts merged across all ads on this day. Keys are platform-native action types. | [optional] |
19
20
  | **action_values** | **Hash<String, Float>** | Monetary mirror of `actions` in native currency. | [optional] |
@@ -36,6 +37,7 @@ instance = Zernio::AdsTimelineResponseRowsInner.new(
36
37
  cpc: null,
37
38
  cpm: null,
38
39
  conversions: null,
40
+ all_conversions: null,
39
41
  cost_per_conversion: null,
40
42
  actions: null,
41
43
  action_values: null,
@@ -13,6 +13,7 @@
13
13
  | **cpm** | **Float** | Cost per 1000 impressions | [optional] |
14
14
  | **engagement** | **Integer** | | [optional] |
15
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's promoted_object.custom_event_type (PURCHASE, LEAD, etc.). Google: the account'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] |
16
17
  | **cost_per_conversion** | **Float** | Derived spend / conversions in the same currency as spend. 0 when conversions is 0. | [optional] |
17
18
  | **actions** | **Hash<String, Integer>** | Per-action-type counts summed over the date range, keyed by the platform's action-type names. Meta: raw Insights action_type keys (link_click, offsite_conversion.fb_pixel_purchase, onsite_conversion.lead_grouped, ...) — 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't synced per ad). Empty object when no actions are reported. NOTE: keys differ by platform, so branch on the ad's platform when interpreting them. | [optional] |
18
19
  | **action_values** | **Hash<String, Float>** | Monetary mirror of `actions`, from Meta's Insights `action_values[]` array. Same keying — values are the revenue attributed to each action_type, in ad-account native currency (same unit as `spend`; see the campaign node's `currency` field). Use this to compute revenue-per-event (e.g. avg purchase value). Meta-only; other platforms return {}. | [optional] |
@@ -55,6 +56,7 @@ instance = Zernio::CampaignAnalyticsResponseAnalyticsDailyInner.new(
55
56
  cpm: null,
56
57
  engagement: null,
57
58
  conversions: null,
59
+ all_conversions: null,
58
60
  cost_per_conversion: null,
59
61
  actions: {link_click=160, post_engagement=300, offsite_conversion.fb_pixel_purchase=42},
60
62
  action_values: {offsite_conversion.fb_pixel_purchase=2456.78, offsite_conversion.fb_pixel_add_to_cart=980.5},
data/docs/ConnectApi.md CHANGED
@@ -993,7 +993,7 @@ Zernio.configure do |config|
993
993
  end
994
994
 
995
995
  api_instance = Zernio::ConnectApi.new
996
- platform = 'facebook' # String | Social media platform to connect
996
+ platform = 'facebook' # String | Social media platform to connect. `snapchat` is a closed beta with no public release date: it returns 403 `PLATFORM_BETA_RESTRICTED` until the account is approved.
997
997
  profile_id = 'profile_id_example' # String | Your Zernio profile ID (get from /v1/profiles). For WhatsApp, a Zernio-provisioned number can only be connected on the profile it was provisioned to; connecting from any other profile is rejected with a 409.
998
998
  opts = {
999
999
  redirect_url: 'redirect_url_example', # String | Your custom redirect URL after connection completes. MUST be an absolute http(s) URL or a custom app scheme for mobile deeplinks (e.g. myapp://callback); a relative path is rejected with 400 INVALID_REDIRECT_URL. Result params are appended with the URL API, so an existing query string is preserved. Standard mode appends connected={platform}&profileId=X&accountId=Y&username=Z. Headless mode appends OAuth data params for platforms requiring selection (e.g. LinkedIn orgs, Facebook pages). If no selection is needed, the account is created directly and the redirect includes accountId. On failure, the browser is sent to the same redirect_url with `error` and `platform` appended. `error` and `platform` are always present. `error_message`, `is_user_fixable`, `reason` and `dashboard_url` are conditional and must be treated as optional. This list is NOT exhaustive and new values may be added at any time. Treat an unrecognized value as a generic failure rather than matching it exhaustively. Existing values are not renamed or removed without notice. OAuth and callback: oauth_denied, invalid_callback, invalid_state, unsupported_platform, connection_failed, internal_error, token_exchange_failed, byok_config_error, personal_account_not_supported, missing_google_permissions, platform_requires_destination, reconnect_account_mismatch, invalid_request Access and limits: profile_not_found, invalid_profile_id, access_denied, account_limit_exceeded, profile_limit_exceeded, payment_required Destination selection: no_facebook_pages, facebook_pages_error, no_google_locations, google_locations_error, google_permission_denied, no_snapchat_public_profiles, snapchat_profiles_error, discord_no_guild, slack_no_team WhatsApp: whatsapp_error, one_whatsapp_per_profile, whatsapp_number_already_connected, whatsapp_number_pinned_to_profile, connection_cancelled Google Ads (platform=googleads): google_ads_auth_failed, google_ads_invalid_state, google_ads_config_error, google_ads_token_failed, google_ads_quota_exhausted, google_ads_callback_error TikTok Ads (platform=tiktokads): tiktok_ads_auth_failed, tiktok_ads_invalid_state, tiktok_ads_access_denied, tiktok_ads_config_error, tiktok_ads_token_failed, tiktok_ads_account_not_found, tiktok_ads_callback_error X Ads (platform=xads): x_ads_denied, x_ads_auth_failed, x_ads_config_error, x_ads_account_not_found, x_ads_state_error, x_ads_token_failed, x_ads_token_missing, x_ads_callback_error Shopify (platform=shopify): shopify_auth_failed, shopify_config_error, shopify_invalid_state, shopify_invalid_hmac, shopify_invalid_shop, shopify_missing_scopes, shopify_callback_error 1. On this endpoint every upstream OAuth error is collapsed into `oauth_denied`. The provider's own value (for example Meta's `access_denied`) is not forwarded. The dedicated ads flows below are different: they use their own denial slugs and `google_ads_auth_failed` and `tiktok_ads_auth_failed` may carry the provider's raw error string in `error_message`. 2. On the tiktok and twitter ads flows `platform` carries the ads platform id (`tiktokads`, `xads`), not the value used in the request path. The googleads and shopify flows report `googleads` and `shopify`.
@@ -1033,7 +1033,7 @@ end
1033
1033
 
1034
1034
  | Name | Type | Description | Notes |
1035
1035
  | ---- | ---- | ----------- | ----- |
1036
- | **platform** | **String** | Social media platform to connect | |
1036
+ | **platform** | **String** | Social media platform to connect. `snapchat` is a closed beta with no public release date: it returns 403 `PLATFORM_BETA_RESTRICTED` until the account is approved. | |
1037
1037
  | **profile_id** | **String** | Your Zernio profile ID (get from /v1/profiles). For WhatsApp, a Zernio-provisioned number can only be connected on the profile it was provisioned to; connecting from any other profile is rejected with a 409. | |
1038
1038
  | **redirect_url** | **String** | Your custom redirect URL after connection completes. MUST be an absolute http(s) URL or a custom app scheme for mobile deeplinks (e.g. myapp://callback); a relative path is rejected with 400 INVALID_REDIRECT_URL. Result params are appended with the URL API, so an existing query string is preserved. Standard mode appends connected={platform}&profileId=X&accountId=Y&username=Z. Headless mode appends OAuth data params for platforms requiring selection (e.g. LinkedIn orgs, Facebook pages). If no selection is needed, the account is created directly and the redirect includes accountId. On failure, the browser is sent to the same redirect_url with `error` and `platform` appended. `error` and `platform` are always present. `error_message`, `is_user_fixable`, `reason` and `dashboard_url` are conditional and must be treated as optional. This list is NOT exhaustive and new values may be added at any time. Treat an unrecognized value as a generic failure rather than matching it exhaustively. Existing values are not renamed or removed without notice. OAuth and callback: oauth_denied, invalid_callback, invalid_state, unsupported_platform, connection_failed, internal_error, token_exchange_failed, byok_config_error, personal_account_not_supported, missing_google_permissions, platform_requires_destination, reconnect_account_mismatch, invalid_request Access and limits: profile_not_found, invalid_profile_id, access_denied, account_limit_exceeded, profile_limit_exceeded, payment_required Destination selection: no_facebook_pages, facebook_pages_error, no_google_locations, google_locations_error, google_permission_denied, no_snapchat_public_profiles, snapchat_profiles_error, discord_no_guild, slack_no_team WhatsApp: whatsapp_error, one_whatsapp_per_profile, whatsapp_number_already_connected, whatsapp_number_pinned_to_profile, connection_cancelled Google Ads (platform=googleads): google_ads_auth_failed, google_ads_invalid_state, google_ads_config_error, google_ads_token_failed, google_ads_quota_exhausted, google_ads_callback_error TikTok Ads (platform=tiktokads): tiktok_ads_auth_failed, tiktok_ads_invalid_state, tiktok_ads_access_denied, tiktok_ads_config_error, tiktok_ads_token_failed, tiktok_ads_account_not_found, tiktok_ads_callback_error X Ads (platform=xads): x_ads_denied, x_ads_auth_failed, x_ads_config_error, x_ads_account_not_found, x_ads_state_error, x_ads_token_failed, x_ads_token_missing, x_ads_callback_error Shopify (platform=shopify): shopify_auth_failed, shopify_config_error, shopify_invalid_state, shopify_invalid_hmac, shopify_invalid_shop, shopify_missing_scopes, shopify_callback_error 1. On this endpoint every upstream OAuth error is collapsed into `oauth_denied`. The provider's own value (for example Meta's `access_denied`) is not forwarded. The dedicated ads flows below are different: they use their own denial slugs and `google_ads_auth_failed` and `tiktok_ads_auth_failed` may carry the provider's raw error string in `error_message`. 2. On the tiktok and twitter ads flows `platform` carries the ads platform id (`tiktokads`, `xads`), not the value used in the request path. The googleads and shopify flows report `googleads` and `shopify`. | [optional] |
1039
1039
  | **headless** | **Boolean** | When true, the user is redirected to your redirect_url with raw OAuth data (code, state) instead of Zernio's default account selection UI. Use this to build a custom connect experience. | [optional][default to false] |
@@ -6,17 +6,17 @@
6
6
  | ---- | ---- | ----------- | ----- |
7
7
  | **title** | **String** | Stored on the post for reference/display only. This field is NOT used as the video title when publishing. To set a YouTube video title, use platformSpecificData.title on the youtube platform target (falls back to the first line of content when omitted). | [optional] |
8
8
  | **content** | **String** | Post caption/text. Optional when media is attached, all platforms have customContent, every platform entry is an X Article (platformSpecificData.article), or every platform entry is a LinkedIn text-free reshare (platformSpecificData.reshareUrl with no text). Required for other text-only posts. | [optional] |
9
- | **media_items** | [**Array<MediaItem>**](MediaItem.md) | | [optional] |
9
+ | **media_items** | [**Array<MediaItem>**](MediaItem.md) | Media attached to every platform in the request (a platform entry can override it with `customMedia`). Each entry needs a publicly reachable HTTPS `url`; `type` (image, video, gif, document) is inferred from the URL extension when omitted and a `type` that contradicts the extension is rejected with 400. Upload files with `POST /v1/media/presign` first; per-platform size, duration and format limits are listed on each platform schema. | [optional] |
10
10
  | **platforms** | [**Array<CreatePostRequestPlatformsInner>**](CreatePostRequestPlatformsInner.md) | Target platforms and accounts for this post. Required for non-draft posts (returns 400 if empty). Drafts can omit platforms. | [optional] |
11
- | **scheduled_for** | **Time** | | [optional] |
12
- | **publish_now** | **Boolean** | | [optional][default to false] |
11
+ | **scheduled_for** | **Time** | When to publish. Required unless `publishNow` is true, `queuedFromProfile` is set, or the post is a draft. An ISO 8601 value with a `Z` or offset (`2026-01-15T10:00:00Z`, `2026-01-15T11:00:00+01:00`) is taken as-is; a value without one (`2026-01-15T10:00:00` or `2026-01-15 10:00`) is read as local time in `timezone`. A value already in the past is published synchronously in the same request. Ignored when `publishNow` is true. | [optional] |
12
+ | **publish_now** | **Boolean** | Publish to every platform synchronously in this request instead of scheduling; the response then carries each platform result and `platformPostUrl`, with HTTP 207 when some platforms failed. Takes precedence over `scheduledFor`; ignored when `isDraft` is true. | [optional][default to false] |
13
13
  | **is_draft** | **Boolean** | When true, saves the post as a draft. When none of scheduledFor, publishNow, or queuedFromProfile are provided, the post defaults to draft automatically. | [optional][default to false] |
14
- | **timezone** | **String** | | [optional][default to 'UTC'] |
14
+ | **timezone** | **String** | IANA timezone (`Europe/Madrid`, `America/New_York`) used to interpret a `scheduledFor` (root or per-platform) that carries no `Z` or offset. Has no effect on values that already carry one. An unknown name returns 400 when `scheduledFor` is set. | [optional][default to 'UTC'] |
15
15
  | **tags** | **Array<String>** | Tags/keywords. YouTube constraints: each tag max 100 chars, combined max 500 chars, duplicates auto-removed. | [optional] |
16
16
  | **hashtags** | **Array<String>** | Stored for reference only. Hashtags are NOT automatically appended to the caption when publishing. Include hashtags directly in the content field (platforms like Instagram only support hashtags as caption text). For YouTube keywords, use the tags field instead. | [optional] |
17
17
  | **mentions** | **Array<String>** | Stored for reference only. This field does NOT automatically create @mentions when publishing. For LinkedIn @mentions, use the /v1/accounts/{accountId}/linkedin-mentions endpoint to resolve profile URLs to URNs, then embed the returned mentionFormat directly in the post content field. | [optional] |
18
- | **crossposting_enabled** | **Boolean** | | [optional][default to true] |
19
- | **metadata** | **Hash<String, Object>** | | [optional] |
18
+ | **crossposting_enabled** | **Boolean** | Stored on the post and echoed back on reads. Publishing does not branch on it: every entry in `platforms` is published regardless, so treat it as a label for your own tooling. | [optional][default to true] |
19
+ | **metadata** | **Hash<String, Object>** | Free-form key/value pairs of your own, stored on the post and returned on reads and in webhook payloads. Zernio also writes the bookkeeping keys `usageCounted`, `usageRefunded` and `hidden` into this object; do not set them, and they are stripped from webhook payloads. | [optional] |
20
20
  | **tiktok_settings** | [**TikTokPlatformData**](TikTokPlatformData.md) | Root-level TikTok settings applied to the TikTok platforms sent in the same request. Merged into each platform's platformSpecificData, with platform-specific settings taking precedence. | [optional] |
21
21
  | **facebook_settings** | [**FacebookSettings**](FacebookSettings.md) | Root-level Facebook settings applied to the Facebook platforms sent in the same request. Merged into each platform's platformSpecificData.facebookSettings, with platform-specific settings taking precedence. | [optional] |
22
22
  | **recycling** | [**RecyclingConfig**](RecyclingConfig.md) | | [optional] |
@@ -6,6 +6,7 @@
6
6
  | ---- | ---- | ----------- | ----- |
7
7
  | **ad_account_id** | **String** | Meta ad account id, e.g. `act_123456789`. Required by this endpoint but ignored for OpenAI Ads. | |
8
8
  | **name** | **String** | | |
9
+ | **default_event_type** | **String** | OpenAI Ads only (ignored by Meta). When set, also provisions a standard conversion event setting wired to the new pixel, so `goal: conversions` ad creates on `POST /v1/ads/create` have an event to reference immediately. | [optional] |
9
10
 
10
11
  ## Example
11
12
 
@@ -14,7 +15,8 @@ require 'zernio-sdk'
14
15
 
15
16
  instance = Zernio::CreateTrackingTagRequest.new(
16
17
  ad_account_id: null,
17
- name: null
18
+ name: null,
19
+ default_event_type: null
18
20
  )
19
21
  ```
20
22
 
data/docs/PostsApi.md CHANGED
@@ -95,7 +95,7 @@ end
95
95
 
96
96
  Create post
97
97
 
98
- Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text). See each platform's schema for media constraints. ## Idempotency Two layers of duplicate-protection apply, so safe-to-retry callers (network blips, n8n / Zapier retries, etc.) don't accidentally double-post. **1. Same-request idempotency (5-minute window).** Pass an `x-request-id` header to mark a logical request. If a second request arrives with the same `x-request-id` while the first is in-flight (or within ~5 minutes of completion), we return **HTTP 200** with the original post in the `existingPost` field — no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. If you're using a generic HTTP client (curl, n8n's HTTP node, Zapier, custom code), either: - Set a unique `x-request-id` per logical call (recommended — UUIDv4 is fine) - Or simply omit the header — we'll treat each request as new **Common pitfall**: if your workflow tool uses a single execution-level request ID and reuses it across multiple HTTP nodes (e.g. one ID for the whole run, shared across 6 different platform calls), every call after the first will look like a retry of the first and return its post. Generate a fresh ID per node. **2. Content-hash dedup (24-hour window).** Independently, we hash `(platform, accountId, content + media URLs)` and reject duplicates within 24 hours with **HTTP 409**. This catches genuine \"same content posted twice to the same account\" cases regardless of `x-request-id`. Returns `error`, `accountId`, `platform`, and `existingPostId` so you can find the original. To intentionally re-post identical content within 24h, change something (the caption, the media, the account) — the dedup is keyed on the full content fingerprint. Order: same-`x-request-id` retries (200) are checked first; if no idempotency match, the content-hash dedup (409) runs.
98
+ Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text). See each platform's schema for media constraints. ## Scheduling Pick one of `scheduledFor` (schedule), `publishNow: true` (publish synchronously) or `queuedFromProfile` (next queue slot). With none of them and `isDraft` unset, the post is saved as a draft. `platforms` is required unless the post is a draft. `isDraft: true` wins over `publishNow` and `scheduledFor` (the post is saved, never published); `publishNow: true` wins over `scheduledFor`. A `scheduledFor` already in the past is not rejected: the post is published synchronously in the same request, exactly like `publishNow`. ## Idempotency Two layers of duplicate-protection apply, so safe-to-retry callers (network blips, n8n / Zapier retries, etc.) don't accidentally double-post. **1. Same-request idempotency (5-minute window).** Pass an `x-request-id` header to mark a logical request. If a second request arrives with the same `x-request-id` while the first is in-flight (or within ~5 minutes of completion), we return **HTTP 200** with the original post in the `existingPost` field — no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. If you're using a generic HTTP client (curl, n8n's HTTP node, Zapier, custom code), either: - Set a unique `x-request-id` per logical call (recommended — UUIDv4 is fine) - Or simply omit the header — we'll treat each request as new **Common pitfall**: if your workflow tool uses a single execution-level request ID and reuses it across multiple HTTP nodes (e.g. one ID for the whole run, shared across 6 different platform calls), every call after the first will look like a retry of the first and return its post. Generate a fresh ID per node. **2. Content-hash dedup (24-hour window).** Independently, we hash `(platform, accountId, content + media URLs)` and reject duplicates within 24 hours with **HTTP 409**. This catches genuine \"same content posted twice to the same account\" cases regardless of `x-request-id`. Returns `error`, `accountId`, `platform`, and `existingPostId` so you can find the original. To intentionally re-post identical content within 24h, change something (the caption, the media, the account) — the dedup is keyed on the full content fingerprint. Order: same-`x-request-id` retries (200) are checked first; if no idempotency match, the content-hash dedup (409) runs.
99
99
 
100
100
  ### Examples
101
101
 
@@ -95,7 +95,7 @@ end
95
95
 
96
96
  Create a tracking tag
97
97
 
98
- Meta: creates a Meta Pixel on the given ad account (`POST /act_{id}/adspixels` — `name` is the only input). Returns the created tag including its install `code`. The pixel is owned by the Business Manager that owns the ad account; a pixel created on a personal (non-BM) ad account ends up with `ownerBusinessId: null` and can't be shared with other ad accounts. Creating a Meta pixel does NOT install it — install the returned `code` snippet on the site, or send events server-side via `POST /v1/ads/conversions`. The check `installed` is derived from `lastFiredTime`. OpenAI Ads: creates an OpenAI pixel AND provisions a Conversions API key for it in the same call (`adAccountId` is required by this endpoint but ignored — one API key maps to exactly one ad account, so there's nothing to select). Returns 422 (`FEATURE_NOT_AVAILABLE`) if the ad account isn't enabled for pixel management; contact your OpenAI partner representative to enable it. There is no delete API for OpenAI pixels. If the pixel is created but the Conversions API key provisioning then fails, the pixel is left live on OpenAI (it cannot be cleaned up) and the error message names the surviving pixel id and warns against retrying, since a retry would create a second, orphaned pixel. NOT idempotent on either platform: each call creates a new pixel (and, for OpenAI, a new Conversions API key). Do not retry blindly on timeout. Meta (platform `metaads`) and OpenAI Ads (platform `openaiads`); other platforms return 405.
98
+ Meta: creates a Meta Pixel on the given ad account (`POST /act_{id}/adspixels` — `name` is the only input). Returns the created tag including its install `code`. The pixel is owned by the Business Manager that owns the ad account; a pixel created on a personal (non-BM) ad account ends up with `ownerBusinessId: null` and can't be shared with other ad accounts. Creating a Meta pixel does NOT install it — install the returned `code` snippet on the site, or send events server-side via `POST /v1/ads/conversions`. The check `installed` is derived from `lastFiredTime`. OpenAI Ads: creates an OpenAI pixel AND provisions a Conversions API key for it in the same call (`adAccountId` is required by this endpoint but ignored — one API key maps to exactly one ad account, so there's nothing to select). Returns 422 (`FEATURE_NOT_AVAILABLE`) if the ad account isn't enabled for pixel management; contact your OpenAI partner representative to enable it. There is no delete API for OpenAI pixels. If the pixel is created but the Conversions API key provisioning then fails, the pixel is left live on OpenAI (it cannot be cleaned up) and the error message names the surviving pixel id and warns against retrying, since a retry would create a second, orphaned pixel. NOT idempotent on either platform: each call creates a new pixel (and, for OpenAI, a new Conversions API key plus, with `defaultEventType`, a new conversion event setting). Do not retry blindly on timeout. Meta (platform `metaads`) and OpenAI Ads (platform `openaiads`); other platforms return 405.
99
99
 
100
100
  ### Examples
101
101
 
data/docs/WebhooksApi.md CHANGED
@@ -19,7 +19,7 @@ All URIs are relative to *https://zernio.com/api*
19
19
 
20
20
  Create webhook
21
21
 
22
- Create a new webhook configuration. Maximum 50 webhooks per user. `name`, `url` and `events` are required. `url` must be a valid URL and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are automatically disabled after 10 consecutive delivery failures. A restricted (zrk_) API key can only subscribe to events whose resource group the key holds; an event outside the key's groups is rejected with 403, so a restricted key can never create a subscription broader than itself. `disabledResourceGroups` restricts the subscription itself, independently of which key or session later reads it. Events in a disabled group are dropped before delivery to this endpoint, on live delivery and on every replay path (test fire, redelivery, dead-letter requeue), even if they are listed in `events`. Omit it to receive everything in `events`, which is how existing subscriptions behave. A restricted key's own disabled groups are always unioned in.
22
+ Create a new webhook configuration. Maximum 50 webhooks per user. `name`, `url` and `events` are required. `url` must be a valid URL and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are auto-disabled only once the endpoint has had no successful delivery for 3 days AND has either reached 20 consecutive terminal failures (each one an event that exhausted the full retry ladder) or been failing continuously for 3 days. The owner is emailed; re-enable it with `isActive: true`. A restricted (zrk_) API key can only subscribe to events whose resource group the key holds; an event outside the key's groups is rejected with 403, so a restricted key can never create a subscription broader than itself. `disabledResourceGroups` restricts the subscription itself, independently of which key or session later reads it. Events in a disabled group are dropped before delivery to this endpoint, on live delivery and on every replay path (test fire, redelivery, dead-letter requeue), even if they are listed in `events`. Omit it to receive everything in `events`, which is how existing subscriptions behave. A restricted key's own disabled groups are always unioned in.
23
23
 
24
24
  ### Examples
25
25
 
@@ -442,7 +442,7 @@ end
442
442
 
443
443
  Update webhook
444
444
 
445
- Update an existing webhook configuration. All fields except `_id` are optional; only provided fields will be updated. When provided, `name` must be 1-50 characters, `url` must be a valid URL, and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are automatically disabled after 10 consecutive delivery failures. A restricted (zrk_) API key can only set `events` to events whose resource group the key holds; an event outside the key's groups is rejected with 403. It also cannot widen an existing subscription past its own groups. `disabledResourceGroups` replaces the subscription's own denylist, which applies to delivery regardless of which key or session created it. Send an empty array to clear it. A restricted key's own disabled groups are unioned into the stored value on every update, so repointing a legacy unrestricted subscription with a restricted key also narrows it. Timing: the new denylist applies to every event emitted after the update. Events already queued for delivery when the update landed were filtered against the previous denylist and can still arrive at your endpoint for up to five minutes after they were enqueued, because the delivery worker trusts a five-minute enqueue-time snapshot before re-checking the subscription. Retries beyond that window, dead-letter replays, test fires, and redeliveries are all checked against the current denylist.
445
+ Update an existing webhook configuration. All fields except `_id` are optional; only provided fields will be updated. When provided, `name` must be 1-50 characters, `url` must be a valid URL, and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are auto-disabled only once the endpoint has had no successful delivery for 3 days AND has either reached 20 consecutive terminal failures (each one an event that exhausted the full retry ladder) or been failing continuously for 3 days. The owner is emailed; re-enable it with `isActive: true`. A restricted (zrk_) API key can only set `events` to events whose resource group the key holds; an event outside the key's groups is rejected with 403. It also cannot widen an existing subscription past its own groups. `disabledResourceGroups` replaces the subscription's own denylist, which applies to delivery regardless of which key or session created it. Send an empty array to clear it. A restricted key's own disabled groups are unioned into the stored value on every update, so repointing a legacy unrestricted subscription with a restricted key also narrows it. Timing: the new denylist applies to every event emitted after the update. Events already queued for delivery when the update landed were filtered against the previous denylist and can still arrive at your endpoint for up to five minutes after they were enqueued, because the delivery worker trusts a five-minute enqueue-time snapshot before re-checking the subscription. Retries beyond that window, dead-letter replays, test fires, and redeliveries are all checked against the current denylist.
446
446
 
447
447
  ### Examples
448
448
 
@@ -1106,7 +1106,7 @@ module Zernio
1106
1106
  end
1107
1107
 
1108
1108
  # Get daily account metrics
1109
- # Returns daily aggregate metrics across all ads in a SocialAccount as a single time series — one row per calendar day in the requested range. Use this for dashboards that draw a daily-spend or daily-conversions chart, instead of calling `/v1/ads/tree` once per day. `accountId` is required. The lookup is sibling-expanded so passing the `metaads` ID also includes ads under the linked `facebook` / `instagram` posting account (and vice-versa) — same convention as `/v1/ads/tree` and `/v1/ads`. Date range defaults to the last 90 days. Capped at 730 days. Ranges older than the ingested history return a `202` immediately with the covered part and `backfillPending: true` while the rest is backfilled in the background; repeat the request shortly until it returns 200 with full data.
1109
+ # Returns daily aggregate metrics across all ads in a SocialAccount as a single time series — one row per calendar day in the requested range. Use this for dashboards that draw a daily-spend or daily-conversions chart, instead of calling `/v1/ads/tree` once per day. `accountId` is required. The lookup is sibling-expanded so passing the `metaads` ID also includes ads under the linked `facebook` / `instagram` posting account (and vice-versa) — same convention as `/v1/ads/tree` and `/v1/ads`. Date range defaults to the last 90 days. Capped at 730 days. Ranges older than the ingested history return a `202` immediately with the covered part and `backfillPending: true` while the rest is backfilled in the background; repeat the request shortly until it returns 200 with full data. With adAccountId set to a Google customer id this is the customer-level performance report (clicks, cost, impressions, conversions, all conversions per day).
1110
1110
  # @param account_id [String] Social account ID. Sibling-expanded to its linked posting↔ads pair.
1111
1111
  # @param [Hash] opts the optional parameters
1112
1112
  # @option opts [String] :ad_account_id Optional platform-native ad account ID (e.g. Meta `act_…`, TikTok advertiser ID). Use when the connection wraps multiple platform ad accounts and the chart should show one only. Note: rows ingested before 2026-05-13 don't carry this column; the recurring 7-day re-sync repopulates them naturally.
@@ -1120,7 +1120,7 @@ module Zernio
1120
1120
  end
1121
1121
 
1122
1122
  # Get daily account metrics
1123
- # Returns daily aggregate metrics across all ads in a SocialAccount as a single time series — one row per calendar day in the requested range. Use this for dashboards that draw a daily-spend or daily-conversions chart, instead of calling `/v1/ads/tree` once per day. `accountId` is required. The lookup is sibling-expanded so passing the `metaads` ID also includes ads under the linked `facebook` / `instagram` posting account (and vice-versa) — same convention as `/v1/ads/tree` and `/v1/ads`. Date range defaults to the last 90 days. Capped at 730 days. Ranges older than the ingested history return a `202` immediately with the covered part and `backfillPending: true` while the rest is backfilled in the background; repeat the request shortly until it returns 200 with full data.
1123
+ # Returns daily aggregate metrics across all ads in a SocialAccount as a single time series — one row per calendar day in the requested range. Use this for dashboards that draw a daily-spend or daily-conversions chart, instead of calling `/v1/ads/tree` once per day. `accountId` is required. The lookup is sibling-expanded so passing the `metaads` ID also includes ads under the linked `facebook` / `instagram` posting account (and vice-versa) — same convention as `/v1/ads/tree` and `/v1/ads`. Date range defaults to the last 90 days. Capped at 730 days. Ranges older than the ingested history return a `202` immediately with the covered part and `backfillPending: true` while the rest is backfilled in the background; repeat the request shortly until it returns 200 with full data. With adAccountId set to a Google customer id this is the customer-level performance report (clicks, cost, impressions, conversions, all conversions per day).
1124
1124
  # @param account_id [String] Social account ID. Sibling-expanded to its linked posting↔ads pair.
1125
1125
  # @param [Hash] opts the optional parameters
1126
1126
  # @option opts [String] :ad_account_id Optional platform-native ad account ID (e.g. Meta `act_…`, TikTok advertiser ID). Use when the connection wraps multiple platform ad accounts and the chart should show one only. Note: rows ingested before 2026-05-13 don't carry this column; the recurring 7-day re-sync repopulates them naturally.
@@ -941,7 +941,7 @@ module Zernio
941
941
 
942
942
  # Get OAuth connect URL
943
943
  # Initiate an OAuth connection flow. Returns an authUrl to redirect the user to. Standard flow: Zernio hosts the selection UI, then redirects to your redirect_url. Headless mode (headless=true): user is redirected to your redirect_url with OAuth data for custom UI. Use the platform-specific selection endpoints to complete.
944
- # @param platform [String] Social media platform to connect
944
+ # @param platform [String] Social media platform to connect. `snapchat` is a closed beta with no public release date: it returns 403 `PLATFORM_BETA_RESTRICTED` until the account is approved.
945
945
  # @param profile_id [String] Your Zernio profile ID (get from /v1/profiles). For WhatsApp, a Zernio-provisioned number can only be connected on the profile it was provisioned to; connecting from any other profile is rejected with a 409.
946
946
  # @param [Hash] opts the optional parameters
947
947
  # @option opts [String] :redirect_url Your custom redirect URL after connection completes. MUST be an absolute http(s) URL or a custom app scheme for mobile deeplinks (e.g. myapp://callback); a relative path is rejected with 400 INVALID_REDIRECT_URL. Result params are appended with the URL API, so an existing query string is preserved. Standard mode appends connected={platform}&profileId=X&accountId=Y&username=Z. Headless mode appends OAuth data params for platforms requiring selection (e.g. LinkedIn orgs, Facebook pages). If no selection is needed, the account is created directly and the redirect includes accountId. On failure, the browser is sent to the same redirect_url with `error` and `platform` appended. `error` and `platform` are always present. `error_message`, `is_user_fixable`, `reason` and `dashboard_url` are conditional and must be treated as optional. This list is NOT exhaustive and new values may be added at any time. Treat an unrecognized value as a generic failure rather than matching it exhaustively. Existing values are not renamed or removed without notice. OAuth and callback: oauth_denied, invalid_callback, invalid_state, unsupported_platform, connection_failed, internal_error, token_exchange_failed, byok_config_error, personal_account_not_supported, missing_google_permissions, platform_requires_destination, reconnect_account_mismatch, invalid_request Access and limits: profile_not_found, invalid_profile_id, access_denied, account_limit_exceeded, profile_limit_exceeded, payment_required Destination selection: no_facebook_pages, facebook_pages_error, no_google_locations, google_locations_error, google_permission_denied, no_snapchat_public_profiles, snapchat_profiles_error, discord_no_guild, slack_no_team WhatsApp: whatsapp_error, one_whatsapp_per_profile, whatsapp_number_already_connected, whatsapp_number_pinned_to_profile, connection_cancelled Google Ads (platform=googleads): google_ads_auth_failed, google_ads_invalid_state, google_ads_config_error, google_ads_token_failed, google_ads_quota_exhausted, google_ads_callback_error TikTok Ads (platform=tiktokads): tiktok_ads_auth_failed, tiktok_ads_invalid_state, tiktok_ads_access_denied, tiktok_ads_config_error, tiktok_ads_token_failed, tiktok_ads_account_not_found, tiktok_ads_callback_error X Ads (platform=xads): x_ads_denied, x_ads_auth_failed, x_ads_config_error, x_ads_account_not_found, x_ads_state_error, x_ads_token_failed, x_ads_token_missing, x_ads_callback_error Shopify (platform=shopify): shopify_auth_failed, shopify_config_error, shopify_invalid_state, shopify_invalid_hmac, shopify_invalid_shop, shopify_missing_scopes, shopify_callback_error 1. On this endpoint every upstream OAuth error is collapsed into `oauth_denied`. The provider's own value (for example Meta's `access_denied`) is not forwarded. The dedicated ads flows below are different: they use their own denial slugs and `google_ads_auth_failed` and `tiktok_ads_auth_failed` may carry the provider's raw error string in `error_message`. 2. On the tiktok and twitter ads flows `platform` carries the ads platform id (`tiktokads`, `xads`), not the value used in the request path. The googleads and shopify flows report `googleads` and `shopify`.
@@ -956,7 +956,7 @@ module Zernio
956
956
 
957
957
  # Get OAuth connect URL
958
958
  # Initiate an OAuth connection flow. Returns an authUrl to redirect the user to. Standard flow: Zernio hosts the selection UI, then redirects to your redirect_url. Headless mode (headless=true): user is redirected to your redirect_url with OAuth data for custom UI. Use the platform-specific selection endpoints to complete.
959
- # @param platform [String] Social media platform to connect
959
+ # @param platform [String] Social media platform to connect. `snapchat` is a closed beta with no public release date: it returns 403 `PLATFORM_BETA_RESTRICTED` until the account is approved.
960
960
  # @param profile_id [String] Your Zernio profile ID (get from /v1/profiles). For WhatsApp, a Zernio-provisioned number can only be connected on the profile it was provisioned to; connecting from any other profile is rejected with a 409.
961
961
  # @param [Hash] opts the optional parameters
962
962
  # @option opts [String] :redirect_url Your custom redirect URL after connection completes. MUST be an absolute http(s) URL or a custom app scheme for mobile deeplinks (e.g. myapp://callback); a relative path is rejected with 400 INVALID_REDIRECT_URL. Result params are appended with the URL API, so an existing query string is preserved. Standard mode appends connected={platform}&profileId=X&accountId=Y&username=Z. Headless mode appends OAuth data params for platforms requiring selection (e.g. LinkedIn orgs, Facebook pages). If no selection is needed, the account is created directly and the redirect includes accountId. On failure, the browser is sent to the same redirect_url with `error` and `platform` appended. `error` and `platform` are always present. `error_message`, `is_user_fixable`, `reason` and `dashboard_url` are conditional and must be treated as optional. This list is NOT exhaustive and new values may be added at any time. Treat an unrecognized value as a generic failure rather than matching it exhaustively. Existing values are not renamed or removed without notice. OAuth and callback: oauth_denied, invalid_callback, invalid_state, unsupported_platform, connection_failed, internal_error, token_exchange_failed, byok_config_error, personal_account_not_supported, missing_google_permissions, platform_requires_destination, reconnect_account_mismatch, invalid_request Access and limits: profile_not_found, invalid_profile_id, access_denied, account_limit_exceeded, profile_limit_exceeded, payment_required Destination selection: no_facebook_pages, facebook_pages_error, no_google_locations, google_locations_error, google_permission_denied, no_snapchat_public_profiles, snapchat_profiles_error, discord_no_guild, slack_no_team WhatsApp: whatsapp_error, one_whatsapp_per_profile, whatsapp_number_already_connected, whatsapp_number_pinned_to_profile, connection_cancelled Google Ads (platform=googleads): google_ads_auth_failed, google_ads_invalid_state, google_ads_config_error, google_ads_token_failed, google_ads_quota_exhausted, google_ads_callback_error TikTok Ads (platform=tiktokads): tiktok_ads_auth_failed, tiktok_ads_invalid_state, tiktok_ads_access_denied, tiktok_ads_config_error, tiktok_ads_token_failed, tiktok_ads_account_not_found, tiktok_ads_callback_error X Ads (platform=xads): x_ads_denied, x_ads_auth_failed, x_ads_config_error, x_ads_account_not_found, x_ads_state_error, x_ads_token_failed, x_ads_token_missing, x_ads_callback_error Shopify (platform=shopify): shopify_auth_failed, shopify_config_error, shopify_invalid_state, shopify_invalid_hmac, shopify_invalid_shop, shopify_missing_scopes, shopify_callback_error 1. On this endpoint every upstream OAuth error is collapsed into `oauth_denied`. The provider's own value (for example Meta's `access_denied`) is not forwarded. The dedicated ads flows below are different: they use their own denial slugs and `google_ads_auth_failed` and `tiktok_ads_auth_failed` may carry the provider's raw error string in `error_message`. 2. On the tiktok and twitter ads flows `platform` carries the ads platform id (`tiktokads`, `xads`), not the value used in the request path. The googleads and shopify flows report `googleads` and `shopify`.
@@ -88,7 +88,7 @@ module Zernio
88
88
  end
89
89
 
90
90
  # Create post
91
- # Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text). See each platform's schema for media constraints. ## Idempotency Two layers of duplicate-protection apply, so safe-to-retry callers (network blips, n8n / Zapier retries, etc.) don't accidentally double-post. **1. Same-request idempotency (5-minute window).** Pass an `x-request-id` header to mark a logical request. If a second request arrives with the same `x-request-id` while the first is in-flight (or within ~5 minutes of completion), we return **HTTP 200** with the original post in the `existingPost` field — no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. If you're using a generic HTTP client (curl, n8n's HTTP node, Zapier, custom code), either: - Set a unique `x-request-id` per logical call (recommended — UUIDv4 is fine) - Or simply omit the header — we'll treat each request as new **Common pitfall**: if your workflow tool uses a single execution-level request ID and reuses it across multiple HTTP nodes (e.g. one ID for the whole run, shared across 6 different platform calls), every call after the first will look like a retry of the first and return its post. Generate a fresh ID per node. **2. Content-hash dedup (24-hour window).** Independently, we hash `(platform, accountId, content + media URLs)` and reject duplicates within 24 hours with **HTTP 409**. This catches genuine \"same content posted twice to the same account\" cases regardless of `x-request-id`. Returns `error`, `accountId`, `platform`, and `existingPostId` so you can find the original. To intentionally re-post identical content within 24h, change something (the caption, the media, the account) — the dedup is keyed on the full content fingerprint. Order: same-`x-request-id` retries (200) are checked first; if no idempotency match, the content-hash dedup (409) runs.
91
+ # Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text). See each platform's schema for media constraints. ## Scheduling Pick one of `scheduledFor` (schedule), `publishNow: true` (publish synchronously) or `queuedFromProfile` (next queue slot). With none of them and `isDraft` unset, the post is saved as a draft. `platforms` is required unless the post is a draft. `isDraft: true` wins over `publishNow` and `scheduledFor` (the post is saved, never published); `publishNow: true` wins over `scheduledFor`. A `scheduledFor` already in the past is not rejected: the post is published synchronously in the same request, exactly like `publishNow`. ## Idempotency Two layers of duplicate-protection apply, so safe-to-retry callers (network blips, n8n / Zapier retries, etc.) don't accidentally double-post. **1. Same-request idempotency (5-minute window).** Pass an `x-request-id` header to mark a logical request. If a second request arrives with the same `x-request-id` while the first is in-flight (or within ~5 minutes of completion), we return **HTTP 200** with the original post in the `existingPost` field — no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. If you're using a generic HTTP client (curl, n8n's HTTP node, Zapier, custom code), either: - Set a unique `x-request-id` per logical call (recommended — UUIDv4 is fine) - Or simply omit the header — we'll treat each request as new **Common pitfall**: if your workflow tool uses a single execution-level request ID and reuses it across multiple HTTP nodes (e.g. one ID for the whole run, shared across 6 different platform calls), every call after the first will look like a retry of the first and return its post. Generate a fresh ID per node. **2. Content-hash dedup (24-hour window).** Independently, we hash `(platform, accountId, content + media URLs)` and reject duplicates within 24 hours with **HTTP 409**. This catches genuine \"same content posted twice to the same account\" cases regardless of `x-request-id`. Returns `error`, `accountId`, `platform`, and `existingPostId` so you can find the original. To intentionally re-post identical content within 24h, change something (the caption, the media, the account) — the dedup is keyed on the full content fingerprint. Order: same-`x-request-id` retries (200) are checked first; if no idempotency match, the content-hash dedup (409) runs.
92
92
  # @param create_post_request [CreatePostRequest]
93
93
  # @param [Hash] opts the optional parameters
94
94
  # @option opts [String] :x_request_id Optional client-generated request identifier for safe retry (idempotency). When two requests carry the same value, the second is treated as a retry of the first and returns the original post (HTTP 200) instead of creating a duplicate. Window is ~5 minutes from the first request. Generate a UUID per logical call. SDKs do this automatically; HTTP clients should set it themselves or omit it. See the operation description for the full idempotency contract.
@@ -99,7 +99,7 @@ module Zernio
99
99
  end
100
100
 
101
101
  # Create post
102
- # Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text). See each platform's schema for media constraints. ## Idempotency Two layers of duplicate-protection apply, so safe-to-retry callers (network blips, n8n / Zapier retries, etc.) don't accidentally double-post. **1. Same-request idempotency (5-minute window).** Pass an `x-request-id` header to mark a logical request. If a second request arrives with the same `x-request-id` while the first is in-flight (or within ~5 minutes of completion), we return **HTTP 200** with the original post in the `existingPost` field — no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. If you're using a generic HTTP client (curl, n8n's HTTP node, Zapier, custom code), either: - Set a unique `x-request-id` per logical call (recommended — UUIDv4 is fine) - Or simply omit the header — we'll treat each request as new **Common pitfall**: if your workflow tool uses a single execution-level request ID and reuses it across multiple HTTP nodes (e.g. one ID for the whole run, shared across 6 different platform calls), every call after the first will look like a retry of the first and return its post. Generate a fresh ID per node. **2. Content-hash dedup (24-hour window).** Independently, we hash `(platform, accountId, content + media URLs)` and reject duplicates within 24 hours with **HTTP 409**. This catches genuine \"same content posted twice to the same account\" cases regardless of `x-request-id`. Returns `error`, `accountId`, `platform`, and `existingPostId` so you can find the original. To intentionally re-post identical content within 24h, change something (the caption, the media, the account) — the dedup is keyed on the full content fingerprint. Order: same-`x-request-id` retries (200) are checked first; if no idempotency match, the content-hash dedup (409) runs.
102
+ # Create and optionally publish a post. Immediate posts (`publishNow: true`) include `platformPostUrl` in the response. Content is optional when media is attached, all platforms have `customContent`, every platform entry is an X Article (`platformSpecificData.article`), or every platform entry is a LinkedIn text-free reshare (`platformSpecificData.reshareUrl` with no text). See each platform's schema for media constraints. ## Scheduling Pick one of `scheduledFor` (schedule), `publishNow: true` (publish synchronously) or `queuedFromProfile` (next queue slot). With none of them and `isDraft` unset, the post is saved as a draft. `platforms` is required unless the post is a draft. `isDraft: true` wins over `publishNow` and `scheduledFor` (the post is saved, never published); `publishNow: true` wins over `scheduledFor`. A `scheduledFor` already in the past is not rejected: the post is published synchronously in the same request, exactly like `publishNow`. ## Idempotency Two layers of duplicate-protection apply, so safe-to-retry callers (network blips, n8n / Zapier retries, etc.) don't accidentally double-post. **1. Same-request idempotency (5-minute window).** Pass an `x-request-id` header to mark a logical request. If a second request arrives with the same `x-request-id` while the first is in-flight (or within ~5 minutes of completion), we return **HTTP 200** with the original post in the `existingPost` field — no new post is created. The official Zernio SDKs auto-generate a unique `x-request-id` per call. If you're using a generic HTTP client (curl, n8n's HTTP node, Zapier, custom code), either: - Set a unique `x-request-id` per logical call (recommended — UUIDv4 is fine) - Or simply omit the header — we'll treat each request as new **Common pitfall**: if your workflow tool uses a single execution-level request ID and reuses it across multiple HTTP nodes (e.g. one ID for the whole run, shared across 6 different platform calls), every call after the first will look like a retry of the first and return its post. Generate a fresh ID per node. **2. Content-hash dedup (24-hour window).** Independently, we hash `(platform, accountId, content + media URLs)` and reject duplicates within 24 hours with **HTTP 409**. This catches genuine \"same content posted twice to the same account\" cases regardless of `x-request-id`. Returns `error`, `accountId`, `platform`, and `existingPostId` so you can find the original. To intentionally re-post identical content within 24h, change something (the caption, the media, the account) — the dedup is keyed on the full content fingerprint. Order: same-`x-request-id` retries (200) are checked first; if no idempotency match, the content-hash dedup (409) runs.
103
103
  # @param create_post_request [CreatePostRequest]
104
104
  # @param [Hash] opts the optional parameters
105
105
  # @option opts [String] :x_request_id Optional client-generated request identifier for safe retry (idempotency). When two requests carry the same value, the second is treated as a retry of the first and returns the original post (HTTP 200) instead of creating a duplicate. Window is ~5 minutes from the first request. Generate a UUID per logical call. SDKs do this automatically; HTTP clients should set it themselves or omit it. See the operation description for the full idempotency contract.
@@ -100,7 +100,7 @@ module Zernio
100
100
  end
101
101
 
102
102
  # Create a tracking tag
103
- # Meta: creates a Meta Pixel on the given ad account (`POST /act_{id}/adspixels` — `name` is the only input). Returns the created tag including its install `code`. The pixel is owned by the Business Manager that owns the ad account; a pixel created on a personal (non-BM) ad account ends up with `ownerBusinessId: null` and can't be shared with other ad accounts. Creating a Meta pixel does NOT install it — install the returned `code` snippet on the site, or send events server-side via `POST /v1/ads/conversions`. The check `installed` is derived from `lastFiredTime`. OpenAI Ads: creates an OpenAI pixel AND provisions a Conversions API key for it in the same call (`adAccountId` is required by this endpoint but ignored — one API key maps to exactly one ad account, so there's nothing to select). Returns 422 (`FEATURE_NOT_AVAILABLE`) if the ad account isn't enabled for pixel management; contact your OpenAI partner representative to enable it. There is no delete API for OpenAI pixels. If the pixel is created but the Conversions API key provisioning then fails, the pixel is left live on OpenAI (it cannot be cleaned up) and the error message names the surviving pixel id and warns against retrying, since a retry would create a second, orphaned pixel. NOT idempotent on either platform: each call creates a new pixel (and, for OpenAI, a new Conversions API key). Do not retry blindly on timeout. Meta (platform `metaads`) and OpenAI Ads (platform `openaiads`); other platforms return 405.
103
+ # Meta: creates a Meta Pixel on the given ad account (`POST /act_{id}/adspixels` — `name` is the only input). Returns the created tag including its install `code`. The pixel is owned by the Business Manager that owns the ad account; a pixel created on a personal (non-BM) ad account ends up with `ownerBusinessId: null` and can't be shared with other ad accounts. Creating a Meta pixel does NOT install it — install the returned `code` snippet on the site, or send events server-side via `POST /v1/ads/conversions`. The check `installed` is derived from `lastFiredTime`. OpenAI Ads: creates an OpenAI pixel AND provisions a Conversions API key for it in the same call (`adAccountId` is required by this endpoint but ignored — one API key maps to exactly one ad account, so there's nothing to select). Returns 422 (`FEATURE_NOT_AVAILABLE`) if the ad account isn't enabled for pixel management; contact your OpenAI partner representative to enable it. There is no delete API for OpenAI pixels. If the pixel is created but the Conversions API key provisioning then fails, the pixel is left live on OpenAI (it cannot be cleaned up) and the error message names the surviving pixel id and warns against retrying, since a retry would create a second, orphaned pixel. NOT idempotent on either platform: each call creates a new pixel (and, for OpenAI, a new Conversions API key plus, with `defaultEventType`, a new conversion event setting). Do not retry blindly on timeout. Meta (platform `metaads`) and OpenAI Ads (platform `openaiads`); other platforms return 405.
104
104
  # @param account_id [String] Ads SocialAccount id (platform `metaads` or `openaiads`).
105
105
  # @param create_tracking_tag_request [CreateTrackingTagRequest]
106
106
  # @param [Hash] opts the optional parameters
@@ -111,7 +111,7 @@ module Zernio
111
111
  end
112
112
 
113
113
  # Create a tracking tag
114
- # Meta: creates a Meta Pixel on the given ad account (`POST /act_{id}/adspixels` — `name` is the only input). Returns the created tag including its install `code`. The pixel is owned by the Business Manager that owns the ad account; a pixel created on a personal (non-BM) ad account ends up with `ownerBusinessId: null` and can't be shared with other ad accounts. Creating a Meta pixel does NOT install it — install the returned `code` snippet on the site, or send events server-side via `POST /v1/ads/conversions`. The check `installed` is derived from `lastFiredTime`. OpenAI Ads: creates an OpenAI pixel AND provisions a Conversions API key for it in the same call (`adAccountId` is required by this endpoint but ignored — one API key maps to exactly one ad account, so there's nothing to select). Returns 422 (`FEATURE_NOT_AVAILABLE`) if the ad account isn't enabled for pixel management; contact your OpenAI partner representative to enable it. There is no delete API for OpenAI pixels. If the pixel is created but the Conversions API key provisioning then fails, the pixel is left live on OpenAI (it cannot be cleaned up) and the error message names the surviving pixel id and warns against retrying, since a retry would create a second, orphaned pixel. NOT idempotent on either platform: each call creates a new pixel (and, for OpenAI, a new Conversions API key). Do not retry blindly on timeout. Meta (platform `metaads`) and OpenAI Ads (platform `openaiads`); other platforms return 405.
114
+ # Meta: creates a Meta Pixel on the given ad account (`POST /act_{id}/adspixels` — `name` is the only input). Returns the created tag including its install `code`. The pixel is owned by the Business Manager that owns the ad account; a pixel created on a personal (non-BM) ad account ends up with `ownerBusinessId: null` and can't be shared with other ad accounts. Creating a Meta pixel does NOT install it — install the returned `code` snippet on the site, or send events server-side via `POST /v1/ads/conversions`. The check `installed` is derived from `lastFiredTime`. OpenAI Ads: creates an OpenAI pixel AND provisions a Conversions API key for it in the same call (`adAccountId` is required by this endpoint but ignored — one API key maps to exactly one ad account, so there's nothing to select). Returns 422 (`FEATURE_NOT_AVAILABLE`) if the ad account isn't enabled for pixel management; contact your OpenAI partner representative to enable it. There is no delete API for OpenAI pixels. If the pixel is created but the Conversions API key provisioning then fails, the pixel is left live on OpenAI (it cannot be cleaned up) and the error message names the surviving pixel id and warns against retrying, since a retry would create a second, orphaned pixel. NOT idempotent on either platform: each call creates a new pixel (and, for OpenAI, a new Conversions API key plus, with `defaultEventType`, a new conversion event setting). Do not retry blindly on timeout. Meta (platform `metaads`) and OpenAI Ads (platform `openaiads`); other platforms return 405.
115
115
  # @param account_id [String] Ads SocialAccount id (platform `metaads` or `openaiads`).
116
116
  # @param create_tracking_tag_request [CreateTrackingTagRequest]
117
117
  # @param [Hash] opts the optional parameters
@@ -20,7 +20,7 @@ module Zernio
20
20
  @api_client = api_client
21
21
  end
22
22
  # Create webhook
23
- # Create a new webhook configuration. Maximum 50 webhooks per user. `name`, `url` and `events` are required. `url` must be a valid URL and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are automatically disabled after 10 consecutive delivery failures. A restricted (zrk_) API key can only subscribe to events whose resource group the key holds; an event outside the key's groups is rejected with 403, so a restricted key can never create a subscription broader than itself. `disabledResourceGroups` restricts the subscription itself, independently of which key or session later reads it. Events in a disabled group are dropped before delivery to this endpoint, on live delivery and on every replay path (test fire, redelivery, dead-letter requeue), even if they are listed in `events`. Omit it to receive everything in `events`, which is how existing subscriptions behave. A restricted key's own disabled groups are always unioned in.
23
+ # Create a new webhook configuration. Maximum 50 webhooks per user. `name`, `url` and `events` are required. `url` must be a valid URL and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are auto-disabled only once the endpoint has had no successful delivery for 3 days AND has either reached 20 consecutive terminal failures (each one an event that exhausted the full retry ladder) or been failing continuously for 3 days. The owner is emailed; re-enable it with `isActive: true`. A restricted (zrk_) API key can only subscribe to events whose resource group the key holds; an event outside the key's groups is rejected with 403, so a restricted key can never create a subscription broader than itself. `disabledResourceGroups` restricts the subscription itself, independently of which key or session later reads it. Events in a disabled group are dropped before delivery to this endpoint, on live delivery and on every replay path (test fire, redelivery, dead-letter requeue), even if they are listed in `events`. Omit it to receive everything in `events`, which is how existing subscriptions behave. A restricted key's own disabled groups are always unioned in.
24
24
  # @param create_webhook_settings_request [CreateWebhookSettingsRequest]
25
25
  # @param [Hash] opts the optional parameters
26
26
  # @return [UpdateWebhookSettings200Response]
@@ -30,7 +30,7 @@ module Zernio
30
30
  end
31
31
 
32
32
  # Create webhook
33
- # Create a new webhook configuration. Maximum 50 webhooks per user. `name`, `url` and `events` are required. `url` must be a valid URL and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are automatically disabled after 10 consecutive delivery failures. A restricted (zrk_) API key can only subscribe to events whose resource group the key holds; an event outside the key's groups is rejected with 403, so a restricted key can never create a subscription broader than itself. `disabledResourceGroups` restricts the subscription itself, independently of which key or session later reads it. Events in a disabled group are dropped before delivery to this endpoint, on live delivery and on every replay path (test fire, redelivery, dead-letter requeue), even if they are listed in `events`. Omit it to receive everything in `events`, which is how existing subscriptions behave. A restricted key's own disabled groups are always unioned in.
33
+ # Create a new webhook configuration. Maximum 50 webhooks per user. `name`, `url` and `events` are required. `url` must be a valid URL and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are auto-disabled only once the endpoint has had no successful delivery for 3 days AND has either reached 20 consecutive terminal failures (each one an event that exhausted the full retry ladder) or been failing continuously for 3 days. The owner is emailed; re-enable it with `isActive: true`. A restricted (zrk_) API key can only subscribe to events whose resource group the key holds; an event outside the key's groups is rejected with 403, so a restricted key can never create a subscription broader than itself. `disabledResourceGroups` restricts the subscription itself, independently of which key or session later reads it. Events in a disabled group are dropped before delivery to this endpoint, on live delivery and on every replay path (test fire, redelivery, dead-letter requeue), even if they are listed in `events`. Omit it to receive everything in `events`, which is how existing subscriptions behave. A restricted key's own disabled groups are always unioned in.
34
34
  # @param create_webhook_settings_request [CreateWebhookSettingsRequest]
35
35
  # @param [Hash] opts the optional parameters
36
36
  # @return [Array<(UpdateWebhookSettings200Response, Integer, Hash)>] UpdateWebhookSettings200Response data, response status code and response headers
@@ -469,7 +469,7 @@ module Zernio
469
469
  end
470
470
 
471
471
  # Update webhook
472
- # Update an existing webhook configuration. All fields except `_id` are optional; only provided fields will be updated. When provided, `name` must be 1-50 characters, `url` must be a valid URL, and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are automatically disabled after 10 consecutive delivery failures. A restricted (zrk_) API key can only set `events` to events whose resource group the key holds; an event outside the key's groups is rejected with 403. It also cannot widen an existing subscription past its own groups. `disabledResourceGroups` replaces the subscription's own denylist, which applies to delivery regardless of which key or session created it. Send an empty array to clear it. A restricted key's own disabled groups are unioned into the stored value on every update, so repointing a legacy unrestricted subscription with a restricted key also narrows it. Timing: the new denylist applies to every event emitted after the update. Events already queued for delivery when the update landed were filtered against the previous denylist and can still arrive at your endpoint for up to five minutes after they were enqueued, because the delivery worker trusts a five-minute enqueue-time snapshot before re-checking the subscription. Retries beyond that window, dead-letter replays, test fires, and redeliveries are all checked against the current denylist.
472
+ # Update an existing webhook configuration. All fields except `_id` are optional; only provided fields will be updated. When provided, `name` must be 1-50 characters, `url` must be a valid URL, and `events` must contain at least one event. Whitespace is trimmed from `url` before validation. Webhooks are auto-disabled only once the endpoint has had no successful delivery for 3 days AND has either reached 20 consecutive terminal failures (each one an event that exhausted the full retry ladder) or been failing continuously for 3 days. The owner is emailed; re-enable it with `isActive: true`. A restricted (zrk_) API key can only set `events` to events whose resource group the key holds; an event outside the key's groups is rejected with 403. It also cannot widen an existing subscription past its own groups. `disabledResourceGroups` replaces the subscription's own denylist, which applies to delivery regardless of which key or session created it. Send an empty array to clear it. A restricted key's own disabled groups are unioned into the stored value on every update, so repointing a legacy unrestricted subscription with a restricted key also narrows it. Timing: the new denylist applies to every event emitted after the update. Events already queued for delivery when the update landed were filtered against the previous denylist and can still arrive at your endpoint for up to five minutes after they were enqueued, because the delivery worker trusts a five-minute enqueue-time snapshot before re-checking the subscription. Retries beyond that window, dead-letter replays, test fires, and redeliveries are all checked against the current denylist.
473
473
  # @param update_webhook_settings_request [UpdateWebhookSettingsRequest]
474
474
  # @param [Hash] opts the optional parameters
475
475
  # @return [UpdateWebhookSettings200Response]
@@ -479,7 +479,7 @@ module Zernio
479
479
  end
480
480
 
481
481
  # Update webhook
482
- # Update an existing webhook configuration. All fields except &#x60;_id&#x60; are optional; only provided fields will be updated. When provided, &#x60;name&#x60; must be 1-50 characters, &#x60;url&#x60; must be a valid URL, and &#x60;events&#x60; must contain at least one event. Whitespace is trimmed from &#x60;url&#x60; before validation. Webhooks are automatically disabled after 10 consecutive delivery failures. A restricted (zrk_) API key can only set &#x60;events&#x60; to events whose resource group the key holds; an event outside the key&#39;s groups is rejected with 403. It also cannot widen an existing subscription past its own groups. &#x60;disabledResourceGroups&#x60; replaces the subscription&#39;s own denylist, which applies to delivery regardless of which key or session created it. Send an empty array to clear it. A restricted key&#39;s own disabled groups are unioned into the stored value on every update, so repointing a legacy unrestricted subscription with a restricted key also narrows it. Timing: the new denylist applies to every event emitted after the update. Events already queued for delivery when the update landed were filtered against the previous denylist and can still arrive at your endpoint for up to five minutes after they were enqueued, because the delivery worker trusts a five-minute enqueue-time snapshot before re-checking the subscription. Retries beyond that window, dead-letter replays, test fires, and redeliveries are all checked against the current denylist.
482
+ # Update an existing webhook configuration. All fields except &#x60;_id&#x60; are optional; only provided fields will be updated. When provided, &#x60;name&#x60; must be 1-50 characters, &#x60;url&#x60; must be a valid URL, and &#x60;events&#x60; must contain at least one event. Whitespace is trimmed from &#x60;url&#x60; before validation. Webhooks are auto-disabled only once the endpoint has had no successful delivery for 3 days AND has either reached 20 consecutive terminal failures (each one an event that exhausted the full retry ladder) or been failing continuously for 3 days. The owner is emailed; re-enable it with &#x60;isActive: true&#x60;. A restricted (zrk_) API key can only set &#x60;events&#x60; to events whose resource group the key holds; an event outside the key&#39;s groups is rejected with 403. It also cannot widen an existing subscription past its own groups. &#x60;disabledResourceGroups&#x60; replaces the subscription&#39;s own denylist, which applies to delivery regardless of which key or session created it. Send an empty array to clear it. A restricted key&#39;s own disabled groups are unioned into the stored value on every update, so repointing a legacy unrestricted subscription with a restricted key also narrows it. Timing: the new denylist applies to every event emitted after the update. Events already queued for delivery when the update landed were filtered against the previous denylist and can still arrive at your endpoint for up to five minutes after they were enqueued, because the delivery worker trusts a five-minute enqueue-time snapshot before re-checking the subscription. Retries beyond that window, dead-letter replays, test fires, and redeliveries are all checked against the current denylist.
483
483
  # @param update_webhook_settings_request [UpdateWebhookSettingsRequest]
484
484
  # @param [Hash] opts the optional parameters
485
485
  # @return [Array<(UpdateWebhookSettings200Response, Integer, Hash)>] UpdateWebhookSettings200Response data, response status code and response headers
@@ -39,6 +39,9 @@ module Zernio
39
39
  # 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's promoted_object.custom_event_type (PURCHASE, LEAD, etc.). Google: the account'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.
40
40
  attr_accessor :conversions
41
41
 
42
+ # All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.
43
+ attr_accessor :all_conversions
44
+
42
45
  # Derived spend / conversions in the same currency as spend. 0 when conversions is 0.
43
46
  attr_accessor :cost_per_conversion
44
47
 
@@ -127,6 +130,7 @@ module Zernio
127
130
  :'cpm' => :'cpm',
128
131
  :'engagement' => :'engagement',
129
132
  :'conversions' => :'conversions',
133
+ :'all_conversions' => :'allConversions',
130
134
  :'cost_per_conversion' => :'costPerConversion',
131
135
  :'actions' => :'actions',
132
136
  :'action_values' => :'actionValues',
@@ -178,6 +182,7 @@ module Zernio
178
182
  :'cpm' => :'Float',
179
183
  :'engagement' => :'Integer',
180
184
  :'conversions' => :'Float',
185
+ :'all_conversions' => :'Float',
181
186
  :'cost_per_conversion' => :'Float',
182
187
  :'actions' => :'Hash<String, Integer>',
183
188
  :'action_values' => :'Hash<String, Float>',
@@ -272,6 +277,10 @@ module Zernio
272
277
  self.conversions = attributes[:'conversions']
273
278
  end
274
279
 
280
+ if attributes.key?(:'all_conversions')
281
+ self.all_conversions = attributes[:'all_conversions']
282
+ end
283
+
275
284
  if attributes.key?(:'cost_per_conversion')
276
285
  self.cost_per_conversion = attributes[:'cost_per_conversion']
277
286
  end
@@ -412,6 +421,7 @@ module Zernio
412
421
  cpm == o.cpm &&
413
422
  engagement == o.engagement &&
414
423
  conversions == o.conversions &&
424
+ all_conversions == o.all_conversions &&
415
425
  cost_per_conversion == o.cost_per_conversion &&
416
426
  actions == o.actions &&
417
427
  action_values == o.action_values &&
@@ -449,7 +459,7 @@ module Zernio
449
459
  # Calculates hash code according to all attributes.
450
460
  # @return [Integer] Hash code
451
461
  def hash
452
- [spend, impressions, reach, clicks, ctr, cpc, cpm, engagement, conversions, cost_per_conversion, actions, action_values, purchase_value, roas, cost_per_action, outbound_clicks, outbound_clicks_ctr, inline_link_clicks, inline_link_click_ctr, unique_clicks, unique_ctr, video_play_actions, video30_sec_watched_actions, video_thruplay_watched_actions, video_p25_watched_actions, video_p50_watched_actions, video_p75_watched_actions, video_p95_watched_actions, video_p100_watched_actions, video_avg_time_watched_actions, cost_per_thruplay, funnel, engagement_breakdown, last_synced_at, date].hash
462
+ [spend, impressions, reach, clicks, ctr, cpc, cpm, engagement, conversions, all_conversions, cost_per_conversion, actions, action_values, purchase_value, roas, cost_per_action, outbound_clicks, outbound_clicks_ctr, inline_link_clicks, inline_link_click_ctr, unique_clicks, unique_ctr, video_play_actions, video30_sec_watched_actions, video_thruplay_watched_actions, video_p25_watched_actions, video_p50_watched_actions, video_p75_watched_actions, video_p95_watched_actions, video_p100_watched_actions, video_avg_time_watched_actions, cost_per_thruplay, funnel, engagement_breakdown, last_synced_at, date].hash
453
463
  end
454
464
 
455
465
  # Builds the object from hash
@@ -38,6 +38,9 @@ module Zernio
38
38
  # 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's promoted_object.custom_event_type (PURCHASE, LEAD, etc.). Google: the account'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.
39
39
  attr_accessor :conversions
40
40
 
41
+ # All conversions, including actions excluded from the Conversions column (Google metrics.all_conversions). 0 on platforms without the concept.
42
+ attr_accessor :all_conversions
43
+
41
44
  # Derived spend / conversions in the same currency as spend. 0 when conversions is 0.
42
45
  attr_accessor :cost_per_conversion
43
46
 
@@ -123,6 +126,7 @@ module Zernio
123
126
  :'cpm' => :'cpm',
124
127
  :'engagement' => :'engagement',
125
128
  :'conversions' => :'conversions',
129
+ :'all_conversions' => :'allConversions',
126
130
  :'cost_per_conversion' => :'costPerConversion',
127
131
  :'actions' => :'actions',
128
132
  :'action_values' => :'actionValues',
@@ -173,6 +177,7 @@ module Zernio
173
177
  :'cpm' => :'Float',
174
178
  :'engagement' => :'Integer',
175
179
  :'conversions' => :'Float',
180
+ :'all_conversions' => :'Float',
176
181
  :'cost_per_conversion' => :'Float',
177
182
  :'actions' => :'Hash<String, Integer>',
178
183
  :'action_values' => :'Hash<String, Float>',
@@ -259,6 +264,10 @@ module Zernio
259
264
  self.conversions = attributes[:'conversions']
260
265
  end
261
266
 
267
+ if attributes.key?(:'all_conversions')
268
+ self.all_conversions = attributes[:'all_conversions']
269
+ end
270
+
262
271
  if attributes.key?(:'cost_per_conversion')
263
272
  self.cost_per_conversion = attributes[:'cost_per_conversion']
264
273
  end
@@ -395,6 +404,7 @@ module Zernio
395
404
  cpm == o.cpm &&
396
405
  engagement == o.engagement &&
397
406
  conversions == o.conversions &&
407
+ all_conversions == o.all_conversions &&
398
408
  cost_per_conversion == o.cost_per_conversion &&
399
409
  actions == o.actions &&
400
410
  action_values == o.action_values &&
@@ -431,7 +441,7 @@ module Zernio
431
441
  # Calculates hash code according to all attributes.
432
442
  # @return [Integer] Hash code
433
443
  def hash
434
- [spend, impressions, reach, clicks, ctr, cpc, cpm, engagement, conversions, cost_per_conversion, actions, action_values, purchase_value, roas, cost_per_action, outbound_clicks, outbound_clicks_ctr, inline_link_clicks, inline_link_click_ctr, unique_clicks, unique_ctr, video_play_actions, video30_sec_watched_actions, video_thruplay_watched_actions, video_p25_watched_actions, video_p50_watched_actions, video_p75_watched_actions, video_p95_watched_actions, video_p100_watched_actions, video_avg_time_watched_actions, cost_per_thruplay, funnel, engagement_breakdown, last_synced_at].hash
444
+ [spend, impressions, reach, clicks, ctr, cpc, cpm, engagement, conversions, all_conversions, cost_per_conversion, actions, action_values, purchase_value, roas, cost_per_action, outbound_clicks, outbound_clicks_ctr, inline_link_clicks, inline_link_click_ctr, unique_clicks, unique_ctr, video_play_actions, video30_sec_watched_actions, video_thruplay_watched_actions, video_p25_watched_actions, video_p50_watched_actions, video_p75_watched_actions, video_p95_watched_actions, video_p100_watched_actions, video_avg_time_watched_actions, cost_per_thruplay, funnel, engagement_breakdown, last_synced_at].hash
435
445
  end
436
446
 
437
447
  # Builds the object from hash