@getlatedev/node 0.2.1321 → 0.2.1323

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
@@ -46923,6 +46923,10 @@ type ListTikTokSmartPlusReviewsData = {
46923
46923
  * Also return Smart+ ads deleted on TikTok (listed with `primary_status: STATUS_ALL`).
46924
46924
  */
46925
46925
  includeDeleted?: boolean;
46926
+ /**
46927
+ * Freshness window in seconds. Reviews, refusals and the listing read within it are served without calling TikTok; older ones are still returned but read again, oldest first.
46928
+ */
46929
+ maxAgeSeconds?: number;
46926
46930
  page?: number;
46927
46931
  pageSize?: number;
46928
46932
  };
@@ -46930,6 +46934,10 @@ type ListTikTokSmartPlusReviewsData = {
46930
46934
  type ListTikTokSmartPlusReviewsResponse = ({
46931
46935
  adAccountId?: string;
46932
46936
  includeDeleted?: boolean;
46937
+ /**
46938
+ * The freshness window this page was read with.
46939
+ */
46940
+ maxAgeSeconds?: number;
46933
46941
  page?: number;
46934
46942
  pageSize?: number;
46935
46943
  totalPages?: number;
@@ -46937,6 +46945,58 @@ type ListTikTokSmartPlusReviewsResponse = ({
46937
46945
  * Smart+ ads of the advertiser across all pages.
46938
46946
  */
46939
46947
  totalSmartPlusAds?: number;
46948
+ /**
46949
+ * The Smart+ ad listing this page was cut from.
46950
+ */
46951
+ listing?: {
46952
+ /**
46953
+ * When the listing was read from TikTok.
46954
+ */
46955
+ readAt?: string;
46956
+ /**
46957
+ * `fresh`: read within `maxAgeSeconds`. `fallback`: relisting failed and this is the older stored listing.
46958
+ */
46959
+ source?: 'fresh' | 'fallback';
46960
+ /**
46961
+ * The relist error on a fallback, otherwise null.
46962
+ */
46963
+ error?: {
46964
+ tiktokCode?: (number) | null;
46965
+ message?: string;
46966
+ } | null;
46967
+ };
46968
+ /**
46969
+ * Set when TikTok refused both halves of a review batch the same way (for example a permission error) and the page was served from stored reviews instead of being refreshed. Null otherwise.
46970
+ */
46971
+ reviewError?: {
46972
+ tiktokCode?: (number) | null;
46973
+ message?: string;
46974
+ } | null;
46975
+ /**
46976
+ * The Smart+ ads on this page split by state; the four counts add up to the Smart+ ads on this page (fewer than `pageSize` on the last page).
46977
+ */
46978
+ counts?: {
46979
+ /**
46980
+ * Items read within `maxAgeSeconds`.
46981
+ */
46982
+ fresh?: number;
46983
+ /**
46984
+ * Items read earlier, returned with their `readAt` and due for a refresh.
46985
+ */
46986
+ stale?: number;
46987
+ /**
46988
+ * Smart+ ads never read (`pendingSmartPlusAdIds`).
46989
+ */
46990
+ pending?: number;
46991
+ /**
46992
+ * Entries of `failedSmartPlusAds`.
46993
+ */
46994
+ failed?: number;
46995
+ };
46996
+ /**
46997
+ * The oldest `readAt` in `items`. Null when `items` is empty.
46998
+ */
46999
+ oldestReadAt?: (string) | null;
46940
47000
  items?: Array<{
46941
47001
  smartPlusAdId?: string;
46942
47002
  adGroupId?: (string) | null;
@@ -46947,12 +47007,12 @@ type ListTikTokSmartPlusReviewsResponse = ({
46947
47007
  */
46948
47008
  materials?: Array<TikTokSmartPlusMaterialReview>;
46949
47009
  /**
46950
- * When the verdict was read from TikTok.
47010
+ * When the verdict was read from TikTok, kept as is when served from the store. Older than `maxAgeSeconds` means stale.
46951
47011
  */
46952
47012
  readAt?: string;
46953
47013
  }>;
46954
47014
  /**
46955
- * Smart+ ads of this page whose review TikTok refused on its own (for example an ad deleted on TikTok since the listing was cached). Zernio splits a refused batch in halves (at most 16 extra calls per page), so the other ads of the batch are still read; ads left unresolved by that cap carry the batch error. Empty when none.
47015
+ * Smart+ ads of this page whose review TikTok refused on its own (for example an ad deleted on TikTok since the listing was read). Zernio splits a refused batch in halves (at most 16 extra calls per page), so the other ads of the batch are still read; ads left unresolved by that cap stay in `items` with their stored review or in `pendingSmartPlusAdIds`. Empty when none.
46956
47016
  */
46957
47017
  failedSmartPlusAds?: Array<{
46958
47018
  smartPlusAdId?: string;
@@ -46968,17 +47028,25 @@ type ListTikTokSmartPlusReviewsResponse = ({
46968
47028
  */
46969
47029
  message?: string;
46970
47030
  };
47031
+ /**
47032
+ * When TikTok refused this ad. Null for a refusal stored before this field existed.
47033
+ */
47034
+ refusedAt?: (string) | null;
46971
47035
  }>;
46972
47036
  /**
46973
- * True when some Smart+ ads of this page could not be read because of TikTok's review quota.
47037
+ * True while some Smart+ ads of this page were never read (`counts.pending > 0`). Stale items alone keep it false.
46974
47038
  */
46975
47039
  incomplete?: boolean;
46976
47040
  /**
46977
- * Smart+ ads of this page still to read. Empty when complete.
47041
+ * True when every item and refusal of this page was read within `maxAgeSeconds` and nothing is pending. False with `incomplete: false` means the page is complete but some reviews are older than the window; a later read refreshes them oldest first.
47042
+ */
47043
+ allFresh?: boolean;
47044
+ /**
47045
+ * Smart+ ads of this page never read. Empty when every ad has a stored review or refusal.
46978
47046
  */
46979
47047
  pendingSmartPlusAdIds?: Array<(string)>;
46980
47048
  /**
46981
- * Seconds to wait before reading this page again. Null when complete.
47049
+ * Seconds to wait before reading this page again, set only while `incomplete` is true and review reads are paused. Null when complete (stale items included), or when the page is incomplete without a quota pause (read it again right away).
46982
47050
  */
46983
47051
  retryAfterSeconds?: (number) | null;
46984
47052
  });
@@ -50016,10 +50084,25 @@ type BoostPostData = {
50016
50084
  * "engagement"` to objective `OUTCOME_AWARENESS`, which accepts
50017
50085
  * `REACH`, `IMPRESSIONS`, `AD_RECALL_LIFT`, or THRUPLAY-class values, and
50018
50086
  * rejects `POST_ENGAGEMENT` (that value is only valid under
50019
- * `OUTCOME_ENGAGEMENT`, which create uses for the same goal name).
50087
+ * `OUTCOME_ENGAGEMENT`, which create uses for the same goal name, and
50088
+ * which `metaObjective` selects on a boost).
50020
50089
  *
50021
50090
  */
50022
50091
  optimizationGoal?: string;
50092
+ /**
50093
+ * Meta only, with `goal: engagement` and without `adSetId` (400 otherwise).
50094
+ * `OUTCOME_ENGAGEMENT` creates the campaign with objective `OUTCOME_ENGAGEMENT`
50095
+ * and the ad set with `optimization_goal` `POST_ENGAGEMENT` (unless
50096
+ * `optimizationGoal` is set) and `destination_type` `ON_POST` (unless
50097
+ * `destinationType` is set), the shape Ads Manager uses to boost an existing
50098
+ * post. When omitted, an engagement boost keeps `OUTCOME_AWARENESS` with
50099
+ * `REACH`. Returns 400 with `leadGenFormId` or with a `callToAction` whose objective
50100
+ * is not `OUTCOME_ENGAGEMENT` (`CALL_NOW`); messaging CTAs keep their own
50101
+ * `CONVERSATIONS` ad set. Verified against Meta on Facebook posts; Instagram posts
50102
+ * are accepted but not yet verified.
50103
+ *
50104
+ */
50105
+ metaObjective?: 'OUTCOME_ENGAGEMENT';
50023
50106
  };
50024
50107
  headers?: {
50025
50108
  /**
package/dist/index.d.ts CHANGED
@@ -46923,6 +46923,10 @@ type ListTikTokSmartPlusReviewsData = {
46923
46923
  * Also return Smart+ ads deleted on TikTok (listed with `primary_status: STATUS_ALL`).
46924
46924
  */
46925
46925
  includeDeleted?: boolean;
46926
+ /**
46927
+ * Freshness window in seconds. Reviews, refusals and the listing read within it are served without calling TikTok; older ones are still returned but read again, oldest first.
46928
+ */
46929
+ maxAgeSeconds?: number;
46926
46930
  page?: number;
46927
46931
  pageSize?: number;
46928
46932
  };
@@ -46930,6 +46934,10 @@ type ListTikTokSmartPlusReviewsData = {
46930
46934
  type ListTikTokSmartPlusReviewsResponse = ({
46931
46935
  adAccountId?: string;
46932
46936
  includeDeleted?: boolean;
46937
+ /**
46938
+ * The freshness window this page was read with.
46939
+ */
46940
+ maxAgeSeconds?: number;
46933
46941
  page?: number;
46934
46942
  pageSize?: number;
46935
46943
  totalPages?: number;
@@ -46937,6 +46945,58 @@ type ListTikTokSmartPlusReviewsResponse = ({
46937
46945
  * Smart+ ads of the advertiser across all pages.
46938
46946
  */
46939
46947
  totalSmartPlusAds?: number;
46948
+ /**
46949
+ * The Smart+ ad listing this page was cut from.
46950
+ */
46951
+ listing?: {
46952
+ /**
46953
+ * When the listing was read from TikTok.
46954
+ */
46955
+ readAt?: string;
46956
+ /**
46957
+ * `fresh`: read within `maxAgeSeconds`. `fallback`: relisting failed and this is the older stored listing.
46958
+ */
46959
+ source?: 'fresh' | 'fallback';
46960
+ /**
46961
+ * The relist error on a fallback, otherwise null.
46962
+ */
46963
+ error?: {
46964
+ tiktokCode?: (number) | null;
46965
+ message?: string;
46966
+ } | null;
46967
+ };
46968
+ /**
46969
+ * Set when TikTok refused both halves of a review batch the same way (for example a permission error) and the page was served from stored reviews instead of being refreshed. Null otherwise.
46970
+ */
46971
+ reviewError?: {
46972
+ tiktokCode?: (number) | null;
46973
+ message?: string;
46974
+ } | null;
46975
+ /**
46976
+ * The Smart+ ads on this page split by state; the four counts add up to the Smart+ ads on this page (fewer than `pageSize` on the last page).
46977
+ */
46978
+ counts?: {
46979
+ /**
46980
+ * Items read within `maxAgeSeconds`.
46981
+ */
46982
+ fresh?: number;
46983
+ /**
46984
+ * Items read earlier, returned with their `readAt` and due for a refresh.
46985
+ */
46986
+ stale?: number;
46987
+ /**
46988
+ * Smart+ ads never read (`pendingSmartPlusAdIds`).
46989
+ */
46990
+ pending?: number;
46991
+ /**
46992
+ * Entries of `failedSmartPlusAds`.
46993
+ */
46994
+ failed?: number;
46995
+ };
46996
+ /**
46997
+ * The oldest `readAt` in `items`. Null when `items` is empty.
46998
+ */
46999
+ oldestReadAt?: (string) | null;
46940
47000
  items?: Array<{
46941
47001
  smartPlusAdId?: string;
46942
47002
  adGroupId?: (string) | null;
@@ -46947,12 +47007,12 @@ type ListTikTokSmartPlusReviewsResponse = ({
46947
47007
  */
46948
47008
  materials?: Array<TikTokSmartPlusMaterialReview>;
46949
47009
  /**
46950
- * When the verdict was read from TikTok.
47010
+ * When the verdict was read from TikTok, kept as is when served from the store. Older than `maxAgeSeconds` means stale.
46951
47011
  */
46952
47012
  readAt?: string;
46953
47013
  }>;
46954
47014
  /**
46955
- * Smart+ ads of this page whose review TikTok refused on its own (for example an ad deleted on TikTok since the listing was cached). Zernio splits a refused batch in halves (at most 16 extra calls per page), so the other ads of the batch are still read; ads left unresolved by that cap carry the batch error. Empty when none.
47015
+ * Smart+ ads of this page whose review TikTok refused on its own (for example an ad deleted on TikTok since the listing was read). Zernio splits a refused batch in halves (at most 16 extra calls per page), so the other ads of the batch are still read; ads left unresolved by that cap stay in `items` with their stored review or in `pendingSmartPlusAdIds`. Empty when none.
46956
47016
  */
46957
47017
  failedSmartPlusAds?: Array<{
46958
47018
  smartPlusAdId?: string;
@@ -46968,17 +47028,25 @@ type ListTikTokSmartPlusReviewsResponse = ({
46968
47028
  */
46969
47029
  message?: string;
46970
47030
  };
47031
+ /**
47032
+ * When TikTok refused this ad. Null for a refusal stored before this field existed.
47033
+ */
47034
+ refusedAt?: (string) | null;
46971
47035
  }>;
46972
47036
  /**
46973
- * True when some Smart+ ads of this page could not be read because of TikTok's review quota.
47037
+ * True while some Smart+ ads of this page were never read (`counts.pending > 0`). Stale items alone keep it false.
46974
47038
  */
46975
47039
  incomplete?: boolean;
46976
47040
  /**
46977
- * Smart+ ads of this page still to read. Empty when complete.
47041
+ * True when every item and refusal of this page was read within `maxAgeSeconds` and nothing is pending. False with `incomplete: false` means the page is complete but some reviews are older than the window; a later read refreshes them oldest first.
47042
+ */
47043
+ allFresh?: boolean;
47044
+ /**
47045
+ * Smart+ ads of this page never read. Empty when every ad has a stored review or refusal.
46978
47046
  */
46979
47047
  pendingSmartPlusAdIds?: Array<(string)>;
46980
47048
  /**
46981
- * Seconds to wait before reading this page again. Null when complete.
47049
+ * Seconds to wait before reading this page again, set only while `incomplete` is true and review reads are paused. Null when complete (stale items included), or when the page is incomplete without a quota pause (read it again right away).
46982
47050
  */
46983
47051
  retryAfterSeconds?: (number) | null;
46984
47052
  });
@@ -50016,10 +50084,25 @@ type BoostPostData = {
50016
50084
  * "engagement"` to objective `OUTCOME_AWARENESS`, which accepts
50017
50085
  * `REACH`, `IMPRESSIONS`, `AD_RECALL_LIFT`, or THRUPLAY-class values, and
50018
50086
  * rejects `POST_ENGAGEMENT` (that value is only valid under
50019
- * `OUTCOME_ENGAGEMENT`, which create uses for the same goal name).
50087
+ * `OUTCOME_ENGAGEMENT`, which create uses for the same goal name, and
50088
+ * which `metaObjective` selects on a boost).
50020
50089
  *
50021
50090
  */
50022
50091
  optimizationGoal?: string;
50092
+ /**
50093
+ * Meta only, with `goal: engagement` and without `adSetId` (400 otherwise).
50094
+ * `OUTCOME_ENGAGEMENT` creates the campaign with objective `OUTCOME_ENGAGEMENT`
50095
+ * and the ad set with `optimization_goal` `POST_ENGAGEMENT` (unless
50096
+ * `optimizationGoal` is set) and `destination_type` `ON_POST` (unless
50097
+ * `destinationType` is set), the shape Ads Manager uses to boost an existing
50098
+ * post. When omitted, an engagement boost keeps `OUTCOME_AWARENESS` with
50099
+ * `REACH`. Returns 400 with `leadGenFormId` or with a `callToAction` whose objective
50100
+ * is not `OUTCOME_ENGAGEMENT` (`CALL_NOW`); messaging CTAs keep their own
50101
+ * `CONVERSATIONS` ad set. Verified against Meta on Facebook posts; Instagram posts
50102
+ * are accepted but not yet verified.
50103
+ *
50104
+ */
50105
+ metaObjective?: 'OUTCOME_ENGAGEMENT';
50023
50106
  };
50024
50107
  headers?: {
50025
50108
  /**
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: "@getlatedev/node",
39
- version: "0.2.1321",
39
+ version: "0.2.1323",
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: "@getlatedev/node",
8
- version: "0.2.1321",
8
+ version: "0.2.1323",
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": "@getlatedev/node",
3
- "version": "0.2.1321",
3
+ "version": "0.2.1323",
4
4
  "description": "The official Node.js library for the Zernio API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -11666,14 +11666,15 @@ export const getAdReview = <ThrowOnError extends boolean = false>(options: Optio
11666
11666
  * carousel under its own material id, so those entries come back with the review verdict and
11667
11667
  * null descriptive fields. TikTok returns no review timestamp; `readAt` is when Zernio read it.
11668
11668
  *
11669
- * TikTok's review endpoint has a strict quota of its own, which behaves per advertiser. One TikTok call reads the
11669
+ * TikTok's review endpoint has a strict quota of its own (TikTok documents neither the quota nor its scope). One TikTok call reads the
11670
11670
  * review of the live Smart+ ads of the ad group up to 50 creatives in total (TikTok refuses more),
11671
- * and each review is cached for 10 minutes per connection, advertiser and Smart+ ad, so sibling ads
11672
- * are answered from the cache and `readAt` can be up to 10 minutes old. Read reviews when you need
11671
+ * and each review is stored per connection, advertiser and Smart+ ad. This read serves a review read
11672
+ * in the last 10 minutes from the store, so sibling ads are answered without a TikTok call and `readAt`
11673
+ * can be up to 10 minutes old; an older one is read again. Read reviews when you need
11673
11674
  * them instead of sweeping every ad on a loop. When TikTok answers over quota, Zernio returns 429
11674
- * and answers 429 for that advertiser and connection without calling TikTok for 60 seconds, then
11675
- * 120, then 240 while TikTok keeps refusing (back to 60 after a successful call), with the time left
11676
- * as `Retry-After`; cached reviews are still served.
11675
+ * and answers 429 for that advertiser and connection without calling TikTok for about 60 seconds, then
11676
+ * 120, then 240 while TikTok keeps refusing (one step down after a successful call, each with up to 10%
11677
+ * of random jitter), with the time left as `Retry-After`; reviews read in the last 10 minutes are still served.
11677
11678
  */
11678
11679
  export const getTikTokSmartPlusAdReview = <ThrowOnError extends boolean = false>(options: OptionsLegacyParser<GetTikTokSmartPlusAdReviewData, ThrowOnError>) => {
11679
11680
  return (options?.client ?? client).get<GetTikTokSmartPlusAdReviewResponse, GetTikTokSmartPlusAdReviewError, ThrowOnError>({
@@ -12197,13 +12198,17 @@ export const getTikTokSmartPlusMaterialReport = <ThrowOnError extends boolean =
12197
12198
  * Review status of every TikTok Smart+ ad of an advertiser
12198
12199
  * Returns the review verdict of every Upgraded Smart+ ad of one TikTok advertiser, with each creative's verdict, in one paginated read. Use it to refresh reviews periodically: one call (plus its pages) per advertiser per refresh, instead of `GET /v1/ads/{adId}/tiktok-smart-plus-review` per ad.
12199
12200
  *
12200
- * Zernio lists the advertiser's Smart+ ads with `/smart_plus/ad/get/` (deleted ones only with `includeDeleted=true`; the listing is cached for 10 minutes) and reads `/smart_plus/ad/review_info/` for Smart+ ads holding up to 50 creatives in total per call (TikTok refuses more; a Smart+ ad with more than 50 creatives is read alone), across ad groups, one call after another. A full refresh of N Smart+ ads with C creatives in total costs about `ceil(N / 100)` listing calls and `ceil(C / 50)` review calls on TikTok. When TikTok still refuses a call for its creative count, Zernio lowers the creative cap for that advertiser and reads the same ads again in smaller calls, never resending the refused size. Each review is cached for 10 minutes per connection, advertiser and Smart+ ad, shared with the single-ad read, so cached reviews are served without calling TikTok and `readAt` can be up to 10 minutes old.
12201
+ * Zernio lists the advertiser's Smart+ ads with `/smart_plus/ad/get/` (deleted ones only with `includeDeleted=true`) and reads `/smart_plus/ad/review_info/` for Smart+ ads holding up to 50 creatives in total per call (TikTok refuses more; a Smart+ ad with more than 50 creatives is read alone), across ad groups, one call after another. A full refresh of N Smart+ ads with C creatives in total costs about `ceil(N / 100)` listing calls and `ceil(C / 50)` review calls on TikTok. When TikTok still refuses a call for its creative count, Zernio lowers the creative cap for that advertiser and reads the same ads again in smaller calls, never resending the refused size.
12201
12202
  *
12202
- * TikTok's review endpoint has a strict quota of its own, which behaves per advertiser. When it is over quota (or Zernio is holding review reads for this advertiser and connection after an overage: 60 seconds, then 120, then 240 while TikTok keeps refusing, back to 60 after a successful call), Zernio stops calling TikTok and answers 200 with the reviews it has: `incomplete: true`, the Smart+ ads still to read in `pendingSmartPlusAdIds`, and `retryAfterSeconds` (also in the `Retry-After` header). Every Smart+ ad of the page is in `items`, `failedSmartPlusAds` or `pendingSmartPlusAdIds`. Wait `retryAfterSeconds` and read the same page again: only the pending ads reach TikTok.
12203
+ * Stale while refreshing: every review is stored for 24 hours per connection, advertiser and Smart+ ad (shared with the single-ad read), and `readAt` is always the time TikTok answered, never rewritten when served from the store. `maxAgeSeconds` (default 3600) is the freshness window: a review read within it is fresh and costs no TikTok call; an older one is still returned in `items` but is read again, and so is a Smart+ ad never read. Each request first reads every Smart+ ad of the page never read (live, then deleted with `includeDeleted=true`) and only then refreshes stale ones, oldest `readAt` first, so a quota pause cannot leave never-read ads behind stale ones, progress carries over between requests and an ad already read never goes back to pending. A stored review is replaced only by a successful read. `counts` splits the Smart+ ads on this page into `fresh`, `stale`, `pending` and `failed`, and `oldestReadAt` is the oldest `readAt` of `items`. `incomplete` is true only while some Smart+ ad of the page has never been read (`pending > 0`). Staleness is reported apart: `allFresh` is true when every item and refusal of the page is within `maxAgeSeconds` and nothing is pending. A page with stale items and nothing pending is complete (`incomplete: false`, no `Retry-After`): move on, and a later read refreshes it oldest first. On 2026-10-25 TikTok's quota allowed about 130 to 230 Smart+ ads per advertiser per hour (about 11.5 ads and 4 creatives per successful call), so a larger advertiser cannot be fully refreshed within one hour and its pages stay complete but not `allFresh`.
12203
12204
  *
12204
- * A Smart+ ad whose review TikTok refuses on its own (for example one deleted on TikTok since the listing was cached) is returned in `failedSmartPlusAds` with TikTok's error, and the rest of the page is still read. Zernio finds it by splitting the refused batch in halves, at most 16 extra TikTok calls per page; ads still unresolved after that come back in `failedSmartPlusAds` with the batch error. A refusal of a single ad is remembered for 10 minutes. When both halves of a refused batch are refused with the same TikTok error (for example a permission error), the whole request fails with that error instead.
12205
+ * The listing is stored with the time it was read (`listing.readAt`) and listed again when it is older than `maxAgeSeconds`, so it can be up to `maxAgeSeconds` old: a Smart+ ad created on TikTok appears after at most that long (one hour by default). If that relisting fails, Zernio serves the stored listing with `listing.source: fallback` and the relist error in `listing.error`, instead of failing the request; `listing.source: fresh` means the listing was read within `maxAgeSeconds`. Only when no listing was ever stored does the listing error fail the request.
12205
12206
  *
12206
- * Items are sorted by `adGroupId`, then `smartPlusAdId`, so pages are stable. Keep one page in flight per advertiser and read its pages one after another: parallel pages of one advertiser spend its review quota at the same time and come back incomplete. The quota behaves per advertiser (observed, not documented by TikTok), so different advertisers can be read in parallel.
12207
+ * TikTok's review endpoint has a strict quota of its own (TikTok documents neither the quota nor its scope). When it is over quota (or Zernio is holding review reads for this advertiser and connection after an overage: about 60 seconds, then 120, then 240 while TikTok keeps refusing, one step down after a successful call, each with up to 10% of random jitter), Zernio stops calling TikTok and answers 200 with the reviews it has: stale reviews in `items`, the Smart+ ads never read in `pendingSmartPlusAdIds` and, when any are pending, `incomplete: true` with `retryAfterSeconds` (also in the `Retry-After` header). Every Smart+ ad of the page is in `items`, `failedSmartPlusAds` or `pendingSmartPlusAdIds`. Wait `retryAfterSeconds` and read the same page again: only the stale and pending ads reach TikTok.
12208
+ *
12209
+ * A Smart+ ad whose review TikTok refuses on its own (for example one deleted on TikTok since the listing was read) is returned in `failedSmartPlusAds` with TikTok's error and `refusedAt`, and the rest of the page is still read. Zernio finds it by splitting the refused batch in halves, at most 16 extra TikTok calls per page; ads still unresolved after that keep their stored review, or stay in `pendingSmartPlusAdIds` when they have none, and are read first by the next request. A refusal of a single ad is stored for 24 hours and read again once it is older than `maxAgeSeconds`; when an ad has both a stored review and a stored refusal, the more recent one is returned. When both halves of a refused batch are refused with the same TikTok error (for example a permission error), Zernio stops calling TikTok for that page: when every Smart+ ad of the page has a stored review or refusal, it serves them and returns the refusal in `reviewError`; when some ad was never read, the whole request fails with that error.
12210
+ *
12211
+ * Items are sorted by `adGroupId`, then `smartPlusAdId`, so pages are stable. Keep one page in flight per advertiser and read its pages one after another: parallel pages of one advertiser spend its review quota at the same time and come back incomplete. Production logs suggest the quota is counted per advertiser (not confirmed by TikTok), so different advertisers have been read in parallel without throttling each other.
12207
12212
  */
12208
12213
  export const listTikTokSmartPlusReviews = <ThrowOnError extends boolean = false>(options: OptionsLegacyParser<ListTikTokSmartPlusReviewsData, ThrowOnError>) => {
12209
12214
  return (options?.client ?? client).get<ListTikTokSmartPlusReviewsResponse, ListTikTokSmartPlusReviewsError, ThrowOnError>({
@@ -47625,6 +47625,10 @@ export type ListTikTokSmartPlusReviewsData = {
47625
47625
  * Also return Smart+ ads deleted on TikTok (listed with `primary_status: STATUS_ALL`).
47626
47626
  */
47627
47627
  includeDeleted?: boolean;
47628
+ /**
47629
+ * Freshness window in seconds. Reviews, refusals and the listing read within it are served without calling TikTok; older ones are still returned but read again, oldest first.
47630
+ */
47631
+ maxAgeSeconds?: number;
47628
47632
  page?: number;
47629
47633
  pageSize?: number;
47630
47634
  };
@@ -47633,6 +47637,10 @@ export type ListTikTokSmartPlusReviewsData = {
47633
47637
  export type ListTikTokSmartPlusReviewsResponse = ({
47634
47638
  adAccountId?: string;
47635
47639
  includeDeleted?: boolean;
47640
+ /**
47641
+ * The freshness window this page was read with.
47642
+ */
47643
+ maxAgeSeconds?: number;
47636
47644
  page?: number;
47637
47645
  pageSize?: number;
47638
47646
  totalPages?: number;
@@ -47640,6 +47648,58 @@ export type ListTikTokSmartPlusReviewsResponse = ({
47640
47648
  * Smart+ ads of the advertiser across all pages.
47641
47649
  */
47642
47650
  totalSmartPlusAds?: number;
47651
+ /**
47652
+ * The Smart+ ad listing this page was cut from.
47653
+ */
47654
+ listing?: {
47655
+ /**
47656
+ * When the listing was read from TikTok.
47657
+ */
47658
+ readAt?: string;
47659
+ /**
47660
+ * `fresh`: read within `maxAgeSeconds`. `fallback`: relisting failed and this is the older stored listing.
47661
+ */
47662
+ source?: 'fresh' | 'fallback';
47663
+ /**
47664
+ * The relist error on a fallback, otherwise null.
47665
+ */
47666
+ error?: {
47667
+ tiktokCode?: (number) | null;
47668
+ message?: string;
47669
+ } | null;
47670
+ };
47671
+ /**
47672
+ * Set when TikTok refused both halves of a review batch the same way (for example a permission error) and the page was served from stored reviews instead of being refreshed. Null otherwise.
47673
+ */
47674
+ reviewError?: {
47675
+ tiktokCode?: (number) | null;
47676
+ message?: string;
47677
+ } | null;
47678
+ /**
47679
+ * The Smart+ ads on this page split by state; the four counts add up to the Smart+ ads on this page (fewer than `pageSize` on the last page).
47680
+ */
47681
+ counts?: {
47682
+ /**
47683
+ * Items read within `maxAgeSeconds`.
47684
+ */
47685
+ fresh?: number;
47686
+ /**
47687
+ * Items read earlier, returned with their `readAt` and due for a refresh.
47688
+ */
47689
+ stale?: number;
47690
+ /**
47691
+ * Smart+ ads never read (`pendingSmartPlusAdIds`).
47692
+ */
47693
+ pending?: number;
47694
+ /**
47695
+ * Entries of `failedSmartPlusAds`.
47696
+ */
47697
+ failed?: number;
47698
+ };
47699
+ /**
47700
+ * The oldest `readAt` in `items`. Null when `items` is empty.
47701
+ */
47702
+ oldestReadAt?: (string) | null;
47643
47703
  items?: Array<{
47644
47704
  smartPlusAdId?: string;
47645
47705
  adGroupId?: (string) | null;
@@ -47650,12 +47710,12 @@ export type ListTikTokSmartPlusReviewsResponse = ({
47650
47710
  */
47651
47711
  materials?: Array<TikTokSmartPlusMaterialReview>;
47652
47712
  /**
47653
- * When the verdict was read from TikTok.
47713
+ * When the verdict was read from TikTok, kept as is when served from the store. Older than `maxAgeSeconds` means stale.
47654
47714
  */
47655
47715
  readAt?: string;
47656
47716
  }>;
47657
47717
  /**
47658
- * Smart+ ads of this page whose review TikTok refused on its own (for example an ad deleted on TikTok since the listing was cached). Zernio splits a refused batch in halves (at most 16 extra calls per page), so the other ads of the batch are still read; ads left unresolved by that cap carry the batch error. Empty when none.
47718
+ * Smart+ ads of this page whose review TikTok refused on its own (for example an ad deleted on TikTok since the listing was read). Zernio splits a refused batch in halves (at most 16 extra calls per page), so the other ads of the batch are still read; ads left unresolved by that cap stay in `items` with their stored review or in `pendingSmartPlusAdIds`. Empty when none.
47659
47719
  */
47660
47720
  failedSmartPlusAds?: Array<{
47661
47721
  smartPlusAdId?: string;
@@ -47671,17 +47731,25 @@ export type ListTikTokSmartPlusReviewsResponse = ({
47671
47731
  */
47672
47732
  message?: string;
47673
47733
  };
47734
+ /**
47735
+ * When TikTok refused this ad. Null for a refusal stored before this field existed.
47736
+ */
47737
+ refusedAt?: (string) | null;
47674
47738
  }>;
47675
47739
  /**
47676
- * True when some Smart+ ads of this page could not be read because of TikTok's review quota.
47740
+ * True while some Smart+ ads of this page were never read (`counts.pending > 0`). Stale items alone keep it false.
47677
47741
  */
47678
47742
  incomplete?: boolean;
47679
47743
  /**
47680
- * Smart+ ads of this page still to read. Empty when complete.
47744
+ * True when every item and refusal of this page was read within `maxAgeSeconds` and nothing is pending. False with `incomplete: false` means the page is complete but some reviews are older than the window; a later read refreshes them oldest first.
47745
+ */
47746
+ allFresh?: boolean;
47747
+ /**
47748
+ * Smart+ ads of this page never read. Empty when every ad has a stored review or refusal.
47681
47749
  */
47682
47750
  pendingSmartPlusAdIds?: Array<(string)>;
47683
47751
  /**
47684
- * Seconds to wait before reading this page again. Null when complete.
47752
+ * Seconds to wait before reading this page again, set only while `incomplete` is true and review reads are paused. Null when complete (stale items included), or when the page is incomplete without a quota pause (read it again right away).
47685
47753
  */
47686
47754
  retryAfterSeconds?: (number) | null;
47687
47755
  });
@@ -50922,10 +50990,25 @@ export type BoostPostData = {
50922
50990
  * "engagement"` to objective `OUTCOME_AWARENESS`, which accepts
50923
50991
  * `REACH`, `IMPRESSIONS`, `AD_RECALL_LIFT`, or THRUPLAY-class values, and
50924
50992
  * rejects `POST_ENGAGEMENT` (that value is only valid under
50925
- * `OUTCOME_ENGAGEMENT`, which create uses for the same goal name).
50993
+ * `OUTCOME_ENGAGEMENT`, which create uses for the same goal name, and
50994
+ * which `metaObjective` selects on a boost).
50926
50995
  *
50927
50996
  */
50928
50997
  optimizationGoal?: string;
50998
+ /**
50999
+ * Meta only, with `goal: engagement` and without `adSetId` (400 otherwise).
51000
+ * `OUTCOME_ENGAGEMENT` creates the campaign with objective `OUTCOME_ENGAGEMENT`
51001
+ * and the ad set with `optimization_goal` `POST_ENGAGEMENT` (unless
51002
+ * `optimizationGoal` is set) and `destination_type` `ON_POST` (unless
51003
+ * `destinationType` is set), the shape Ads Manager uses to boost an existing
51004
+ * post. When omitted, an engagement boost keeps `OUTCOME_AWARENESS` with
51005
+ * `REACH`. Returns 400 with `leadGenFormId` or with a `callToAction` whose objective
51006
+ * is not `OUTCOME_ENGAGEMENT` (`CALL_NOW`); messaging CTAs keep their own
51007
+ * `CONVERSATIONS` ad set. Verified against Meta on Facebook posts; Instagram posts
51008
+ * are accepted but not yet verified.
51009
+ *
51010
+ */
51011
+ metaObjective?: 'OUTCOME_ENGAGEMENT';
50929
51012
  };
50930
51013
  headers?: {
50931
51014
  /**