late-sdk 0.0.724 → 0.0.725

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.
@@ -0,0 +1,185 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Zernio
17
+ class ReplaceAdAudienceCompaniesRequest < ApiModelBase
18
+ # The complete company list. Each row needs at least one of name, domain, website or linkedinPageUrl.
19
+ attr_accessor :companies
20
+
21
+ # Attribute mapping from ruby-style variable name to JSON key.
22
+ def self.attribute_map
23
+ {
24
+ :'companies' => :'companies'
25
+ }
26
+ end
27
+
28
+ # Returns attribute mapping this model knows about
29
+ def self.acceptable_attribute_map
30
+ attribute_map
31
+ end
32
+
33
+ # Returns all the JSON keys this model knows about
34
+ def self.acceptable_attributes
35
+ acceptable_attribute_map.values
36
+ end
37
+
38
+ # Attribute type mapping.
39
+ def self.openapi_types
40
+ {
41
+ :'companies' => :'Array<ReplaceAdAudienceCompaniesRequestCompaniesInner>'
42
+ }
43
+ end
44
+
45
+ # List of attributes with nullable: true
46
+ def self.openapi_nullable
47
+ Set.new([
48
+ ])
49
+ end
50
+
51
+ # Initializes the object
52
+ # @param [Hash] attributes Model attributes in the form of hash
53
+ def initialize(attributes = {})
54
+ if (!attributes.is_a?(Hash))
55
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Zernio::ReplaceAdAudienceCompaniesRequest` initialize method"
56
+ end
57
+
58
+ # check to see if the attribute exists and convert string to symbol for hash key
59
+ acceptable_attribute_map = self.class.acceptable_attribute_map
60
+ attributes = attributes.each_with_object({}) { |(k, v), h|
61
+ if (!acceptable_attribute_map.key?(k.to_sym))
62
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Zernio::ReplaceAdAudienceCompaniesRequest`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
63
+ end
64
+ h[k.to_sym] = v
65
+ }
66
+
67
+ if attributes.key?(:'companies')
68
+ if (value = attributes[:'companies']).is_a?(Array)
69
+ self.companies = value
70
+ end
71
+ else
72
+ self.companies = nil
73
+ end
74
+ end
75
+
76
+ # Show invalid properties with the reasons. Usually used together with valid?
77
+ # @return Array for valid properties with the reasons
78
+ def list_invalid_properties
79
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
80
+ invalid_properties = Array.new
81
+ if @companies.nil?
82
+ invalid_properties.push('invalid value for "companies", companies cannot be nil.')
83
+ end
84
+
85
+ if @companies.length > 300000
86
+ invalid_properties.push('invalid value for "companies", number of items must be less than or equal to 300000.')
87
+ end
88
+
89
+ if @companies.length < 1
90
+ invalid_properties.push('invalid value for "companies", number of items must be greater than or equal to 1.')
91
+ end
92
+
93
+ invalid_properties
94
+ end
95
+
96
+ # Check to see if the all the properties in the model are valid
97
+ # @return true if the model is valid
98
+ def valid?
99
+ warn '[DEPRECATED] the `valid?` method is obsolete'
100
+ return false if @companies.nil?
101
+ return false if @companies.length > 300000
102
+ return false if @companies.length < 1
103
+ true
104
+ end
105
+
106
+ # Custom attribute writer method with validation
107
+ # @param [Object] companies Value to be assigned
108
+ def companies=(companies)
109
+ if companies.nil?
110
+ fail ArgumentError, 'companies cannot be nil'
111
+ end
112
+
113
+ if companies.length > 300000
114
+ fail ArgumentError, 'invalid value for "companies", number of items must be less than or equal to 300000.'
115
+ end
116
+
117
+ if companies.length < 1
118
+ fail ArgumentError, 'invalid value for "companies", number of items must be greater than or equal to 1.'
119
+ end
120
+
121
+ @companies = companies
122
+ end
123
+
124
+ # Checks equality by comparing each attribute.
125
+ # @param [Object] Object to be compared
126
+ def ==(o)
127
+ return true if self.equal?(o)
128
+ self.class == o.class &&
129
+ companies == o.companies
130
+ end
131
+
132
+ # @see the `==` method
133
+ # @param [Object] Object to be compared
134
+ def eql?(o)
135
+ self == o
136
+ end
137
+
138
+ # Calculates hash code according to all attributes.
139
+ # @return [Integer] Hash code
140
+ def hash
141
+ [companies].hash
142
+ end
143
+
144
+ # Builds the object from hash
145
+ # @param [Hash] attributes Model attributes in the form of hash
146
+ # @return [Object] Returns the model itself
147
+ def self.build_from_hash(attributes)
148
+ return nil unless attributes.is_a?(Hash)
149
+ attributes = attributes.transform_keys(&:to_sym)
150
+ transformed_hash = {}
151
+ openapi_types.each_pair do |key, type|
152
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
153
+ transformed_hash["#{key}"] = nil
154
+ elsif type =~ /\AArray<(.*)>/i
155
+ # check to ensure the input is an array given that the attribute
156
+ # is documented as an array but the input is not
157
+ if attributes[attribute_map[key]].is_a?(Array)
158
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
159
+ end
160
+ elsif !attributes[attribute_map[key]].nil?
161
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
162
+ end
163
+ end
164
+ new(transformed_hash)
165
+ end
166
+
167
+ # Returns the object in the form of hash
168
+ # @return [Hash] Returns the object in the form of hash
169
+ def to_hash
170
+ hash = {}
171
+ self.class.attribute_map.each_pair do |attr, param|
172
+ value = self.send(attr)
173
+ if value.nil?
174
+ is_nullable = self.class.openapi_nullable.include?(attr)
175
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
176
+ end
177
+
178
+ hash[param] = _to_hash(value)
179
+ end
180
+ hash
181
+ end
182
+
183
+ end
184
+
185
+ end
@@ -0,0 +1,231 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'date'
14
+ require 'time'
15
+
16
+ module Zernio
17
+ class ReplaceAdAudienceCompaniesRequestCompaniesInner < ApiModelBase
18
+ attr_accessor :name
19
+
20
+ attr_accessor :domain
21
+
22
+ attr_accessor :website
23
+
24
+ attr_accessor :linkedin_page_url
25
+
26
+ # Attribute mapping from ruby-style variable name to JSON key.
27
+ def self.attribute_map
28
+ {
29
+ :'name' => :'name',
30
+ :'domain' => :'domain',
31
+ :'website' => :'website',
32
+ :'linkedin_page_url' => :'linkedinPageUrl'
33
+ }
34
+ end
35
+
36
+ # Returns attribute mapping this model knows about
37
+ def self.acceptable_attribute_map
38
+ attribute_map
39
+ end
40
+
41
+ # Returns all the JSON keys this model knows about
42
+ def self.acceptable_attributes
43
+ acceptable_attribute_map.values
44
+ end
45
+
46
+ # Attribute type mapping.
47
+ def self.openapi_types
48
+ {
49
+ :'name' => :'String',
50
+ :'domain' => :'String',
51
+ :'website' => :'String',
52
+ :'linkedin_page_url' => :'String'
53
+ }
54
+ end
55
+
56
+ # List of attributes with nullable: true
57
+ def self.openapi_nullable
58
+ Set.new([
59
+ ])
60
+ end
61
+
62
+ # Initializes the object
63
+ # @param [Hash] attributes Model attributes in the form of hash
64
+ def initialize(attributes = {})
65
+ if (!attributes.is_a?(Hash))
66
+ fail ArgumentError, "The input argument (attributes) must be a hash in `Zernio::ReplaceAdAudienceCompaniesRequestCompaniesInner` initialize method"
67
+ end
68
+
69
+ # check to see if the attribute exists and convert string to symbol for hash key
70
+ acceptable_attribute_map = self.class.acceptable_attribute_map
71
+ attributes = attributes.each_with_object({}) { |(k, v), h|
72
+ if (!acceptable_attribute_map.key?(k.to_sym))
73
+ fail ArgumentError, "`#{k}` is not a valid attribute in `Zernio::ReplaceAdAudienceCompaniesRequestCompaniesInner`. Please check the name to make sure it's valid. List of attributes: " + acceptable_attribute_map.keys.inspect
74
+ end
75
+ h[k.to_sym] = v
76
+ }
77
+
78
+ if attributes.key?(:'name')
79
+ self.name = attributes[:'name']
80
+ end
81
+
82
+ if attributes.key?(:'domain')
83
+ self.domain = attributes[:'domain']
84
+ end
85
+
86
+ if attributes.key?(:'website')
87
+ self.website = attributes[:'website']
88
+ end
89
+
90
+ if attributes.key?(:'linkedin_page_url')
91
+ self.linkedin_page_url = attributes[:'linkedin_page_url']
92
+ end
93
+ end
94
+
95
+ # Show invalid properties with the reasons. Usually used together with valid?
96
+ # @return Array for valid properties with the reasons
97
+ def list_invalid_properties
98
+ warn '[DEPRECATED] the `list_invalid_properties` method is obsolete'
99
+ invalid_properties = Array.new
100
+ if !@name.nil? && @name.to_s.length > 255
101
+ invalid_properties.push('invalid value for "name", the character length must be smaller than or equal to 255.')
102
+ end
103
+
104
+ if !@domain.nil? && @domain.to_s.length > 100
105
+ invalid_properties.push('invalid value for "domain", the character length must be smaller than or equal to 100.')
106
+ end
107
+
108
+ if !@website.nil? && @website.to_s.length > 100
109
+ invalid_properties.push('invalid value for "website", the character length must be smaller than or equal to 100.')
110
+ end
111
+
112
+ invalid_properties
113
+ end
114
+
115
+ # Check to see if the all the properties in the model are valid
116
+ # @return true if the model is valid
117
+ def valid?
118
+ warn '[DEPRECATED] the `valid?` method is obsolete'
119
+ return false if !@name.nil? && @name.to_s.length > 255
120
+ return false if !@domain.nil? && @domain.to_s.length > 100
121
+ return false if !@website.nil? && @website.to_s.length > 100
122
+ true
123
+ end
124
+
125
+ # Custom attribute writer method with validation
126
+ # @param [Object] name Value to be assigned
127
+ def name=(name)
128
+ if name.nil?
129
+ fail ArgumentError, 'name cannot be nil'
130
+ end
131
+
132
+ if name.to_s.length > 255
133
+ fail ArgumentError, 'invalid value for "name", the character length must be smaller than or equal to 255.'
134
+ end
135
+
136
+ @name = name
137
+ end
138
+
139
+ # Custom attribute writer method with validation
140
+ # @param [Object] domain Value to be assigned
141
+ def domain=(domain)
142
+ if domain.nil?
143
+ fail ArgumentError, 'domain cannot be nil'
144
+ end
145
+
146
+ if domain.to_s.length > 100
147
+ fail ArgumentError, 'invalid value for "domain", the character length must be smaller than or equal to 100.'
148
+ end
149
+
150
+ @domain = domain
151
+ end
152
+
153
+ # Custom attribute writer method with validation
154
+ # @param [Object] website Value to be assigned
155
+ def website=(website)
156
+ if website.nil?
157
+ fail ArgumentError, 'website cannot be nil'
158
+ end
159
+
160
+ if website.to_s.length > 100
161
+ fail ArgumentError, 'invalid value for "website", the character length must be smaller than or equal to 100.'
162
+ end
163
+
164
+ @website = website
165
+ end
166
+
167
+ # Checks equality by comparing each attribute.
168
+ # @param [Object] Object to be compared
169
+ def ==(o)
170
+ return true if self.equal?(o)
171
+ self.class == o.class &&
172
+ name == o.name &&
173
+ domain == o.domain &&
174
+ website == o.website &&
175
+ linkedin_page_url == o.linkedin_page_url
176
+ end
177
+
178
+ # @see the `==` method
179
+ # @param [Object] Object to be compared
180
+ def eql?(o)
181
+ self == o
182
+ end
183
+
184
+ # Calculates hash code according to all attributes.
185
+ # @return [Integer] Hash code
186
+ def hash
187
+ [name, domain, website, linkedin_page_url].hash
188
+ end
189
+
190
+ # Builds the object from hash
191
+ # @param [Hash] attributes Model attributes in the form of hash
192
+ # @return [Object] Returns the model itself
193
+ def self.build_from_hash(attributes)
194
+ return nil unless attributes.is_a?(Hash)
195
+ attributes = attributes.transform_keys(&:to_sym)
196
+ transformed_hash = {}
197
+ openapi_types.each_pair do |key, type|
198
+ if attributes.key?(attribute_map[key]) && attributes[attribute_map[key]].nil?
199
+ transformed_hash["#{key}"] = nil
200
+ elsif type =~ /\AArray<(.*)>/i
201
+ # check to ensure the input is an array given that the attribute
202
+ # is documented as an array but the input is not
203
+ if attributes[attribute_map[key]].is_a?(Array)
204
+ transformed_hash["#{key}"] = attributes[attribute_map[key]].map { |v| _deserialize($1, v) }
205
+ end
206
+ elsif !attributes[attribute_map[key]].nil?
207
+ transformed_hash["#{key}"] = _deserialize(type, attributes[attribute_map[key]])
208
+ end
209
+ end
210
+ new(transformed_hash)
211
+ end
212
+
213
+ # Returns the object in the form of hash
214
+ # @return [Hash] Returns the object in the form of hash
215
+ def to_hash
216
+ hash = {}
217
+ self.class.attribute_map.each_pair do |attr, param|
218
+ value = self.send(attr)
219
+ if value.nil?
220
+ is_nullable = self.class.openapi_nullable.include?(attr)
221
+ next if !is_nullable || (is_nullable && !instance_variable_defined?(:"@#{attr}"))
222
+ end
223
+
224
+ hash[param] = _to_hash(value)
225
+ end
226
+ hash
227
+ end
228
+
229
+ end
230
+
231
+ end
@@ -42,7 +42,7 @@ module Zernio
42
42
  # Required for engagement audiences. Campaign URNs for the ad source types, organization URNs for pages and events. LinkedIn creates one rule per source, all sharing the same trigger and lookbackDays.
43
43
  attr_accessor :engagement_sources
44
44
 
45
- # Required for company_list audiences (LinkedIn only): plain-text company rows for account targeting. Each row needs at least one identifier. LinkedIn recommends 1,000+ companies for a usable match rate and takes up to 48h to process the list.
45
+ # Required for company_list audiences (LinkedIn only): plain-text company rows for account targeting. Each row needs at least one identifier. Not hashed, LinkedIn matches these against its own company graph. LinkedIn recommends 1,000+ companies for a usable match rate and takes up to 48h to process the list. Replace the list later with POST /v1/ads/audiences/{audienceId}/companies.
46
46
  attr_accessor :companies
47
47
 
48
48
  # Required for website audiences
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Zernio
14
- VERSION = '0.0.724'
14
+ VERSION = '0.0.725'
15
15
  end
data/lib/zernio-sdk.rb CHANGED
@@ -1136,6 +1136,9 @@ require 'zernio-sdk/models/remove_bookmark200_response'
1136
1136
  require 'zernio-sdk/models/remove_conversion_associations200_response'
1137
1137
  require 'zernio-sdk/models/remove_discord_member_role200_response'
1138
1138
  require 'zernio-sdk/models/remove_whats_app_group_participants_request'
1139
+ require 'zernio-sdk/models/replace_ad_audience_companies200_response'
1140
+ require 'zernio-sdk/models/replace_ad_audience_companies_request'
1141
+ require 'zernio-sdk/models/replace_ad_audience_companies_request_companies_inner'
1139
1142
  require 'zernio-sdk/models/reply_to_google_business_review200_response'
1140
1143
  require 'zernio-sdk/models/reply_to_google_business_review_request'
1141
1144
  require 'zernio-sdk/models/reply_to_inbox_post200_response'
data/openapi.yaml CHANGED
@@ -43784,11 +43784,21 @@ paths:
43784
43784
  summary: Create custom audience
43785
43785
  description: |
43786
43786
  Create a custom audience. `customer_list` is supported on Meta, Google, X, LinkedIn, TikTok, and Pinterest;
43787
- `website` and `lookalike` are Meta-only. `saved_targeting` stores a reusable TargetingSpec (no member upload,
43788
- no adAccountId) that you reference later via `savedTargetingId` on `POST /v1/ads/create`. Upload-backed audiences
43789
- are created empty, add members via `POST /v1/ads/audiences/{audienceId}/users`. On TikTok and Pinterest the
43790
- audience is provisioned lazily on the first member upload (until then its status is `pending`). Create is not
43791
- idempotent, never auto-retry.
43787
+ `website` and `lookalike` are Meta-only; `company_list`, `engagement` and `website_retargeting` are LinkedIn-only.
43788
+ `saved_targeting` stores a reusable TargetingSpec (no member upload, no adAccountId) that you reference later via
43789
+ `savedTargetingId` on `POST /v1/ads/create`.
43790
+
43791
+ How the audience gets filled depends on the type:
43792
+
43793
+ - `customer_list` is created empty. Add members with `POST /v1/ads/audiences/{audienceId}/users`.
43794
+ On TikTok and Pinterest the audience is provisioned lazily on that first upload (until then its status is `pending`).
43795
+ - `company_list` is filled AT CREATION from the `companies` array below, which is required. To change the list
43796
+ afterwards send the new full list to `POST /v1/ads/audiences/{audienceId}/companies` (a replace, not a merge).
43797
+ The `/users` endpoint rejects these audiences with a 422.
43798
+ - `website`, `website_retargeting`, `engagement`, `meta_engagement` and `lookalike` fill themselves from the pixel,
43799
+ engagement source or seed audience you point them at. They take no member upload at all.
43800
+
43801
+ Create is not idempotent, never auto-retry.
43792
43802
  security:
43793
43803
  - bearerAuth: []
43794
43804
  requestBody:
@@ -43866,8 +43876,10 @@ paths:
43866
43876
  description: |
43867
43877
  Required for company_list audiences (LinkedIn only): plain-text
43868
43878
  company rows for account targeting. Each row needs at least one
43869
- identifier. LinkedIn recommends 1,000+ companies for a usable
43870
- match rate and takes up to 48h to process the list.
43879
+ identifier. Not hashed, LinkedIn matches these against its own
43880
+ company graph. LinkedIn recommends 1,000+ companies for a usable
43881
+ match rate and takes up to 48h to process the list. Replace the
43882
+ list later with POST /v1/ads/audiences/{audienceId}/companies.
43871
43883
  items:
43872
43884
  type: object
43873
43885
  additionalProperties: false
@@ -44069,6 +44081,9 @@ paths:
44069
44081
  Upload user data to a customer_list audience. Data is SHA256-hashed server-side before sending to the platform.
44070
44082
  Email is used on every platform; phone is used on Meta only (other platforms ignore it). On TikTok and Pinterest,
44071
44083
  the first upload also provisions the audience (deferred create). LinkedIn uploads are full-replace. Max 10,000 users per request.
44084
+
44085
+ customer_list only. A LinkedIn `company_list` audience takes company rows, not people: send those to
44086
+ `POST /v1/ads/audiences/{audienceId}/companies`. This endpoint 422s for every other audience type.
44072
44087
  security:
44073
44088
  - bearerAuth: []
44074
44089
  parameters:
@@ -44110,6 +44125,73 @@ paths:
44110
44125
  '422':
44111
44126
  description: Audience is not a customer_list type or has no platform ID yet
44112
44127
 
44128
+ /v1/ads/audiences/{audienceId}/companies:
44129
+ post:
44130
+ x-resource-group: "ads"
44131
+ operationId: replaceAdAudienceCompanies
44132
+ tags: ["Ad Audiences"]
44133
+ x-platforms: ["linkedin"]
44134
+ summary: Replace audience companies
44135
+ description: |
44136
+ Upload the company rows of a LinkedIn `company_list` audience (account-based marketing).
44137
+ LinkedIn-only, every other platform returns 422.
44138
+
44139
+ A LinkedIn audience segment holds exactly one uploaded list, so the list you send here REPLACES the
44140
+ segment's list instead of being appended to it: always send the full set of companies. LinkedIn returns
44141
+ only the identifier of the uploaded file, never its rows, so the merge cannot be done for you, keep the
44142
+ source list on your side. LinkedIn does not document how quickly companies dropped from the list stop
44143
+ being targeted, so treat removals as eventual rather than immediate.
44144
+ Rows are plain text (not hashed), matched against LinkedIn's own company graph. Matching is asynchronous:
44145
+ LinkedIn takes up to 48h for a new audience and up to 24h for a later update, and the audience stays
44146
+ `processing` meanwhile. LinkedIn recommends at least 1,000 companies for a usable match rate, and caps a
44147
+ list at 300,000.
44148
+
44149
+ The initial list is sent with `companies` on `POST /v1/ads/audiences`; this endpoint is for every
44150
+ change after that.
44151
+ security:
44152
+ - bearerAuth: []
44153
+ parameters:
44154
+ - { name: audienceId, in: path, required: true, schema: { type: string } }
44155
+ requestBody:
44156
+ required: true
44157
+ content:
44158
+ application/json:
44159
+ schema:
44160
+ type: object
44161
+ required: [companies]
44162
+ properties:
44163
+ companies:
44164
+ type: array
44165
+ minItems: 1
44166
+ maxItems: 300000
44167
+ description: 'The complete company list. Each row needs at least one of name, domain, website or linkedinPageUrl.'
44168
+ items:
44169
+ type: object
44170
+ additionalProperties: false
44171
+ properties:
44172
+ name: { type: string, maxLength: 255 }
44173
+ domain: { type: string, maxLength: 100 }
44174
+ website: { type: string, maxLength: 100 }
44175
+ linkedinPageUrl: { type: string }
44176
+ responses:
44177
+ '200':
44178
+ description: Companies uploaded
44179
+ content:
44180
+ application/json:
44181
+ schema:
44182
+ type: object
44183
+ properties:
44184
+ message: { type: string }
44185
+ numReceived: { type: integer, description: 'Rows sent to LinkedIn. Matching happens asynchronously, so this is not the matched company count.' }
44186
+ '400':
44187
+ description: 'Invalid input (malformed audienceId, empty companies array, a row with no identifier)'
44188
+ '401': { $ref: '#/components/responses/Unauthorized' }
44189
+ '403':
44190
+ description: Ads access required. Legacy plans need the Ads add-on; included by default on usage-based plans.
44191
+ '404': { $ref: '#/components/responses/NotFound' }
44192
+ '422':
44193
+ description: 'Audience is not a company_list type, is not on LinkedIn, or has no platform ID yet'
44194
+
44113
44195
  /v1/ads/conversions/quality:
44114
44196
  get:
44115
44197
  x-resource-group: "ads"
@@ -34,7 +34,7 @@ describe 'AdAudiencesApi' do
34
34
 
35
35
  # unit tests for add_users_to_ad_audience
36
36
  # Add users to audience
37
- # Upload user data to a customer_list audience. Data is SHA256-hashed server-side before sending to the platform. Email is used on every platform; phone is used on Meta only (other platforms ignore it). On TikTok and Pinterest, the first upload also provisions the audience (deferred create). LinkedIn uploads are full-replace. Max 10,000 users per request.
37
+ # Upload user data to a customer_list audience. Data is SHA256-hashed server-side before sending to the platform. Email is used on every platform; phone is used on Meta only (other platforms ignore it). On TikTok and Pinterest, the first upload also provisions the audience (deferred create). LinkedIn uploads are full-replace. Max 10,000 users per request. customer_list only. A LinkedIn &#x60;company_list&#x60; audience takes company rows, not people: send those to &#x60;POST /v1/ads/audiences/{audienceId}/companies&#x60;. This endpoint 422s for every other audience type.
38
38
  # @param audience_id
39
39
  # @param add_users_to_ad_audience_request
40
40
  # @param [Hash] opts the optional parameters
@@ -47,7 +47,7 @@ describe 'AdAudiencesApi' do
47
47
 
48
48
  # unit tests for create_ad_audience
49
49
  # Create custom audience
50
- # Create a custom audience. &#x60;customer_list&#x60; is supported on Meta, Google, X, LinkedIn, TikTok, and Pinterest; &#x60;website&#x60; and &#x60;lookalike&#x60; are Meta-only. &#x60;saved_targeting&#x60; stores a reusable TargetingSpec (no member upload, no adAccountId) that you reference later via &#x60;savedTargetingId&#x60; on &#x60;POST /v1/ads/create&#x60;. Upload-backed audiences are created empty, add members via &#x60;POST /v1/ads/audiences/{audienceId}/users&#x60;. On TikTok and Pinterest the audience is provisioned lazily on the first member upload (until then its status is &#x60;pending&#x60;). Create is not idempotent, never auto-retry.
50
+ # Create a custom audience. &#x60;customer_list&#x60; is supported on Meta, Google, X, LinkedIn, TikTok, and Pinterest; &#x60;website&#x60; and &#x60;lookalike&#x60; are Meta-only; &#x60;company_list&#x60;, &#x60;engagement&#x60; and &#x60;website_retargeting&#x60; are LinkedIn-only. &#x60;saved_targeting&#x60; stores a reusable TargetingSpec (no member upload, no adAccountId) that you reference later via &#x60;savedTargetingId&#x60; on &#x60;POST /v1/ads/create&#x60;. How the audience gets filled depends on the type: - &#x60;customer_list&#x60; is created empty. Add members with &#x60;POST /v1/ads/audiences/{audienceId}/users&#x60;. On TikTok and Pinterest the audience is provisioned lazily on that first upload (until then its status is &#x60;pending&#x60;). - &#x60;company_list&#x60; is filled AT CREATION from the &#x60;companies&#x60; array below, which is required. To change the list afterwards send the new full list to &#x60;POST /v1/ads/audiences/{audienceId}/companies&#x60; (a replace, not a merge). The &#x60;/users&#x60; endpoint rejects these audiences with a 422. - &#x60;website&#x60;, &#x60;website_retargeting&#x60;, &#x60;engagement&#x60;, &#x60;meta_engagement&#x60; and &#x60;lookalike&#x60; fill themselves from the pixel, engagement source or seed audience you point them at. They take no member upload at all. Create is not idempotent, never auto-retry.
51
51
  # @param create_ad_audience_request
52
52
  # @param [Hash] opts the optional parameters
53
53
  # @return [CreateAdAudience201Response]
@@ -96,6 +96,19 @@ describe 'AdAudiencesApi' do
96
96
  end
97
97
  end
98
98
 
99
+ # unit tests for replace_ad_audience_companies
100
+ # Replace audience companies
101
+ # Upload the company rows of a LinkedIn &#x60;company_list&#x60; audience (account-based marketing). LinkedIn-only, every other platform returns 422. A LinkedIn audience segment holds exactly one uploaded list, so the list you send here REPLACES the segment&#39;s list instead of being appended to it: always send the full set of companies. LinkedIn returns only the identifier of the uploaded file, never its rows, so the merge cannot be done for you, keep the source list on your side. LinkedIn does not document how quickly companies dropped from the list stop being targeted, so treat removals as eventual rather than immediate. Rows are plain text (not hashed), matched against LinkedIn&#39;s own company graph. Matching is asynchronous: LinkedIn takes up to 48h for a new audience and up to 24h for a later update, and the audience stays &#x60;processing&#x60; meanwhile. LinkedIn recommends at least 1,000 companies for a usable match rate, and caps a list at 300,000. The initial list is sent with &#x60;companies&#x60; on &#x60;POST /v1/ads/audiences&#x60;; this endpoint is for every change after that.
102
+ # @param audience_id
103
+ # @param replace_ad_audience_companies_request
104
+ # @param [Hash] opts the optional parameters
105
+ # @return [ReplaceAdAudienceCompanies200Response]
106
+ describe 'replace_ad_audience_companies test' do
107
+ it 'should work' do
108
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
109
+ end
110
+ end
111
+
99
112
  # unit tests for update_ad_audience
100
113
  # Update an audience
101
114
  # Update an audience. &#x60;saved_targeting&#x60; audiences accept &#x60;name&#x60;, &#x60;description&#x60;, and &#x60;spec&#x60; (full replacement, no merge, Zernio-only, no platform call). Platform audiences (uploaded/website/lookalike) accept &#x60;name&#x60; and &#x60;description&#x60; only, updated on the platform first and then mirrored locally; their rules are immutable, so &#x60;spec&#x60; returns 400 for them. Platform audience updates are Meta-only for now (other platforms return 501). Ads already created from a saved_targeting audience are unaffected, they snapshot the targeting at creation.
@@ -0,0 +1,42 @@
1
+ =begin
2
+ #Zernio API
3
+
4
+ #API reference for Zernio. Authenticate with a Bearer API key. Base URL: https://zernio.com/api
5
+
6
+ The version of the OpenAPI document: 1.0.4
7
+ Contact: support@zernio.com
8
+ Generated by: https://openapi-generator.tech
9
+ Generator version: 7.19.0
10
+
11
+ =end
12
+
13
+ require 'spec_helper'
14
+ require 'json'
15
+ require 'date'
16
+
17
+ # Unit tests for Zernio::ReplaceAdAudienceCompanies200Response
18
+ # Automatically generated by openapi-generator (https://openapi-generator.tech)
19
+ # Please update as you see appropriate
20
+ describe Zernio::ReplaceAdAudienceCompanies200Response do
21
+ #let(:instance) { Zernio::ReplaceAdAudienceCompanies200Response.new }
22
+
23
+ describe 'test an instance of ReplaceAdAudienceCompanies200Response' do
24
+ it 'should create an instance of ReplaceAdAudienceCompanies200Response' do
25
+ # uncomment below to test the instance creation
26
+ #expect(instance).to be_instance_of(Zernio::ReplaceAdAudienceCompanies200Response)
27
+ end
28
+ end
29
+
30
+ describe 'test attribute "message"' do
31
+ it 'should work' do
32
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
33
+ end
34
+ end
35
+
36
+ describe 'test attribute "num_received"' do
37
+ it 'should work' do
38
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
39
+ end
40
+ end
41
+
42
+ end