late-sdk 0.0.855 → 0.0.857
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +19 -2
- data/docs/AdCampaignsApi.md +364 -6
- data/docs/{ListAdKeywords200ResponseKeywordsInner.md → AdKeyword.md} +7 -3
- data/docs/AdKeywordMetrics.md +30 -0
- data/docs/AddAdKeywords201Response.md +18 -0
- data/docs/AddAdKeywordsRequest.md +24 -0
- data/docs/AddAdKeywordsRequestKeywordsInner.md +20 -0
- data/docs/AddAdKeywordsRequestKeywordsInnerAnyOf.md +20 -0
- data/docs/ConnectApi.md +2 -2
- data/docs/CreatePostRequest.md +6 -6
- data/docs/CreateStandaloneAdRequest.md +4 -2
- data/docs/CreateTrackingTagRequest.md +3 -1
- data/docs/KeywordEntry.md +49 -0
- data/docs/ListAdKeywords200Response.md +1 -1
- data/docs/ListCampaignNegativeKeywords200Response.md +18 -0
- data/docs/ListCampaignNegativeKeywords200ResponseKeywordsInner.md +22 -0
- data/docs/PostsApi.md +1 -1
- data/docs/RemoveAdKeyword200Response.md +20 -0
- data/docs/ReplaceCampaignNegativeKeywords200Response.md +22 -0
- data/docs/ReplaceCampaignNegativeKeywordsRequest.md +20 -0
- data/docs/TrackingTagsApi.md +1 -1
- data/docs/UpdateAdKeyword200Response.md +18 -0
- data/docs/{UpdateAdStatusRequest.md → UpdateAdKeywordRequest.md} +2 -2
- data/docs/WebhooksApi.md +2 -2
- data/lib/zernio-sdk/api/ad_campaigns_api.rb +358 -9
- data/lib/zernio-sdk/api/connect_api.rb +2 -2
- data/lib/zernio-sdk/api/posts_api.rb +2 -2
- data/lib/zernio-sdk/api/tracking_tags_api.rb +2 -2
- data/lib/zernio-sdk/api/webhooks_api.rb +4 -4
- data/lib/zernio-sdk/models/{list_ad_keywords200_response_keywords_inner.rb → ad_keyword.rb} +28 -8
- data/lib/zernio-sdk/models/ad_keyword_metrics.rb +207 -0
- data/lib/zernio-sdk/models/add_ad_keywords201_response.rb +149 -0
- data/lib/zernio-sdk/models/add_ad_keywords_request.rb +250 -0
- data/lib/zernio-sdk/models/add_ad_keywords_request_keywords_inner.rb +103 -0
- data/lib/zernio-sdk/models/add_ad_keywords_request_keywords_inner_any_of.rb +225 -0
- data/lib/zernio-sdk/models/create_post_request.rb +6 -0
- data/lib/zernio-sdk/models/create_standalone_ad_request.rb +55 -5
- data/lib/zernio-sdk/models/create_tracking_tag_request.rb +48 -4
- data/lib/zernio-sdk/models/keyword_entry.rb +105 -0
- data/lib/zernio-sdk/models/list_ad_keywords200_response.rb +1 -1
- data/lib/zernio-sdk/models/list_campaign_negative_keywords200_response.rb +149 -0
- data/lib/zernio-sdk/models/list_campaign_negative_keywords200_response_keywords_inner.rb +199 -0
- data/lib/zernio-sdk/models/remove_ad_keyword200_response.rb +157 -0
- data/lib/zernio-sdk/models/replace_campaign_negative_keywords200_response.rb +170 -0
- data/lib/zernio-sdk/models/replace_campaign_negative_keywords_request.rb +219 -0
- data/lib/zernio-sdk/models/update_ad_keyword200_response.rb +147 -0
- data/lib/zernio-sdk/models/{update_ad_status_request.rb → update_ad_keyword_request.rb} +3 -3
- data/lib/zernio-sdk/version.rb +1 -1
- data/lib/zernio-sdk.rb +14 -2
- data/openapi.yaml +299 -32
- data/spec/api/ad_campaigns_api_spec.rb +64 -1
- data/spec/api/connect_api_spec.rb +1 -1
- data/spec/api/posts_api_spec.rb +1 -1
- data/spec/api/tracking_tags_api_spec.rb +1 -1
- data/spec/api/webhooks_api_spec.rb +2 -2
- data/spec/models/ad_keyword_metrics_spec.rb +72 -0
- data/spec/models/{list_ad_keywords200_response_keywords_inner_spec.rb → ad_keyword_spec.rb} +18 -6
- data/spec/models/add_ad_keywords201_response_spec.rb +36 -0
- data/spec/models/add_ad_keywords_request_keywords_inner_any_of_spec.rb +46 -0
- data/spec/models/add_ad_keywords_request_keywords_inner_spec.rb +21 -0
- data/spec/models/add_ad_keywords_request_spec.rb +54 -0
- data/spec/models/create_standalone_ad_request_spec.rb +6 -0
- data/spec/models/create_tracking_tag_request_spec.rb +10 -0
- data/spec/models/keyword_entry_spec.rb +32 -0
- data/spec/models/list_campaign_negative_keywords200_response_keywords_inner_spec.rb +52 -0
- data/spec/models/list_campaign_negative_keywords200_response_spec.rb +36 -0
- data/spec/models/remove_ad_keyword200_response_spec.rb +42 -0
- data/spec/models/replace_campaign_negative_keywords200_response_spec.rb +48 -0
- data/spec/models/replace_campaign_negative_keywords_request_spec.rb +46 -0
- data/spec/models/update_ad_keyword200_response_spec.rb +36 -0
- data/spec/models/{update_ad_status_request_spec.rb → update_ad_keyword_request_spec.rb} +6 -6
- data/zernio-sdk-0.0.857.gem +0 -0
- metadata +58 -10
- data/zernio-sdk-0.0.855.gem +0 -0
|
@@ -19,6 +19,74 @@ module Zernio
|
|
|
19
19
|
def initialize(api_client = ApiClient.default)
|
|
20
20
|
@api_client = api_client
|
|
21
21
|
end
|
|
22
|
+
# Add Search keywords to an ad group
|
|
23
|
+
# Adds one or more keyword criteria to an existing Google Search ad group, without touching the keywords already there (unlike the whole-set diff on `PUT /v1/ads/{adId}`, `keywords`/`negativeKeywords` in `platformSpecificData`, which replaces the set). Set `negative: true` to add ad-group-level negatives instead of positive keywords.
|
|
24
|
+
# @param add_ad_keywords_request [AddAdKeywordsRequest]
|
|
25
|
+
# @param [Hash] opts the optional parameters
|
|
26
|
+
# @return [AddAdKeywords201Response]
|
|
27
|
+
def add_ad_keywords(add_ad_keywords_request, opts = {})
|
|
28
|
+
data, _status_code, _headers = add_ad_keywords_with_http_info(add_ad_keywords_request, opts)
|
|
29
|
+
data
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Add Search keywords to an ad group
|
|
33
|
+
# Adds one or more keyword criteria to an existing Google Search ad group, without touching the keywords already there (unlike the whole-set diff on `PUT /v1/ads/{adId}`, `keywords`/`negativeKeywords` in `platformSpecificData`, which replaces the set). Set `negative: true` to add ad-group-level negatives instead of positive keywords.
|
|
34
|
+
# @param add_ad_keywords_request [AddAdKeywordsRequest]
|
|
35
|
+
# @param [Hash] opts the optional parameters
|
|
36
|
+
# @return [Array<(AddAdKeywords201Response, Integer, Hash)>] AddAdKeywords201Response data, response status code and response headers
|
|
37
|
+
def add_ad_keywords_with_http_info(add_ad_keywords_request, opts = {})
|
|
38
|
+
if @api_client.config.debugging
|
|
39
|
+
@api_client.config.logger.debug 'Calling API: AdCampaignsApi.add_ad_keywords ...'
|
|
40
|
+
end
|
|
41
|
+
# verify the required parameter 'add_ad_keywords_request' is set
|
|
42
|
+
if @api_client.config.client_side_validation && add_ad_keywords_request.nil?
|
|
43
|
+
fail ArgumentError, "Missing the required parameter 'add_ad_keywords_request' when calling AdCampaignsApi.add_ad_keywords"
|
|
44
|
+
end
|
|
45
|
+
# resource path
|
|
46
|
+
local_var_path = '/v1/ads/keywords'
|
|
47
|
+
|
|
48
|
+
# query parameters
|
|
49
|
+
query_params = opts[:query_params] || {}
|
|
50
|
+
|
|
51
|
+
# header parameters
|
|
52
|
+
header_params = opts[:header_params] || {}
|
|
53
|
+
# HTTP header 'Accept' (if needed)
|
|
54
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
55
|
+
# HTTP header 'Content-Type'
|
|
56
|
+
content_type = @api_client.select_header_content_type(['application/json'])
|
|
57
|
+
if !content_type.nil?
|
|
58
|
+
header_params['Content-Type'] = content_type
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# form parameters
|
|
62
|
+
form_params = opts[:form_params] || {}
|
|
63
|
+
|
|
64
|
+
# http body (model)
|
|
65
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(add_ad_keywords_request)
|
|
66
|
+
|
|
67
|
+
# return_type
|
|
68
|
+
return_type = opts[:debug_return_type] || 'AddAdKeywords201Response'
|
|
69
|
+
|
|
70
|
+
# auth_names
|
|
71
|
+
auth_names = opts[:debug_auth_names] || ['bearerAuth']
|
|
72
|
+
|
|
73
|
+
new_options = opts.merge(
|
|
74
|
+
:operation => :"AdCampaignsApi.add_ad_keywords",
|
|
75
|
+
:header_params => header_params,
|
|
76
|
+
:query_params => query_params,
|
|
77
|
+
:form_params => form_params,
|
|
78
|
+
:body => post_body,
|
|
79
|
+
:auth_names => auth_names,
|
|
80
|
+
:return_type => return_type
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
data, status_code, headers = @api_client.call_api(:POST, local_var_path, new_options)
|
|
84
|
+
if @api_client.config.debugging
|
|
85
|
+
@api_client.config.logger.debug "API called: AdCampaignsApi#add_ad_keywords\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
86
|
+
end
|
|
87
|
+
return data, status_code, headers
|
|
88
|
+
end
|
|
89
|
+
|
|
22
90
|
# Attach extension assets to a Google Search campaign
|
|
23
91
|
# Attach sitelinks, callouts and/or structured snippets to an already-existing Google Search campaign — the same builders POST /v1/ads/create uses, but without rebuilding the hierarchy. At least one of sitelinks, callouts or structuredSnippets is required. Google-only. Other platforms have no equivalent extension surface and return 501. Approval status is Google-async; poll `asset.policy_summary` after review. Assets stay in the account library even if the campaign is later deleted.
|
|
24
92
|
# @param campaign_id [String] Numeric Google platform campaign id.
|
|
@@ -1547,6 +1615,213 @@ module Zernio
|
|
|
1547
1615
|
return data, status_code, headers
|
|
1548
1616
|
end
|
|
1549
1617
|
|
|
1618
|
+
# List campaign-level negative keywords
|
|
1619
|
+
# Returns the campaign-level negative keywords (`campaign_criterion.negative`), distinct from the ad-group-level negatives under `GET /v1/ads/keywords`. Read live from Google on every call (not synced to Postgres), and gated by the shared Google Ads operations budget like every other on-demand Google surface. The platform is always discovered from the campaign itself; a non-Google campaign returns 501 rather than 404, whether or not `platform` was passed.
|
|
1620
|
+
# @param campaign_id [String] Platform campaign ID
|
|
1621
|
+
# @param [Hash] opts the optional parameters
|
|
1622
|
+
# @option opts [String] :platform Optional and NOT authoritative: the resolved campaign's own platform decides 200 vs 501, never this hint.
|
|
1623
|
+
# @return [ListCampaignNegativeKeywords200Response]
|
|
1624
|
+
def list_campaign_negative_keywords(campaign_id, opts = {})
|
|
1625
|
+
data, _status_code, _headers = list_campaign_negative_keywords_with_http_info(campaign_id, opts)
|
|
1626
|
+
data
|
|
1627
|
+
end
|
|
1628
|
+
|
|
1629
|
+
# List campaign-level negative keywords
|
|
1630
|
+
# Returns the campaign-level negative keywords (`campaign_criterion.negative`), distinct from the ad-group-level negatives under `GET /v1/ads/keywords`. Read live from Google on every call (not synced to Postgres), and gated by the shared Google Ads operations budget like every other on-demand Google surface. The platform is always discovered from the campaign itself; a non-Google campaign returns 501 rather than 404, whether or not `platform` was passed.
|
|
1631
|
+
# @param campaign_id [String] Platform campaign ID
|
|
1632
|
+
# @param [Hash] opts the optional parameters
|
|
1633
|
+
# @option opts [String] :platform Optional and NOT authoritative: the resolved campaign's own platform decides 200 vs 501, never this hint.
|
|
1634
|
+
# @return [Array<(ListCampaignNegativeKeywords200Response, Integer, Hash)>] ListCampaignNegativeKeywords200Response data, response status code and response headers
|
|
1635
|
+
def list_campaign_negative_keywords_with_http_info(campaign_id, opts = {})
|
|
1636
|
+
if @api_client.config.debugging
|
|
1637
|
+
@api_client.config.logger.debug 'Calling API: AdCampaignsApi.list_campaign_negative_keywords ...'
|
|
1638
|
+
end
|
|
1639
|
+
# verify the required parameter 'campaign_id' is set
|
|
1640
|
+
if @api_client.config.client_side_validation && campaign_id.nil?
|
|
1641
|
+
fail ArgumentError, "Missing the required parameter 'campaign_id' when calling AdCampaignsApi.list_campaign_negative_keywords"
|
|
1642
|
+
end
|
|
1643
|
+
allowable_values = ["facebook", "instagram", "tiktok", "linkedin", "pinterest", "google", "twitter", "openai"]
|
|
1644
|
+
if @api_client.config.client_side_validation && opts[:'platform'] && !allowable_values.include?(opts[:'platform'])
|
|
1645
|
+
fail ArgumentError, "invalid value for \"platform\", must be one of #{allowable_values}"
|
|
1646
|
+
end
|
|
1647
|
+
# resource path
|
|
1648
|
+
local_var_path = '/v1/ads/campaigns/{campaignId}/negative-keywords'.sub('{' + 'campaignId' + '}', CGI.escape(campaign_id.to_s))
|
|
1649
|
+
|
|
1650
|
+
# query parameters
|
|
1651
|
+
query_params = opts[:query_params] || {}
|
|
1652
|
+
query_params[:'platform'] = opts[:'platform'] if !opts[:'platform'].nil?
|
|
1653
|
+
|
|
1654
|
+
# header parameters
|
|
1655
|
+
header_params = opts[:header_params] || {}
|
|
1656
|
+
# HTTP header 'Accept' (if needed)
|
|
1657
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
1658
|
+
|
|
1659
|
+
# form parameters
|
|
1660
|
+
form_params = opts[:form_params] || {}
|
|
1661
|
+
|
|
1662
|
+
# http body (model)
|
|
1663
|
+
post_body = opts[:debug_body]
|
|
1664
|
+
|
|
1665
|
+
# return_type
|
|
1666
|
+
return_type = opts[:debug_return_type] || 'ListCampaignNegativeKeywords200Response'
|
|
1667
|
+
|
|
1668
|
+
# auth_names
|
|
1669
|
+
auth_names = opts[:debug_auth_names] || ['bearerAuth']
|
|
1670
|
+
|
|
1671
|
+
new_options = opts.merge(
|
|
1672
|
+
:operation => :"AdCampaignsApi.list_campaign_negative_keywords",
|
|
1673
|
+
:header_params => header_params,
|
|
1674
|
+
:query_params => query_params,
|
|
1675
|
+
:form_params => form_params,
|
|
1676
|
+
:body => post_body,
|
|
1677
|
+
:auth_names => auth_names,
|
|
1678
|
+
:return_type => return_type
|
|
1679
|
+
)
|
|
1680
|
+
|
|
1681
|
+
data, status_code, headers = @api_client.call_api(:GET, local_var_path, new_options)
|
|
1682
|
+
if @api_client.config.debugging
|
|
1683
|
+
@api_client.config.logger.debug "API called: AdCampaignsApi#list_campaign_negative_keywords\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
1684
|
+
end
|
|
1685
|
+
return data, status_code, headers
|
|
1686
|
+
end
|
|
1687
|
+
|
|
1688
|
+
# Remove a Search keyword
|
|
1689
|
+
# Removes one keyword criterion (positive or negative) from its ad group (M.140).
|
|
1690
|
+
# @param keyword_id [String] Zernio keyword ID (not the Google criterion ID)
|
|
1691
|
+
# @param [Hash] opts the optional parameters
|
|
1692
|
+
# @return [RemoveAdKeyword200Response]
|
|
1693
|
+
def remove_ad_keyword(keyword_id, opts = {})
|
|
1694
|
+
data, _status_code, _headers = remove_ad_keyword_with_http_info(keyword_id, opts)
|
|
1695
|
+
data
|
|
1696
|
+
end
|
|
1697
|
+
|
|
1698
|
+
# Remove a Search keyword
|
|
1699
|
+
# Removes one keyword criterion (positive or negative) from its ad group (M.140).
|
|
1700
|
+
# @param keyword_id [String] Zernio keyword ID (not the Google criterion ID)
|
|
1701
|
+
# @param [Hash] opts the optional parameters
|
|
1702
|
+
# @return [Array<(RemoveAdKeyword200Response, Integer, Hash)>] RemoveAdKeyword200Response data, response status code and response headers
|
|
1703
|
+
def remove_ad_keyword_with_http_info(keyword_id, opts = {})
|
|
1704
|
+
if @api_client.config.debugging
|
|
1705
|
+
@api_client.config.logger.debug 'Calling API: AdCampaignsApi.remove_ad_keyword ...'
|
|
1706
|
+
end
|
|
1707
|
+
# verify the required parameter 'keyword_id' is set
|
|
1708
|
+
if @api_client.config.client_side_validation && keyword_id.nil?
|
|
1709
|
+
fail ArgumentError, "Missing the required parameter 'keyword_id' when calling AdCampaignsApi.remove_ad_keyword"
|
|
1710
|
+
end
|
|
1711
|
+
# resource path
|
|
1712
|
+
local_var_path = '/v1/ads/keywords/{keywordId}'.sub('{' + 'keywordId' + '}', CGI.escape(keyword_id.to_s))
|
|
1713
|
+
|
|
1714
|
+
# query parameters
|
|
1715
|
+
query_params = opts[:query_params] || {}
|
|
1716
|
+
|
|
1717
|
+
# header parameters
|
|
1718
|
+
header_params = opts[:header_params] || {}
|
|
1719
|
+
# HTTP header 'Accept' (if needed)
|
|
1720
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
1721
|
+
|
|
1722
|
+
# form parameters
|
|
1723
|
+
form_params = opts[:form_params] || {}
|
|
1724
|
+
|
|
1725
|
+
# http body (model)
|
|
1726
|
+
post_body = opts[:debug_body]
|
|
1727
|
+
|
|
1728
|
+
# return_type
|
|
1729
|
+
return_type = opts[:debug_return_type] || 'RemoveAdKeyword200Response'
|
|
1730
|
+
|
|
1731
|
+
# auth_names
|
|
1732
|
+
auth_names = opts[:debug_auth_names] || ['bearerAuth']
|
|
1733
|
+
|
|
1734
|
+
new_options = opts.merge(
|
|
1735
|
+
:operation => :"AdCampaignsApi.remove_ad_keyword",
|
|
1736
|
+
:header_params => header_params,
|
|
1737
|
+
:query_params => query_params,
|
|
1738
|
+
:form_params => form_params,
|
|
1739
|
+
:body => post_body,
|
|
1740
|
+
:auth_names => auth_names,
|
|
1741
|
+
:return_type => return_type
|
|
1742
|
+
)
|
|
1743
|
+
|
|
1744
|
+
data, status_code, headers = @api_client.call_api(:DELETE, local_var_path, new_options)
|
|
1745
|
+
if @api_client.config.debugging
|
|
1746
|
+
@api_client.config.logger.debug "API called: AdCampaignsApi#remove_ad_keyword\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
1747
|
+
end
|
|
1748
|
+
return data, status_code, headers
|
|
1749
|
+
end
|
|
1750
|
+
|
|
1751
|
+
# Replace campaign-level negative keywords
|
|
1752
|
+
# Replaces the FULL set of campaign-level negative keywords (C.270): the desired list is diffed against what Google already has, and the difference is applied as one `create`/`remove` mutate. Send an empty array to clear every campaign negative. The platform is always discovered from the campaign itself; a non-Google campaign returns 501 rather than 404, whether or not `platform` was sent.
|
|
1753
|
+
# @param campaign_id [String] Platform campaign ID
|
|
1754
|
+
# @param replace_campaign_negative_keywords_request [ReplaceCampaignNegativeKeywordsRequest]
|
|
1755
|
+
# @param [Hash] opts the optional parameters
|
|
1756
|
+
# @return [ReplaceCampaignNegativeKeywords200Response]
|
|
1757
|
+
def replace_campaign_negative_keywords(campaign_id, replace_campaign_negative_keywords_request, opts = {})
|
|
1758
|
+
data, _status_code, _headers = replace_campaign_negative_keywords_with_http_info(campaign_id, replace_campaign_negative_keywords_request, opts)
|
|
1759
|
+
data
|
|
1760
|
+
end
|
|
1761
|
+
|
|
1762
|
+
# Replace campaign-level negative keywords
|
|
1763
|
+
# Replaces the FULL set of campaign-level negative keywords (C.270): the desired list is diffed against what Google already has, and the difference is applied as one `create`/`remove` mutate. Send an empty array to clear every campaign negative. The platform is always discovered from the campaign itself; a non-Google campaign returns 501 rather than 404, whether or not `platform` was sent.
|
|
1764
|
+
# @param campaign_id [String] Platform campaign ID
|
|
1765
|
+
# @param replace_campaign_negative_keywords_request [ReplaceCampaignNegativeKeywordsRequest]
|
|
1766
|
+
# @param [Hash] opts the optional parameters
|
|
1767
|
+
# @return [Array<(ReplaceCampaignNegativeKeywords200Response, Integer, Hash)>] ReplaceCampaignNegativeKeywords200Response data, response status code and response headers
|
|
1768
|
+
def replace_campaign_negative_keywords_with_http_info(campaign_id, replace_campaign_negative_keywords_request, opts = {})
|
|
1769
|
+
if @api_client.config.debugging
|
|
1770
|
+
@api_client.config.logger.debug 'Calling API: AdCampaignsApi.replace_campaign_negative_keywords ...'
|
|
1771
|
+
end
|
|
1772
|
+
# verify the required parameter 'campaign_id' is set
|
|
1773
|
+
if @api_client.config.client_side_validation && campaign_id.nil?
|
|
1774
|
+
fail ArgumentError, "Missing the required parameter 'campaign_id' when calling AdCampaignsApi.replace_campaign_negative_keywords"
|
|
1775
|
+
end
|
|
1776
|
+
# verify the required parameter 'replace_campaign_negative_keywords_request' is set
|
|
1777
|
+
if @api_client.config.client_side_validation && replace_campaign_negative_keywords_request.nil?
|
|
1778
|
+
fail ArgumentError, "Missing the required parameter 'replace_campaign_negative_keywords_request' when calling AdCampaignsApi.replace_campaign_negative_keywords"
|
|
1779
|
+
end
|
|
1780
|
+
# resource path
|
|
1781
|
+
local_var_path = '/v1/ads/campaigns/{campaignId}/negative-keywords'.sub('{' + 'campaignId' + '}', CGI.escape(campaign_id.to_s))
|
|
1782
|
+
|
|
1783
|
+
# query parameters
|
|
1784
|
+
query_params = opts[:query_params] || {}
|
|
1785
|
+
|
|
1786
|
+
# header parameters
|
|
1787
|
+
header_params = opts[:header_params] || {}
|
|
1788
|
+
# HTTP header 'Accept' (if needed)
|
|
1789
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
1790
|
+
# HTTP header 'Content-Type'
|
|
1791
|
+
content_type = @api_client.select_header_content_type(['application/json'])
|
|
1792
|
+
if !content_type.nil?
|
|
1793
|
+
header_params['Content-Type'] = content_type
|
|
1794
|
+
end
|
|
1795
|
+
|
|
1796
|
+
# form parameters
|
|
1797
|
+
form_params = opts[:form_params] || {}
|
|
1798
|
+
|
|
1799
|
+
# http body (model)
|
|
1800
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(replace_campaign_negative_keywords_request)
|
|
1801
|
+
|
|
1802
|
+
# return_type
|
|
1803
|
+
return_type = opts[:debug_return_type] || 'ReplaceCampaignNegativeKeywords200Response'
|
|
1804
|
+
|
|
1805
|
+
# auth_names
|
|
1806
|
+
auth_names = opts[:debug_auth_names] || ['bearerAuth']
|
|
1807
|
+
|
|
1808
|
+
new_options = opts.merge(
|
|
1809
|
+
:operation => :"AdCampaignsApi.replace_campaign_negative_keywords",
|
|
1810
|
+
:header_params => header_params,
|
|
1811
|
+
:query_params => query_params,
|
|
1812
|
+
:form_params => form_params,
|
|
1813
|
+
:body => post_body,
|
|
1814
|
+
:auth_names => auth_names,
|
|
1815
|
+
:return_type => return_type
|
|
1816
|
+
)
|
|
1817
|
+
|
|
1818
|
+
data, status_code, headers = @api_client.call_api(:PUT, local_var_path, new_options)
|
|
1819
|
+
if @api_client.config.debugging
|
|
1820
|
+
@api_client.config.logger.debug "API called: AdCampaignsApi#replace_campaign_negative_keywords\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
1821
|
+
end
|
|
1822
|
+
return data, status_code, headers
|
|
1823
|
+
end
|
|
1824
|
+
|
|
1550
1825
|
# Update ad
|
|
1551
1826
|
# Patch one or more fields on an ad. Status, budget, targeting, and creative changes are propagated to the platform. Per-platform support: - **Meta** (Facebook + Instagram): all fields supported. - **TikTok**: status, budget, targeting (via `/v2/adgroup/update/`), and creative (via `/v2/ad/update/` patch-style — `headline` is ignored, `body` becomes `ad_text`). - **Google**: status, budget, and KEYWORD edits via `targeting.keywords` / `targeting.negativeKeywords` — each list you send becomes the FULL new set of its kind on the ad group (criteria not in the list are removed); a kind left out is untouched. Any other `targeting` field returns 400: Google cannot mutate broad targeting post-create without recreating the campaign. `creative` returns 501. - **LinkedIn**: status, budget, targeting (geo countries only, applied to the LinkedIn Campaign via PARTIAL_UPDATE), and creative (uploads new media, creates a replacement inline creative on the same campaign, pauses the old one). - **Pinterest / X / OpenAI Ads**: status + budget only. Sending `targeting` or `creative` returns 501 with code `unsupported_platform_operation`. OpenAI Ads budget is lifetime-only (see `budget.type` below).
|
|
1552
1827
|
# @param ad_id [String]
|
|
@@ -1769,6 +2044,80 @@ module Zernio
|
|
|
1769
2044
|
return data, status_code, headers
|
|
1770
2045
|
end
|
|
1771
2046
|
|
|
2047
|
+
# Pause or enable a Search keyword
|
|
2048
|
+
# Changes `ad_group_criterion.status` for one keyword criterion (M.140). Negative keywords have no status on Google and cannot be paused or enabled.
|
|
2049
|
+
# @param keyword_id [String] Zernio keyword ID (not the Google criterion ID)
|
|
2050
|
+
# @param update_ad_keyword_request [UpdateAdKeywordRequest]
|
|
2051
|
+
# @param [Hash] opts the optional parameters
|
|
2052
|
+
# @return [UpdateAdKeyword200Response]
|
|
2053
|
+
def update_ad_keyword(keyword_id, update_ad_keyword_request, opts = {})
|
|
2054
|
+
data, _status_code, _headers = update_ad_keyword_with_http_info(keyword_id, update_ad_keyword_request, opts)
|
|
2055
|
+
data
|
|
2056
|
+
end
|
|
2057
|
+
|
|
2058
|
+
# Pause or enable a Search keyword
|
|
2059
|
+
# Changes `ad_group_criterion.status` for one keyword criterion (M.140). Negative keywords have no status on Google and cannot be paused or enabled.
|
|
2060
|
+
# @param keyword_id [String] Zernio keyword ID (not the Google criterion ID)
|
|
2061
|
+
# @param update_ad_keyword_request [UpdateAdKeywordRequest]
|
|
2062
|
+
# @param [Hash] opts the optional parameters
|
|
2063
|
+
# @return [Array<(UpdateAdKeyword200Response, Integer, Hash)>] UpdateAdKeyword200Response data, response status code and response headers
|
|
2064
|
+
def update_ad_keyword_with_http_info(keyword_id, update_ad_keyword_request, opts = {})
|
|
2065
|
+
if @api_client.config.debugging
|
|
2066
|
+
@api_client.config.logger.debug 'Calling API: AdCampaignsApi.update_ad_keyword ...'
|
|
2067
|
+
end
|
|
2068
|
+
# verify the required parameter 'keyword_id' is set
|
|
2069
|
+
if @api_client.config.client_side_validation && keyword_id.nil?
|
|
2070
|
+
fail ArgumentError, "Missing the required parameter 'keyword_id' when calling AdCampaignsApi.update_ad_keyword"
|
|
2071
|
+
end
|
|
2072
|
+
# verify the required parameter 'update_ad_keyword_request' is set
|
|
2073
|
+
if @api_client.config.client_side_validation && update_ad_keyword_request.nil?
|
|
2074
|
+
fail ArgumentError, "Missing the required parameter 'update_ad_keyword_request' when calling AdCampaignsApi.update_ad_keyword"
|
|
2075
|
+
end
|
|
2076
|
+
# resource path
|
|
2077
|
+
local_var_path = '/v1/ads/keywords/{keywordId}'.sub('{' + 'keywordId' + '}', CGI.escape(keyword_id.to_s))
|
|
2078
|
+
|
|
2079
|
+
# query parameters
|
|
2080
|
+
query_params = opts[:query_params] || {}
|
|
2081
|
+
|
|
2082
|
+
# header parameters
|
|
2083
|
+
header_params = opts[:header_params] || {}
|
|
2084
|
+
# HTTP header 'Accept' (if needed)
|
|
2085
|
+
header_params['Accept'] = @api_client.select_header_accept(['application/json']) unless header_params['Accept']
|
|
2086
|
+
# HTTP header 'Content-Type'
|
|
2087
|
+
content_type = @api_client.select_header_content_type(['application/json'])
|
|
2088
|
+
if !content_type.nil?
|
|
2089
|
+
header_params['Content-Type'] = content_type
|
|
2090
|
+
end
|
|
2091
|
+
|
|
2092
|
+
# form parameters
|
|
2093
|
+
form_params = opts[:form_params] || {}
|
|
2094
|
+
|
|
2095
|
+
# http body (model)
|
|
2096
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(update_ad_keyword_request)
|
|
2097
|
+
|
|
2098
|
+
# return_type
|
|
2099
|
+
return_type = opts[:debug_return_type] || 'UpdateAdKeyword200Response'
|
|
2100
|
+
|
|
2101
|
+
# auth_names
|
|
2102
|
+
auth_names = opts[:debug_auth_names] || ['bearerAuth']
|
|
2103
|
+
|
|
2104
|
+
new_options = opts.merge(
|
|
2105
|
+
:operation => :"AdCampaignsApi.update_ad_keyword",
|
|
2106
|
+
:header_params => header_params,
|
|
2107
|
+
:query_params => query_params,
|
|
2108
|
+
:form_params => form_params,
|
|
2109
|
+
:body => post_body,
|
|
2110
|
+
:auth_names => auth_names,
|
|
2111
|
+
:return_type => return_type
|
|
2112
|
+
)
|
|
2113
|
+
|
|
2114
|
+
data, status_code, headers = @api_client.call_api(:PATCH, local_var_path, new_options)
|
|
2115
|
+
if @api_client.config.debugging
|
|
2116
|
+
@api_client.config.logger.debug "API called: AdCampaignsApi#update_ad_keyword\nData: #{data.inspect}\nStatus code: #{status_code}\nHeaders: #{headers}"
|
|
2117
|
+
end
|
|
2118
|
+
return data, status_code, headers
|
|
2119
|
+
end
|
|
2120
|
+
|
|
1772
2121
|
# Update an ad set
|
|
1773
2122
|
# Ad-set-level writes. Use this for ABO budget updates, ad-set-scoped pause/resume, bid-strategy edits, Meta value-rule-set attach/detach, and Meta-only post-launch delivery settings via `platformSpecificData`. At least one updatable field is required. Value rule sets (Meta only, see `/v1/ads/value-rule-sets`): - ATTACH or REPLACE: send `valueRuleSetId`. Attachment is driven by the id's presence, so `valueRulesApplied: true` is optional. Sending a different id replaces the previous association; there is no separate replace call. - DETACH: send `valueRulesApplied: false` and OMIT `valueRuleSetId`. - Sending `valueRulesApplied: false` TOGETHER with `valueRuleSetId` returns 400 `mutually_exclusive_fields`. This is deliberate: Meta attaches the rule set whenever `value_rule_set_id` is present, even with `value_rules_applied` false, so echoing stored state while asking to detach would silently keep the bid adjustments live. - Eligibility: only ad sets on `LOWEST_COST_WITHOUT_CAP` or `COST_CAP`. Meta rejects the rest server-side. - Read back with `GET /v1/ads/ad-sets/{adSetId}?fields=value_rule_set_id`. Meta does not document `value_rules_applied` as a readable ad-set field, so the boolean cannot be read back. Bid strategy compatibility (per Meta's spec): - `LOWEST_COST_WITHOUT_CAP`: no `bidAmount`, no `roasAverageFloor`. - `LOWEST_COST_WITH_BID_CAP` / `COST_CAP`: `bidAmount` REQUIRED (whole currency units). - `LOWEST_COST_WITH_MIN_ROAS`: `roasAverageFloor` REQUIRED (decimal multiplier, e.g. 2.0 = 2.0x ROAS). - Meta only: send `bidAmount` WITHOUT `bidStrategy` to change the cap amount on an ad set under a COST_CAP / LOWEST_COST_WITH_BID_CAP parent campaign, leaving the strategy itself (inherited from the campaign) untouched. `roasAverageFloor` without `bidStrategy` is rejected (it has no meaning outside LOWEST_COST_WITH_MIN_ROAS). Delivery settings are validated by Meta against the campaign objective; incompatible combinations (e.g. a billingEvent the optimization goal doesn't allow) surface as 400s from Meta. When updating `budget` on an ABO campaign: if the parent campaign is CBO, the response is 409 with code BUDGET_LEVEL_MISMATCH — route to PUT /v1/ads/campaigns/{campaignId} instead.
|
|
1774
2123
|
# @param ad_set_id [String] Platform ad set ID
|
|
@@ -1920,21 +2269,21 @@ module Zernio
|
|
|
1920
2269
|
# Pause or resume a single ad
|
|
1921
2270
|
# Ad-scoped pause/resume — touches ONLY this ad, never its parent ad set or campaign (so sibling ads keep running). Thin wrapper over the `status` field of PUT /v1/ads/{adId}, for callers that want a URL symmetric to /v1/ads/campaigns/{campaignId}/status and /v1/ads/ad-sets/{adSetId}/status. `{adId}` accepts the same identifier dialects as GET/PUT /v1/ads/{adId} (Zernio hex `_id`, Meta numeric `platformAdId`, or the creative's effective story/media IDs). `platform` is inferred from the ad, so it's not required in the body. Ads in terminal statuses (rejected, completed, cancelled) and no-op flips (already in the target state) are skipped.
|
|
1922
2271
|
# @param ad_id [String] Zernio `_id` (hex), Meta `platformAdId` (numeric), or one of the creative's effective story/media IDs.
|
|
1923
|
-
# @param
|
|
2272
|
+
# @param update_ad_keyword_request [UpdateAdKeywordRequest]
|
|
1924
2273
|
# @param [Hash] opts the optional parameters
|
|
1925
2274
|
# @return [UpdateAdStatus200Response]
|
|
1926
|
-
def update_ad_status(ad_id,
|
|
1927
|
-
data, _status_code, _headers = update_ad_status_with_http_info(ad_id,
|
|
2275
|
+
def update_ad_status(ad_id, update_ad_keyword_request, opts = {})
|
|
2276
|
+
data, _status_code, _headers = update_ad_status_with_http_info(ad_id, update_ad_keyword_request, opts)
|
|
1928
2277
|
data
|
|
1929
2278
|
end
|
|
1930
2279
|
|
|
1931
2280
|
# Pause or resume a single ad
|
|
1932
2281
|
# Ad-scoped pause/resume — touches ONLY this ad, never its parent ad set or campaign (so sibling ads keep running). Thin wrapper over the `status` field of PUT /v1/ads/{adId}, for callers that want a URL symmetric to /v1/ads/campaigns/{campaignId}/status and /v1/ads/ad-sets/{adSetId}/status. `{adId}` accepts the same identifier dialects as GET/PUT /v1/ads/{adId} (Zernio hex `_id`, Meta numeric `platformAdId`, or the creative's effective story/media IDs). `platform` is inferred from the ad, so it's not required in the body. Ads in terminal statuses (rejected, completed, cancelled) and no-op flips (already in the target state) are skipped.
|
|
1933
2282
|
# @param ad_id [String] Zernio `_id` (hex), Meta `platformAdId` (numeric), or one of the creative's effective story/media IDs.
|
|
1934
|
-
# @param
|
|
2283
|
+
# @param update_ad_keyword_request [UpdateAdKeywordRequest]
|
|
1935
2284
|
# @param [Hash] opts the optional parameters
|
|
1936
2285
|
# @return [Array<(UpdateAdStatus200Response, Integer, Hash)>] UpdateAdStatus200Response data, response status code and response headers
|
|
1937
|
-
def update_ad_status_with_http_info(ad_id,
|
|
2286
|
+
def update_ad_status_with_http_info(ad_id, update_ad_keyword_request, opts = {})
|
|
1938
2287
|
if @api_client.config.debugging
|
|
1939
2288
|
@api_client.config.logger.debug 'Calling API: AdCampaignsApi.update_ad_status ...'
|
|
1940
2289
|
end
|
|
@@ -1942,9 +2291,9 @@ module Zernio
|
|
|
1942
2291
|
if @api_client.config.client_side_validation && ad_id.nil?
|
|
1943
2292
|
fail ArgumentError, "Missing the required parameter 'ad_id' when calling AdCampaignsApi.update_ad_status"
|
|
1944
2293
|
end
|
|
1945
|
-
# verify the required parameter '
|
|
1946
|
-
if @api_client.config.client_side_validation &&
|
|
1947
|
-
fail ArgumentError, "Missing the required parameter '
|
|
2294
|
+
# verify the required parameter 'update_ad_keyword_request' is set
|
|
2295
|
+
if @api_client.config.client_side_validation && update_ad_keyword_request.nil?
|
|
2296
|
+
fail ArgumentError, "Missing the required parameter 'update_ad_keyword_request' when calling AdCampaignsApi.update_ad_status"
|
|
1948
2297
|
end
|
|
1949
2298
|
# resource path
|
|
1950
2299
|
local_var_path = '/v1/ads/{adId}/status'.sub('{' + 'adId' + '}', CGI.escape(ad_id.to_s))
|
|
@@ -1966,7 +2315,7 @@ module Zernio
|
|
|
1966
2315
|
form_params = opts[:form_params] || {}
|
|
1967
2316
|
|
|
1968
2317
|
# http body (model)
|
|
1969
|
-
post_body = opts[:debug_body] || @api_client.object_to_http_body(
|
|
2318
|
+
post_body = opts[:debug_body] || @api_client.object_to_http_body(update_ad_keyword_request)
|
|
1970
2319
|
|
|
1971
2320
|
# return_type
|
|
1972
2321
|
return_type = opts[:debug_return_type] || 'UpdateAdStatus200Response'
|
|
@@ -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
|
|
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
|
|
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
|
|
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 `_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
|
|
482
|
+
# 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.
|
|
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
|