@wix/auto_sdk_seo_blog-post-candidates 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,795 @@
1
+ import { NonNullablePaths } from '@wix/sdk-types';
2
+
3
+ /**
4
+ * A blog post candidate is a single blog post brief in a site's content plan.
5
+ *
6
+ * Each candidate pairs a target keyword with a suggested title, the search
7
+ * data behind that keyword, and the site page the post should support. A site
8
+ * owner uses a candidate as the starting point for writing a post.
9
+ *
10
+ * Candidates are generated by the content plan pipeline and are read-only.
11
+ * Call Create Content Plan to generate them, and List Blog Post Candidates to
12
+ * read them.
13
+ */
14
+ interface BlogPostCandidate {
15
+ /**
16
+ * Blog post candidate ID.
17
+ *
18
+ * Treat this value as opaque. Don't parse it or build it yourself, and
19
+ * pass it back exactly as received. The individual IDs it's built from are
20
+ * available on `candidateData`.
21
+ * @maxLength 100
22
+ * @readonly
23
+ */
24
+ _id?: string | null;
25
+ /** IDs that identify the candidate and the flow that generated it. */
26
+ candidateData?: CandidateData;
27
+ /**
28
+ * The blog post brief itself: the suggested title, the target keywords,
29
+ * and the search data behind them.
30
+ */
31
+ briefData?: BriefData;
32
+ /**
33
+ * SEO tags suggested for the blog post, such as its title tag and meta
34
+ * description.
35
+ */
36
+ seoData?: SeoSchema;
37
+ }
38
+ interface CandidateData {
39
+ /**
40
+ * ID of the blog post candidate within its content plan flow.
41
+ * @format GUID
42
+ * @readonly
43
+ */
44
+ blogPostCandidateId?: string | null;
45
+ /**
46
+ * ID of the content plan flow that generated this candidate.
47
+ * @format GUID
48
+ * @readonly
49
+ */
50
+ contentPlanFlowId?: string | null;
51
+ }
52
+ interface BriefData {
53
+ /**
54
+ * Suggested title for the blog post.
55
+ * @maxLength 1000
56
+ */
57
+ h1Title?: string | null;
58
+ /**
59
+ * Keyword the blog post targets.
60
+ * @maxLength 1000
61
+ */
62
+ keyword?: string | null;
63
+ /**
64
+ * Primary keyword for the page the blog post supports.
65
+ *
66
+ * A page has a single main keyword, and several blog posts can support the
67
+ * same one.
68
+ * @maxLength 1000
69
+ */
70
+ mainKeyword?: string | null;
71
+ /**
72
+ * Search engine results data for `mainKeyword`, such as its search volume
73
+ * and how hard it is to rank for.
74
+ *
75
+ * List Blog Post Candidates doesn't currently return this field.
76
+ */
77
+ serpData?: SerpData;
78
+ /**
79
+ * URL of the site page the blog post is meant to support.
80
+ * @maxLength 1000
81
+ */
82
+ pageUrl?: string | null;
83
+ }
84
+ interface SerpData {
85
+ /**
86
+ * SerpDataResult ID
87
+ * @format GUID
88
+ * @readonly
89
+ */
90
+ _id?: string | null;
91
+ /**
92
+ * list of people also ask questions
93
+ * @maxSize 4
94
+ */
95
+ peopleAlsoAskSuggestions?: PeopleAlsoAskQuestion[];
96
+ /**
97
+ * list of related searches
98
+ * @maxSize 10
99
+ * @maxLength 10000
100
+ */
101
+ peopleAlsoSearchSuggestions?: string[] | null;
102
+ /**
103
+ * list of autocomplete suggestions
104
+ * @maxSize 15
105
+ * @maxLength 10000
106
+ */
107
+ autocompleteSuggestions?: string[] | null;
108
+ }
109
+ interface PeopleAlsoAskQuestion {
110
+ /**
111
+ * people also ask question title
112
+ * @maxLength 10000
113
+ */
114
+ question?: string | null;
115
+ /**
116
+ * answers to the question
117
+ * @maxSize 2
118
+ */
119
+ answers?: PeopleAlsoAskAnswer[];
120
+ }
121
+ interface PeopleAlsoAskAnswer {
122
+ /**
123
+ * people also ask answer title
124
+ * @maxLength 10000
125
+ */
126
+ title?: string | null;
127
+ /**
128
+ * description of the answer
129
+ * @maxLength 10000
130
+ */
131
+ description?: string | null;
132
+ }
133
+ /**
134
+ * The SEO schema object contains data about different types of meta tags. It makes sure that the information about your page is presented properly to search engines.
135
+ * The search engines use this information for ranking purposes, or to display snippets in the search results.
136
+ * This data will override other sources of tags (for example patterns) and will be included in the <head> section of the HTML document, while not being displayed on the page itself.
137
+ */
138
+ interface SeoSchema {
139
+ /** SEO tag information. */
140
+ tags?: Tag[];
141
+ /** SEO general settings. */
142
+ settings?: Settings;
143
+ }
144
+ interface Keyword {
145
+ /** Keyword value. */
146
+ term?: string;
147
+ /** Whether the keyword is the main focus keyword. */
148
+ isMain?: boolean;
149
+ /**
150
+ * The source that added the keyword terms to the SEO settings.
151
+ * @maxLength 1000
152
+ */
153
+ origin?: string | null;
154
+ }
155
+ interface Tag {
156
+ /**
157
+ * SEO tag type.
158
+ *
159
+ *
160
+ * Supported values: `title`, `meta`, `script`, `link`.
161
+ *
162
+ * Which of these an API actually accepts depends on where the tag is being set: this
163
+ * list is not a blanket guarantee across every API that reuses this message. Site SEO
164
+ * Tags in particular accepts only `meta` (see `SiteSeoTags.tags`) and rejects
165
+ * `title`/`script`/`link` with a validation error even though they appear here —
166
+ * check the field description of the specific `tags`-typed field you're writing to
167
+ * for the types it actually supports and the error it returns.
168
+ *
169
+ * Limitation: `title` and `script` (e.g. a `script` tag with `props.type`
170
+ * `"application/ld+json"` carrying structured data) are supported only when
171
+ * `custom` is unset or `false`. Setting `custom: true` on a `title` or `script`
172
+ * tag is rejected with `TAG_TYPE_NOT_ALLOWED`, because `custom: true` routes the
173
+ * write through the site's Advanced/Custom Tags list. To write structured data,
174
+ * omit `custom` (or set it to `false`).
175
+ */
176
+ type?: string;
177
+ /**
178
+ * A `{"key": "value"}` pair object where each SEO tag property (`"name"`, `"content"`, `"rel"`, `"href"`) contains a value.
179
+ * For example: `{"name": "description", "content": "the description itself"}`.
180
+ */
181
+ props?: Record<string, any> | null;
182
+ /** SEO tag metadata. For example, `{"height": 300, "width": 240}`. */
183
+ meta?: Record<string, any> | null;
184
+ /** SEO tag inner content. For example, `<title> inner content </title>`. */
185
+ children?: string;
186
+ /**
187
+ * Whether the tag is a [custom tag](https://support.wix.com/en/article/adding-additional-meta-tags-to-your-sites-pages) —
188
+ * i.e. an entry from the site's Advanced/Custom Tags list.
189
+ *
190
+ * Setting this to `true` on a write restricts which `type` values are accepted
191
+ * — the same restriction the Advanced/Custom Tags UI enforces. `title` and
192
+ * `script` tags (including JSON-LD structured data) must be sent with `custom`
193
+ * omitted or `false`; sending them with `custom: true` is rejected with
194
+ * `TAG_TYPE_NOT_ALLOWED`.
195
+ *
196
+ * Note this is a separate restriction from Site SEO Tags' own type restriction on
197
+ * `SiteSeoTags.tags`: even with `custom` unset, Site SEO Tags rejects `script` (e.g.
198
+ * for site-wide structured data) unconditionally. There is currently no way to set
199
+ * site-wide, every-page structured data through any of these APIs — write a per-page
200
+ * `script` tag through the Item SEO Tags API instead.
201
+ *
202
+ * This flag is scoped to that feature only. It is NOT an indicator of whether a standard tag
203
+ * (`title`, `description`, Open Graph, etc.) reflects a manually configured value versus a computed
204
+ * default/pattern — standard tags always resolve with `custom: false`, even when their content comes
205
+ * from a page's manually saved SEO title/description override. Don't use this field to verify whether
206
+ * a live page reflects a manual per-page SEO edit.
207
+ *
208
+ * Limitation: when `ResolveStaticPageSeoTags` is called without `seoData`, the per-page SEO data is read
209
+ * only from the Vibe/Wix-managed-headless override store. That store holds nothing for classic Wix Editor
210
+ * or Wix Studio pages, so even genuine Advanced/Custom Tags saved on those pages are missing from the
211
+ * response entirely — there, `false` means this API could not tell, not that no custom tag exists.
212
+ * Pass `seoData` explicitly to resolve against a known set of tags.
213
+ */
214
+ custom?: boolean;
215
+ /** Whether the tag is disabled. If the tag is disabled, people can't find your page when searching for this phrase in search engines. */
216
+ disabled?: boolean;
217
+ }
218
+ interface Settings {
219
+ /**
220
+ * Whether the [automatical redirect visits](https://support.wix.com/en/article/customizing-your-pages-seo-settings-in-the-seo-panel) from the old URL to the new one is enabled.
221
+ *
222
+ *
223
+ * Default: `false` (automatical redirect is enabled).
224
+ */
225
+ preventAutoRedirect?: boolean;
226
+ /**
227
+ * User-selected keyword terms for a specific page.
228
+ * @maxSize 5
229
+ */
230
+ keywords?: Keyword[];
231
+ }
232
+ interface GetBlogPostCandidateRequest {
233
+ /**
234
+ * id of the content plan flow this blog post candidate belongs to
235
+ * @format GUID
236
+ */
237
+ contentPlanFlowId?: string | null;
238
+ }
239
+ interface GetBlogPostCandidateResponse {
240
+ /** blog post candidate */
241
+ blogPostCandidate?: BlogPostCandidate;
242
+ }
243
+ interface GetBlogPostCandidateByIdRequest {
244
+ /**
245
+ * id of the blog post candidate
246
+ * @minLength 1
247
+ * @maxLength 100
248
+ */
249
+ blogPostCandidateId?: string | null;
250
+ }
251
+ interface GetBlogPostCandidateByIdResponse {
252
+ /** blog post candidate */
253
+ blogPostCandidate?: BlogPostCandidate;
254
+ }
255
+ interface MarkBlogPostCandidateRequest {
256
+ /** ids of the blog post candidate */
257
+ candidateData?: CandidateData;
258
+ /**
259
+ * ID of the blog post that was created from this candidate.
260
+ * @format GUID
261
+ */
262
+ blogPostId?: string | null;
263
+ }
264
+ interface MarkBlogPostCandidateResponse {
265
+ }
266
+ interface BulkMarkBlogPostCandidatesRequest {
267
+ /**
268
+ * id of the content plan flow these blog post candidates belong to
269
+ * @format GUID
270
+ */
271
+ contentPlanFlowId?: string | null;
272
+ /**
273
+ * List of blog post candidates to mark
274
+ * @maxSize 1000
275
+ */
276
+ items?: BulkMarkBlogPostCandidateItem[];
277
+ }
278
+ interface BulkMarkBlogPostCandidateItem {
279
+ /**
280
+ * id of the blog post candidate
281
+ * @format GUID
282
+ */
283
+ blogPostCandidateId?: string | null;
284
+ /**
285
+ * generated blog post id
286
+ * @format GUID
287
+ */
288
+ blogPostId?: string | null;
289
+ }
290
+ interface BulkMarkBlogPostCandidatesResponse {
291
+ /**
292
+ * Per-entry results, correlated by `itemMetadata.originalIndex`.
293
+ * @maxSize 1000
294
+ */
295
+ results?: BulkMarkBlogPostCandidateResult[];
296
+ /** How many entries succeeded and how many failed. */
297
+ bulkActionMetadata?: BulkActionMetadata;
298
+ }
299
+ interface ItemMetadata {
300
+ /**
301
+ * Item ID. Should always be available, unless it's impossible (for example, when failing to create an item).
302
+ * @maxLength 100
303
+ */
304
+ _id?: string | null;
305
+ /** Index of the item within the request array. Allows for correlation between request and response items. */
306
+ originalIndex?: number;
307
+ /** Whether the requested action was successful for this item. When `false`, the `error` field is populated. */
308
+ success?: boolean;
309
+ /** Details about the error in case of failure. */
310
+ error?: ApplicationError;
311
+ }
312
+ interface ApplicationError {
313
+ /** Error code. */
314
+ code?: string;
315
+ /** Description of the error. */
316
+ description?: string;
317
+ /** Data related to the error. */
318
+ data?: Record<string, any> | null;
319
+ }
320
+ /** Result of marking one blog post candidate in a bulk request. */
321
+ interface BulkMarkBlogPostCandidateResult {
322
+ /** Success/failure and error detail for this entry. */
323
+ itemMetadata?: ItemMetadata;
324
+ }
325
+ interface BulkActionMetadata {
326
+ /** Number of items that were successfully processed. */
327
+ totalSuccesses?: number;
328
+ /** Number of items that couldn't be processed. */
329
+ totalFailures?: number;
330
+ /** Number of failures without details because detailed failure threshold was exceeded. */
331
+ undetailedFailures?: number;
332
+ }
333
+ interface ListBlogPostCandidatesRequest {
334
+ /**
335
+ * ID of the content plan flow to retrieve candidates for.
336
+ *
337
+ * Omit to read the site's most recent successful flow.
338
+ * @format GUID
339
+ */
340
+ contentPlanFlowId: string | null;
341
+ /**
342
+ * Whether to return only candidates that haven't been used for a blog post
343
+ * yet.
344
+ *
345
+ * A candidate is marked as used when a blog post is created from it in the
346
+ * Wix Blog product. An app can read this flag but can't set it, so track
347
+ * the posts you've written on your own side as well.
348
+ *
349
+ * Default: `false`, which returns every candidate.
350
+ */
351
+ includeOnlyUnmarked?: boolean | null;
352
+ /**
353
+ * Cursor paging. Omit for the first page.
354
+ *
355
+ * Omit this object entirely to return every candidate in a single response.
356
+ */
357
+ paging?: CursorPaging;
358
+ }
359
+ interface CursorPaging {
360
+ /**
361
+ * Max items per page. Default 50, max 100.
362
+ * @max 100
363
+ */
364
+ limit?: number | null;
365
+ /**
366
+ * Cursor from a previous response. Omit for the first page.
367
+ * @maxLength 16000
368
+ */
369
+ cursor?: string | null;
370
+ }
371
+ interface ListBlogPostCandidatesResponse {
372
+ /**
373
+ * Retrieved blog post candidates.
374
+ * @maxSize 1000
375
+ */
376
+ blogPostCandidates?: BlogPostCandidate[];
377
+ /** Paging metadata. */
378
+ pagingMetadata?: CursorPagingMetadata;
379
+ }
380
+ interface CursorPagingMetadata {
381
+ /** Items returned in this page. */
382
+ count?: number | null;
383
+ /** Cursors for next/previous page. */
384
+ cursors?: Cursors;
385
+ /** Whether there are more pages. */
386
+ hasNext?: boolean | null;
387
+ }
388
+ interface Cursors {
389
+ /**
390
+ * Cursor for the next page.
391
+ * @maxLength 16000
392
+ */
393
+ next?: string | null;
394
+ /**
395
+ * Cursor for the previous page.
396
+ * @maxLength 16000
397
+ */
398
+ prev?: string | null;
399
+ }
400
+ /** Deprecated alias request. Same fields as ListBlogPostCandidatesRequest. */
401
+ interface QueryBlogPostCandidatesRequest {
402
+ /**
403
+ * Content plan flow ID.
404
+ * @format GUID
405
+ */
406
+ contentPlanFlowId?: string | null;
407
+ /** Whether to return only unmarked candidates. */
408
+ includeOnlyUnmarked?: boolean | null;
409
+ /** Cursor paging. */
410
+ paging?: CursorPaging;
411
+ }
412
+ /** Deprecated alias response. Same fields as ListBlogPostCandidatesResponse. */
413
+ interface QueryBlogPostCandidatesResponse {
414
+ /**
415
+ * Blog post candidates.
416
+ * @maxSize 1000
417
+ */
418
+ blogPostCandidates?: BlogPostCandidate[];
419
+ /** Paging metadata. */
420
+ pagingMetadata?: CursorPagingMetadata;
421
+ }
422
+ interface GetContentPlanRequest {
423
+ /** requested start date */
424
+ startDate?: Date | null;
425
+ /** requested end date */
426
+ endDate?: Date | null;
427
+ }
428
+ interface GetContentPlanResponse {
429
+ /** content plan */
430
+ contentPlan?: ContentPlan;
431
+ }
432
+ interface ContentPlan {
433
+ /**
434
+ * content plan columns
435
+ * @maxSize 10
436
+ */
437
+ columns?: Column[];
438
+ /**
439
+ * content plan rows
440
+ * @maxSize 1000
441
+ */
442
+ rows?: Row[];
443
+ /**
444
+ * description to show the user
445
+ * @maxLength 1000
446
+ */
447
+ description?: string | null;
448
+ }
449
+ interface Column {
450
+ /**
451
+ * key is the column identifier (e.g. "date", "post-h1", "tags")
452
+ * @maxLength 100
453
+ */
454
+ key?: string | null;
455
+ /** type of the column */
456
+ type?: ColumnTypeWithLiterals;
457
+ /** editable flag */
458
+ editable?: boolean;
459
+ /** limit of characters for the column */
460
+ limit?: number | null;
461
+ /**
462
+ * width of the column
463
+ * @maxLength 100
464
+ */
465
+ width?: string | null;
466
+ }
467
+ declare enum ColumnType {
468
+ TEXT = "TEXT",
469
+ DATE = "DATE",
470
+ TEXT_LONG = "TEXT_LONG"
471
+ }
472
+ /** @enumType */
473
+ type ColumnTypeWithLiterals = ColumnType | 'TEXT' | 'DATE' | 'TEXT_LONG';
474
+ interface Row {
475
+ /**
476
+ * id of the row
477
+ * @readonly
478
+ * @format GUID
479
+ */
480
+ _id?: string | null;
481
+ /** order of the row */
482
+ order?: number | null;
483
+ /** data of the row (key = column key, value = cell value) */
484
+ data?: Record<string, any> | null;
485
+ /** status */
486
+ status?: RowStatusWithLiterals;
487
+ }
488
+ declare enum RowStatus {
489
+ DRAFT = "DRAFT",
490
+ PUBLISHED = "PUBLISHED"
491
+ }
492
+ /** @enumType */
493
+ type RowStatusWithLiterals = RowStatus | 'DRAFT' | 'PUBLISHED';
494
+ interface UpdateContentPlanRequest {
495
+ /**
496
+ * updated content plan rows
497
+ * @maxSize 100
498
+ */
499
+ updatedRows?: Row[];
500
+ /**
501
+ * deleted content plan rows
502
+ * @maxSize 1000
503
+ * @maxLength 1000
504
+ */
505
+ deletedRows?: string[] | null;
506
+ }
507
+ interface UpdateContentPlanResponse {
508
+ /** updated content plan */
509
+ contentPlan?: ContentPlan;
510
+ }
511
+ interface CreateContentPlanRequest {
512
+ /**
513
+ * ID of the content plan flow to generate the blog post briefs for.
514
+ *
515
+ * Omit to use the site's most recent eligible flow.
516
+ * Do not remove the fallback — existing callers depend on it.
517
+ * @format GUID
518
+ */
519
+ contentPlanFlowId?: string | null;
520
+ }
521
+ interface CreateContentPlanResponse {
522
+ /**
523
+ * Whether the blog post briefs were generated.
524
+ *
525
+ * Check this field as well as the HTTP status. Some failures return `false`
526
+ * here rather than an error.
527
+ */
528
+ success?: boolean | null;
529
+ /**
530
+ * Reason the generation failed.
531
+ *
532
+ * Returned only when `success` is `false`.
533
+ * @maxLength 1000
534
+ */
535
+ message?: string | null;
536
+ /**
537
+ * ID of the content plan flow the briefs were generated under.
538
+ *
539
+ * When this method regenerates a plan for a flow that already succeeded,
540
+ * this is a new ID. Poll this ID rather than the one you sent.
541
+ * @format GUID
542
+ */
543
+ contentPlanFlowId?: string | null;
544
+ }
545
+ interface DomainEvent extends DomainEventBodyOneOf {
546
+ createdEvent?: EntityCreatedEvent;
547
+ updatedEvent?: EntityUpdatedEvent;
548
+ deletedEvent?: EntityDeletedEvent;
549
+ actionEvent?: ActionEvent;
550
+ /** Event ID. With this ID you can easily spot duplicated events and ignore them. */
551
+ _id?: string;
552
+ /**
553
+ * Fully Qualified Domain Name of an entity. This is a unique identifier assigned to the API main business entities.
554
+ * For example, `wix.stores.catalog.product`, `wix.bookings.session`, `wix.payments.transaction`.
555
+ */
556
+ entityFqdn?: string;
557
+ /**
558
+ * Event action name, placed at the top level to make it easier for users to dispatch messages.
559
+ * For example: `created`/`updated`/`deleted`/`started`/`completed`/`email_opened`.
560
+ */
561
+ slug?: string;
562
+ /** ID of the entity associated with the event. */
563
+ entityId?: string;
564
+ /** Event timestamp in [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) format and UTC time. For example, `2020-04-26T13:57:50.699Z`. */
565
+ eventTime?: Date | null;
566
+ /**
567
+ * Whether the event was triggered as a result of a privacy regulation application
568
+ * (for example, GDPR).
569
+ */
570
+ triggeredByAnonymizeRequest?: boolean | null;
571
+ /** If present, indicates the action that triggered the event. */
572
+ originatedFrom?: string | null;
573
+ /**
574
+ * A sequence number that indicates the order of updates to an entity. For example, if an entity was updated at `16:00` and then again at `16:01`, the second update will always have a higher sequence number.
575
+ * You can use this number to make sure you're handling updates in the right order. Just save the latest sequence number on your end and compare it to the one in each new message. If the new message has an older (lower) number, you can safely ignore it.
576
+ */
577
+ entityEventSequence?: string | null;
578
+ }
579
+ /** @oneof */
580
+ interface DomainEventBodyOneOf {
581
+ createdEvent?: EntityCreatedEvent;
582
+ updatedEvent?: EntityUpdatedEvent;
583
+ deletedEvent?: EntityDeletedEvent;
584
+ actionEvent?: ActionEvent;
585
+ }
586
+ interface EntityCreatedEvent {
587
+ entity?: string;
588
+ }
589
+ interface RestoreInfo {
590
+ deletedDate?: Date | null;
591
+ }
592
+ interface EntityUpdatedEvent {
593
+ /**
594
+ * Since platformized APIs only expose PATCH and not PUT we can't assume that the fields sent from the client are the actual diff.
595
+ * This means that to generate a list of changed fields (as opposed to sent fields) one needs to traverse both objects.
596
+ * We don't want to impose this on all developers and so we leave this traversal to the notification recipients which need it.
597
+ */
598
+ currentEntity?: string;
599
+ }
600
+ interface EntityDeletedEvent {
601
+ /** Entity that was deleted. */
602
+ deletedEntity?: string | null;
603
+ }
604
+ interface ActionEvent {
605
+ body?: string;
606
+ }
607
+ interface MessageEnvelope {
608
+ /**
609
+ * App instance ID.
610
+ * @format GUID
611
+ */
612
+ instanceId?: string | null;
613
+ /**
614
+ * Event type.
615
+ * @maxLength 150
616
+ */
617
+ eventType?: string;
618
+ /** The identification type and identity data. */
619
+ identity?: IdentificationData;
620
+ /** Stringify payload. */
621
+ data?: string;
622
+ /** Details related to the account */
623
+ accountInfo?: AccountInfo;
624
+ }
625
+ interface IdentificationData extends IdentificationDataIdOneOf {
626
+ /**
627
+ * ID of a site visitor that has not logged in to the site.
628
+ * @format GUID
629
+ */
630
+ anonymousVisitorId?: string;
631
+ /**
632
+ * ID of a site visitor that has logged in to the site.
633
+ * @format GUID
634
+ */
635
+ memberId?: string;
636
+ /**
637
+ * ID of a Wix user (site owner, contributor, etc.).
638
+ * @format GUID
639
+ */
640
+ wixUserId?: string;
641
+ /**
642
+ * ID of an app.
643
+ * @format GUID
644
+ */
645
+ appId?: string;
646
+ /** @readonly */
647
+ identityType?: WebhookIdentityTypeWithLiterals;
648
+ }
649
+ /** @oneof */
650
+ interface IdentificationDataIdOneOf {
651
+ /**
652
+ * ID of a site visitor that has not logged in to the site.
653
+ * @format GUID
654
+ */
655
+ anonymousVisitorId?: string;
656
+ /**
657
+ * ID of a site visitor that has logged in to the site.
658
+ * @format GUID
659
+ */
660
+ memberId?: string;
661
+ /**
662
+ * ID of a Wix user (site owner, contributor, etc.).
663
+ * @format GUID
664
+ */
665
+ wixUserId?: string;
666
+ /**
667
+ * ID of an app.
668
+ * @format GUID
669
+ */
670
+ appId?: string;
671
+ }
672
+ declare enum WebhookIdentityType {
673
+ UNKNOWN = "UNKNOWN",
674
+ ANONYMOUS_VISITOR = "ANONYMOUS_VISITOR",
675
+ MEMBER = "MEMBER",
676
+ WIX_USER = "WIX_USER",
677
+ APP = "APP"
678
+ }
679
+ /** @enumType */
680
+ type WebhookIdentityTypeWithLiterals = WebhookIdentityType | 'UNKNOWN' | 'ANONYMOUS_VISITOR' | 'MEMBER' | 'WIX_USER' | 'APP';
681
+ interface AccountInfo {
682
+ /**
683
+ * ID of the Wix account associated with the event.
684
+ * @format GUID
685
+ */
686
+ accountId?: string | null;
687
+ /**
688
+ * ID of the parent Wix account. Only included when accountId belongs to a child account.
689
+ * @format GUID
690
+ */
691
+ parentAccountId?: string | null;
692
+ /**
693
+ * ID of the Wix site associated with the event. Only included when the event is tied to a specific site.
694
+ * @format GUID
695
+ */
696
+ siteId?: string | null;
697
+ }
698
+ /** @docsIgnore */
699
+ type CreateContentPlanApplicationErrors = {
700
+ code?: 'FLOW_NOT_READY_FOR_CONTENT_PLAN';
701
+ description?: string;
702
+ data?: Record<string, any>;
703
+ } | {
704
+ code?: 'CONTENT_PLAN_FLOW_NOT_FOUND';
705
+ description?: string;
706
+ data?: Record<string, any>;
707
+ } | {
708
+ code?: 'CONTENT_PLAN_FLOW_CANCELED';
709
+ description?: string;
710
+ data?: Record<string, any>;
711
+ };
712
+ /**
713
+ * Retrieves a list of blog post candidates for a content plan flow.
714
+ *
715
+ * Omit `contentPlanFlowId` to read the site's most recent successful flow.
716
+ * A site whose flows are all still running, failed, or canceled returns a
717
+ * not found error.
718
+ *
719
+ * Omit `paging` to return every candidate in a single response. When
720
+ * `paging` is present, `limit` accepts 1 to 100 and defaults to 50.
721
+ *
722
+ * Results are sorted by the order the content plan assigns them, then by
723
+ * descending keyword score. The sort isn't configurable.
724
+ * @param contentPlanFlowId - ID of the content plan flow to retrieve candidates for.
725
+ *
726
+ * Omit to read the site's most recent successful flow.
727
+ * @public
728
+ * @documentationMaturity preview
729
+ * @requiredField contentPlanFlowId
730
+ * @permissionId promote:seo:v1:content_plan_blog_post_candidate:list_blog_post_candidates
731
+ * @applicableIdentity APP
732
+ * @fqn wix.promote.seo.content.plan.v1.SeoBlogPostCandidateServiceV1.ListBlogPostCandidates
733
+ */
734
+ declare function listBlogPostCandidates(contentPlanFlowId: string, options?: ListBlogPostCandidatesOptions): Promise<NonNullablePaths<ListBlogPostCandidatesResponse, `blogPostCandidates` | `blogPostCandidates.${number}.seoData.settings.preventAutoRedirect`, 6>>;
735
+ interface ListBlogPostCandidatesOptions {
736
+ /**
737
+ * Whether to return only candidates that haven't been used for a blog post
738
+ * yet.
739
+ *
740
+ * A candidate is marked as used when a blog post is created from it in the
741
+ * Wix Blog product. An app can read this flag but can't set it, so track
742
+ * the posts you've written on your own side as well.
743
+ *
744
+ * Default: `false`, which returns every candidate.
745
+ */
746
+ includeOnlyUnmarked?: boolean | null;
747
+ /**
748
+ * Cursor paging. Omit for the first page.
749
+ *
750
+ * Omit this object entirely to return every candidate in a single response.
751
+ */
752
+ paging?: CursorPaging;
753
+ }
754
+ /**
755
+ * Generates the blog post briefs for a content plan flow.
756
+ *
757
+ * A content plan flow stops at `KEYWORD_RESEARCH` and waits. Call this
758
+ * method to generate the briefs and let the flow continue to `SUCCESS`,
759
+ * then poll Get Content Plan Flow to follow it. A flow that's only polled
760
+ * never completes.
761
+ *
762
+ * Called on a flow that already reached `SUCCESS`, this method regenerates
763
+ * the plan under a separate content plan flow. The response carries the new
764
+ * `contentPlanFlowId`, and you poll that ID rather than the original. The
765
+ * original flow keeps its own candidates.
766
+ *
767
+ * Check `success` in the response as well as the HTTP status. A request
768
+ * that omits `contentPlanFlowId` reports every failure that way, with
769
+ * `success` set to `false` and the reason in `message` rather than an
770
+ * error. A generation failure reports that way even when you do send the
771
+ * ID.
772
+ *
773
+ * Call this method once for a flow and wait for it to return. Concurrent
774
+ * calls for the same site can produce duplicate content plans.
775
+ * @public
776
+ * @documentationMaturity preview
777
+ * @permissionId promote:seo:v1:content_plan_blog_post_candidate:create_content_plan
778
+ * @applicableIdentity APP
779
+ * @fqn wix.promote.seo.content.plan.v1.SeoBlogPostCandidateServiceV1.CreateContentPlan
780
+ */
781
+ declare function createContentPlan(options?: CreateContentPlanOptions): Promise<CreateContentPlanResponse & {
782
+ __applicationErrorsType?: CreateContentPlanApplicationErrors;
783
+ }>;
784
+ interface CreateContentPlanOptions {
785
+ /**
786
+ * ID of the content plan flow to generate the blog post briefs for.
787
+ *
788
+ * Omit to use the site's most recent eligible flow.
789
+ * Do not remove the fallback — existing callers depend on it.
790
+ * @format GUID
791
+ */
792
+ contentPlanFlowId?: string | null;
793
+ }
794
+
795
+ export { type AccountInfo, type ActionEvent, type ApplicationError, type BlogPostCandidate, type BriefData, type BulkActionMetadata, type BulkMarkBlogPostCandidateItem, type BulkMarkBlogPostCandidateResult, type BulkMarkBlogPostCandidatesRequest, type BulkMarkBlogPostCandidatesResponse, type CandidateData, type Column, ColumnType, type ColumnTypeWithLiterals, type ContentPlan, type CreateContentPlanApplicationErrors, type CreateContentPlanOptions, type CreateContentPlanRequest, type CreateContentPlanResponse, type CursorPaging, type CursorPagingMetadata, type Cursors, type DomainEvent, type DomainEventBodyOneOf, type EntityCreatedEvent, type EntityDeletedEvent, type EntityUpdatedEvent, type GetBlogPostCandidateByIdRequest, type GetBlogPostCandidateByIdResponse, type GetBlogPostCandidateRequest, type GetBlogPostCandidateResponse, type GetContentPlanRequest, type GetContentPlanResponse, type IdentificationData, type IdentificationDataIdOneOf, type ItemMetadata, type Keyword, type ListBlogPostCandidatesOptions, type ListBlogPostCandidatesRequest, type ListBlogPostCandidatesResponse, type MarkBlogPostCandidateRequest, type MarkBlogPostCandidateResponse, type MessageEnvelope, type PeopleAlsoAskAnswer, type PeopleAlsoAskQuestion, type QueryBlogPostCandidatesRequest, type QueryBlogPostCandidatesResponse, type RestoreInfo, type Row, RowStatus, type RowStatusWithLiterals, type SeoSchema, type SerpData, type Settings, type Tag, type UpdateContentPlanRequest, type UpdateContentPlanResponse, WebhookIdentityType, type WebhookIdentityTypeWithLiterals, createContentPlan, listBlogPostCandidates };