@wix/agent-skills 1.19.0 → 1.19.1

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.
Files changed (58) hide show
  1. package/package.json +1 -1
  2. package/skills/wix-app/SKILL.md +33 -31
  3. package/skills/wix-app/references/DASHBOARD_PAGE.md +6 -10
  4. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +16 -7
  5. package/skills/wix-app/references/WIX_PATTERNS_DOCS.md +53 -131
  6. package/skills/wix-app/references/dashboard-page/UX_SUCCESS_MODEL.md +1 -2
  7. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +83 -73
  8. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +3 -2
  9. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +9 -0
  10. package/skills/wix-app/references/editor-react-component/PARTS.md +5 -2
  11. package/skills/wix-app/references/editor-react-component/REACT-GUIDELINES.md +1 -1
  12. package/skills/wix-app/scripts/pkg-root.cjs +73 -0
  13. package/skills/wix-app/scripts/scan-a11y-code.cjs +310 -40
  14. package/skills/wix-app/scripts/scan-a11y-eslint.cjs +118 -24
  15. package/skills/wix-app/scripts/scan-a11y-render.cjs +551 -0
  16. package/skills/wix-app/scripts/scan-a11y-review.cjs +373 -0
  17. package/skills/wix-base44-connector/SKILL.md +24 -22
  18. package/skills/wix-base44-connector/scripts/utils.cjs +39 -3
  19. package/skills/wix-docs/SKILL.md +47 -20
  20. package/skills/wix-headless/entry/bootstrap.mjs +106 -50
  21. package/skills/wix-headless/entry/skill.md +5 -3
  22. package/skills/wix-headless/references/managed/AUTHENTICATION.md +25 -5
  23. package/skills/wix-headless-fast/SKILL.md +25 -7
  24. package/skills/wix-headless-fast/entry/skill.md +23 -14
  25. package/skills/wix-headless-fast/install/fast-path.mjs +48 -5
  26. package/skills/wix-headless-fast/install/pin-agents-md.mjs +57 -0
  27. package/skills/wix-headless-fast/references/shared/CUSTOM_OPERATIONS.md +3 -3
  28. package/skills/wix-headless-fast/references/storefront/INSTRUCTIONS.md +204 -35
  29. package/skills/wix-headless-fast/references/storefront/app/hooks/storefront/useShop.ts +146 -36
  30. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/cart-store.ts +8 -2
  31. package/skills/wix-headless-fast/references/storefront/app/wix/storefront/catalog.ts +95 -20
  32. package/skills/wix-headless-fast/references/storefront/seed/SEED.md +21 -2
  33. package/skills/wix-headless-fast/references/storefront/seed/seed-store.mjs +104 -18
  34. package/skills/wix-manage/SKILL.md +13 -7
  35. package/skills/wix-manage/references/google-ads/billing-and-payment.md +3 -3
  36. package/skills/wix-manage/references/google-ads/create-performance-max-campaign.md +8 -8
  37. package/skills/wix-manage/references/google-ads/get-campaign-suggestions.md +4 -4
  38. package/skills/wix-manage/references/google-ads/google-ads-dashboard-navigation.md +1 -1
  39. package/skills/wix-manage/references/google-ads/install-and-create-account.md +9 -9
  40. package/skills/wix-manage/references/google-ads/query-campaign-analytics.md +7 -7
  41. package/skills/wix-manage/references/seo/manage-content-plan.md +181 -135
  42. package/skills/wix-manage/references/seo/manage-google-search-console.md +272 -0
  43. package/skills/wix-manage/references/sites/upload-static-site.md +53 -0
  44. package/skills/wix-manage/references/stores/change-store-currency.md +1 -1
  45. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed-with-install.md +3 -1
  46. package/skills/wix-vibe-headless/platforms/base44-ecom-light-seed.md +3 -1
  47. package/skills/wix-vibe-headless/platforms/base44-ecom-light.md +1 -1
  48. package/skills/wix-vibe-headless/references/storefront/INSTRUCTIONS.md +1 -1
  49. package/skills/wix-app/references/dashboard-page/COLLECTION_TOOLKIT.md +0 -80
  50. package/skills/wix-app/references/dashboard-page/ENTITY_PAGE_TOOLKIT.md +0 -140
  51. package/skills/wix-app/references/dashboard-page/PATTERNS_BUNDLE_READING.md +0 -112
  52. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductCard.tsx +0 -100
  53. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductDetailView.tsx +0 -130
  54. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ProductGrid.tsx +0 -48
  55. package/skills/wix-headless-fast/references/storefront/app/components/storefront/ShopView.tsx +0 -66
  56. package/skills/wix-headless-fast/references/storefront/app/components/storefront/VariantPicker.tsx +0 -103
  57. package/skills/wix-headless-fast/references/storefront/app-astro/pages/products/[slug].astro +0 -56
  58. package/skills/wix-headless-fast/references/storefront/app-astro/pages/shop.astro +0 -23
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: "Install Google Ads and Create an Account"
3
- description: "One-time setup for running Google paid ads on a Wix site: install the Wix Google Ads app, then create the Google Ads account that every campaign, suggestion, and analytics call depends on. Covers checking whether an account already exists, choosing a currency, optionally attaching a promotional incentive (credit offer), linking a Google Merchant Center account, and deleting an account. Use when the user wants to 'set up Google Ads', 'connect Google Ads', 'start advertising on Google', 'create a Google Ads account', or hits an ACCOUNT_NOT_FOUND / app-not-installed error before creating a campaign. Google Ads REST API, base https://www.wixapis.com/google-ads/v1."
3
+ description: "One-time setup for running Google paid ads on a Wix site: install the Wix Google Ads app, then create the Google Ads account that every campaign, suggestion, and analytics call depends on. Covers checking whether an account already exists, choosing a currency, optionally attaching a promotional incentive (credit offer), linking a Google Merchant Center account, and deleting an account. Use when the user wants to 'set up Google Ads', 'connect Google Ads', 'start advertising on Google', 'create a Google Ads account', or hits an ACCOUNT_NOT_FOUND / app-not-installed error before creating a campaign. Google Ads REST API, base https://www.wixapis.com/_serverless/pa-google/v1."
4
4
  ---
5
5
  # RECIPE: Install Google Ads and Create an Account
6
6
 
7
7
  Setting up Google Ads on a Wix site is a **strict two-step prerequisite** for everything else in this area: (1) install the Wix Google Ads app, then (2) create the Google Ads account. Campaigns, suggestions, analytics, and billing all fail with `ACCOUNT_NOT_FOUND` (or an app-not-installed error) until both are done. This is a one-time setup per site.
8
8
 
9
- Base URL for all endpoints: `https://www.wixapis.com/google-ads/v1`. The `<AUTH>` placeholder is shorthand for the `Authorization` header; body-bearing calls also need `Content-Type: application/json`.
9
+ Base URL for all endpoints: `https://www.wixapis.com/_serverless/pa-google/v1`. The `<AUTH>` placeholder is shorthand for the `Authorization` header; body-bearing calls also need `Content-Type: application/json`.
10
10
 
11
11
  > **This flow creates a billable advertising account.** Creating the account and launching campaigns spends the site owner's real money. Confirm intent with the user before calling **Create Account**, and surface the chosen currency.
12
12
 
@@ -17,7 +17,7 @@ Base URL for all endpoints: `https://www.wixapis.com/google-ads/v1`. The `<AUTH>
17
17
  Before installing or creating anything, check for an existing account. **Get Account For Current Site** returns an empty response (not an error) when none exists, so it's the safe probe.
18
18
 
19
19
  ```bash
20
- curl -X GET 'https://www.wixapis.com/google-ads/v1/accounts/current-site' -H 'Authorization: <AUTH>'
20
+ curl -X GET 'https://www.wixapis.com/_serverless/pa-google/v1/accounts/current-site' -H 'Authorization: <AUTH>'
21
21
  ```
22
22
 
23
23
  - **`account` present** → setup is already done. Skip to whatever the user actually wants (create a campaign, view analytics, etc.). Do **not** create a second account — Create Account returns `ACCOUNT_ALREADY_EXISTS`.
@@ -48,7 +48,7 @@ Example response for an existing account:
48
48
  Idempotent — safe to call even if already installed (no effect). Required before Create Account.
49
49
 
50
50
  ```bash
51
- curl -X POST 'https://www.wixapis.com/google-ads/v1/install-if-not-installed' \
51
+ curl -X POST 'https://www.wixapis.com/_serverless/pa-google/v1/install-if-not-installed' \
52
52
  -H 'Authorization: <AUTH>' -H 'Content-Type: application/json' -d '{}'
53
53
  ```
54
54
 
@@ -61,7 +61,7 @@ Returns `{}`. Always run this before the first Create Account on a site.
61
61
  New accounts in supported currencies can attach an **incentive** — a promotional credit granted after the account spends a threshold. Skip this step for unsupported currencies (the call returns no offers).
62
62
 
63
63
  ```bash
64
- curl -X GET 'https://www.wixapis.com/google-ads/v1/incentives?currency=USD' -H 'Authorization: <AUTH>'
64
+ curl -X GET 'https://www.wixapis.com/_serverless/pa-google/v1/incentives?currency=USD' -H 'Authorization: <AUTH>'
65
65
  ```
66
66
 
67
67
  Returns up to three tiers (`lowOffer`, `mediumOffer`, `highOffer`), each with an `incentiveId`, an `awardAmount` (credit granted), and a `requiredAmount` (spend needed to unlock it), plus a `consolidatedTermsAndConditionsUrl`. Present the tiers to the user and let them pick; carry the chosen `incentiveId` into STEP 3 as `selectedIncentiveId`. The incentive is recorded now and applied automatically once the account's budget is assigned — there is no separate apply call in this flow.
@@ -73,7 +73,7 @@ Returns up to three tiers (`lowOffer`, `mediumOffer`, `highOffer`), each with an
73
73
  Requires `currency` (ISO-4217, e.g. `USD`). Pass `selectedIncentiveId` if the user picked one in STEP 2. **Confirm with the user before this call** — it provisions a billable account.
74
74
 
75
75
  ```bash
76
- curl -X POST 'https://www.wixapis.com/google-ads/v1/accounts' \
76
+ curl -X POST 'https://www.wixapis.com/_serverless/pa-google/v1/accounts' \
77
77
  -H 'Authorization: <AUTH>' -H 'Content-Type: application/json' \
78
78
  -d '{
79
79
  "currency": "USD",
@@ -107,7 +107,7 @@ The currency choice is durable and drives budget minimums/maximums and manager-a
107
107
  `UpdateAccount` is a partial update — send only the fields you're changing. Merchant Center linking is needed before a retail Performance Max campaign can serve product ads.
108
108
 
109
109
  ```bash
110
- curl -X PATCH 'https://www.wixapis.com/google-ads/v1/accounts/a1b2c3d4-e5f6-7890-abcd-ef1234567890' \
110
+ curl -X PATCH 'https://www.wixapis.com/_serverless/pa-google/v1/accounts/a1b2c3d4-e5f6-7890-abcd-ef1234567890' \
111
111
  -H 'Authorization: <AUTH>' -H 'Content-Type: application/json' \
112
112
  -d '{ "account": { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "merchantCenterAccountId": "9876543210" } }'
113
113
  ```
@@ -119,7 +119,7 @@ The response's `merchantCenterAccountLinkStatus.status` starts at `PENDING` —
119
119
  Conversion actions (Purchase, Page View, etc.) are what campaigns optimize toward. To inspect them:
120
120
 
121
121
  ```bash
122
- curl -X GET 'https://www.wixapis.com/google-ads/v1/accounts/current-site/conversion-actions' -H 'Authorization: <AUTH>'
122
+ curl -X GET 'https://www.wixapis.com/_serverless/pa-google/v1/accounts/current-site/conversion-actions' -H 'Authorization: <AUTH>'
123
123
  ```
124
124
 
125
125
  ### Delete the account
@@ -127,7 +127,7 @@ curl -X GET 'https://www.wixapis.com/google-ads/v1/accounts/current-site/convers
127
127
  `DeleteAccount` unlinks and removes the account. This is destructive and cannot be undone — **always confirm with the user first**, and prefer pausing campaigns over deleting the whole account when the user just wants to stop spending.
128
128
 
129
129
  ```bash
130
- curl -X DELETE 'https://www.wixapis.com/google-ads/v1/accounts/a1b2c3d4-e5f6-7890-abcd-ef1234567890' -H 'Authorization: <AUTH>'
130
+ curl -X DELETE 'https://www.wixapis.com/_serverless/pa-google/v1/accounts/a1b2c3d4-e5f6-7890-abcd-ef1234567890' -H 'Authorization: <AUTH>'
131
131
  ```
132
132
 
133
133
  Returns `{}`. Errors with `ACCOUNT_NOT_FOUND` if no account exists.
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: "Query Campaign Performance Analytics"
3
- description: "Reads performance analytics for a Google Ads campaign on a Wix site: daily performance metrics (impressions, clicks, CTR, cost, leads, phone calls) with optional previous-period comparison and trends; conversion metrics from Wix Analytics (orders, revenue, leads, CPL, ROAS); the search terms that triggered a campaign's ads; per-product shopping performance for retail campaigns; and per-asset performance (headlines, descriptions, images) for PMAX Leads. Explains when to use campaignResourceName vs the Wix campaignId, the dateRange shape, field enums, sorting, and paging. Use when the user asks 'how is my campaign doing', 'show ad performance', 'what search terms triggered my ads', 'which products/assets perform best', 'campaign ROI/ROAS', or 'conversions from my Google ads'. REST base https://www.wixapis.com/google-ads/v1."
3
+ description: "Reads performance analytics for a Google Ads campaign on a Wix site: daily performance metrics (impressions, clicks, CTR, cost, leads, phone calls) with optional previous-period comparison and trends; conversion metrics from Wix Analytics (orders, revenue, leads, CPL, ROAS); the search terms that triggered a campaign's ads; per-product shopping performance for retail campaigns; and per-asset performance (headlines, descriptions, images) for PMAX Leads. Explains when to use campaignResourceName vs the Wix campaignId, the dateRange shape, field enums, sorting, and paging. Use when the user asks 'how is my campaign doing', 'show ad performance', 'what search terms triggered my ads', 'which products/assets perform best', 'campaign ROI/ROAS', or 'conversions from my Google ads'. REST base https://www.wixapis.com/_serverless/pa-google/v1."
4
4
  ---
5
5
  # RECIPE: Query Campaign Performance Analytics
6
6
 
7
7
  Read how a Google Ads campaign is performing. Six query endpoints cover different breakdowns; picking the right one depends on the metric and the campaign type. Performance data is only available once a campaign is `LIVE`, and typically appears within a few hours of activity.
8
8
 
9
- Base URL: `https://www.wixapis.com/google-ads/v1` (search-term V2 is under `/v2`). `<AUTH>` is the `Authorization` header; body calls also need `Content-Type: application/json`. All endpoints are read-only.
9
+ Base URL: `https://www.wixapis.com/_serverless/pa-google/v1` (search-term V2 is under `/v2`). `<AUTH>` is the `Authorization` header; body calls also need `Content-Type: application/json`. All endpoints are read-only.
10
10
 
11
11
  **Two identifiers — get them right:**
12
12
  - **`campaignResourceName`** — the Google Ads resource name `customers/{customerId}/campaigns/{campaignId}` (from `campaign.resourceName`). Used by **Performance Metrics** and **Search Term Metrics (v1)**.
@@ -33,7 +33,7 @@ Both come from Get/List Campaign (see [Manage Campaign Lifecycle](manage-campaig
33
33
  Clicks, impressions, CTR, cost, leads, phone calls — per day, plus a summary row. `fields` chooses which metrics to return (defaults to clicks, impressions, CTR, cost, phone calls, date). `includePreviousPeriod: true` adds a `previousPeriodSummaryRow` and `trends` (decimal % change vs the equivalent preceding period).
34
34
 
35
35
  ```bash
36
- curl -X POST 'https://www.wixapis.com/google-ads/v1/performance-metrics' \
36
+ curl -X POST 'https://www.wixapis.com/_serverless/pa-google/v1/performance-metrics' \
37
37
  -H 'Authorization: <AUTH>' -H 'Content-Type: application/json' \
38
38
  -d '{
39
39
  "campaignResourceName": "customers/3827461950/campaigns/7412836509",
@@ -60,7 +60,7 @@ curl -X POST 'https://www.wixapis.com/google-ads/v1/performance-metrics' \
60
60
  Business outcomes from **Wix Analytics** (not Google). Both `campaignId` and `dateRange` are **required**. Complex query — 120s SLA.
61
61
 
62
62
  ```bash
63
- curl -X POST 'https://www.wixapis.com/google-ads/v1/conversion-metrics' \
63
+ curl -X POST 'https://www.wixapis.com/_serverless/pa-google/v1/conversion-metrics' \
64
64
  -H 'Authorization: <AUTH>' -H 'Content-Type: application/json' \
65
65
  -d '{ "campaignId": "b3f8e241-7c4a-4d19-a562-9f1e30d87c05", "dateRange": { "custom": { "from": "2026-03-01", "to": "2026-03-31" } } }'
66
66
  ```
@@ -74,7 +74,7 @@ curl -X POST 'https://www.wixapis.com/google-ads/v1/conversion-metrics' \
74
74
  The actual queries users typed. Use **V2** (`/v2/search-term-metrics`, keyed by `campaignId`) — it supports both Smart and PMAX Leads. Optional `searchTermText` (contains-match) and `searchTermTextsFilter` (`{ type: "MATCH" | "NOT_MATCH", searchTermTexts: [...] }`). Sortable by `COST`/`CLICKS`/`IMPRESSIONS`; paged with `nextPageToken`.
75
75
 
76
76
  ```bash
77
- curl -X POST 'https://www.wixapis.com/google-ads/v2/search-term-metrics' \
77
+ curl -X POST 'https://www.wixapis.com/_serverless/pa-google/v2/search-term-metrics' \
78
78
  -H 'Authorization: <AUTH>' -H 'Content-Type: application/json' \
79
79
  -d '{
80
80
  "campaignId": "b3f8e241-7c4a-4d19-a562-9f1e30d87c05",
@@ -100,7 +100,7 @@ curl -X POST 'https://www.wixapis.com/google-ads/v2/search-term-metrics' \
100
100
  Product-level rows for a Shopping campaign, plus a summary with total conversions, revenue, and ROAS. `resultSetting` controls the payload: `SUMMARY_ONLY`, `RESULTS_ONLY`, or `SUMMARY_AND_RESULTS`. 120s SLA. Note: per-product `conversions`/`conversionRate` always return 0 (not queried from Google) — use the summary's `totalConversions`/`roas` for outcomes.
101
101
 
102
102
  ```bash
103
- curl -X POST 'https://www.wixapis.com/google-ads/v1/shopping-performance-metrics' \
103
+ curl -X POST 'https://www.wixapis.com/_serverless/pa-google/v1/shopping-performance-metrics' \
104
104
  -H 'Authorization: <AUTH>' -H 'Content-Type: application/json' \
105
105
  -d '{
106
106
  "campaignId": "b3f8e241-7c4a-4d19-a562-9f1e30d87c05",
@@ -119,7 +119,7 @@ Results carry `productTitle`, `productImageUrl`, and the Wix `productId`; the `s
119
119
  Which creative assets perform best. `filter.assetTypes` narrows to specific roles (`HEADLINE`, `DESCRIPTION`, `MARKETING_IMAGE`, …).
120
120
 
121
121
  ```bash
122
- curl -X POST 'https://www.wixapis.com/google-ads/v1/asset-performance-metrics' \
122
+ curl -X POST 'https://www.wixapis.com/_serverless/pa-google/v1/asset-performance-metrics' \
123
123
  -H 'Authorization: <AUTH>' -H 'Content-Type: application/json' \
124
124
  -d '{
125
125
  "campaignId": "b3f8e241-7c4a-4d19-a562-9f1e30d87c05",
@@ -5,163 +5,225 @@ description: Generate an SEO content plan and read its blog post topics, or trou
5
5
 
6
6
  # Generate and Read a Wix Site's Content Plan
7
7
 
8
- ## Choose the request path before calling an API
9
-
10
- For a request to **generate a new plan**, follow the generation sequence below.
11
- For a request about an **existing flow**, use this branch instead; do not start
12
- the generation sequence or make a discovery call to look for the flow.
13
-
14
- `KEYWORD_RESEARCH` is an intentional pause, even after ten minutes. Explain
15
- that Create Content Plan (step 3) releases the existing flow; do not cancel it
16
- or trigger a replacement just because it is parked.
17
- First check whether the conversation or a prior response contains the actual
18
- `contentPlanFlowId`:
19
-
20
- - **Missing ID:** Explain the intentional pause and ask for the existing flow
21
- ID. End the turn without making a status or release call. You can name the
22
- release endpoint, `POST https://www.wixapis.com/promote/seo/v1/create-content-plan`,
23
- but do not execute an example request. Placeholder text such as
24
- `<YOUR_FLOW_ID>` is never an API argument.
25
- - **Known ID:** Use that actual flow UUID in the step 3 request's
26
- `contentPlanFlowId` field to release the existing flow when requested.
27
-
28
- For example, when the user reports a flow parked at `KEYWORD_RESEARCH` but
29
- provides only a site ID, the next action is a reply, not an API call:
30
-
31
- > That status is an intentional pause. Create Content Plan releases the
32
- > existing flow. Please send the content plan flow ID from your trigger or
33
- > status response so I can use it in the release request.
34
-
35
- The user's reported status is enough to explain the pause; checking it first
36
- requires the very flow ID that is missing. A site ID is not a flow ID, even
37
- though both have UUID format.
38
- Do not guess a collection endpoint to discover the active flow.
39
-
40
- The complete status URL is
41
- `https://www.wixapis.com/promote/seo/v1/content-plan-flows/{contentPlanFlowId}`.
42
- Use this exact public base path and substitute the known ID. Do not call
43
- `GET /content-plan-flows` without an ID or construct a URL from a service name.
44
-
45
- Trigger, poll, release, poll, read. That is the full loop. The API is
46
- asynchronous — generation takes minutes — and the flow **parks at
47
- `KEYWORD_RESEARCH` until you explicitly release it**.
48
-
49
- All paths are relative to `https://www.wixapis.com/promote/seo/v1`.
50
- The API selects the site from the caller's authorization context.
51
- Writing requires the **Manage SEO Settings** permission.
52
-
53
- For a generation request, the only writes in this workflow are Trigger and
54
- Create Content Plan. Do not update the site's business profile, name,
55
- description, categories, or publication state to try to accelerate generation.
56
- Those are separate tasks requiring the user's actual data and authorization.
57
- `CREATED` can persist while work is queued; it does not justify setup changes
58
- or extra discovery calls. Continue checking the same flow without modifying
59
- the site.
60
-
61
- Keep every call scoped to the site the user selected. If site context cannot
62
- be resolved, report the lookup failure and request clarification; do not
63
- substitute another available site or change its business information. Missing
64
- context is not proof that the selected site does not exist or belongs to a
65
- different account. Say that its context could not be retrieved; do not claim
66
- that the user's site ID is invalid or offer replacement sites. Likewise, unmet
67
- prerequisites do not authorize switching sites or inventing business data.
8
+ A **content plan** is a set of suggested blog post briefs, including titles,
9
+ keywords, and the existing site pages they support. A **content plan flow** is
10
+ the asynchronous job that generates those briefs. Its `contentPlanFlowId` is
11
+ a flow UUID, distinct from the site's ID, and its `status` reports progress.
12
+ Generation creates briefs, not published posts.
13
+
14
+ `KEYWORD_RESEARCH` means keyword research is complete and the job is waiting
15
+ for the **Create Content Plan** request to generate the briefs. This request
16
+ releases the intentional pause; polling alone does not advance it.
17
+
18
+ Use the selected site's authorization context. Trigger and Create Content Plan
19
+ are writes requiring **Manage SEO Settings**; execute them when the user has
20
+ requested generation or explicitly confirmed it.
21
+
22
+ ## Resume or read an existing flow
23
+
24
+ An existing flow is a job already started by a previous trigger, including one
25
+ discussed earlier in the conversation. To finish it or read its results:
26
+
27
+ 1. Find its actual `contentPlanFlowId` in the conversation or a previous
28
+ trigger/status response. A site ID is not a flow ID, even though both are
29
+ UUIDs. If the ID is missing, explain the intentional pause when the user
30
+ reports `KEYWORD_RESEARCH`, ask for the flow ID, and end the turn without an
31
+ API call. Never submit a placeholder. Do not offer a new flow or a different
32
+ site as an alternative to recovering the ID.
33
+ 2. Read that flow with
34
+ `GET https://www.wixapis.com/promote/seo/v1/content-plan-flows/{contentPlanFlowId}`.
35
+ Read `contentPlanFlow.status`; see the response and status table in
36
+ [Check the flow status](#2-poll-until-keyword_research).
37
+ 3. At `SUCCESS`, go directly to [Read the briefs](#5-read-the-briefs).
38
+ At `KEYWORD_RESEARCH`, when completion is requested, call
39
+ [Create Content Plan](#3-release-the-flow) once with this flow ID.
40
+ For an earlier in-progress status, continue checking this same flow until
41
+ it reaches the pause. If already at `CONTENT_PLAN`, continue to step 4
42
+ without calling Create Content Plan again. For a terminal or unmet-requirement
43
+ status, follow the status table and stop.
44
+ 4. After Create Content Plan succeeds, retain its returned flow ID and
45
+ [check until SUCCESS](#4-poll-until-success), then
46
+ [read the briefs](#5-read-the-briefs). Do not trigger a replacement or release
47
+ a successful flow just to retrieve its results.
48
+
49
+ ## Generate a new plan
50
+
51
+ When the user requests a new plan, follow these steps in order. The request and
52
+ response examples for each step are in [API steps](#api-steps).
53
+
54
+ 1. [Trigger](#1-trigger) once and retain the returned flow ID.
55
+ 2. [Check the flow status](#2-poll-until-keyword_research) until `KEYWORD_RESEARCH`.
56
+ 3. [Call Create Content Plan](#3-release-the-flow) once to continue generation.
57
+ 4. [Check until SUCCESS](#4-poll-until-success).
58
+ 5. [Read the briefs](#5-read-the-briefs) and report the actual returned topics.
59
+
60
+ Only Trigger and Create Content Plan write data in the generation path. Do not
61
+ change the site's business profile, name, description, categories, or publication
62
+ state to accelerate it. Those are separate tasks requiring real user data and
63
+ authorization. `CREATED` can mean queued work, not missing setup.
68
64
 
69
65
  ## Polling without losing progress
70
66
 
71
- Treat each numbered step below as a separate API execution, not sections of
72
- one script. Even a loop capped at 60 polls can outlive the execution timeout
73
- and lose the returned flow ID. A polling script must issue one GET and return
74
- `{ contentPlanFlowId, status }` immediately; decide the next action after that
75
- response. Never embed the trigger, polling loops, release, and candidate read
76
- in a single execution. Trigger and release are mutations: if the client asks
77
- whether an execution changes data, identify them as writes, not read-only.
78
-
79
- Generation waits on an external process. Do not put the entire generation in
80
- one long-running function, an unbounded `while` loop, or a busy-wait. Trigger
81
- once and return the flow ID immediately. Use separate, bounded status checks
82
- for the same ID so each response is visible and you can act on its status.
83
- A status check is one GET, not a loop that waits for a terminal state.
84
- Use the client's supported waiting mechanism between checks; do not assume
85
- that timers or sleep functions exist inside an API execution sandbox.
86
-
87
- Continue across status checks while the flow is progressing. At
88
- `KEYWORD_RESEARCH`, release it immediately once, then keep checking that same
89
- flow until `SUCCESS` and read its candidates. Do not keep polling the parked
90
- state instead of releasing it, or stop with only a promise to finish later.
91
- If the client cannot continue waiting, report the flow ID and last observed
92
- status honestly; that is an incomplete generation, not success.
93
-
94
- ## The exact call sequence
67
+ **One API execution makes one HTTP request and returns.** The sequence below
68
+ is a series of separate calls, with a decision after each response. It is not
69
+ one code block containing the entire workflow. Never wrap API calls in a
70
+ `for`/`while` loop, a timer, or a function that polls until a target status.
71
+
72
+ Retain each response's flow ID before the next call. Wait between status checks
73
+ using the client's supported waiting capability, outside the API execution;
74
+ do not assume timers exist inside that execution or busy-wait there.
75
+
76
+ Keep checking while work progresses. If waiting cannot continue, report the
77
+ flow ID and last observed status as incomplete; do not claim success or merely
78
+ promise to finish later. Identify trigger and release as writes if asked
79
+ whether an execution changes data.
80
+
81
+ ## API steps
95
82
 
96
83
  ### 1. Trigger
97
84
 
98
85
  ```
99
- POST /content-plan-flows/trigger
86
+ POST https://www.wixapis.com/promote/seo/v1/content-plan-flows/trigger
100
87
  {}
101
88
  ```
102
89
 
103
- Returns `{ "contentPlanFlowId": "..." }`. Return this response and end this
104
- execution here. Save the ID in the conversation before making any status
105
- request. Do not append step 2 to the trigger script.
90
+ Response:
91
+
92
+ ```json
93
+ { "contentPlanFlowId": "<flow-uuid>" }
94
+ ```
95
+
96
+ `<flow-uuid>` and other angle-bracket values in these examples are placeholders;
97
+ substitute actual returned values before making requests. Return this response
98
+ and end this execution here. Save the ID before making any status request.
99
+ Do not append step 2 to the trigger script.
100
+ See [Trigger Content Plan Generation Flow](https://dev.wix.com/docs/api-reference/business-management/seo/content-plan-content-plan-flow-v1/trigger-content-plan-generation-flow).
106
101
 
107
102
  ### 2. Poll until KEYWORD_RESEARCH
108
103
 
109
104
  ```
110
- GET /content-plan-flows/{contentPlanFlowId}
105
+ GET https://www.wixapis.com/promote/seo/v1/content-plan-flows/{contentPlanFlowId}
111
106
  ```
112
107
 
113
108
  Execute this GET once and return its response. This execution contains no
114
109
  `for`/`while` loop and no timer. Repeat it as a separate call when another
115
110
  status check is needed. Keep the response compact: flow ID and status suffice.
116
111
 
117
- The response is `{ "contentPlanFlow": { "id": "...", "status": "..." } }`.
118
- Read `contentPlanFlow.status`, not a top-level `status`. A missing status is a
119
- response-shape problem: inspect the response instead of silently looping.
120
- `CREATED` alone does not identify a missing prerequisite. If the flow remains
121
- there without progressing, report the stalled flow ID and observed status; do
122
- not invent a missing business category or description.
123
- Always send the trigger's ID when following this generation. The documented
124
- omitted-ID behavior selects a previous successful flow, not the active flow;
125
- it is not a way to discover the ID of a parked flow.
126
- See [Get Content Plan Flow](https://dev.wix.com/docs/api-reference/business-management/seo/content-plan-content-plan-flow-v1/get-content-plan-flow).
112
+ Example response, showing the public flow fields (optional fields may be absent):
113
+
114
+ ```json
115
+ {
116
+ "contentPlanFlow": {
117
+ "id": "<flow-uuid>",
118
+ "createdAt": "2026-09-08T10:00:00.000Z",
119
+ "updatedAt": "2026-09-08T10:01:00.000Z",
120
+ "status": "KEYWORD_RESEARCH",
121
+ "origin": "AGENT",
122
+ "summaryId": "<summary-uuid>",
123
+ "keywordResearchId": "<keyword-research-uuid>"
124
+ }
125
+ }
126
+ ```
127
127
 
128
- Typical status progression: `CREATED` → `SITE_ANALYSIS` → `KEYWORD_RESEARCH`. Check every
129
- few seconds using the bounded approach above. Completion time varies.
128
+ Read `contentPlanFlow.status`, not a top-level `status`. If it is missing,
129
+ inspect the response instead of silently looping. Always use this generation's
130
+ flow ID; if it stays `CREATED`, report the ID and observed status without
131
+ inventing missing business prerequisites.
132
+ See [Get Content Plan Flow](https://dev.wix.com/docs/api-reference/business-management/seo/content-plan-content-plan-flow-v1/get-content-plan-flow).
130
133
 
131
- **Stop polling and act on these terminal states:**
132
- - `PENDING_REQUIREMENTS` — the site has unmet prerequisites, such as missing
133
- business location information. Identify the actual missing prerequisite from
134
- available evidence; do not assume category or description is the cause.
135
- Report what needs completing and do not repeatedly trigger new flows.
136
- - `FAIL` — the pipeline failed. Trigger a new flow to retry.
137
- - `CANCELED` — someone canceled the flow.
134
+ `contentPlanFlow.status` is a string enum. Status checks may skip intermediate
135
+ states; decide from the returned value rather than requiring every transition.
136
+ Typical status progression: `CREATED` → `SITE_ANALYSIS` → `KEYWORD_RESEARCH`
137
+ → **call Create Content Plan** → `CONTENT_PLAN` → `SUCCESS`.
138
+
139
+ | Status | Meaning and next action |
140
+ | --- | --- |
141
+ | `CREATED` | Queued or starting. Check the same flow again; do not change site settings. |
142
+ | `SITE_ANALYSIS` | Analyzing site pages. Continue separate checks. |
143
+ | `SITE_SUMMARY` | Summarizing existing content. Continue separate checks. |
144
+ | `KEYWORD_RESEARCH` | Waiting for Create Content Plan. Release once when generation is requested. |
145
+ | `CONTENT_PLAN` | Generating briefs. Continue separate checks; do not release again. |
146
+ | `SUCCESS` | Ready. Read candidates in step 5. |
147
+ | `PENDING_REQUIREMENTS` | Missing business information. Stop polling and report the actual unmet requirement from evidence. Do not invent or update business data, or repeatedly trigger replacements. |
148
+ | `FAIL` | Generation failed. Report the flow ID and failure; do not silently start a replacement. |
149
+ | `CANCELED` | Canceled and cannot be resumed. Report it and stop. |
150
+ | `UNKNOWN` | No usable status. Inspect the response and report uncertainty instead of guessing progress. |
151
+
152
+ Check every few seconds using separate calls. Completion time varies.
138
153
 
139
154
  ### 3. Release the flow
140
155
 
141
156
  ```
142
- POST /create-content-plan
143
- { "contentPlanFlowId": "..." }
157
+ POST https://www.wixapis.com/promote/seo/v1/create-content-plan
158
+ { "contentPlanFlowId": "<flow-uuid>" }
159
+ ```
160
+
161
+ Successful response:
162
+
163
+ ```json
164
+ {
165
+ "success": true,
166
+ "contentPlanFlowId": "<flow-uuid>"
167
+ }
168
+ ```
169
+
170
+ Failure response fields (the diagnostic text comes from the API):
171
+
172
+ ```json
173
+ {
174
+ "success": false,
175
+ "message": "<reason returned by the API>"
176
+ }
144
177
  ```
145
178
 
146
- This advances the flow past `KEYWORD_RESEARCH`. Check `success` in the
147
- response. If `false`, read `message`.
179
+ The response fields are `success` (boolean), `message` (failure reason, only
180
+ when `success` is false), and `contentPlanFlowId` (flow UUID when returned).
181
+ Check `success` as well as the HTTP status. If false, report `message` and stop;
182
+ a successful HTTP response alone is not a completed plan.
148
183
 
149
- **Without this call the flow waits forever.**
184
+ On success, retain the returned `contentPlanFlowId` for the next status check
185
+ and candidate read. This response is not the list of briefs: continue to steps
186
+ 4 and 5. Do not call release again to retrieve results; on an already successful
187
+ flow it regenerates a plan under a new flow ID.
188
+ See [Create Content Plan](https://dev.wix.com/docs/api-reference/business-management/seo/content-plan-blog-post-candidate-v1/create-content-plan).
150
189
 
151
190
  ### 4. Poll until SUCCESS
152
191
 
153
- Same single-GET execution as step 2, returning after each check. Status walks
192
+ Same single-GET execution and nested response as step 2, using the release
193
+ response's flow ID and returning after each check. Typical status progression:
154
194
  `CONTENT_PLAN` → `SUCCESS`. Read candidates in a subsequent execution after
155
195
  observing `SUCCESS`.
156
196
 
157
197
  ### 5. Read the briefs
158
198
 
159
199
  ```
160
- GET /content-plan-flows/{contentPlanFlowId}/blog-post-candidates
200
+ GET https://www.wixapis.com/promote/seo/v1/content-plan-flows/{contentPlanFlowId}/blog-post-candidates
201
+ ```
202
+
203
+ Example response showing the fields needed to display one topic:
204
+
205
+ ```json
206
+ {
207
+ "blogPostCandidates": [
208
+ {
209
+ "id": "<candidate-id>",
210
+ "briefData": {
211
+ "h1Title": "How to Care for Handmade Ceramic Mugs",
212
+ "keyword": "ceramic mug care",
213
+ "mainKeyword": "handmade ceramic mugs",
214
+ "pageUrl": "https://www.example.com/mugs"
215
+ }
216
+ }
217
+ ],
218
+ "pagingMetadata": { "count": 1, "cursors": {}, "hasNext": false }
219
+ }
161
220
  ```
162
221
 
163
- Returns `{ "blogPostCandidates": [...] }`. Each candidate's brief fields are
164
- nested under `briefData`, not at the candidate's top level. Map them directly:
222
+ This is illustrative data, not the user's results. Candidates can contain
223
+ additional fields; see the linked reference for the full contract. Omitting
224
+ `paging` returns all candidates in a single response. Each candidate's brief
225
+ fields are nested under `briefData`, not at the candidate's top level. Map them
226
+ directly:
165
227
 
166
228
  ```js
167
229
  const topics = response.blogPostCandidates.map(candidate => ({
@@ -204,13 +266,13 @@ would help assess or refine them, without modifying the site's settings.
204
266
  After step 2, before or after step 3, read the keywords:
205
267
 
206
268
  ```
207
- GET /content-plan-keyword-research-items
269
+ GET https://www.wixapis.com/promote/seo/v1/content-plan-keyword-research-items
208
270
  ```
209
271
 
210
272
  Edit one keyword (field-masked, only `keyword` and `main_keyword` writable):
211
273
 
212
274
  ```
213
- PATCH /keyword-research-items/{itemId}
275
+ PATCH https://www.wixapis.com/promote/seo/v1/keyword-research-items/{itemId}
214
276
  {
215
277
  "keywordResearchId": "...",
216
278
  "item": { "id": "...", "keyword": "new keyword" },
@@ -222,22 +284,6 @@ PATCH /keyword-research-items/{itemId}
222
284
  Always use the one from the response for the next write. Edits are not
223
285
  durable across generations.
224
286
 
225
- ## What this recipe adds over the docs
226
-
227
- The published reference documents each method. This recipe adds:
228
-
229
- 1. **The parking gate.** The docs say `KEYWORD_RESEARCH` is a status. This
230
- recipe says: the flow stops there until you call Create Content Plan.
231
- Without that call, polling runs forever.
232
-
233
- 2. **PENDING_REQUIREMENTS handling.** This explicit status signals unmet
234
- prerequisites. Report it and identify the missing requirement only from
235
- evidence; do not infer it from a queued `CREATED` status or fill in business
236
- information on the user's behalf.
237
-
238
- 3. **Copy-on-write on keyword edits.** The `keywordResearchId` can change
239
- on the first write. Use the one from the response.
240
-
241
287
  ## Do not
242
288
 
243
289
  - Poll forever without calling Create Content Plan (step 3).