zernio-sdk 0.0.804 → 0.0.806

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a95651099e2701934e04a1e7a1cf92e078966302868e91e65a3a8368aaa4856
4
- data.tar.gz: e4bef56410dffb7fcfec0950e333a47c41d1dc4700cadd1f42c5cf6411c5322a
3
+ metadata.gz: d91182d227cba8a3f1c482347300303f38c32616ea4edf351fad9d25b8623c3d
4
+ data.tar.gz: da87c3ea30706fef9a9e4b0f488ab88e98f1e4c57d6ae3846688b9f21b16cf73
5
5
  SHA512:
6
- metadata.gz: b51cdc20292a5514c5a79e90659bcbfaf4c03bc1d204161a4570749da90a9d643e21235bd180ff60242641b91e7ad01d9b5c9eb1f60b7e644d856d8a7c909d22
7
- data.tar.gz: 50f1f5c439a747c0171e5055d911f4fa181956623f66a6d80699adcd90b5d639222799eb9c80786c8ae44ffcae82f7839917d7981bdc3e3094611ac279e801e6
6
+ metadata.gz: 7dd6cd78db4369858d39f2d74485a05f33aed44c9e25da069e65c02b666bc590b3285b51a35828dea7222f9d667c31242c2bf5bb91dfdacc8043c0109031267b
7
+ data.tar.gz: 2dc2eaf066d78dee7443e302e3697e6af03028d95655bc24e62e43e9fdcc2ef43873c4216dec6370140408f441b78f04d8a71be6a330e22c2c195b7857787241
@@ -1442,7 +1442,7 @@ end
1442
1442
 
1443
1443
  Update ad
1444
1444
 
1445
- 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. - **Pinterest / X / LinkedIn / 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).
1445
+ 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).
1446
1446
 
1447
1447
  ### Examples
1448
1448
 
@@ -30,6 +30,8 @@
30
30
  | **spark_auth_code** | **String** | TikTok-only. Spark Code (creator's `auth_code`) authorizing cross-creator Spark Ads — the advertiser can boost a video owned by a DIFFERENT TikTok account. Without this, boosts are limited to videos owned by the same account running the ads (same-BC creators only). The creator generates the code in their TikTok app's Promote settings and shares it with the advertiser. Maps to `auth_code` on the creative entry of /v2/ad/create/. | [optional] |
31
31
  | **dsa_beneficiary** | **String** | Legal entity that benefits from the ad. Required when targeting EU users (EU DSA, Article 26). Optional if the ad account has a default beneficiary: set it once via `PATCH /v1/ads/accounts` or in Meta Ads Manager, and Meta fills it in whenever the field is omitted. | [optional] |
32
32
  | **dsa_payor** | **String** | Legal entity that pays for the ad. Can differ from `dsaBeneficiary` (for example, an agency paying for a client's ads). Same rules as `dsaBeneficiary`: required for EU targeting unless the ad account has a default payor. | [optional] |
33
+ | **lead_gen_form_id** | **String** | Lead Gen form ID to attach to the boosted ad's creative. REQUIRED when `goal` is `lead_generation`. On Meta this is the leadgen_forms ID (create one via POST /v1/ads/lead-forms). On LinkedIn this is the adForm ID (create one via POST /v1/ads/lead-forms with a LinkedIn account); the creative's `leadgenCallToAction.destination` is set to `urn:li:adForm:{id}`. Ignored for other goals. | [optional] |
34
+ | **status** | **String** | Meta, TikTok, and LinkedIn. Publish state of the created entities. Omitted or ACTIVE publishes live (default); PAUSED creates them paused so you can review before they spend. On LinkedIn the whole campaign group, campaign, and creative hierarchy stays PAUSED (intendedStatus PAUSED on each). | [optional] |
33
35
  | **optimization_goal** | **String** | Meta only. Explicit ad-set `optimization_goal` override. When omitted, defaults to the value derived from `goal`. The value must be compatible with the objective Meta derives from `goal`, not with the objective used by `POST /v1/ads/create` for the same `goal` name: boost maps `goal: \"engagement\"` to objective `OUTCOME_AWARENESS`, which accepts `REACH`, `IMPRESSIONS`, `AD_RECALL_LIFT`, or THRUPLAY-class values, and rejects `POST_ENGAGEMENT` (that value is only valid under `OUTCOME_ENGAGEMENT`, which create uses for the same goal name). | [optional] |
34
36
 
35
37
  ## Example
@@ -64,6 +66,8 @@ instance = Zernio::BoostPostRequest.new(
64
66
  spark_auth_code: null,
65
67
  dsa_beneficiary: null,
66
68
  dsa_payor: null,
69
+ lead_gen_form_id: null,
70
+ status: null,
67
71
  optimization_goal: null
68
72
  )
69
73
  ```
@@ -8,7 +8,7 @@
8
8
  | **valid** | **Integer** | Count of rows that succeeded (results[].ok === true) | [optional] |
9
9
  | **invalid** | **Integer** | Count of rows that failed (total - valid) | [optional] |
10
10
  | **results** | [**Array<BulkUploadResultResultsInner>**](BulkUploadResultResultsInner.md) | One entry per CSV data row, in row order. | [optional] |
11
- | **warnings** | **Array<String>** | Top-level advisory warnings (e.g. `rows_exceed_advisory_limit:500`). Empty when none. | [optional] |
11
+ | **warnings** | **Array<String>** | Top-level advisory warnings, e.g. `rows_exceed_advisory_limit:500` or `unknown_columns:<a,b,c>` (comma-separated unrecognized CSV column names). Empty when none. | [optional] |
12
12
  | **rate_limited_accounts** | [**Array<BulkUploadResultRateLimitedAccountsInner>**](BulkUploadResultRateLimitedAccountsInner.md) | Present only when one or more rows targeted an account currently in cooldown. Lets callers map `rate_limited:*` row errors back to structured metadata without parsing the error strings. | [optional] |
13
13
 
14
14
  ## Example
@@ -11,7 +11,7 @@
11
11
  | **ad_set_name** | **String** | Meta only. Exact ad set name. Overrides the default `<name> - Ad Set`. (For per-ad names on the multi-creative shape, set `name` on each `creatives[]` entry.) | [optional] |
12
12
  | **ad_name** | **String** | Meta only. Exact ad name (the single-creative ad object's name). Overrides the default, which is `name`. (For per-ad names on the multi-creative shape, set `name` on each `creatives[]` entry instead.) | [optional] |
13
13
  | **tracking** | [**CreateStandaloneAdRequestTracking**](CreateStandaloneAdRequestTracking.md) | | [optional] |
14
- | **goal** | **String** | Required on legacy and multi-creative shapes; the attach shape inherits it from the ad set. Available goals vary by platform. **Meta** - `conversions`: OUTCOME_SALES. Requires `promotedObject.pixelId` and `promotedObject.customEventType` with a commerce event such as PURCHASE or START_TRIAL, or `promotedObject.customConversionId` to optimise against a Custom Conversion, or `customEventType: OTHER` + `customEventStr` to optimise against a pixel custom event. - `lead_conversion`: OUTCOME_LEADS optimizing website pixel leads. Same pixel and event fields, but with a leads-class event such as LEAD, SUBMIT_APPLICATION, SCHEDULE or CONTACT (or `promotedObject.customConversionId` to optimise against a Custom Conversion instead). Meta gates conversion events by objective, so leads-class events are rejected under `conversions`. - `lead_generation`: OUTCOME_LEADS with instant forms. Requires `leadGenFormId`. `promotedObject.pageId` is optional and auto-filled from the connected Page. - `app_promotion`: requires `promotedObject.applicationId` and `promotedObject.objectStoreUrl`. - `catalog_sales`: Advantage+ catalog ads, for example vehicle inventory. Requires `promotedObject.productSetId`, `promotedObject.pixelId` and `promotedObject.customEventType`. Builds a catalog TEMPLATE creative from the copy fields, which may carry template tags like {{product.name}} or {{vehicle.make}}. No imageUrl or video is sent; Meta renders the visuals per catalog item. Discover catalogs via GET /v1/ads/catalogs and product sets via GET /v1/ads/catalogs/{catalogId}/product-sets. Single shape only, no creatives[], adSetId, dynamicCreative or placementAssets. - `page_likes`: Page Likes conversion location under OUTCOME_ENGAGEMENT (destination_type ON_PAGE, optimization PAGE_LIKES). `promotedObject.pageId` is optional and auto-filled from the connected Page. The creative CTA is fixed to LIKE_PAGE targeting that Page; headline / body / linkUrl / callToAction / imageUrl / video are all optional (Meta derives the link and the Like button from the Page). **TikTok** - `conversions`: website-conversion ad group. Requires `promotedObject.pixelId`, your TikTok Pixel ID. Accepts an optional `promotedObject.customEventType` with a TikTok optimization_event code your pixel tracks (newer pixels use e.g. SHOPPING for purchase events; legacy pixels use ON_WEB_ORDER, INITIATE_ORDER, ON_WEB_REGISTER or FORM). To inherit pixel and event from an existing ad group, pass `adSetId` instead. **LinkedIn** - `engagement`, `traffic`, `awareness` and `video_views` create standalone Direct Sponsored Content ads. `traffic` requires `linkUrl`; `video_views` requires `video`. - `job_applicants` requires a `platformSpecificData.jobs` creative. - For `lead_generation` or `conversions` on LinkedIn, or to promote an existing post, use POST /v1/ads/boost. **OpenAI Ads** - Only `traffic`, `awareness`, and `conversions` are supported (other goals return 400). Maps to OpenAI's `bidding_type` (clicks, impressions, conversions respectively). `conversions` requires an active conversion event setting on the account; create a tracking tag with `defaultEventType` via the tracking-tags API (`POST /v1/accounts/{accountId}/tracking-tags`), or configure a conversion event in OpenAI Ads Manager, or the request returns 422. | [optional] |
14
+ | **goal** | **String** | Required on legacy and multi-creative shapes; the attach shape inherits it from the ad set. Available goals vary by platform. **Meta** - `conversions`: OUTCOME_SALES. Requires `promotedObject.pixelId` and `promotedObject.customEventType` with a commerce event such as PURCHASE or START_TRIAL, or `promotedObject.customConversionId` to optimise against a Custom Conversion, or `customEventType: OTHER` + `customEventStr` to optimise against a pixel custom event. - `lead_conversion`: OUTCOME_LEADS optimizing website pixel leads. Same pixel and event fields, but with a leads-class event such as LEAD, SUBMIT_APPLICATION, SCHEDULE or CONTACT (or `promotedObject.customConversionId` to optimise against a Custom Conversion instead). Meta gates conversion events by objective, so leads-class events are rejected under `conversions`. - `lead_generation`: OUTCOME_LEADS with instant forms. Requires `leadGenFormId`. `promotedObject.pageId` is optional and auto-filled from the connected Page. - `app_promotion`: requires `promotedObject.applicationId` and `promotedObject.objectStoreUrl`. - `catalog_sales`: Advantage+ catalog ads, for example vehicle inventory. Requires `promotedObject.productSetId`, `promotedObject.pixelId` and `promotedObject.customEventType`. Builds a catalog TEMPLATE creative from the copy fields, which may carry template tags like {{product.name}} or {{vehicle.make}}. No imageUrl or video is sent; Meta renders the visuals per catalog item. Discover catalogs via GET /v1/ads/catalogs and product sets via GET /v1/ads/catalogs/{catalogId}/product-sets. Single shape only, no creatives[], adSetId, dynamicCreative or placementAssets. - `page_likes`: Page Likes conversion location under OUTCOME_ENGAGEMENT (destination_type ON_PAGE, optimization PAGE_LIKES). `promotedObject.pageId` is optional and auto-filled from the connected Page. The creative CTA is fixed to LIKE_PAGE targeting that Page; headline / body / linkUrl / callToAction / imageUrl / video are all optional (Meta derives the link and the Like button from the Page). **TikTok** - `conversions`: website-conversion ad group. Requires `promotedObject.pixelId`, your TikTok Pixel ID. Accepts an optional `promotedObject.customEventType` with a TikTok optimization_event code your pixel tracks (newer pixels use e.g. SHOPPING for purchase events; legacy pixels use ON_WEB_ORDER, INITIATE_ORDER, ON_WEB_REGISTER or FORM). To inherit pixel and event from an existing ad group, pass `adSetId` instead. **LinkedIn** - `engagement`, `traffic`, `awareness` and `video_views` create standalone Direct Sponsored Content ads. `traffic` requires `linkUrl`; `video_views` requires `video`. - `lead_generation`: requires `leadGenFormId` (an adForm ID from POST /v1/ads/lead-forms). The campaign objective is set to MAX_LEAD and the creative's `leadgenCallToAction` destination is set to `urn:li:adForm:{id}`. - `job_applicants` requires a `platformSpecificData.jobs` creative. - For `conversions` on LinkedIn, or to promote an existing post, use POST /v1/ads/boost. **OpenAI Ads** - Only `traffic`, `awareness`, and `conversions` are supported (other goals return 400). Maps to OpenAI's `bidding_type` (clicks, impressions, conversions respectively). `conversions` requires an active conversion event setting on the account; create a tracking tag with `defaultEventType` via the tracking-tags API (`POST /v1/accounts/{accountId}/tracking-tags`), or configure a conversion event in OpenAI Ads Manager, or the request returns 422. | [optional] |
15
15
  | **optimization_goal** | **String** | Meta only. Explicit ad-set `optimization_goal` (e.g. `LANDING_PAGE_VIEWS`, `LINK_CLICKS`, `REACH`, `IMPRESSIONS`, `OFFSITE_CONVERSIONS`, `THRUPLAY`, `LEAD_GENERATION`). Overrides the default derived from `goal` (e.g. `traffic` defaults to `LINK_CLICKS`). Forwarded verbatim to Meta, which validates compatibility with the campaign objective and rejects incompatible combinations. | [optional] |
16
16
  | **billing_event** | **String** | Meta only. Explicit ad-set `billing_event`. Defaults to `IMPRESSIONS`. Forwarded verbatim to Meta, which validates compatibility with the optimization goal. | [optional] |
17
17
  | **buying_type** | **String** | Meta only. RESERVED = Reach & Frequency: requires `rfPredictionId` (a RESERVED prediction from /v1/ads/rf-predictions + /reserve). Budget, schedule and pricing come from the reservation, so budgetAmount/budgetType are not required and bid fields are ignored. Only the plain single-ad shape (no creatives[], adSetId, existingCampaignId or dynamicCreative). | [optional] |
@@ -21,7 +21,7 @@
21
21
  | **validate_only** | **Boolean** | Meta only, single standalone shape only (no creatives[], adSetId, or RESERVED). Dry-run: each node runs Meta's execution_options validate_only and NOTHING is created or persisted. Children need real parents, so a fresh tree validates the campaign + creative (the ad set needs its campaign to exist — pass existingCampaignId to validate it too; the ad itself is never validatable pre-create). A Meta validation failure returns the 400 verbatim; success returns 200 with per-node results instead of an ad. | [optional] |
22
22
  | **budget_amount** | **Float** | Budget in WHOLE currency units (USD: 50 = $50.00), NOT cents — Meta's own Marketing API takes this same number in minor units, so it is an easy and expensive mix-up. Required on legacy + multi-creative shapes. Inherited on attach. OpenAI Ads requires a $1 minimum (its budget is lifetime-only, see budgetType). | [optional] |
23
23
  | **budget_type** | **String** | Required on legacy + multi-creative shapes. Inherited on attach. OpenAI Ads accepts lifetime only (no daily-budget concept on the platform); sending daily returns 422. OpenAI Ads lifetime budgets require `endDate` to give the lifetime cap a spend window. | [optional] |
24
- | **status** | **String** | Meta and TikTok. Publish state of the created entities. Omitted or ACTIVE publishes live (default, back-compat); PAUSED creates them paused so you can review before they spend. On Meta the pause is held on the campaign this call creates, leaving the ad set and ad switched on, so a single PUT /v1/ads/campaigns/{campaignId}/status with `active` brings the whole thing live. It is held at every level instead when the pause cannot rely on the campaign: `existingCampaignId` (that campaign may be running and is never touched) or `campaignStatus: ACTIVE`. On TikTok the whole campaign > ad group > ad hierarchy stays paused. | [optional] |
24
+ | **status** | **String** | Meta, TikTok, and LinkedIn. Publish state of the created entities. Omitted or ACTIVE publishes live (default, back-compat); PAUSED creates them paused so you can review before they spend. On Meta the pause is held on the campaign this call creates, leaving the ad set and ad switched on, so a single PUT /v1/ads/campaigns/{campaignId}/status with `active` brings the whole thing live. It is held at every level instead when the pause cannot rely on the campaign: `existingCampaignId` (that campaign may be running and is never touched) or `campaignStatus: ACTIVE`. On TikTok the whole campaign > ad group > ad hierarchy stays paused. On LinkedIn the whole campaign group, campaign, and creative hierarchy stays PAUSED (intendedStatus PAUSED on each). | [optional] |
25
25
  | **campaign_status** | **String** | Meta only. Overrides `status` for the campaign level alone, so you can create a live campaign whose ad set and ad stay paused, or the reverse. Omitted, it follows `status`. | [optional] |
26
26
  | **budget_level** | **String** | Meta only. Where the budget lives, which selects the Meta budget model: - `adset` (default): ABO (Ad-set Budget Optimization). The budget is set on the ad set. This is the back-compatible behaviour — omit this field to keep it. - `campaign`: CBO (Campaign Budget Optimization / Advantage Campaign Budget). The budget AND `bidStrategy` are set on the CAMPAIGN, and Meta distributes spend across ad sets automatically. Meta requires the budget at exactly one level, never both. Non-Meta platforms ignore this field. Ignored on the attach shape (`adSetId`), which inherits the existing budget. | [optional][default to 'adset'] |
27
27
  | **currency** | **String** | ISO 4217 currency code matching the ad account's currency (e.g. `USD`). Meta only. Optional: Zernio resolves it from the ad account when omitted. The value selects the minor-unit exponent Zernio converts budget/bid amounts by before calling Meta (most currencies are cents; zero-decimal currencies like JPY/KRW are sent as-is). | [optional] |
@@ -31,7 +31,7 @@
31
31
  | **description** | **String** | Meta only (facebook/instagram). Link description — the secondary text shown below the headline (Meta's link_data.description; on video creatives mapped to video_data.link_description). When omitted, Meta auto-pulls the destination URL's OpenGraph description. Applies on legacy, attach, and placementAssets shapes; for multi-creative use creatives[].description (this field is the shared fallback). For multi-text variations use dynamicCreative.descriptions instead. | [optional] |
32
32
  | **call_to_action** | **String** | Required on legacy + attach shapes for Meta. Honoured on TikTok (passes through to the Spark Ad creative's `call_to_action`) and on LinkedIn (the CTA button on the ad; defaults to LEARN_MORE when `linkUrl` is set). LinkedIn accepts: LEARN_MORE, SIGN_UP, DOWNLOAD, SUBSCRIBE, REGISTER, JOIN, ATTEND, REQUEST_DEMO, VIEW_QUOTE, APPLY, SEE_MORE, SHOP_NOW, BUY_NOW. Ignored by Google, Pinterest, and X/Twitter. | [optional] |
33
33
  | **link_url** | **String** | Required on legacy + attach shapes (skip for multi-creative). On LinkedIn it's the ad's destination URL; required for `traffic` ads, optional for `engagement` / `awareness`. NOT required when `goal` is `lead_generation` (the ad opens a Lead Gen form instead of a destination). On LinkedIn, `imageUrl` + `linkUrl` publishes an ARTICLE-content creative; this is LinkedIn's article ad format, with the image as thumbnail and `longHeadline` as description. Required for OpenAI Ads (the chat card's target_url). | [optional] |
34
- | **lead_gen_form_id** | **String** | Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`, and on every ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` (or `videoUrls`) entry plus your text variations to get Meta's \"Multiple Text Options\" behavior on a lead ad. | [optional] |
34
+ | **lead_gen_form_id** | **String** | Lead Gen form ID to attach to the ad's creative. REQUIRED when `goal` is `lead_generation`. Create one via POST /v1/ads/lead-forms. On Meta (facebook/instagram) this is the leadgen_forms ID; the ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. On LinkedIn this is the adForm ID; the creative's `leadgenCallToAction.destination` is set to `urn:li:adForm:{id}` and the campaign objective is set to MAX_LEAD. Forms must be owned by the sponsoredAccount (not the organization) for the URN to resolve. Also required on every Meta ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on Meta instant-form lead ads. | [optional] |
35
35
  | **image_url** | **String** | Image creative for Meta/Google/Pinterest/LinkedIn on legacy + attach shapes (mutually exclusive with `video`). Required for LinkedIn ads unless `video` is set. Not required for Google Search campaigns. For TikTok, this field carries the VIDEO URL (the TikTok ads endpoint is video-only; the field retains the `imageUrl` name for cross-platform consistency). Ignored for X/Twitter. For Google Display, treated as the landscape image (alias of `images.landscape`); supply `images.square` alongside or the request is rejected. For LinkedIn the image is uploaded to LinkedIn under the authoring Company Page (see `organizationId`); recommended ratio 1.91:1 (e.g. 1200×627). Required for OpenAI Ads (uploaded as the chat card's image; OpenAI has no video ad format). | [optional] |
36
36
  | **images** | [**CreateStandaloneAdRequestImages**](CreateStandaloneAdRequestImages.md) | | [optional] |
37
37
  | **video** | [**CreateStandaloneAdRequestVideo**](CreateStandaloneAdRequestVideo.md) | | [optional] |
@@ -6,6 +6,7 @@
6
6
  | ---- | ---- | ----------- | ----- |
7
7
  | **message** | **String** | | [optional] |
8
8
  | **post** | [**Post**](Post.md) | | [optional] |
9
+ | **warnings** | **Array<String>** | Advisory notices about a post that was still created: media truncated for a platform, a recycling caveat, or a field that was ignored because it sat outside platforms[].platformSpecificData. Absent when there are none. | [optional] |
9
10
 
10
11
  ## Example
11
12
 
@@ -14,7 +15,8 @@ require 'zernio-sdk'
14
15
 
15
16
  instance = Zernio::PostCreateResponse.new(
16
17
  message: null,
17
- post: null
18
+ post: null,
19
+ warnings: null
18
20
  )
19
21
  ```
20
22
 
data/docs/PostsApi.md CHANGED
@@ -22,7 +22,7 @@ All URIs are relative to *https://zernio.com/api*
22
22
 
23
23
  Bulk upload from CSV
24
24
 
25
- Create multiple posts by uploading a CSV file. Use dryRun=true to validate without creating posts.
25
+ Create multiple posts by uploading a CSV file. Use dryRun=true to validate without creating posts. CSV columns: - Required: `platforms`, `profiles`, and a schedule (one of `schedule_time`, a `schedule_time_<platform>` override, `publish_now=true`, `use_queue=true`, or `is_draft=true`). - Content: at least one of `post_content`, `title`, or `media_urls` is required. - Aliases: a handful of columns accept the JSON field name from POST /v1/posts, since integrators infer the CSV shape from that endpoint's body. When both are present the real CSV column wins, unless it is blank for that row, in which case the alias value is used. - `content` aliases `post_content` - `timezone` aliases `tz` - `scheduledFor` aliases `schedule_time` - `mediaUrls` aliases `media_urls` - Per-platform overrides use three dynamic column prefixes, one column per platform (e.g. `schedule_time_instagram`, `custom_content_tiktok`, `custom_media_youtube`): `schedule_time_<platform>`, `custom_content_<platform>`, `custom_media_<platform>`. - Any other column is not read. It does not error, but it is reported in the response's `warnings` array as `unknown_columns:<a,b,c>` (see BulkUploadResult), so a misnamed or unsupported column is never silently dropped. - Row limits: 5000 rows is a hard cap that returns 400 above it. 500 rows is only an advisory threshold, it adds `rows_exceed_advisory_limit:500` to `warnings` and the request still processes. Example row (header + one data row): ``` post_content,platforms,profiles,schedule_time,tz \"Hello world\",instagram,MyProfile,2026-09-01 10:00,America/New_York ```
26
26
 
27
27
  ### Examples
28
28
 
@@ -1545,7 +1545,7 @@ module Zernio
1545
1545
  end
1546
1546
 
1547
1547
  # Update ad
1548
- # 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. - **Pinterest / X / LinkedIn / 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).
1548
+ # 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).
1549
1549
  # @param ad_id [String]
1550
1550
  # @param update_ad_request [UpdateAdRequest]
1551
1551
  # @param [Hash] opts the optional parameters
@@ -1556,7 +1556,7 @@ module Zernio
1556
1556
  end
1557
1557
 
1558
1558
  # Update ad
1559
- # 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 &#x60;/v2/adgroup/update/&#x60;), and creative (via &#x60;/v2/ad/update/&#x60; patch-style — &#x60;headline&#x60; is ignored, &#x60;body&#x60; becomes &#x60;ad_text&#x60;). - **Google**: status, budget, and KEYWORD edits via &#x60;targeting.keywords&#x60; / &#x60;targeting.negativeKeywords&#x60; — 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 &#x60;targeting&#x60; field returns 400: Google cannot mutate broad targeting post-create without recreating the campaign. &#x60;creative&#x60; returns 501. - **Pinterest / X / LinkedIn / OpenAI Ads**: status + budget only. Sending &#x60;targeting&#x60; or &#x60;creative&#x60; returns 501 with code &#x60;unsupported_platform_operation&#x60;. OpenAI Ads budget is lifetime-only (see &#x60;budget.type&#x60; below).
1559
+ # 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 &#x60;/v2/adgroup/update/&#x60;), and creative (via &#x60;/v2/ad/update/&#x60; patch-style — &#x60;headline&#x60; is ignored, &#x60;body&#x60; becomes &#x60;ad_text&#x60;). - **Google**: status, budget, and KEYWORD edits via &#x60;targeting.keywords&#x60; / &#x60;targeting.negativeKeywords&#x60; — 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 &#x60;targeting&#x60; field returns 400: Google cannot mutate broad targeting post-create without recreating the campaign. &#x60;creative&#x60; 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 &#x60;targeting&#x60; or &#x60;creative&#x60; returns 501 with code &#x60;unsupported_platform_operation&#x60;. OpenAI Ads budget is lifetime-only (see &#x60;budget.type&#x60; below).
1560
1560
  # @param ad_id [String]
1561
1561
  # @param update_ad_request [UpdateAdRequest]
1562
1562
  # @param [Hash] opts the optional parameters
@@ -20,7 +20,7 @@ module Zernio
20
20
  @api_client = api_client
21
21
  end
22
22
  # Bulk upload from CSV
23
- # Create multiple posts by uploading a CSV file. Use dryRun=true to validate without creating posts.
23
+ # Create multiple posts by uploading a CSV file. Use dryRun=true to validate without creating posts. CSV columns: - Required: `platforms`, `profiles`, and a schedule (one of `schedule_time`, a `schedule_time_<platform>` override, `publish_now=true`, `use_queue=true`, or `is_draft=true`). - Content: at least one of `post_content`, `title`, or `media_urls` is required. - Aliases: a handful of columns accept the JSON field name from POST /v1/posts, since integrators infer the CSV shape from that endpoint's body. When both are present the real CSV column wins, unless it is blank for that row, in which case the alias value is used. - `content` aliases `post_content` - `timezone` aliases `tz` - `scheduledFor` aliases `schedule_time` - `mediaUrls` aliases `media_urls` - Per-platform overrides use three dynamic column prefixes, one column per platform (e.g. `schedule_time_instagram`, `custom_content_tiktok`, `custom_media_youtube`): `schedule_time_<platform>`, `custom_content_<platform>`, `custom_media_<platform>`. - Any other column is not read. It does not error, but it is reported in the response's `warnings` array as `unknown_columns:<a,b,c>` (see BulkUploadResult), so a misnamed or unsupported column is never silently dropped. - Row limits: 5000 rows is a hard cap that returns 400 above it. 500 rows is only an advisory threshold, it adds `rows_exceed_advisory_limit:500` to `warnings` and the request still processes. Example row (header + one data row): ``` post_content,platforms,profiles,schedule_time,tz \"Hello world\",instagram,MyProfile,2026-09-01 10:00,America/New_York ```
24
24
  # @param [Hash] opts the optional parameters
25
25
  # @option opts [Boolean] :dry_run (default to false)
26
26
  # @option opts [File] :file
@@ -31,7 +31,7 @@ module Zernio
31
31
  end
32
32
 
33
33
  # Bulk upload from CSV
34
- # Create multiple posts by uploading a CSV file. Use dryRun&#x3D;true to validate without creating posts.
34
+ # Create multiple posts by uploading a CSV file. Use dryRun&#x3D;true to validate without creating posts. CSV columns: - Required: &#x60;platforms&#x60;, &#x60;profiles&#x60;, and a schedule (one of &#x60;schedule_time&#x60;, a &#x60;schedule_time_&lt;platform&gt;&#x60; override, &#x60;publish_now&#x3D;true&#x60;, &#x60;use_queue&#x3D;true&#x60;, or &#x60;is_draft&#x3D;true&#x60;). - Content: at least one of &#x60;post_content&#x60;, &#x60;title&#x60;, or &#x60;media_urls&#x60; is required. - Aliases: a handful of columns accept the JSON field name from POST /v1/posts, since integrators infer the CSV shape from that endpoint&#39;s body. When both are present the real CSV column wins, unless it is blank for that row, in which case the alias value is used. - &#x60;content&#x60; aliases &#x60;post_content&#x60; - &#x60;timezone&#x60; aliases &#x60;tz&#x60; - &#x60;scheduledFor&#x60; aliases &#x60;schedule_time&#x60; - &#x60;mediaUrls&#x60; aliases &#x60;media_urls&#x60; - Per-platform overrides use three dynamic column prefixes, one column per platform (e.g. &#x60;schedule_time_instagram&#x60;, &#x60;custom_content_tiktok&#x60;, &#x60;custom_media_youtube&#x60;): &#x60;schedule_time_&lt;platform&gt;&#x60;, &#x60;custom_content_&lt;platform&gt;&#x60;, &#x60;custom_media_&lt;platform&gt;&#x60;. - Any other column is not read. It does not error, but it is reported in the response&#39;s &#x60;warnings&#x60; array as &#x60;unknown_columns:&lt;a,b,c&gt;&#x60; (see BulkUploadResult), so a misnamed or unsupported column is never silently dropped. - Row limits: 5000 rows is a hard cap that returns 400 above it. 500 rows is only an advisory threshold, it adds &#x60;rows_exceed_advisory_limit:500&#x60; to &#x60;warnings&#x60; and the request still processes. Example row (header + one data row): &#x60;&#x60;&#x60; post_content,platforms,profiles,schedule_time,tz \&quot;Hello world\&quot;,instagram,MyProfile,2026-09-01 10:00,America/New_York &#x60;&#x60;&#x60;
35
35
  # @param [Hash] opts the optional parameters
36
36
  # @option opts [Boolean] :dry_run (default to false)
37
37
  # @option opts [File] :file
@@ -87,6 +87,12 @@ module Zernio
87
87
  # Legal entity that pays for the ad. Can differ from `dsaBeneficiary` (for example, an agency paying for a client's ads). Same rules as `dsaBeneficiary`: required for EU targeting unless the ad account has a default payor.
88
88
  attr_accessor :dsa_payor
89
89
 
90
+ # Lead Gen form ID to attach to the boosted ad's creative. REQUIRED when `goal` is `lead_generation`. On Meta this is the leadgen_forms ID (create one via POST /v1/ads/lead-forms). On LinkedIn this is the adForm ID (create one via POST /v1/ads/lead-forms with a LinkedIn account); the creative's `leadgenCallToAction.destination` is set to `urn:li:adForm:{id}`. Ignored for other goals.
91
+ attr_accessor :lead_gen_form_id
92
+
93
+ # Meta, TikTok, and LinkedIn. Publish state of the created entities. Omitted or ACTIVE publishes live (default); PAUSED creates them paused so you can review before they spend. On LinkedIn the whole campaign group, campaign, and creative hierarchy stays PAUSED (intendedStatus PAUSED on each).
94
+ attr_accessor :status
95
+
90
96
  # Meta only. Explicit ad-set `optimization_goal` override. When omitted, defaults to the value derived from `goal`. The value must be compatible with the objective Meta derives from `goal`, not with the objective used by `POST /v1/ads/create` for the same `goal` name: boost maps `goal: \"engagement\"` to objective `OUTCOME_AWARENESS`, which accepts `REACH`, `IMPRESSIONS`, `AD_RECALL_LIFT`, or THRUPLAY-class values, and rejects `POST_ENGAGEMENT` (that value is only valid under `OUTCOME_ENGAGEMENT`, which create uses for the same goal name).
91
97
  attr_accessor :optimization_goal
92
98
 
@@ -141,6 +147,8 @@ module Zernio
141
147
  :'spark_auth_code' => :'sparkAuthCode',
142
148
  :'dsa_beneficiary' => :'dsaBeneficiary',
143
149
  :'dsa_payor' => :'dsaPayor',
150
+ :'lead_gen_form_id' => :'leadGenFormId',
151
+ :'status' => :'status',
144
152
  :'optimization_goal' => :'optimizationGoal'
145
153
  }
146
154
  end
@@ -184,6 +192,8 @@ module Zernio
184
192
  :'spark_auth_code' => :'String',
185
193
  :'dsa_beneficiary' => :'String',
186
194
  :'dsa_payor' => :'String',
195
+ :'lead_gen_form_id' => :'String',
196
+ :'status' => :'String',
187
197
  :'optimization_goal' => :'String'
188
198
  }
189
199
  end
@@ -328,6 +338,14 @@ module Zernio
328
338
  self.dsa_payor = attributes[:'dsa_payor']
329
339
  end
330
340
 
341
+ if attributes.key?(:'lead_gen_form_id')
342
+ self.lead_gen_form_id = attributes[:'lead_gen_form_id']
343
+ end
344
+
345
+ if attributes.key?(:'status')
346
+ self.status = attributes[:'status']
347
+ end
348
+
331
349
  if attributes.key?(:'optimization_goal')
332
350
  self.optimization_goal = attributes[:'optimization_goal']
333
351
  end
@@ -394,6 +412,8 @@ module Zernio
394
412
  return false if !@currency.nil? && @currency.to_s.length < 3
395
413
  return false if !@dsa_beneficiary.nil? && @dsa_beneficiary.to_s.length > 100
396
414
  return false if !@dsa_payor.nil? && @dsa_payor.to_s.length > 100
415
+ status_validator = EnumAttributeValidator.new('String', ["ACTIVE", "PAUSED"])
416
+ return false unless status_validator.valid?(@status)
397
417
  true
398
418
  end
399
419
 
@@ -497,6 +517,16 @@ module Zernio
497
517
  @dsa_payor = dsa_payor
498
518
  end
499
519
 
520
+ # Custom attribute writer method checking allowed values (enum).
521
+ # @param [Object] status Object to be assigned
522
+ def status=(status)
523
+ validator = EnumAttributeValidator.new('String', ["ACTIVE", "PAUSED"])
524
+ unless validator.valid?(status)
525
+ fail ArgumentError, "invalid value for \"status\", must be one of #{validator.allowable_values}."
526
+ end
527
+ @status = status
528
+ end
529
+
500
530
  # Checks equality by comparing each attribute.
501
531
  # @param [Object] Object to be compared
502
532
  def ==(o)
@@ -528,6 +558,8 @@ module Zernio
528
558
  spark_auth_code == o.spark_auth_code &&
529
559
  dsa_beneficiary == o.dsa_beneficiary &&
530
560
  dsa_payor == o.dsa_payor &&
561
+ lead_gen_form_id == o.lead_gen_form_id &&
562
+ status == o.status &&
531
563
  optimization_goal == o.optimization_goal
532
564
  end
533
565
 
@@ -540,7 +572,7 @@ module Zernio
540
572
  # Calculates hash code according to all attributes.
541
573
  # @return [Integer] Hash code
542
574
  def hash
543
- [post_id, platform_post_id, account_id, ad_account_id, name, goal, ad_set_id, budget, instagram_account_id, destination_type, currency, schedule, targeting, raw_targeting, bid_strategy, bid_amount, roas_average_floor, platform_specific_data, tracking, special_ad_categories, special_ad_category_country, link_url, call_to_action, spark_auth_code, dsa_beneficiary, dsa_payor, optimization_goal].hash
575
+ [post_id, platform_post_id, account_id, ad_account_id, name, goal, ad_set_id, budget, instagram_account_id, destination_type, currency, schedule, targeting, raw_targeting, bid_strategy, bid_amount, roas_average_floor, platform_specific_data, tracking, special_ad_categories, special_ad_category_country, link_url, call_to_action, spark_auth_code, dsa_beneficiary, dsa_payor, lead_gen_form_id, status, optimization_goal].hash
544
576
  end
545
577
 
546
578
  # Builds the object from hash
@@ -28,7 +28,7 @@ module Zernio
28
28
  # One entry per CSV data row, in row order.
29
29
  attr_accessor :results
30
30
 
31
- # Top-level advisory warnings (e.g. `rows_exceed_advisory_limit:500`). Empty when none.
31
+ # Top-level advisory warnings, e.g. `rows_exceed_advisory_limit:500` or `unknown_columns:<a,b,c>` (comma-separated unrecognized CSV column names). Empty when none.
32
32
  attr_accessor :warnings
33
33
 
34
34
  # Present only when one or more rows targeted an account currently in cooldown. Lets callers map `rate_limited:*` row errors back to structured metadata without parsing the error strings.
@@ -32,7 +32,7 @@ module Zernio
32
32
 
33
33
  attr_accessor :tracking
34
34
 
35
- # Required on legacy and multi-creative shapes; the attach shape inherits it from the ad set. Available goals vary by platform. **Meta** - `conversions`: OUTCOME_SALES. Requires `promotedObject.pixelId` and `promotedObject.customEventType` with a commerce event such as PURCHASE or START_TRIAL, or `promotedObject.customConversionId` to optimise against a Custom Conversion, or `customEventType: OTHER` + `customEventStr` to optimise against a pixel custom event. - `lead_conversion`: OUTCOME_LEADS optimizing website pixel leads. Same pixel and event fields, but with a leads-class event such as LEAD, SUBMIT_APPLICATION, SCHEDULE or CONTACT (or `promotedObject.customConversionId` to optimise against a Custom Conversion instead). Meta gates conversion events by objective, so leads-class events are rejected under `conversions`. - `lead_generation`: OUTCOME_LEADS with instant forms. Requires `leadGenFormId`. `promotedObject.pageId` is optional and auto-filled from the connected Page. - `app_promotion`: requires `promotedObject.applicationId` and `promotedObject.objectStoreUrl`. - `catalog_sales`: Advantage+ catalog ads, for example vehicle inventory. Requires `promotedObject.productSetId`, `promotedObject.pixelId` and `promotedObject.customEventType`. Builds a catalog TEMPLATE creative from the copy fields, which may carry template tags like {{product.name}} or {{vehicle.make}}. No imageUrl or video is sent; Meta renders the visuals per catalog item. Discover catalogs via GET /v1/ads/catalogs and product sets via GET /v1/ads/catalogs/{catalogId}/product-sets. Single shape only, no creatives[], adSetId, dynamicCreative or placementAssets. - `page_likes`: Page Likes conversion location under OUTCOME_ENGAGEMENT (destination_type ON_PAGE, optimization PAGE_LIKES). `promotedObject.pageId` is optional and auto-filled from the connected Page. The creative CTA is fixed to LIKE_PAGE targeting that Page; headline / body / linkUrl / callToAction / imageUrl / video are all optional (Meta derives the link and the Like button from the Page). **TikTok** - `conversions`: website-conversion ad group. Requires `promotedObject.pixelId`, your TikTok Pixel ID. Accepts an optional `promotedObject.customEventType` with a TikTok optimization_event code your pixel tracks (newer pixels use e.g. SHOPPING for purchase events; legacy pixels use ON_WEB_ORDER, INITIATE_ORDER, ON_WEB_REGISTER or FORM). To inherit pixel and event from an existing ad group, pass `adSetId` instead. **LinkedIn** - `engagement`, `traffic`, `awareness` and `video_views` create standalone Direct Sponsored Content ads. `traffic` requires `linkUrl`; `video_views` requires `video`. - `job_applicants` requires a `platformSpecificData.jobs` creative. - For `lead_generation` or `conversions` on LinkedIn, or to promote an existing post, use POST /v1/ads/boost. **OpenAI Ads** - Only `traffic`, `awareness`, and `conversions` are supported (other goals return 400). Maps to OpenAI's `bidding_type` (clicks, impressions, conversions respectively). `conversions` requires an active conversion event setting on the account; create a tracking tag with `defaultEventType` via the tracking-tags API (`POST /v1/accounts/{accountId}/tracking-tags`), or configure a conversion event in OpenAI Ads Manager, or the request returns 422.
35
+ # Required on legacy and multi-creative shapes; the attach shape inherits it from the ad set. Available goals vary by platform. **Meta** - `conversions`: OUTCOME_SALES. Requires `promotedObject.pixelId` and `promotedObject.customEventType` with a commerce event such as PURCHASE or START_TRIAL, or `promotedObject.customConversionId` to optimise against a Custom Conversion, or `customEventType: OTHER` + `customEventStr` to optimise against a pixel custom event. - `lead_conversion`: OUTCOME_LEADS optimizing website pixel leads. Same pixel and event fields, but with a leads-class event such as LEAD, SUBMIT_APPLICATION, SCHEDULE or CONTACT (or `promotedObject.customConversionId` to optimise against a Custom Conversion instead). Meta gates conversion events by objective, so leads-class events are rejected under `conversions`. - `lead_generation`: OUTCOME_LEADS with instant forms. Requires `leadGenFormId`. `promotedObject.pageId` is optional and auto-filled from the connected Page. - `app_promotion`: requires `promotedObject.applicationId` and `promotedObject.objectStoreUrl`. - `catalog_sales`: Advantage+ catalog ads, for example vehicle inventory. Requires `promotedObject.productSetId`, `promotedObject.pixelId` and `promotedObject.customEventType`. Builds a catalog TEMPLATE creative from the copy fields, which may carry template tags like {{product.name}} or {{vehicle.make}}. No imageUrl or video is sent; Meta renders the visuals per catalog item. Discover catalogs via GET /v1/ads/catalogs and product sets via GET /v1/ads/catalogs/{catalogId}/product-sets. Single shape only, no creatives[], adSetId, dynamicCreative or placementAssets. - `page_likes`: Page Likes conversion location under OUTCOME_ENGAGEMENT (destination_type ON_PAGE, optimization PAGE_LIKES). `promotedObject.pageId` is optional and auto-filled from the connected Page. The creative CTA is fixed to LIKE_PAGE targeting that Page; headline / body / linkUrl / callToAction / imageUrl / video are all optional (Meta derives the link and the Like button from the Page). **TikTok** - `conversions`: website-conversion ad group. Requires `promotedObject.pixelId`, your TikTok Pixel ID. Accepts an optional `promotedObject.customEventType` with a TikTok optimization_event code your pixel tracks (newer pixels use e.g. SHOPPING for purchase events; legacy pixels use ON_WEB_ORDER, INITIATE_ORDER, ON_WEB_REGISTER or FORM). To inherit pixel and event from an existing ad group, pass `adSetId` instead. **LinkedIn** - `engagement`, `traffic`, `awareness` and `video_views` create standalone Direct Sponsored Content ads. `traffic` requires `linkUrl`; `video_views` requires `video`. - `lead_generation`: requires `leadGenFormId` (an adForm ID from POST /v1/ads/lead-forms). The campaign objective is set to MAX_LEAD and the creative's `leadgenCallToAction` destination is set to `urn:li:adForm:{id}`. - `job_applicants` requires a `platformSpecificData.jobs` creative. - For `conversions` on LinkedIn, or to promote an existing post, use POST /v1/ads/boost. **OpenAI Ads** - Only `traffic`, `awareness`, and `conversions` are supported (other goals return 400). Maps to OpenAI's `bidding_type` (clicks, impressions, conversions respectively). `conversions` requires an active conversion event setting on the account; create a tracking tag with `defaultEventType` via the tracking-tags API (`POST /v1/accounts/{accountId}/tracking-tags`), or configure a conversion event in OpenAI Ads Manager, or the request returns 422.
36
36
  attr_accessor :goal
37
37
 
38
38
  # Meta only. Explicit ad-set `optimization_goal` (e.g. `LANDING_PAGE_VIEWS`, `LINK_CLICKS`, `REACH`, `IMPRESSIONS`, `OFFSITE_CONVERSIONS`, `THRUPLAY`, `LEAD_GENERATION`). Overrides the default derived from `goal` (e.g. `traffic` defaults to `LINK_CLICKS`). Forwarded verbatim to Meta, which validates compatibility with the campaign objective and rejects incompatible combinations.
@@ -62,7 +62,7 @@ module Zernio
62
62
  # Required on legacy + multi-creative shapes. Inherited on attach. OpenAI Ads accepts lifetime only (no daily-budget concept on the platform); sending daily returns 422. OpenAI Ads lifetime budgets require `endDate` to give the lifetime cap a spend window.
63
63
  attr_accessor :budget_type
64
64
 
65
- # Meta and TikTok. Publish state of the created entities. Omitted or ACTIVE publishes live (default, back-compat); PAUSED creates them paused so you can review before they spend. On Meta the pause is held on the campaign this call creates, leaving the ad set and ad switched on, so a single PUT /v1/ads/campaigns/{campaignId}/status with `active` brings the whole thing live. It is held at every level instead when the pause cannot rely on the campaign: `existingCampaignId` (that campaign may be running and is never touched) or `campaignStatus: ACTIVE`. On TikTok the whole campaign > ad group > ad hierarchy stays paused.
65
+ # Meta, TikTok, and LinkedIn. Publish state of the created entities. Omitted or ACTIVE publishes live (default, back-compat); PAUSED creates them paused so you can review before they spend. On Meta the pause is held on the campaign this call creates, leaving the ad set and ad switched on, so a single PUT /v1/ads/campaigns/{campaignId}/status with `active` brings the whole thing live. It is held at every level instead when the pause cannot rely on the campaign: `existingCampaignId` (that campaign may be running and is never touched) or `campaignStatus: ACTIVE`. On TikTok the whole campaign > ad group > ad hierarchy stays paused. On LinkedIn the whole campaign group, campaign, and creative hierarchy stays PAUSED (intendedStatus PAUSED on each).
66
66
  attr_accessor :status
67
67
 
68
68
  # Meta only. Overrides `status` for the campaign level alone, so you can create a live campaign whose ad set and ad stay paused, or the reverse. Omitted, it follows `status`.
@@ -92,7 +92,7 @@ module Zernio
92
92
  # Required on legacy + attach shapes (skip for multi-creative). On LinkedIn it's the ad's destination URL; required for `traffic` ads, optional for `engagement` / `awareness`. NOT required when `goal` is `lead_generation` (the ad opens a Lead Gen form instead of a destination). On LinkedIn, `imageUrl` + `linkUrl` publishes an ARTICLE-content creative; this is LinkedIn's article ad format, with the image as thumbnail and `longHeadline` as description. Required for OpenAI Ads (the chat card's target_url).
93
93
  attr_accessor :link_url
94
94
 
95
- # Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`, and on every ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` (or `videoUrls`) entry plus your text variations to get Meta's \"Multiple Text Options\" behavior on a lead ad.
95
+ # Lead Gen form ID to attach to the ad's creative. REQUIRED when `goal` is `lead_generation`. Create one via POST /v1/ads/lead-forms. On Meta (facebook/instagram) this is the leadgen_forms ID; the ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. On LinkedIn this is the adForm ID; the creative's `leadgenCallToAction.destination` is set to `urn:li:adForm:{id}` and the campaign objective is set to MAX_LEAD. Forms must be owned by the sponsoredAccount (not the organization) for the URN to resolve. Also required on every Meta ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on Meta instant-form lead ads.
96
96
  attr_accessor :lead_gen_form_id
97
97
 
98
98
  # Image creative for Meta/Google/Pinterest/LinkedIn on legacy + attach shapes (mutually exclusive with `video`). Required for LinkedIn ads unless `video` is set. Not required for Google Search campaigns. For TikTok, this field carries the VIDEO URL (the TikTok ads endpoint is video-only; the field retains the `imageUrl` name for cross-platform consistency). Ignored for X/Twitter. For Google Display, treated as the landscape image (alias of `images.landscape`); supply `images.square` alongside or the request is rejected. For LinkedIn the image is uploaded to LinkedIn under the authoring Company Page (see `organizationId`); recommended ratio 1.91:1 (e.g. 1200×627). Required for OpenAI Ads (uploaded as the chat card's image; OpenAI has no video ad format).
@@ -19,11 +19,15 @@ module Zernio
19
19
 
20
20
  attr_accessor :post
21
21
 
22
+ # Advisory notices about a post that was still created: media truncated for a platform, a recycling caveat, or a field that was ignored because it sat outside platforms[].platformSpecificData. Absent when there are none.
23
+ attr_accessor :warnings
24
+
22
25
  # Attribute mapping from ruby-style variable name to JSON key.
23
26
  def self.attribute_map
24
27
  {
25
28
  :'message' => :'message',
26
- :'post' => :'post'
29
+ :'post' => :'post',
30
+ :'warnings' => :'warnings'
27
31
  }
28
32
  end
29
33
 
@@ -41,7 +45,8 @@ module Zernio
41
45
  def self.openapi_types
42
46
  {
43
47
  :'message' => :'String',
44
- :'post' => :'Post'
48
+ :'post' => :'Post',
49
+ :'warnings' => :'Array<String>'
45
50
  }
46
51
  end
47
52
 
@@ -74,6 +79,12 @@ module Zernio
74
79
  if attributes.key?(:'post')
75
80
  self.post = attributes[:'post']
76
81
  end
82
+
83
+ if attributes.key?(:'warnings')
84
+ if (value = attributes[:'warnings']).is_a?(Array)
85
+ self.warnings = value
86
+ end
87
+ end
77
88
  end
78
89
 
79
90
  # Show invalid properties with the reasons. Usually used together with valid?
@@ -97,7 +108,8 @@ module Zernio
97
108
  return true if self.equal?(o)
98
109
  self.class == o.class &&
99
110
  message == o.message &&
100
- post == o.post
111
+ post == o.post &&
112
+ warnings == o.warnings
101
113
  end
102
114
 
103
115
  # @see the `==` method
@@ -109,7 +121,7 @@ module Zernio
109
121
  # Calculates hash code according to all attributes.
110
122
  # @return [Integer] Hash code
111
123
  def hash
112
- [message, post].hash
124
+ [message, post, warnings].hash
113
125
  end
114
126
 
115
127
  # Builds the object from hash
@@ -14,7 +14,7 @@ require 'date'
14
14
  require 'time'
15
15
 
16
16
  module Zernio
17
- # Replace the ad's creative. Meta + TikTok only. - **Meta**: requires `headline`, `body`, `callToAction`, `linkUrl`, `imageUrl`. The ad's existing creative is replaced via a new `/act_X/adcreatives` upload + ad update. The old creative is retained on the ad account for historical reporting. - **TikTok**: patch-style. Pass any subset; `headline` is ignored (TikTok creatives have no headline slot). `body` becomes the in-feed `ad_text`; `linkUrl` becomes `landing_page_url`; `videoUrl` triggers a fresh upload.
17
+ # Replace the ad's creative. Meta, TikTok, and LinkedIn. - **Meta**: requires `headline`, `body`, `callToAction`, `linkUrl`, `imageUrl`. The ad's existing creative is replaced via a new `/act_X/adcreatives` upload + ad update. The old creative is retained on the ad account for historical reporting. - **TikTok**: patch-style. Pass any subset; `headline` is ignored (TikTok creatives have no headline slot). `body` becomes the in-feed `ad_text`; `linkUrl` becomes `landing_page_url`; `videoUrl` triggers a fresh upload. - **LinkedIn**: uploads new media (image via `imageUrl` or video via `videoUrl`), creates a new inline media creative on the same campaign, and pauses the old creative (best-effort). The old creative is retained for historical reporting.
18
18
  class UpdateAdRequestCreative < ApiModelBase
19
19
  # Meta only
20
20
  attr_accessor :headline
@@ -14,7 +14,7 @@ require 'date'
14
14
  require 'time'
15
15
 
16
16
  module Zernio
17
- # Meta + TikTok (demographics/interests) and Google (keyword edits only). Pinterest / X / LinkedIn return 501.
17
+ # Meta + TikTok (demographics/interests), Google (keyword edits only), and LinkedIn (geo countries). Pinterest / X return 501.
18
18
  class UpdateAdRequestTargeting < ApiModelBase
19
19
  # Google only. The FULL new set of positive keywords for the ad group; live keywords not listed are removed. Entries are strings (BROAD) or { text, matchType } with matchType exact | phrase | broad. Mirrored to GET /v1/ads/keywords immediately.
20
20
  attr_accessor :keywords
@@ -11,5 +11,5 @@ Generator version: 7.19.0
11
11
  =end
12
12
 
13
13
  module Zernio
14
- VERSION = '0.0.804'
14
+ VERSION = '0.0.806'
15
15
  end
data/openapi.yaml CHANGED
@@ -1384,7 +1384,7 @@ components:
1384
1384
  items: { type: string }
1385
1385
  warnings:
1386
1386
  type: array
1387
- description: "Top-level advisory warnings (e.g. `rows_exceed_advisory_limit:500`). Empty when none."
1387
+ description: "Top-level advisory warnings, e.g. `rows_exceed_advisory_limit:500` or `unknown_columns:<a,b,c>` (comma-separated unrecognized CSV column names). Empty when none."
1388
1388
  items: { type: string }
1389
1389
  rateLimitedAccounts:
1390
1390
  type: array
@@ -7577,6 +7577,11 @@ components:
7577
7577
  type: string
7578
7578
  post:
7579
7579
  $ref: '#/components/schemas/Post'
7580
+ warnings:
7581
+ type: array
7582
+ description: 'Advisory notices about a post that was still created: media truncated for a platform, a recycling caveat, or a field that was ignored because it sat outside platforms[].platformSpecificData. Absent when there are none.'
7583
+ items:
7584
+ type: string
7580
7585
  PostUpdateResponse:
7581
7586
  type: object
7582
7587
  properties:
@@ -15299,7 +15304,26 @@ paths:
15299
15304
  operationId: bulkUploadPosts
15300
15305
  tags: [Posts]
15301
15306
  summary: Bulk upload from CSV
15302
- description: Create multiple posts by uploading a CSV file. Use dryRun=true to validate without creating posts.
15307
+ description: |
15308
+ Create multiple posts by uploading a CSV file. Use dryRun=true to validate without creating posts.
15309
+
15310
+ CSV columns:
15311
+ - Required: `platforms`, `profiles`, and a schedule (one of `schedule_time`, a `schedule_time_<platform>` override, `publish_now=true`, `use_queue=true`, or `is_draft=true`).
15312
+ - Content: at least one of `post_content`, `title`, or `media_urls` is required.
15313
+ - Aliases: a handful of columns accept the JSON field name from POST /v1/posts, since integrators infer the CSV shape from that endpoint's body. When both are present the real CSV column wins, unless it is blank for that row, in which case the alias value is used.
15314
+ - `content` aliases `post_content`
15315
+ - `timezone` aliases `tz`
15316
+ - `scheduledFor` aliases `schedule_time`
15317
+ - `mediaUrls` aliases `media_urls`
15318
+ - Per-platform overrides use three dynamic column prefixes, one column per platform (e.g. `schedule_time_instagram`, `custom_content_tiktok`, `custom_media_youtube`): `schedule_time_<platform>`, `custom_content_<platform>`, `custom_media_<platform>`.
15319
+ - Any other column is not read. It does not error, but it is reported in the response's `warnings` array as `unknown_columns:<a,b,c>` (see BulkUploadResult), so a misnamed or unsupported column is never silently dropped.
15320
+ - Row limits: 5000 rows is a hard cap that returns 400 above it. 500 rows is only an advisory threshold, it adds `rows_exceed_advisory_limit:500` to `warnings` and the request still processes.
15321
+
15322
+ Example row (header + one data row):
15323
+ ```
15324
+ post_content,platforms,profiles,schedule_time,tz
15325
+ "Hello world",instagram,MyProfile,2026-09-01 10:00,America/New_York
15326
+ ```
15303
15327
  parameters:
15304
15328
  - name: dryRun
15305
15329
  in: query
@@ -41290,7 +41314,10 @@ paths:
41290
41314
  kind on the ad group (criteria not in the list are removed); a kind left out is
41291
41315
  untouched. Any other `targeting` field returns 400: Google cannot mutate broad
41292
41316
  targeting post-create without recreating the campaign. `creative` returns 501.
41293
- - **Pinterest / X / LinkedIn / OpenAI Ads**: status + budget only. Sending
41317
+ - **LinkedIn**: status, budget, targeting (geo countries only, applied to the
41318
+ LinkedIn Campaign via PARTIAL_UPDATE), and creative (uploads new media, creates a
41319
+ replacement inline creative on the same campaign, pauses the old one).
41320
+ - **Pinterest / X / OpenAI Ads**: status + budget only. Sending
41294
41321
  `targeting` or `creative` returns 501 with code `unsupported_platform_operation`.
41295
41322
  OpenAI Ads budget is lifetime-only (see `budget.type` below).
41296
41323
  security:
@@ -41313,8 +41340,8 @@ paths:
41313
41340
  targeting:
41314
41341
  type: object
41315
41342
  description: |
41316
- Meta + TikTok (demographics/interests) and Google (keyword edits only).
41317
- Pinterest / X / LinkedIn return 501.
41343
+ Meta + TikTok (demographics/interests), Google (keyword edits only),
41344
+ and LinkedIn (geo countries). Pinterest / X return 501.
41318
41345
  properties:
41319
41346
  keywords:
41320
41347
  type: array
@@ -41346,7 +41373,7 @@ paths:
41346
41373
  creative:
41347
41374
  type: object
41348
41375
  description: |
41349
- Replace the ad's creative. Meta + TikTok only.
41376
+ Replace the ad's creative. Meta, TikTok, and LinkedIn.
41350
41377
 
41351
41378
  - **Meta**: requires `headline`, `body`, `callToAction`, `linkUrl`, `imageUrl`. The
41352
41379
  ad's existing creative is replaced via a new `/act_X/adcreatives` upload + ad
@@ -41354,6 +41381,9 @@ paths:
41354
41381
  - **TikTok**: patch-style. Pass any subset; `headline` is ignored (TikTok creatives
41355
41382
  have no headline slot). `body` becomes the in-feed `ad_text`; `linkUrl` becomes
41356
41383
  `landing_page_url`; `videoUrl` triggers a fresh upload.
41384
+ - **LinkedIn**: uploads new media (image via `imageUrl` or video via `videoUrl`),
41385
+ creates a new inline media creative on the same campaign, and pauses the old
41386
+ creative (best-effort). The old creative is retained for historical reporting.
41357
41387
  properties:
41358
41388
  headline: { type: string, description: "Meta only" }
41359
41389
  body: { type: string }
@@ -41376,7 +41406,7 @@ paths:
41376
41406
  description: Invalid status transition or budget below minimum
41377
41407
  '401': { $ref: '#/components/responses/Unauthorized' }
41378
41408
  '404': { $ref: '#/components/responses/NotFound' }
41379
- '501': { description: "targeting or creative not supported on the platform (Meta + TikTok only)" }
41409
+ '501': { description: "targeting or creative not supported on the platform (supported on Meta, TikTok, and LinkedIn)" }
41380
41410
  '502': { description: "Meta accepted the request then failed to produce the media (upload session, chunk transfer, processing timeout, or a response with no image hash). Inspect `platformError.reason`." }
41381
41411
  delete:
41382
41412
  x-resource-group: "ads"
@@ -43665,6 +43695,11 @@ paths:
43665
43695
  (for example, an agency paying for a client's ads). Same rules as
43666
43696
  `dsaBeneficiary`: required for EU targeting unless the ad account has
43667
43697
  a default payor.
43698
+ leadGenFormId: { type: string, description: "Lead Gen form ID to attach to the boosted ad's creative. REQUIRED when `goal` is `lead_generation`. On Meta this is the leadgen_forms ID (create one via POST /v1/ads/lead-forms). On LinkedIn this is the adForm ID (create one via POST /v1/ads/lead-forms with a LinkedIn account); the creative's `leadgenCallToAction.destination` is set to `urn:li:adForm:{id}`. Ignored for other goals." }
43699
+ status:
43700
+ type: string
43701
+ enum: [ACTIVE, PAUSED]
43702
+ description: 'Meta, TikTok, and LinkedIn. Publish state of the created entities. Omitted or ACTIVE publishes live (default); PAUSED creates them paused so you can review before they spend. On LinkedIn the whole campaign group, campaign, and creative hierarchy stays PAUSED (intendedStatus PAUSED on each).'
43668
43703
  optimizationGoal:
43669
43704
  type: string
43670
43705
  description: |
@@ -43791,8 +43826,9 @@ paths:
43791
43826
 
43792
43827
  **LinkedIn**
43793
43828
  - `engagement`, `traffic`, `awareness` and `video_views` create standalone Direct Sponsored Content ads. `traffic` requires `linkUrl`; `video_views` requires `video`.
43829
+ - `lead_generation`: requires `leadGenFormId` (an adForm ID from POST /v1/ads/lead-forms). The campaign objective is set to MAX_LEAD and the creative's `leadgenCallToAction` destination is set to `urn:li:adForm:{id}`.
43794
43830
  - `job_applicants` requires a `platformSpecificData.jobs` creative.
43795
- - For `lead_generation` or `conversions` on LinkedIn, or to promote an existing post, use POST /v1/ads/boost.
43831
+ - For `conversions` on LinkedIn, or to promote an existing post, use POST /v1/ads/boost.
43796
43832
 
43797
43833
  **OpenAI Ads**
43798
43834
  - Only `traffic`, `awareness`, and `conversions` are supported (other goals return 400). Maps to OpenAI's `bidding_type` (clicks, impressions, conversions respectively). `conversions` requires an active conversion event setting on the account; create a tracking tag with `defaultEventType` via the tracking-tags API (`POST /v1/accounts/{accountId}/tracking-tags`), or configure a conversion event in OpenAI Ads Manager, or the request returns 422.
@@ -43816,7 +43852,7 @@ paths:
43816
43852
  status:
43817
43853
  type: string
43818
43854
  enum: [ACTIVE, PAUSED]
43819
- description: "Meta and TikTok. Publish state of the created entities. Omitted or ACTIVE publishes live (default, back-compat); PAUSED creates them paused so you can review before they spend. On Meta the pause is held on the campaign this call creates, leaving the ad set and ad switched on, so a single PUT /v1/ads/campaigns/{campaignId}/status with `active` brings the whole thing live. It is held at every level instead when the pause cannot rely on the campaign: `existingCampaignId` (that campaign may be running and is never touched) or `campaignStatus: ACTIVE`. On TikTok the whole campaign > ad group > ad hierarchy stays paused."
43855
+ description: "Meta, TikTok, and LinkedIn. Publish state of the created entities. Omitted or ACTIVE publishes live (default, back-compat); PAUSED creates them paused so you can review before they spend. On Meta the pause is held on the campaign this call creates, leaving the ad set and ad switched on, so a single PUT /v1/ads/campaigns/{campaignId}/status with `active` brings the whole thing live. It is held at every level instead when the pause cannot rely on the campaign: `existingCampaignId` (that campaign may be running and is never touched) or `campaignStatus: ACTIVE`. On TikTok the whole campaign > ad group > ad hierarchy stays paused. On LinkedIn the whole campaign group, campaign, and creative hierarchy stays PAUSED (intendedStatus PAUSED on each)."
43820
43856
  campaignStatus:
43821
43857
  type: string
43822
43858
  enum: [ACTIVE, PAUSED]
@@ -43841,7 +43877,7 @@ paths:
43841
43877
  description: { type: string, maxLength: 255, description: "Meta only (facebook/instagram). Link description — the secondary text shown below the headline (Meta's link_data.description; on video creatives mapped to video_data.link_description). When omitted, Meta auto-pulls the destination URL's OpenGraph description. Applies on legacy, attach, and placementAssets shapes; for multi-creative use creatives[].description (this field is the shared fallback). For multi-text variations use dynamicCreative.descriptions instead." }
43842
43878
  callToAction: { type: string, enum: [LEARN_MORE, SHOP_NOW, SIGN_UP, BOOK_TRAVEL, CONTACT_US, DOWNLOAD, GET_OFFER, GET_QUOTE, SUBSCRIBE, WATCH_MORE, ADD_TO_CART, APPLY_NOW, BOOK_NOW, BUY_TICKETS, DONATE, DONATE_NOW, GET_DIRECTIONS, GET_SHOWTIMES, LISTEN_NOW, ORDER_NOW, PLAY_GAME, REQUEST_TIME, SEE_MENU, START_ORDER, INSTALL_MOBILE_APP, USE_APP, REGISTER, JOIN, ATTEND, REQUEST_DEMO, VIEW_QUOTE, APPLY, SEE_MORE, BUY_NOW], description: "Required on legacy + attach shapes for Meta. Honoured on TikTok (passes through to the Spark Ad creative's `call_to_action`) and on LinkedIn (the CTA button on the ad; defaults to LEARN_MORE when `linkUrl` is set). LinkedIn accepts: LEARN_MORE, SIGN_UP, DOWNLOAD, SUBSCRIBE, REGISTER, JOIN, ATTEND, REQUEST_DEMO, VIEW_QUOTE, APPLY, SEE_MORE, SHOP_NOW, BUY_NOW. Ignored by Google, Pinterest, and X/Twitter." }
43843
43879
  linkUrl: { type: string, format: uri, description: "Required on legacy + attach shapes (skip for multi-creative). On LinkedIn it's the ad's destination URL; required for `traffic` ads, optional for `engagement` / `awareness`. NOT required when `goal` is `lead_generation` (the ad opens a Lead Gen form instead of a destination). On LinkedIn, `imageUrl` + `linkUrl` publishes an ARTICLE-content creative; this is LinkedIn's article ad format, with the image as thumbnail and `longHeadline` as description. Required for OpenAI Ads (the chat card's target_url)." }
43844
- leadGenFormId: { type: string, description: "Meta Lead Gen forms only (facebook/instagram). The leadgen_forms ID to attach to the ad's creative — create one via POST /v1/ads/lead-forms. REQUIRED when `goal` is `lead_generation`, and on every ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Ignored otherwise. The ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on instant-form lead ads — the form is attached for you, and for `dynamicCreative` the ad set is created as a Dynamic Creative ad set automatically (Meta requires that for any multi-text feed; there is no non-DCO multi-text path). Send a single `imageUrls` (or `videoUrls`) entry plus your text variations to get Meta's \"Multiple Text Options\" behavior on a lead ad." }
43880
+ leadGenFormId: { type: string, description: "Lead Gen form ID to attach to the ad's creative. REQUIRED when `goal` is `lead_generation`. Create one via POST /v1/ads/lead-forms. On Meta (facebook/instagram) this is the leadgen_forms ID; the ad set's promoted_object.page_id + LEAD_GENERATION optimization + destination_type ON_AD are derived automatically from the goal. On LinkedIn this is the adForm ID; the creative's `leadgenCallToAction.destination` is set to `urn:li:adForm:{id}` and the campaign objective is set to MAX_LEAD. Forms must be owned by the sponsoredAccount (not the organization) for the URN to resolve. Also required on every Meta ATTACH (`adSetId`) call that targets a lead ad set (the form attaches per-ad; Meta rejects a formless ad in a lead ad set). Both `placementAssets` (per-placement creative) and `dynamicCreative` (multi-text / multi-asset pool, e.g. multiple headlines and primary texts) ARE supported on Meta instant-form lead ads." }
43845
43881
  imageUrl: { type: string, format: uri, description: "Image creative for Meta/Google/Pinterest/LinkedIn on legacy + attach shapes (mutually exclusive with `video`). Required for LinkedIn ads unless `video` is set. Not required for Google Search campaigns. For TikTok, this field carries the VIDEO URL (the TikTok ads endpoint is video-only; the field retains the `imageUrl` name for cross-platform consistency). Ignored for X/Twitter. For Google Display, treated as the landscape image (alias of `images.landscape`); supply `images.square` alongside or the request is rejected. For LinkedIn the image is uploaded to LinkedIn under the authoring Company Page (see `organizationId`); recommended ratio 1.91:1 (e.g. 1200×627). Required for OpenAI Ads (uploaded as the chat card's image; OpenAI has no video ad format)." }
43846
43882
  images:
43847
43883
  type: object
@@ -320,7 +320,7 @@ describe 'AdCampaignsApi' do
320
320
 
321
321
  # unit tests for update_ad
322
322
  # Update ad
323
- # 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 &#x60;/v2/adgroup/update/&#x60;), and creative (via &#x60;/v2/ad/update/&#x60; patch-style — &#x60;headline&#x60; is ignored, &#x60;body&#x60; becomes &#x60;ad_text&#x60;). - **Google**: status, budget, and KEYWORD edits via &#x60;targeting.keywords&#x60; / &#x60;targeting.negativeKeywords&#x60; — 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 &#x60;targeting&#x60; field returns 400: Google cannot mutate broad targeting post-create without recreating the campaign. &#x60;creative&#x60; returns 501. - **Pinterest / X / LinkedIn / OpenAI Ads**: status + budget only. Sending &#x60;targeting&#x60; or &#x60;creative&#x60; returns 501 with code &#x60;unsupported_platform_operation&#x60;. OpenAI Ads budget is lifetime-only (see &#x60;budget.type&#x60; below).
323
+ # 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 &#x60;/v2/adgroup/update/&#x60;), and creative (via &#x60;/v2/ad/update/&#x60; patch-style — &#x60;headline&#x60; is ignored, &#x60;body&#x60; becomes &#x60;ad_text&#x60;). - **Google**: status, budget, and KEYWORD edits via &#x60;targeting.keywords&#x60; / &#x60;targeting.negativeKeywords&#x60; — 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 &#x60;targeting&#x60; field returns 400: Google cannot mutate broad targeting post-create without recreating the campaign. &#x60;creative&#x60; 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 &#x60;targeting&#x60; or &#x60;creative&#x60; returns 501 with code &#x60;unsupported_platform_operation&#x60;. OpenAI Ads budget is lifetime-only (see &#x60;budget.type&#x60; below).
324
324
  # @param ad_id
325
325
  # @param update_ad_request
326
326
  # @param [Hash] opts the optional parameters
@@ -34,7 +34,7 @@ describe 'PostsApi' do
34
34
 
35
35
  # unit tests for bulk_upload_posts
36
36
  # Bulk upload from CSV
37
- # Create multiple posts by uploading a CSV file. Use dryRun&#x3D;true to validate without creating posts.
37
+ # Create multiple posts by uploading a CSV file. Use dryRun&#x3D;true to validate without creating posts. CSV columns: - Required: &#x60;platforms&#x60;, &#x60;profiles&#x60;, and a schedule (one of &#x60;schedule_time&#x60;, a &#x60;schedule_time_&lt;platform&gt;&#x60; override, &#x60;publish_now&#x3D;true&#x60;, &#x60;use_queue&#x3D;true&#x60;, or &#x60;is_draft&#x3D;true&#x60;). - Content: at least one of &#x60;post_content&#x60;, &#x60;title&#x60;, or &#x60;media_urls&#x60; is required. - Aliases: a handful of columns accept the JSON field name from POST /v1/posts, since integrators infer the CSV shape from that endpoint&#39;s body. When both are present the real CSV column wins, unless it is blank for that row, in which case the alias value is used. - &#x60;content&#x60; aliases &#x60;post_content&#x60; - &#x60;timezone&#x60; aliases &#x60;tz&#x60; - &#x60;scheduledFor&#x60; aliases &#x60;schedule_time&#x60; - &#x60;mediaUrls&#x60; aliases &#x60;media_urls&#x60; - Per-platform overrides use three dynamic column prefixes, one column per platform (e.g. &#x60;schedule_time_instagram&#x60;, &#x60;custom_content_tiktok&#x60;, &#x60;custom_media_youtube&#x60;): &#x60;schedule_time_&lt;platform&gt;&#x60;, &#x60;custom_content_&lt;platform&gt;&#x60;, &#x60;custom_media_&lt;platform&gt;&#x60;. - Any other column is not read. It does not error, but it is reported in the response&#39;s &#x60;warnings&#x60; array as &#x60;unknown_columns:&lt;a,b,c&gt;&#x60; (see BulkUploadResult), so a misnamed or unsupported column is never silently dropped. - Row limits: 5000 rows is a hard cap that returns 400 above it. 500 rows is only an advisory threshold, it adds &#x60;rows_exceed_advisory_limit:500&#x60; to &#x60;warnings&#x60; and the request still processes. Example row (header + one data row): &#x60;&#x60;&#x60; post_content,platforms,profiles,schedule_time,tz \&quot;Hello world\&quot;,instagram,MyProfile,2026-09-01 10:00,America/New_York &#x60;&#x60;&#x60;
38
38
  # @param [Hash] opts the optional parameters
39
39
  # @option opts [Boolean] :dry_run
40
40
  # @option opts [File] :file
@@ -195,6 +195,22 @@ describe Zernio::BoostPostRequest do
195
195
  end
196
196
  end
197
197
 
198
+ describe 'test attribute "lead_gen_form_id"' do
199
+ it 'should work' do
200
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
201
+ end
202
+ end
203
+
204
+ describe 'test attribute "status"' do
205
+ it 'should work' do
206
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
207
+ # validator = Petstore::EnumTest::EnumAttributeValidator.new('String', ["ACTIVE", "PAUSED"])
208
+ # validator.allowable_values.each do |value|
209
+ # expect { instance.status = value }.not_to raise_error
210
+ # end
211
+ end
212
+ end
213
+
198
214
  describe 'test attribute "optimization_goal"' do
199
215
  it 'should work' do
200
216
  # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
@@ -39,4 +39,10 @@ describe Zernio::PostCreateResponse do
39
39
  end
40
40
  end
41
41
 
42
+ describe 'test attribute "warnings"' do
43
+ it 'should work' do
44
+ # assertion here. ref: https://rspec.info/features/3-12/rspec-expectations/built-in-matchers/
45
+ end
46
+ end
47
+
42
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zernio-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.804
4
+ version: 0.0.806
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenAPI-Generator