@zernio/node 0.2.762 → 0.2.764

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.
package/dist/index.d.mts CHANGED
@@ -8463,7 +8463,7 @@ type TikTokPlatformData = {
8463
8463
  */
8464
8464
  videoCoverTimestampMs?: number;
8465
8465
  /**
8466
- * Optional for video posts. URL of a custom thumbnail image (JPG, PNG, or WebP, max 20MB). The image is stitched as a single frame at the start of the video and used as the cover. Accounts connected through the TikTok for Business app instead pass the URL to TikTok as the cover directly, with no stitching, and the URL must resolve on a domain we have verified with TikTok. Overrides videoCoverTimestampMs when provided.
8466
+ * Optional for video posts. URL of a custom thumbnail image (JPG, PNG, or WebP, max 20MB). Any downloadable URL works: we rehost it ourselves. The image is stitched as a single frame at the start of the video to serve as the cover. Accounts connected through the TikTok for Business app hand it to TikTok as the cover instead, with no stitching, falling back to videoCoverTimestampMs without it. Overrides videoCoverTimestampMs when provided.
8467
8467
  */
8468
8468
  videoCoverImageUrl?: string;
8469
8469
  /**
@@ -14117,7 +14117,7 @@ type CreatePostData = {
14117
14117
  */
14118
14118
  isDraft?: boolean;
14119
14119
  /**
14120
- * TikTok only. Preview whether each `tiktok` entry in `platforms` could publish right now under the TikTok Direct Post daily limits, without creating, scheduling or publishing anything: no post is persisted and no upload slot is claimed, so it can be repeated freely. The request still goes through auth, the payment gate and body validation, then returns HTTP 200 with `{ dryRun: true, canPublish, tiktok: [...] }` instead of 201. Only `tiktok` entries are evaluated; other platforms in the body are ignored, and a body with no `tiktok` entry is rejected with 400 `invalid_field_value` on `platforms`. An entry with `platformSpecificData.tiktokSettings.draft: true` (Creator Inbox upload) is not subject to the limit and always reports `canPublish: true`.
14120
+ * TikTok only. Preview whether each `tiktok` entry in `platforms` could publish right now under the TikTok Direct Post daily limits, without creating, scheduling or publishing anything: no post is persisted and no upload slot is claimed, so it can be repeated freely. The request still goes through auth, the payment gate and body validation, then returns HTTP 200 with `{ dryRun: true, canPublish, tiktok: [...] }` instead of 201. Only `tiktok` entries are evaluated; other platforms in the body are ignored, and a body with no `tiktok` entry is rejected with 400 `invalid_field_value` on `platforms`. An entry with `platformSpecificData.tiktokSettings.draft: true` (Creator Inbox upload) is not subject to the limit and always reports `canPublish: true`. Accounts connected through the TikTok for Business app do not go through these limits at all and also always report `canPublish: true`, so on those accounts a dry run confirms the request is well-formed rather than gating it.
14121
14121
  */
14122
14122
  dryRun?: boolean;
14123
14123
  /**
@@ -15497,8 +15497,8 @@ type GetConnectUrlData = {
15497
15497
  * OAuth and callback:
15498
15498
  * oauth_denied, invalid_callback, invalid_state, unsupported_platform, connection_failed,
15499
15499
  * internal_error, token_exchange_failed, byok_config_error, personal_account_not_supported,
15500
- * missing_google_permissions, platform_requires_destination, reconnect_account_mismatch,
15501
- * invalid_request
15500
+ * missing_google_permissions, missing_tiktok_permissions, platform_requires_destination,
15501
+ * reconnect_account_mismatch, invalid_request
15502
15502
  *
15503
15503
  * Access and limits:
15504
15504
  * profile_not_found, invalid_profile_id, access_denied, account_limit_exceeded,
@@ -15539,6 +15539,10 @@ type GetConnectUrlData = {
15539
15539
  * (`tiktokads`, `xads`), not the value used in the request path. The googleads and shopify
15540
15540
  * flows report `googleads` and `shopify`.
15541
15541
  *
15542
+ * 3. `missing_tiktok_permissions` means the TikTok authorization left out a permission the
15543
+ * already-connected account needs, so nothing was changed and it keeps working as before.
15544
+ * It is user-fixable: connect again and accept every permission on TikTok's screen.
15545
+ *
15542
15546
  */
15543
15547
  redirect_url?: string;
15544
15548
  /**
@@ -32722,7 +32726,7 @@ type GetCampaignTargetingResponse = ({
32722
32726
  device?: 'MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV';
32723
32727
  included?: boolean;
32724
32728
  /**
32725
- * Always null on this read (see description).
32729
+ * Google's bid adjustment for this device: null when it has none, 0 when the device is switched off, otherwise 0.1 to 10.
32726
32730
  */
32727
32731
  bidModifier?: (number) | null;
32728
32732
  }>;
@@ -33485,12 +33489,12 @@ type UpdateAdData = {
33485
33489
  matchType?: 'exact' | 'phrase' | 'broad';
33486
33490
  })>;
33487
33491
  /**
33488
- * Google only. The FULL new set of device criteria for the campaign; devices not listed are excluded. Entries are a device name alone (included, no bid adjustment) or { device, bidModifier }.
33492
+ * Google only. The FULL new set of device bid modifiers for the campaign. Entries are a device name alone (targeted, bid modifier reset to 1) or { device, bidModifier }. A supported device you leave out is switched off, written as a bid modifier of 0. Google never removes a device criterion, so an excluded device reads back as bidModifier 0 rather than disappearing, and a set that switches every device off returns 422. Which devices a campaign carries depends on its channel: Search campaigns have MOBILE, DESKTOP and TABLET, Display campaigns also have CONNECTED_TV, and sending a device the campaign does not carry returns 422.
33489
33493
  */
33490
33494
  devices?: Array<('MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV' | {
33491
33495
  device: 'MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV';
33492
33496
  /**
33493
- * Google device bid modifier, 0.1 to 10 (minus 90% to plus 900%). Omit a device to exclude it.
33497
+ * Google device bid modifier. 0 switches the device off (minus 100%); otherwise 0.1 to 10 (minus 90% to plus 900%). Google rejects any value between 0 and 0.1.
33494
33498
  */
33495
33499
  bidModifier?: number;
33496
33500
  })>;
@@ -36795,11 +36799,11 @@ type CreateStandaloneAdData = {
36795
36799
  */
36796
36800
  budgetType?: 'daily' | 'lifetime';
36797
36801
  /**
36798
- * Google Performance Max accepts PAUSED only and always creates a paused campaign. 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).
36802
+ * Google Performance Max accepts PAUSED only and always creates a paused campaign. Google Search and Display, 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`. Google Search and Display follow the same rule, and because Google keeps an independent switch at campaign, ad group and ad level, a PAUSED create leaves the campaign it creates PAUSED at Google. 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).
36799
36803
  */
36800
36804
  status?: 'ACTIVE' | 'PAUSED';
36801
36805
  /**
36802
- * 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`.
36806
+ * Meta and Google. 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`.
36803
36807
  */
36804
36808
  campaignStatus?: 'ACTIVE' | 'PAUSED';
36805
36809
  /**
@@ -37802,7 +37806,7 @@ type CreateStandaloneAdResponse = ({
37802
37806
  node?: 'campaign' | 'adSet' | 'creative' | 'ad' | 'performanceMaxCampaign';
37803
37807
  status?: 'validated' | 'skipped';
37804
37808
  /**
37805
- * Why the node could not be validated (only on skipped).
37809
+ * Why the node could not be validated (on skipped), or what the dry run could not check and what the request would do as sent (on validated). A Performance Max validation with no location targeting reports here that the campaign would run worldwide.
37806
37810
  */
37807
37811
  reason?: string;
37808
37812
  }>;
package/dist/index.d.ts CHANGED
@@ -8463,7 +8463,7 @@ type TikTokPlatformData = {
8463
8463
  */
8464
8464
  videoCoverTimestampMs?: number;
8465
8465
  /**
8466
- * Optional for video posts. URL of a custom thumbnail image (JPG, PNG, or WebP, max 20MB). The image is stitched as a single frame at the start of the video and used as the cover. Accounts connected through the TikTok for Business app instead pass the URL to TikTok as the cover directly, with no stitching, and the URL must resolve on a domain we have verified with TikTok. Overrides videoCoverTimestampMs when provided.
8466
+ * Optional for video posts. URL of a custom thumbnail image (JPG, PNG, or WebP, max 20MB). Any downloadable URL works: we rehost it ourselves. The image is stitched as a single frame at the start of the video to serve as the cover. Accounts connected through the TikTok for Business app hand it to TikTok as the cover instead, with no stitching, falling back to videoCoverTimestampMs without it. Overrides videoCoverTimestampMs when provided.
8467
8467
  */
8468
8468
  videoCoverImageUrl?: string;
8469
8469
  /**
@@ -14117,7 +14117,7 @@ type CreatePostData = {
14117
14117
  */
14118
14118
  isDraft?: boolean;
14119
14119
  /**
14120
- * TikTok only. Preview whether each `tiktok` entry in `platforms` could publish right now under the TikTok Direct Post daily limits, without creating, scheduling or publishing anything: no post is persisted and no upload slot is claimed, so it can be repeated freely. The request still goes through auth, the payment gate and body validation, then returns HTTP 200 with `{ dryRun: true, canPublish, tiktok: [...] }` instead of 201. Only `tiktok` entries are evaluated; other platforms in the body are ignored, and a body with no `tiktok` entry is rejected with 400 `invalid_field_value` on `platforms`. An entry with `platformSpecificData.tiktokSettings.draft: true` (Creator Inbox upload) is not subject to the limit and always reports `canPublish: true`.
14120
+ * TikTok only. Preview whether each `tiktok` entry in `platforms` could publish right now under the TikTok Direct Post daily limits, without creating, scheduling or publishing anything: no post is persisted and no upload slot is claimed, so it can be repeated freely. The request still goes through auth, the payment gate and body validation, then returns HTTP 200 with `{ dryRun: true, canPublish, tiktok: [...] }` instead of 201. Only `tiktok` entries are evaluated; other platforms in the body are ignored, and a body with no `tiktok` entry is rejected with 400 `invalid_field_value` on `platforms`. An entry with `platformSpecificData.tiktokSettings.draft: true` (Creator Inbox upload) is not subject to the limit and always reports `canPublish: true`. Accounts connected through the TikTok for Business app do not go through these limits at all and also always report `canPublish: true`, so on those accounts a dry run confirms the request is well-formed rather than gating it.
14121
14121
  */
14122
14122
  dryRun?: boolean;
14123
14123
  /**
@@ -15497,8 +15497,8 @@ type GetConnectUrlData = {
15497
15497
  * OAuth and callback:
15498
15498
  * oauth_denied, invalid_callback, invalid_state, unsupported_platform, connection_failed,
15499
15499
  * internal_error, token_exchange_failed, byok_config_error, personal_account_not_supported,
15500
- * missing_google_permissions, platform_requires_destination, reconnect_account_mismatch,
15501
- * invalid_request
15500
+ * missing_google_permissions, missing_tiktok_permissions, platform_requires_destination,
15501
+ * reconnect_account_mismatch, invalid_request
15502
15502
  *
15503
15503
  * Access and limits:
15504
15504
  * profile_not_found, invalid_profile_id, access_denied, account_limit_exceeded,
@@ -15539,6 +15539,10 @@ type GetConnectUrlData = {
15539
15539
  * (`tiktokads`, `xads`), not the value used in the request path. The googleads and shopify
15540
15540
  * flows report `googleads` and `shopify`.
15541
15541
  *
15542
+ * 3. `missing_tiktok_permissions` means the TikTok authorization left out a permission the
15543
+ * already-connected account needs, so nothing was changed and it keeps working as before.
15544
+ * It is user-fixable: connect again and accept every permission on TikTok's screen.
15545
+ *
15542
15546
  */
15543
15547
  redirect_url?: string;
15544
15548
  /**
@@ -32722,7 +32726,7 @@ type GetCampaignTargetingResponse = ({
32722
32726
  device?: 'MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV';
32723
32727
  included?: boolean;
32724
32728
  /**
32725
- * Always null on this read (see description).
32729
+ * Google's bid adjustment for this device: null when it has none, 0 when the device is switched off, otherwise 0.1 to 10.
32726
32730
  */
32727
32731
  bidModifier?: (number) | null;
32728
32732
  }>;
@@ -33485,12 +33489,12 @@ type UpdateAdData = {
33485
33489
  matchType?: 'exact' | 'phrase' | 'broad';
33486
33490
  })>;
33487
33491
  /**
33488
- * Google only. The FULL new set of device criteria for the campaign; devices not listed are excluded. Entries are a device name alone (included, no bid adjustment) or { device, bidModifier }.
33492
+ * Google only. The FULL new set of device bid modifiers for the campaign. Entries are a device name alone (targeted, bid modifier reset to 1) or { device, bidModifier }. A supported device you leave out is switched off, written as a bid modifier of 0. Google never removes a device criterion, so an excluded device reads back as bidModifier 0 rather than disappearing, and a set that switches every device off returns 422. Which devices a campaign carries depends on its channel: Search campaigns have MOBILE, DESKTOP and TABLET, Display campaigns also have CONNECTED_TV, and sending a device the campaign does not carry returns 422.
33489
33493
  */
33490
33494
  devices?: Array<('MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV' | {
33491
33495
  device: 'MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV';
33492
33496
  /**
33493
- * Google device bid modifier, 0.1 to 10 (minus 90% to plus 900%). Omit a device to exclude it.
33497
+ * Google device bid modifier. 0 switches the device off (minus 100%); otherwise 0.1 to 10 (minus 90% to plus 900%). Google rejects any value between 0 and 0.1.
33494
33498
  */
33495
33499
  bidModifier?: number;
33496
33500
  })>;
@@ -36795,11 +36799,11 @@ type CreateStandaloneAdData = {
36795
36799
  */
36796
36800
  budgetType?: 'daily' | 'lifetime';
36797
36801
  /**
36798
- * Google Performance Max accepts PAUSED only and always creates a paused campaign. 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).
36802
+ * Google Performance Max accepts PAUSED only and always creates a paused campaign. Google Search and Display, 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`. Google Search and Display follow the same rule, and because Google keeps an independent switch at campaign, ad group and ad level, a PAUSED create leaves the campaign it creates PAUSED at Google. 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).
36799
36803
  */
36800
36804
  status?: 'ACTIVE' | 'PAUSED';
36801
36805
  /**
36802
- * 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`.
36806
+ * Meta and Google. 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`.
36803
36807
  */
36804
36808
  campaignStatus?: 'ACTIVE' | 'PAUSED';
36805
36809
  /**
@@ -37802,7 +37806,7 @@ type CreateStandaloneAdResponse = ({
37802
37806
  node?: 'campaign' | 'adSet' | 'creative' | 'ad' | 'performanceMaxCampaign';
37803
37807
  status?: 'validated' | 'skipped';
37804
37808
  /**
37805
- * Why the node could not be validated (only on skipped).
37809
+ * Why the node could not be validated (on skipped), or what the dry run could not check and what the request would do as sent (on validated). A Performance Max validation with no location targeting reports here that the campaign would run worldwide.
37806
37810
  */
37807
37811
  reason?: string;
37808
37812
  }>;
package/dist/index.js CHANGED
@@ -36,7 +36,7 @@ module.exports = __toCommonJS(index_exports);
36
36
  // package.json
37
37
  var package_default = {
38
38
  name: "@zernio/node",
39
- version: "0.2.762",
39
+ version: "0.2.764",
40
40
  description: "The official Node.js library for the Zernio API",
41
41
  main: "dist/index.js",
42
42
  module: "dist/index.mjs",
package/dist/index.mjs CHANGED
@@ -5,7 +5,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
5
5
  // package.json
6
6
  var package_default = {
7
7
  name: "@zernio/node",
8
- version: "0.2.762",
8
+ version: "0.2.764",
9
9
  description: "The official Node.js library for the Zernio API",
10
10
  main: "dist/index.js",
11
11
  module: "dist/index.mjs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zernio/node",
3
- "version": "0.2.762",
3
+ "version": "0.2.764",
4
4
  "description": "The official Node.js library for the Zernio API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -1567,6 +1567,15 @@ export const createInviteToken = <ThrowOnError extends boolean = false>(options:
1567
1567
  * Initiate an OAuth connection flow. Returns an authUrl to redirect the user to.
1568
1568
  * Standard flow: Zernio hosts the selection UI, then redirects to your redirect_url. Headless mode (headless=true): user is redirected to your redirect_url with OAuth data for custom UI. Use the platform-specific selection endpoints to complete.
1569
1569
  *
1570
+ * TikTok: every connection now goes through the TikTok for Business app. One TikTok account per
1571
+ * profile, so connecting on a profile that already holds one replaces it. Reconnecting the SAME
1572
+ * account keeps it and all of its history; authorizing a DIFFERENT TikTok account takes the slot
1573
+ * over and permanently deletes the previous account's analytics, inbox and DM history. The two
1574
+ * are told apart by the `@handle` stored at the last connect, so an account whose handle has
1575
+ * been renamed on TikTok since then reads as a different account. An authorization that leaves
1576
+ * out a permission the connected account needs changes nothing at all and comes back as
1577
+ * `missing_tiktok_permissions`; connect again and accept every permission on TikTok's screen.
1578
+ *
1570
1579
  */
1571
1580
  export const getConnectUrl = <ThrowOnError extends boolean = false>(options: OptionsLegacyParser<GetConnectUrlData, ThrowOnError>) => {
1572
1581
  return (options?.client ?? client).get<GetConnectUrlResponse, GetConnectUrlError, ThrowOnError>({
@@ -8177,6 +8186,12 @@ export const createAdCampaign = <ThrowOnError extends boolean = false>(options:
8177
8186
  * On Meta this flips the campaign only. An ad set paused in its own right stays paused, so pair this with
8178
8187
  * PUT /v1/ads/ad-sets/{adSetId}/status when you also need the ad set switched back on.
8179
8188
  *
8189
+ * Google keeps an independent on/off switch at campaign, ad group and ad level and the most restrictive
8190
+ * one wins, so `active` switches the campaign on TOGETHER with the ad groups and ads Zernio tracks under
8191
+ * it, in one mutate. Without that the campaign reads ENABLED while a paused ad group or ad keeps it from
8192
+ * serving. `paused` writes the campaign alone, which already stops delivery and leaves each ad's own
8193
+ * switch as you set it.
8194
+ *
8180
8195
  */
8181
8196
  export const updateAdCampaignStatus = <ThrowOnError extends boolean = false>(options: OptionsLegacyParser<UpdateAdCampaignStatusData, ThrowOnError>) => {
8182
8197
  return (options?.client ?? client).put<UpdateAdCampaignStatusResponse, UpdateAdCampaignStatusError, ThrowOnError>({
@@ -8374,10 +8389,11 @@ export const duplicateAdCampaign = <ThrowOnError extends boolean = false>(option
8374
8389
  * (10 minutes fresh, up to 7 days last-good), not always a live read. Google
8375
8390
  * only; every other platform returns 501.
8376
8391
  *
8377
- * `devices` always lists all four device types with `included` reflecting
8378
- * Google's negative device criteria (a device absent from any negative
8379
- * criterion is included by default). This read has no bid-modifier source,
8380
- * so `bidModifier` is always `null` even for a device with one configured.
8392
+ * `devices` lists the device criteria the campaign carries, which depends on
8393
+ * its channel: Search campaigns have MOBILE, DESKTOP and TABLET, Display
8394
+ * campaigns also have CONNECTED_TV. `bidModifier` is Google's bid adjustment
8395
+ * for that device, `null` when it has none, and `0` when the device is
8396
+ * switched off; `included` is false for exactly that case.
8381
8397
  *
8382
8398
  */
8383
8399
  export const getCampaignTargeting = <ThrowOnError extends boolean = false>(options: OptionsLegacyParser<GetCampaignTargetingData, ThrowOnError>) => {
@@ -8396,6 +8412,11 @@ export const getCampaignTargeting = <ThrowOnError extends boolean = false>(optio
8396
8412
  * out of the body are untouched. Google only; every other platform returns
8397
8413
  * 501.
8398
8414
  *
8415
+ * `devices` is the full set of device bid modifiers: a supported device you
8416
+ * leave out is switched off with a bid modifier of 0, since Google cannot
8417
+ * remove a device criterion. A device the campaign's channel does not carry,
8418
+ * and a set that switches every device off, both return 422.
8419
+ *
8399
8420
  * `locations` accepts the same shapes as campaign creation: a bare array of
8400
8421
  * ISO country codes, or an object with `countries`/`regions`/`cities`/`zips`/`metros`
8401
8422
  * key lists (`key` from GET /v1/ads/targeting/search?dimension=geo). Negative
@@ -8699,7 +8720,9 @@ export const getAd = <ThrowOnError extends boolean = false>(options: OptionsLega
8699
8720
  * `targeting.countries` / `regions` / `cities` / `zips` / `metros`), and LANGUAGE
8700
8721
  * edits via `targeting.languages`.
8701
8722
  * Each list you send becomes the FULL new set of its kind (criteria not in the
8702
- * list are removed); a kind left out is untouched. Any other `targeting` field
8723
+ * list are removed, except devices, which Google cannot remove and which are
8724
+ * switched off with a bid modifier of 0 instead); a kind left out is untouched.
8725
+ * Any other `targeting` field
8703
8726
  * returns 400: Google cannot mutate it post-create without recreating
8704
8727
  * the campaign. Creative edits are dispatched on the ad's `advertisingChannelType`,
8705
8728
  * and every supported field replaces a whole set; a field you omit is preserved.
@@ -7160,7 +7160,7 @@ export type TikTokPlatformData = {
7160
7160
  */
7161
7161
  videoCoverTimestampMs?: number;
7162
7162
  /**
7163
- * Optional for video posts. URL of a custom thumbnail image (JPG, PNG, or WebP, max 20MB). The image is stitched as a single frame at the start of the video and used as the cover. Accounts connected through the TikTok for Business app instead pass the URL to TikTok as the cover directly, with no stitching, and the URL must resolve on a domain we have verified with TikTok. Overrides videoCoverTimestampMs when provided.
7163
+ * Optional for video posts. URL of a custom thumbnail image (JPG, PNG, or WebP, max 20MB). Any downloadable URL works: we rehost it ourselves. The image is stitched as a single frame at the start of the video to serve as the cover. Accounts connected through the TikTok for Business app hand it to TikTok as the cover instead, with no stitching, falling back to videoCoverTimestampMs without it. Overrides videoCoverTimestampMs when provided.
7164
7164
  */
7165
7165
  videoCoverImageUrl?: string;
7166
7166
  /**
@@ -13106,7 +13106,7 @@ export type CreatePostData = {
13106
13106
  */
13107
13107
  isDraft?: boolean;
13108
13108
  /**
13109
- * TikTok only. Preview whether each `tiktok` entry in `platforms` could publish right now under the TikTok Direct Post daily limits, without creating, scheduling or publishing anything: no post is persisted and no upload slot is claimed, so it can be repeated freely. The request still goes through auth, the payment gate and body validation, then returns HTTP 200 with `{ dryRun: true, canPublish, tiktok: [...] }` instead of 201. Only `tiktok` entries are evaluated; other platforms in the body are ignored, and a body with no `tiktok` entry is rejected with 400 `invalid_field_value` on `platforms`. An entry with `platformSpecificData.tiktokSettings.draft: true` (Creator Inbox upload) is not subject to the limit and always reports `canPublish: true`.
13109
+ * TikTok only. Preview whether each `tiktok` entry in `platforms` could publish right now under the TikTok Direct Post daily limits, without creating, scheduling or publishing anything: no post is persisted and no upload slot is claimed, so it can be repeated freely. The request still goes through auth, the payment gate and body validation, then returns HTTP 200 with `{ dryRun: true, canPublish, tiktok: [...] }` instead of 201. Only `tiktok` entries are evaluated; other platforms in the body are ignored, and a body with no `tiktok` entry is rejected with 400 `invalid_field_value` on `platforms`. An entry with `platformSpecificData.tiktokSettings.draft: true` (Creator Inbox upload) is not subject to the limit and always reports `canPublish: true`. Accounts connected through the TikTok for Business app do not go through these limits at all and also always report `canPublish: true`, so on those accounts a dry run confirms the request is well-formed rather than gating it.
13110
13110
  */
13111
13111
  dryRun?: boolean;
13112
13112
  /**
@@ -14593,8 +14593,8 @@ export type GetConnectUrlData = {
14593
14593
  * OAuth and callback:
14594
14594
  * oauth_denied, invalid_callback, invalid_state, unsupported_platform, connection_failed,
14595
14595
  * internal_error, token_exchange_failed, byok_config_error, personal_account_not_supported,
14596
- * missing_google_permissions, platform_requires_destination, reconnect_account_mismatch,
14597
- * invalid_request
14596
+ * missing_google_permissions, missing_tiktok_permissions, platform_requires_destination,
14597
+ * reconnect_account_mismatch, invalid_request
14598
14598
  *
14599
14599
  * Access and limits:
14600
14600
  * profile_not_found, invalid_profile_id, access_denied, account_limit_exceeded,
@@ -14635,6 +14635,10 @@ export type GetConnectUrlData = {
14635
14635
  * (`tiktokads`, `xads`), not the value used in the request path. The googleads and shopify
14636
14636
  * flows report `googleads` and `shopify`.
14637
14637
  *
14638
+ * 3. `missing_tiktok_permissions` means the TikTok authorization left out a permission the
14639
+ * already-connected account needs, so nothing was changed and it keeps working as before.
14640
+ * It is user-fixable: connect again and accept every permission on TikTok's screen.
14641
+ *
14638
14642
  */
14639
14643
  redirect_url?: string;
14640
14644
  /**
@@ -33059,7 +33063,7 @@ export type GetCampaignTargetingResponse = ({
33059
33063
  device?: 'MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV';
33060
33064
  included?: boolean;
33061
33065
  /**
33062
- * Always null on this read (see description).
33066
+ * Google's bid adjustment for this device: null when it has none, 0 when the device is switched off, otherwise 0.1 to 10.
33063
33067
  */
33064
33068
  bidModifier?: (number) | null;
33065
33069
  }>;
@@ -33860,12 +33864,12 @@ export type UpdateAdData = {
33860
33864
  matchType?: 'exact' | 'phrase' | 'broad';
33861
33865
  })>;
33862
33866
  /**
33863
- * Google only. The FULL new set of device criteria for the campaign; devices not listed are excluded. Entries are a device name alone (included, no bid adjustment) or { device, bidModifier }.
33867
+ * Google only. The FULL new set of device bid modifiers for the campaign. Entries are a device name alone (targeted, bid modifier reset to 1) or { device, bidModifier }. A supported device you leave out is switched off, written as a bid modifier of 0. Google never removes a device criterion, so an excluded device reads back as bidModifier 0 rather than disappearing, and a set that switches every device off returns 422. Which devices a campaign carries depends on its channel: Search campaigns have MOBILE, DESKTOP and TABLET, Display campaigns also have CONNECTED_TV, and sending a device the campaign does not carry returns 422.
33864
33868
  */
33865
33869
  devices?: Array<('MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV' | {
33866
33870
  device: 'MOBILE' | 'DESKTOP' | 'TABLET' | 'CONNECTED_TV';
33867
33871
  /**
33868
- * Google device bid modifier, 0.1 to 10 (minus 90% to plus 900%). Omit a device to exclude it.
33872
+ * Google device bid modifier. 0 switches the device off (minus 100%); otherwise 0.1 to 10 (minus 90% to plus 900%). Google rejects any value between 0 and 0.1.
33869
33873
  */
33870
33874
  bidModifier?: number;
33871
33875
  })>;
@@ -37407,11 +37411,11 @@ export type CreateStandaloneAdData = {
37407
37411
  */
37408
37412
  budgetType?: 'daily' | 'lifetime';
37409
37413
  /**
37410
- * Google Performance Max accepts PAUSED only and always creates a paused campaign. 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).
37414
+ * Google Performance Max accepts PAUSED only and always creates a paused campaign. Google Search and Display, 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`. Google Search and Display follow the same rule, and because Google keeps an independent switch at campaign, ad group and ad level, a PAUSED create leaves the campaign it creates PAUSED at Google. 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).
37411
37415
  */
37412
37416
  status?: 'ACTIVE' | 'PAUSED';
37413
37417
  /**
37414
- * 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`.
37418
+ * Meta and Google. 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`.
37415
37419
  */
37416
37420
  campaignStatus?: 'ACTIVE' | 'PAUSED';
37417
37421
  /**
@@ -38415,7 +38419,7 @@ export type CreateStandaloneAdResponse = ({
38415
38419
  node?: 'campaign' | 'adSet' | 'creative' | 'ad' | 'performanceMaxCampaign';
38416
38420
  status?: 'validated' | 'skipped';
38417
38421
  /**
38418
- * Why the node could not be validated (only on skipped).
38422
+ * Why the node could not be validated (on skipped), or what the dry run could not check and what the request would do as sent (on validated). A Performance Max validation with no location targeting reports here that the campaign would run worldwide.
38419
38423
  */
38420
38424
  reason?: string;
38421
38425
  }>;