@wix/agent-skills 1.31.2 → 1.33.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.
Files changed (43) hide show
  1. package/README.md +4 -12
  2. package/package.json +1 -1
  3. package/skills/wix-app/SKILL.md +39 -15
  4. package/skills/wix-app/references/BACKEND_API.md +1 -1
  5. package/skills/wix-app/references/EDITOR_REACT_COMPONENT.md +47 -45
  6. package/skills/wix-app/references/SDK_MODULE_MAP.md +1 -1
  7. package/skills/wix-app/references/STORES_VERSIONING.md +24 -2
  8. package/skills/wix-app/references/dashboard-page/DATA_SOURCES.md +9 -13
  9. package/skills/wix-app/references/dashboard-page/IMAGE_RENDERING.md +61 -0
  10. package/skills/wix-app/references/editor-react-component/ACCESSIBILITY.md +54 -64
  11. package/skills/wix-app/references/editor-react-component/ANIMATED-COMPONENTS.md +25 -27
  12. package/skills/wix-app/references/editor-react-component/COMPONENT-CONTRACT.md +37 -30
  13. package/skills/wix-app/references/editor-react-component/CSS-GUIDELINES.md +43 -29
  14. package/skills/wix-app/references/editor-react-component/DESIGN-STATES.md +42 -42
  15. package/skills/wix-app/references/editor-react-component/DISABLED-INVALID.md +31 -0
  16. package/skills/wix-app/references/editor-react-component/MANIFEST-ERRORS.md +14 -1
  17. package/skills/wix-app/references/editor-react-component/PARTS.md +40 -9
  18. package/skills/wix-app/references/editor-react-component/PROPS-VS-CSS.md +22 -2
  19. package/skills/wix-app/references/editor-react-component/SSR.md +6 -3
  20. package/skills/wix-app/scripts/scan-a11y-eslint.cjs +39 -16
  21. package/skills/wix-app/scripts/sdk-curated.json +45 -0
  22. package/skills/wix-app/scripts/sdk-lookup.cjs +1180 -0
  23. package/skills/wix-base44-connector/SKILL.md +4 -2
  24. package/skills/wix-base44-connector/scripts/utils.cjs +5 -2
  25. package/skills/wix-headless-kit/SKILL.md +4 -1
  26. package/skills/wix-headless-kit/guides/api-run.md +14 -20
  27. package/skills/wix-headless-kit/install/pins.json +1 -1
  28. package/skills/wix-manage/SKILL.md +30 -8
  29. package/skills/wix-manage/references/automations/actions.md +134 -0
  30. package/skills/wix-manage/references/automations/activation-status.md +64 -48
  31. package/skills/wix-manage/references/automations/api-catalog.md +213 -77
  32. package/skills/wix-manage/references/automations/automation-model.md +199 -0
  33. package/skills/wix-manage/references/automations/bracket-expressions.md +132 -0
  34. package/skills/wix-manage/references/automations/build-and-manage-automations.md +305 -26
  35. package/skills/wix-manage/references/automations/triggers.md +190 -0
  36. package/skills/wix-manage/references/collaborators/manage-site-collaborators.md +128 -0
  37. package/skills/wix-manage/references/forms/forms-dashboard-navigation.md +3 -1
  38. package/skills/wix-manage/references/forms/read-forms-and-submissions.md +277 -0
  39. package/skills/wix-manage/references/forms/update-form.md +5 -0
  40. package/skills/wix-manage/references/seo/manage-url-redirects.md +33 -4
  41. package/skills/wix-manage/references/sites/create-headless-site.md +14 -5
  42. package/skills/wix-manage/references/sites/upload-static-site.md +373 -302
  43. package/skills/wix-vibe-headless/references/shared/app/components/WixManageBanner.jsx +3 -3
@@ -1,81 +1,217 @@
1
1
  ---
2
2
  name: "Automations API Catalog"
3
- description: "Discover installed automation triggers and actions and inspect their schemas through site-scoped public catalog APIs."
3
+ description: "Discover site-specific triggers and actions, authenticate public Automation API calls, and choose the API for validation, persistence or catalog lookups."
4
4
  ---
5
5
 
6
- # Discover installed automation capabilities
7
-
8
- Check the site's installed trigger/action catalogs, then inspect the chosen components'
9
- schemas. This recipe is read-only: do not create an automation, install an app, generate email
10
- content, or run an action to establish availability.
11
-
12
- ## Authentication
13
-
14
- Use an authorized site-scoped client with Set Up Automations permission. REST calls use
15
- `Authorization: <token>`. An API key also needs `wix-site-id: <metaSiteId>`; do not combine it
16
- with `wix-account-id`. OAuth app tokens are bound to a site instance. Never print credentials.
17
- A 401/403 is an access failure, not evidence that a catalog component is unavailable.
18
-
19
- ## Resolve, select, inspect
20
-
21
- 1. Use a known key only as a search hint. Resolve an exact candidate first; if it is absent,
22
- browse small pages and compare names/semantics locally. Do not conclude that a remembered
23
- key exists on this site without a successful Resolve response.
24
- 2. For triggers, request `basicFieldsOnly: true` while browsing, then hydrate only the chosen
25
- trigger with Get Trigger By App Id And Key. Compare its payload and filters to the intent.
26
- 3. Actions already include schemas in Resolve. Retain the chosen returned identity and
27
- required input fields; avoid repeating the whole catalog just to read display names.
28
- 4. Summarize the available pair and required configuration, distinguishing what the trigger
29
- supplies from values the user would need to choose. Do not mutate anything to prove it.
30
-
31
- ### Trigger discovery
32
-
33
- `POST https://www.wixapis.com/v1/triggers/resolve`
34
-
35
- ```json
36
- {"basicFieldsOnly":true,"query":{"filter":{"triggerKey":"contacts-new_contact_was_created"},"paging":{"limit":25,"offset":0}}}
37
- ```
38
-
39
- Read `results[]` and `paging`. A nonempty matching result establishes an installed trigger;
40
- use its returned `appId` and `triggerKey` in:
41
-
42
- `GET https://www.wixapis.com/v1/triggers/apps/<appId>/keys/<triggerKey>`
43
-
44
- Read `trigger.payloadDataSchema`, `trigger.filters` and `trigger.automationConfigSchema`.
45
- The contact-created key above is a discovery hint; names and availability may vary by site.
46
-
47
- ### Action discovery
48
-
49
- `POST https://www.wixapis.com/v1/actions/resolve`
50
-
51
- ```json
52
- {"query":{"filter":{"actionKey":"addLabelsToContact"},"paging":{"limit":25,"offset":0}}}
53
- ```
54
-
55
- Read `actions[]`, `paging`, and each chosen action's `appId`, `actionKey`, `inputSchema`,
56
- `outputSchema` and `interfaceConfiguration`. Inspect required properties, types, enums and
57
- field descriptions before explaining configuration. For an existing runtime version use
58
- `GET https://www.wixapis.com/v1/actions/apps/<appId>/keys/<actionKey>` and read `action`.
59
- A site may have Add label to contact without Create task; never substitute one for the other.
60
-
61
- ### Bounded fallback
62
-
63
- Remove the exact-key filter to browse; use offset pages of at most 25 entries, with no sort.
64
- Resolve Actions has no `basicFieldsOnly` option and rejects displayName filters; search names
65
- locally. Compact each page to identities and display names before adding it to reasoning
66
- context. Fetch each catalog page and static schema once, cache it for this site, and hydrate only a
67
- shortlist; never re-fetch a page or schema you already have. Pages can overlap;
68
- de-duplicate by appId+key. Only a complete scan with distinct count equal to `paging.total`
69
- proves absence; state the evidence ("scanned N distinct of `paging.total` N"). Without that
70
- proof, say the component was "not found in the installed catalog", never that it is not
71
- installed. Either way, list the closest related actions you saw in that scan, as findings
72
- rather than substitutes, with their returned `appId`/`actionKey` and display name; don't fetch
73
- their schemas unless the user asks.
74
-
75
- Resolve is site-scoped; global Query catalogs can include uninstalled apps and do not prove
76
- availability. The method schemas below confirm the full public URLs; do not invent a private
77
- transport or guess a new path if access fails.
78
-
79
- Official contracts: [Resolve Triggers](https://dev.wix.com/docs/api-reference/business-management/automations/triggers/trigger-catalog/resolve-triggers),
80
- [Resolve Actions](https://dev.wix.com/docs/api-reference/business-management/automations/actions/action-catalog/resolve-actions).
81
- For current automation status use [Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status).
6
+ > **Stage scope:** this stage covers only what [Build and Manage Wix Automations](https://dev.wix.com/docs/api-reference/business-management/automations/skills/build-and-manage-wix-automations) lists; do not perform anything marked "Later stages only" or any workflow that needs a guide marked "not yet published". "Stage", "Later stages only" and "not yet published" describe how this skill is being rolled out; never mention them to the user. Explain a limit in product terms: what can't be done through the API here and where the user can do it instead (for example, in the automations builder).
7
+
8
+ # API Catalog — the public Wix Automations APIs
9
+
10
+ Every call this skill needs, as a public REST endpoint (base `https://www.wixapis.com`) and the
11
+ matching `@wix/automations` SDK method. Docs live under
12
+ `https://dev.wix.com/docs/api-reference/business-management/automations/` — append `.md` to any
13
+ docs URL to get raw markdown. When a field name here and the docs disagree, the docs win.
14
+
15
+ **TL;DR**
16
+
17
+ - Catalogs: Resolve Triggers / Resolve Actions. Oracle: **Validate Automation** — Create and
18
+ Update do **not** validate.
19
+ - Persist: Create `INACTIVE` → Get read-back; activate only when asked.
20
+ Procedures (create, activate, read-back
21
+ — builder drafts are invisible publicly): [Build and Manage Wix Automations — included validation procedure](https://dev.wix.com/docs/api-reference/business-management/automations/skills/build-and-manage-wix-automations) §3.
22
+ - **Later stages only — not in stage 2:** **Test Automation runs actions for real** — only with explicit user authorization.
23
+ - Resolve responses are large: page small, filter by exact keys, never paste a raw catalog.
24
+
25
+ ## 1. Authentication and transport
26
+
27
+ - **Permission scope**: **Set Up Automations** (`SCOPE.CRM.SETUP-AUTOMATIONS`) for every
28
+ Automations method below. Generate Action Input Mapping and Get / Set Email Content (Automation Email Action API) need **Manage
29
+ Email Marketing** (`SCOPE.DC-PROMOTE.EMAIL-MARKETING`) — a 403 there means that scope is missing.
30
+ Entity lookups in other verticals need that vertical's read scope
31
+ (Automations Entity and Provider Configuration (not yet published)).
32
+ - **Token**: `Authorization: <token>` header — an OAuth app access token (`client_credentials` via
33
+ Create Access Token) or an account API key the site owner generated with the needed scopes.
34
+ - **Site context**: with an **API key**, send `wix-site-id: <metaSiteId>` on every call (all calls
35
+ here are site-level); never together with `wix-account-id`. OAuth app tokens are already bound
36
+ to one site instance.
37
+ - **SDK**: `import { automationsV2, triggerCatalog, actionCatalog, activations } from
38
+ '@wix/automations'`, used through a `createClient` Wix client with an auth strategy.
39
+ - **Secrets**: NEVER print, log, echo or store tokens, API keys, app secrets or auth headers — not
40
+ in chat, files or error reports. Redact them from any request you show.
41
+ - **Site lock**: resolve the target `metaSiteId` once and use it for every call, read-back and
42
+ link. Ask the user to confirm it before the first write only when more than one site is in
43
+ context or the request doesn't make clear which; a site fixed by the request or session is
44
+ confirmed. If anything points at another site, stop.
45
+ - **Errors**: 401 = token expired/invalid (refresh, don't retry blindly). 403 = missing scope, app
46
+ not installed, or — on Create/Update of an automation that validated — a step the public API
47
+ can't create (e.g. the code-variable step, §4 of Automations Delays Variables and Branches (not yet published)). A timeout or 5xx is
48
+ **unknown**, not a verdict — retry read-only calls (Get, Query, Resolve, Validate) a bounded
49
+ number of times. Never blindly retry Create or Update: Query or Get first to see whether the
50
+ write landed ([Build and Manage Wix Automations — included validation procedure](https://dev.wix.com/docs/api-reference/business-management/automations/skills/build-and-manage-wix-automations) §3, Reporting rules).
51
+
52
+ ## 2. Automations V2 (`automationsV2`) — base `/automations-service/v2/automations`
53
+
54
+ > Stage 2 supports Query, Get, Validate, inactive Create, and Update only to activate or deactivate ([Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status)). Configuration updates, Delete and Test Automation below are future-stage reference material; do not call them in this stage.
55
+
56
+ | Purpose | REST | SDK |
57
+ | -------- | ----------------------------------------------------------- | ----------------------------------------- |
58
+ | Validate | `POST https://www.wixapis.com/automations-service/v2/automations/validate` | `validateAutomation(automation, options)` |
59
+ | Create | `POST https://www.wixapis.com/automations-service/v2/automations` | `createAutomation(automation)` |
60
+ | Get | `GET https://www.wixapis.com/automations-service/v2/automations/{automationId}` | `getAutomation(automationId)` |
61
+ | Update | `PATCH https://www.wixapis.com/automations-service/v2/automations/{automation.id}` | `updateAutomation(_id, automation)` |
62
+ | Delete | `DELETE https://www.wixapis.com/automations-service/v2/automations/{automationId}` | `deleteAutomation(automationId)` |
63
+ | Query | `POST https://www.wixapis.com/automations-service/v2/automations/query` | `queryAutomations(query)` |
64
+
65
+ - **Validate** (unsaved or saved): `{automation, validationSettings?{actionIds[],
66
+ skipProviderValidations}}` → `{status: VALID|VALID_WITH_WARNINGS|INVALID,
67
+ triggerValidationErrors[], actionValidationErrors[]}`. The main oracle; send the full object.
68
+ Reading errors: [Build and Manage Wix Automations — included validation procedure](https://dev.wix.com/docs/api-reference/business-management/automations/skills/build-and-manage-wix-automations) §2.
69
+ - **Create**: `{automation}` with `name`, `origin: "USER"`, `configuration{status, trigger{appId,
70
+ triggerKey}, rootActionIds, actions}` → created `automation` (has `id`, `revision`). Does NOT
71
+ validate. Always `status: "INACTIVE"`; don't send `settings`.
72
+ - **Get**: → `automation`. Use for read-back after every write and before every update.
73
+ `trigger.overrideSchema` and `appDefinedInfo.overrideOutputSchema` come back **only** when you
74
+ request them: `fields: ["OVERRIDE_SCHEMA"]` (REST `?fields=OVERRIDE_SCHEMA`). Without it their
75
+ absence is not data loss (Create's response omits them too).
76
+ Request overrides before complete-object updates and status changes too, not just creation read-back.
77
+ - **Update**: in this stage, only to change `configuration.status` (activate / deactivate) as [Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status) describes. Send `{automation}` exactly as fetched with `fields: ["OVERRIDE_SCHEMA"]` — `id`, current `revision`, `name`, `configuration`, plus `origin` and `settings` — with only the status changed. Without `origin` and `settings` it fails `INVALID_ORIGIN_TYPE`; a stale `revision` is rejected. Capture the returned id: a preinstalled automation's site override can change it. Configuration updates are published in stage 3.
78
+ - **Later stages only — not in stage 2:** **Delete** — published in stage 3.
79
+ - **Query**: `{query{filter, sort, cursorPaging{limit ≤ 500, cursor}}}` → `automations[]`,
80
+ `pagingMetadata.cursors.next`. Returns only automations of apps installed on the site (incl.
81
+ overridden preinstalled ones), and never unpublished builder drafts. Full objects are large —
82
+ keep only `id, name, configuration.status, configuration.trigger`. If a filtered query fails on
83
+ a site with many automations, page unfiltered and filter locally.
84
+
85
+ Automation object fields and limits (`name` ≤ 100 for the builder, `description` ≤ 2000,
86
+ `origin`, `settings`, `configuration`): [Automations Graph and Data Model](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-graph-and-data-model) §1.
87
+ Create/Update accept `configuration.trigger.automationConfigMapping` for scheduled/custom/webhook
88
+ configuration even where the docs omit it; use [Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) / Automations Schemas and Scheduling (not yet published).
89
+
90
+ ## 3. Trigger Catalog (`triggerCatalog`)
91
+
92
+ | Purpose | REST | SDK |
93
+ | ---------------------- | ------------------------------------------------- | ----------------------------------------------- |
94
+ | Triggers on this site | `POST https://www.wixapis.com/v1/triggers/resolve` | `resolveTriggers(options)` |
95
+ | Global catalog | `POST https://www.wixapis.com/v1/triggers/query` | `queryTriggers(query)` |
96
+ | One trigger | `GET https://www.wixapis.com/v1/triggers/apps/{appId}/keys/{triggerKey}` | `getTriggerByAppIdAndKey(identifiers, options)` |
97
+ | Dynamic payload schema | `POST https://www.wixapis.com/v1/triggers/dynamic_schema` | `getTriggerDynamicSchema(appId, options)` |
98
+ | Identity enrichment | `POST https://www.wixapis.com/v1/triggers/identities_schema` | `getIdentitiesSchema()` |
99
+
100
+ - **Resolve**: `{basicFieldsOnly?, appId?, query{filter, paging{limit, offset}, fields?}}` →
101
+ `results[]`, `paging`. Installed apps only. `basicFieldsOnly: true` for browsing (drops payload
102
+ schema, config schema, filters).
103
+ - **Query** (global): `{query{filter, …}}` → `results[]` (filterable: `appId`, `triggerKey`,
104
+ `displayName`, `implementedMethods.*`). Includes apps NOT installed on the site — never build on
105
+ a trigger Resolve didn't return.
106
+ - **One trigger**: → `trigger` with `payloadDataSchema`, `filters[]`, `automationConfigSchema`,
107
+ `implementedMethods`. The preferred way to hydrate a shortlisted trigger.
108
+ - **Dynamic schema**: `{appId, triggerKey, selectedFilterOptions[{fieldKey, values[]}] (≤ 5)}` →
109
+ `dynamicSchema`. Only when `implementedMethods.getDynamicSchema` is true, and only after the
110
+ filters that drive it are chosen — no filter chosen ⇒ form answers are unknown, not absent
111
+ (request and merge: [Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) §5).
112
+ - **Identities schema**: `{}` → `identitiesSchema{contact, member, …}` — shape of the `contact` /
113
+ `member` objects added when payload fields carry `identityType`.
114
+
115
+ Trigger objects have no free-text description and display names are ambiguous — decide by the
116
+ payload schema ([Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) §2).
117
+
118
+ ## 4. Action Catalog (`actionCatalog`)
119
+
120
+ | Purpose | REST | SDK |
121
+ | -------------------------- | ------------------------------------------------------ | ---------------------------------------------- |
122
+ | Actions on this site | `POST https://www.wixapis.com/v1/actions/resolve` | `resolveActions(options)` |
123
+ | Global catalog | `POST https://www.wixapis.com/v1/actions/query` (and `/query-latest`) | `queryActions(query)`, `queryLatestActions` |
124
+ | Version active on the site | `GET https://www.wixapis.com/v1/actions/apps/{appId}/keys/{actionKey}` | `getRuntimeAction(identifiers)` |
125
+ | Latest version | `GET https://www.wixapis.com/v1/actions/latest/apps/{appId}/keys/{actionKey}` | `getLatestAction(identifiers, options)` |
126
+ | Dynamic input schema | `POST https://www.wixapis.com/v1/actions/dynamic-input-schema` | `getActionDynamicInputSchema(appId, options)` |
127
+ | Dynamic output schema | `POST https://www.wixapis.com/v1/actions/dynamic-output-schema` | `getActionDynamicOutputSchema(appId, options)` |
128
+
129
+ - **Resolve**: `{query{filter, paging{limit, offset}, fields?}}` → `actions[]`, `paging`. Offset
130
+ paging only (`cursorPaging` is rejected). Entries carry full `inputSchema`, `outputSchema`,
131
+ `uiSchema` — large. Filter by `appId`/`actionKey`, page ≤ 25.
132
+ - **Global catalog**: not site-scoped; "latest" may be newer than what the site runs.
133
+ - **Runtime action**: → `action`. Use this schema when configuring for this site. Latest version
134
+ is for reference only.
135
+ - **Dynamic input**: `{appId, actionKey, inputMapping}` → `{inputSchema, uiSchema}`. Call when an
136
+ input property has `updateSchemaOnChange: true` (no public `getDynamicInputSchema` flag);
137
+ re-call after changing such a field.
138
+ - **Dynamic output**: `{appId, actionKey, inputMapping}` → `outputSchema`; bulk
139
+ (`bulkGetActionDynamicOutputSchemas`, POST `/v1/actions/bulk/dynamic-output-schema`, ≤ 20 items) →
140
+ `results[]{itemMetadata{success, error}, outputSchema}`. Only after that action's mapping is
141
+ final. Safe for any action you place upstream of a step that reads its output (no public flag
142
+ says which are dynamic); an error means "no dynamic output" — keep the static `outputSchema`.
143
+ Merge into the static schema. A failed bulk item = unknown schema, not empty.
144
+ - **Generate Input Mapping From Intent** (`POST https://www.wixapis.com/v1/actions/generate-input-mapping-from-intent`)
145
+ is AI-backed — don't call it. For actions you can't map from their schema, tell the user they can't be configured through the API here and can be set up in the automations builder.
146
+ - **Later stages only — email is outside stage 2:** **Email content of an existing Send an email step** — Get / Set Email Content; procedure in Automations Email Actions (not yet published).
147
+ - **Later stages only — email is outside stage 2:** **New Send an email step** — Generate Action Input Mapping; procedure in Automations Email Actions (not yet published).
148
+
149
+ Action objects: `appId`, `actionKey`, `displayName`, `description`, `inputSchema`, `outputSchema`,
150
+ `interfaceConfiguration{type: GENERIC\|WIDGET_COMPONENT, genericOptions.uiSchema}`,
151
+ `implementedMethods{validateConfiguration, getQuotaInfo}` (public). Resolve Actions has **no**
152
+ `basicFieldsOnly` option (only Resolve Triggers does). Mapping rules: [Automations Action Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-action-configuration).
153
+
154
+ ## 5. Activations (`activations`)
155
+
156
+ - **Later stages only — not in stage 2:** **Test Automation** — runs every action for real; published in stage 3.
157
+ - **Later stages only — not in stage 2:** **Run Automation / Report Event / Rerun Activation** — for the app that owns a trigger; never
158
+ use them to build or "test".
159
+
160
+ ## 6. Catalog discovery without flooding your context
161
+
162
+ 1. **Browse cheaply.** Triggers: `resolveTriggers({basicFieldsOnly: true, query: {paging: {limit: 25,
163
+ offset: N}}})`. Actions: `resolveActions` with small pages; keep only `appId`, `actionKey`/
164
+ `triggerKey`, `displayName`, `description`, `interfaceConfiguration.type`. Field projection (`fields`) may
165
+ be ignored — strip locally in code before anything reaches your reasoning context. Even with
166
+ `basicFieldsOnly`, 100 triggers is ~100 KB: keep pages ≤ 25 when results land in your context.
167
+ 2. **Cache** that compact list per site for the session and search it locally. Fetch each catalog
168
+ page and static schema once; never re-fetch one you already have. Dynamic schemas are the
169
+ exception: re-call them after changing an `updateSchemaOnChange` field.
170
+ 3. **Hydrate the shortlist** with exact keys (Get Trigger By App Id And Key / Get Runtime Action,
171
+ or a Resolve filter `{"appId": "...", "actionKey": "..."}`). Full schemas only for the chosen few.
172
+ 4. **Filters that work**: exact `appId`, `triggerKey`/`actionKey`, and `$in` on the keys (both
173
+ Resolves); on Resolve Triggers also `displayName` `$contains` / `$in` (inside `$or` too) and
174
+ `triggerKey` `$startsWith`. Resolve Actions rejects `displayName` filters — search names
175
+ locally. A rejected filter → fall back to small pages.
176
+ 5. **Don't sort** — `sort: [{fieldName: "id"}]` fails with `SORT_PARSER_ERROR` on both Resolves.
177
+ Unsorted offset pages can **overlap**: page until `paging.total`, de-duplicate by `appId`+key,
178
+ and count distinct entries. An action or trigger is proven **missing** only after a complete,
179
+ de-duplicated scan (distinct count = `paging.total`). Report the evidence ("scanned N distinct
180
+ of `paging.total` N"); without that proof say it was "not found in the installed catalog",
181
+ never that it is not installed. Either way, list the closest related entries you did find with
182
+ their returned `appId` + key and display name — don't omit them, and don't fetch their schemas
183
+ unless the user asks. A shortcut:
184
+ take the `appId` from a related action, then Resolve by `appId`.
185
+
186
+ Discovery hints:
187
+
188
+ - Search by concept with a keyword ladder ("chat" → "message"). Common aliases: send a chat
189
+ message to the contact = `send-message` (not `inbox-send-message`); a note about a contact in
190
+ the site owner's Inbox, nothing sent to the contact = `inbox-send-message` ("Show in Inbox");
191
+ email to anyone, incl. the site
192
+ owner = `triggered-emails` (never the deprecated `send-mail` / "Get an email"); task =
193
+ `createTask`; labels = `addLabelsToContact` / `remove_labels_to_contact`; create a contact =
194
+ `contacts-create_contact` (for triggers whose payload has no contact, e.g. webhooks).
195
+ - Near-duplicates exist (`booking_canceled` vs `bookings_canceled`; new Wix Forms app vs legacy
196
+ "Form submitted"). Compare payload schemas and filters; prefer the one whose entities you can
197
+ actually find on the site (Automations Entity and Provider Configuration (not yet published)).
198
+ - Enum-like fields often list legal values only in the field `description` (e.g. paymentStatus
199
+ NOT_PAID / PAID). Read descriptions before mapping user words; never invent enum values.
200
+
201
+ ## 7. Aggregated schema — computed locally (no API takes an unsaved graph)
202
+
203
+ Node N may read the trigger payload + each **ancestor**'s output (under its namespace) +
204
+ variables + identity enrichment. Recipe and fetch order: [Automations Graph and Data Model](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-graph-and-data-model) §4.
205
+
206
+ ## 8. Selector options and APIs with limitations
207
+
208
+ > **Later stages only:** not available in stage 2; this section is published in stage 3.
209
+
210
+ **In this stage:** a "draft" is an automation created `INACTIVE` (builder drafts are invisible to the public API). To validate a saved automation, Get it and Validate the returned object. Check expressions locally, then with Validate Automation.
211
+
212
+ ## Related API references
213
+
214
+ - [Automations V2](https://dev.wix.com/docs/api-reference/business-management/automations/automations/automations-v2/introduction)
215
+ - [Resolve Triggers](https://dev.wix.com/docs/api-reference/business-management/automations/triggers/trigger-catalog/resolve-triggers)
216
+ - [Resolve Actions](https://dev.wix.com/docs/api-reference/business-management/automations/actions/action-catalog/resolve-actions)
217
+ - [Automation Email Action](https://dev.wix.com/docs/api-reference/business-management/marketing/emails/automation-email-action/introduction)
@@ -0,0 +1,199 @@
1
+ ---
2
+ name: "Automations Graph and Data Model"
3
+ description: "Assemble builder-editable automation graphs with valid node relationships, namespaces and ancestor data access."
4
+ ---
5
+
6
+ > **Stage scope:** this stage covers only what [Build and Manage Wix Automations](https://dev.wix.com/docs/api-reference/business-management/automations/skills/build-and-manage-wix-automations) lists; do not perform anything marked "Later stages only" or any workflow that needs a guide marked "not yet published". "Stage", "Later stages only" and "not yet published" describe how this skill is being rolled out; never mention them to the user. Explain a limit in product terms: what can't be done through the API here and where the user can do it instead (for example, in the automations builder).
7
+
8
+ # Automation Model — Object, Graph Rules, Payload Scope
9
+
10
+ **TL;DR**
11
+
12
+ - An automation = one trigger + a **single-parent tree** of actions. `rootActionIds` has EXACTLY one id; every connection field holds AT MOST one id; no joins, no cycles, no orphans. Parallelism only via SPLIT; "both branches continue" = duplicate the downstream steps per branch (the builder caps an automation at 45 actions — count before duplicating).
13
+ - Every action: `actions[k].id === k`, a fresh uuid v4, a unique `namespace` (except variable steps, which share `setVariable`), and ONLY its own type's `*Info` object.
14
+ - The automation MUST render and be editable in the Wix dashboard builder. The builder rules below are hard MUSTs — the API accepts shapes the builder cannot draw (some hang its loader forever).
15
+ - A step may read (`var("...")`) only its node's **aggregated payload schema**: trigger payload + identity enrichment + outputs of its ANCESTOR steps.
16
+ - Create and Update do NOT validate. Always call Validate Automation before Create, a configuration Update or activation ([Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog)); status-only deactivation is exempt ([Automations Activation Status](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-activation-status)).
17
+
18
+ ---
19
+
20
+ ## 1. The Automation object (public API)
21
+
22
+ > In this stage you create only APP_DEFINED steps. The other step types below are documented so you can read and preserve existing automations, not to author them here.
23
+
24
+ | Field | Rules |
25
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
26
+ | `id`, `revision` | Read-only. `revision` MUST be sent back on Update Automation (§6). |
27
+ | `name` | Required, 1–100 chars (API allows 500; the builder holds 100); the business outcome ("Send welcome email to new subscribers"). |
28
+ | `description` | Optional, ≤2000 chars. |
29
+ | `origin` | Required on create, immutable. `USER` for anything you create. `APPLICATION`/`PREINSTALLED` carry update locks (§4 of Automations Feasibility and Planning (not yet published)). |
30
+ | `settings` | Locks for APPLICATION/PREINSTALLED (`readonly`, `actionSettings`, …). Never set it on create; on Update send it back exactly as fetched. |
31
+ | `configuration.status` | Required, `ACTIVE` \| `INACTIVE`. Create `INACTIVE`; activate only on request. |
32
+ | `configuration.trigger` | `{appId, triggerKey, filters[], scheduledEventOffset?, overrideSchema?, automationConfigMapping?}` — [Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration). |
33
+ | `configuration.rootActionIds` | Exactly one action id. |
34
+ | `configuration.actions` | Map `actionId → Action`. |
35
+
36
+ Action (common fields):
37
+
38
+ - `id` — uuid v4, equal to its map key.
39
+ - `type` — `APP_DEFINED`, `CONDITION`, `CODE_CONDITION`, `DELAY`, `RATE_LIMIT`, `SET_VARIABLES`, `SPLIT` (the last two are not yet in the public API docs, but the builder supports them — Automations Delays Variables and Branches (not yet published)). NEVER `UNKNOWN_ACTION_TYPE`, NEVER `MERGE`.
40
+ - `namespace` — 1–100 chars, unique except the shared `setVariable` namespace (§3). Outputs of this step appear under it.
41
+ - `displayName` — optional but always set it: 1–60 chars, sentence case, purpose-specific (§7 of Automations Delays Variables and Branches (not yet published)). Absent → the canvas shows the catalog name.
42
+ - `skipActionExpression` — absent (runs) or exactly `"{{true}}"` (skipped), the only value the builder writes. A skipped step adds NO outputs downstream (§4).
43
+ - exactly one `*Info` matching `type`: `appDefinedInfo`, `conditionInfo`, `codeConditionInfo`, `delayInfo`, `rateLimitInfo`, `setVariablesInfo`, `splitInfo`.
44
+
45
+ ## 2. Graph invariants — single-parent tree
46
+
47
+ 1. **One root, with no parent.** `rootActionIds` = `[oneId]`, and no action may point at the root. The builder draws only `rootActionIds[0]`; extra roots are saved but invisible.
48
+ 2. **One successor per field.** `appDefinedInfo.postActionIds`, `delayInfo.postActionIds`, `rateLimitInfo.postActionIds`, `setVariablesInfo.postActionIds`, `conditionInfo/codeConditionInfo.truePostActionIds` / `falsePostActionIds` each hold 0 or 1 id (API `maxItems 1`).
49
+ 3. **One parent per action.** Every non-root action is referenced from exactly one place (one connection field or one SPLIT path). A JOIN is drawn under its first parent only — the canvas misrepresents the flow.
50
+ 4. **No orphans.** An action unreachable from the root is deleted by the builder on the next save.
51
+ 5. **No cycles.** Forward only.
52
+ 6. **Empty array = the path ends** there. Use `[]`, never omit the field.
53
+ 7. **Parallel fan-out only via SPLIT** (§5 of Automations Delays Variables and Branches (not yet published)). Never two root ids, never two ids in one field.
54
+ 8. **No MERGE.** The API has a `MERGE` type and `conditionInfo.mergeActionId`, but the canvas cannot draw them (MERGE nodes never finish loading). Never create either; when you read an automation that has them, preserve them untouched and don't add more.
55
+
56
+ ### Builder rendering MUSTs (graph level)
57
+
58
+ - MUST: the trigger's `appId` + `triggerKey` exist in the site's trigger catalog (a missing trigger can leave every node loading).
59
+ - MUST: `actions[k].id === k` for every entry.
60
+ - MUST: ids are unique across ALL of: action ids, SPLIT path ids, the `triggerKey` string (it is the trigger node's id), and the builder's synthetic ids `<id>true`, `<id>false`, `<id>-end`, `<id>true-end`. Duplicates crash the layout. Generate every id as a fresh uuid v4 in code; never reuse ids from these references.
61
+ - MUST: each action carries ONLY its own type's `*Info`. The canvas ignores `type` when finding children and takes the first present of `appDefinedInfo → delayInfo → rateLimitInfo → setVariablesInfo → condition` — even an empty leftover `appDefinedInfo: {postActionIds: []}` on a CONDITION hides both branches.
62
+ - MUST: at most one RATE_LIMIT, and only as the root (§2 of Automations Delays Variables and Branches (not yet published)). A non-root RATE_LIMIT node spins forever.
63
+ - MUST: APP_DEFINED `appId` + `actionKey` match the site's action catalog, else the node shows "Action not available".
64
+
65
+ ### Designing within the tree
66
+
67
+ > **Later stages only:** not available in stage 2; this section is published in stage 3.
68
+
69
+ **In this stage:** put independent actions ("create a task and add a label") in one linear chain A → B → C, most time-sensitive first.
70
+
71
+ ### Only model what the user asked for
72
+
73
+ > **Later stages only:** not available in stage 2; this section is published in stage 3.
74
+
75
+ **In this stage:** add only the steps the user asked for. Audience or copy framing ("a VIP follow-up for high-value customers") is content inside one action, not a condition.
76
+
77
+ ## 3. Namespaces
78
+
79
+ Use the builder's own convention (it derives new indexes from the trailing number):
80
+
81
+ | Type | Namespace |
82
+ | ------------------------------------------------ | -------------------------------------------------------- |
83
+ | APP_DEFINED | `<actionKey>-<N>` (e.g. `triggered-emails-3`) |
84
+ | CONDITION and CODE_CONDITION | `CONDITION-<N>` |
85
+ | DELAY / SPLIT / RATE_LIMIT | `<TYPE>-<N>` (e.g. `DELAY-2`, `SPLIT-5`, `RATE_LIMIT-1`) |
86
+ | SET_VARIABLES (and existing code-variable steps) | always the literal `setVariable` (§4 of Automations Delays Variables and Branches (not yet published)) |
87
+
88
+ `N` = 1 + the largest number after the last `-` among **all** the automation's namespaces (one counter shared across every step type — e.g. `DELAY-1` then `createTask-2`). A namespace with no trailing number (`setVariable`) doesn't count: if it is the only one, the next `N` is 1. A CODE_CONDITION keeps `CONDITION-<N>`. The builder never rewrites an existing namespace — on update keep every existing one as is. Variable and existing code-variable steps intentionally share `setVariable`; their distinct property keys are merged. For other output-producing actions, never reuse a namespace — the later output overwrites the earlier one.
89
+
90
+ ## 4. Aggregated payload schema — what `var()` can read at a node
91
+
92
+ This section owns the rule. Build one JSON Schema object per node, in code, from the root down its own branch, from public schema APIs (calls: [Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog) §3–§4).
93
+
94
+ 1. **Trigger payload** — the trigger's `payloadDataSchema` (custom/webhook triggers: `trigger.overrideSchema` instead, §3 of Automations Schemas and Scheduling (not yet published)). If the trigger implements dynamic schema, call Get Trigger Dynamic Schema with the SELECTED (saved) filter options and MERGE its `properties` over the static ones ([Automations Trigger Configuration](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-trigger-configuration) §5); before filters are chosen, dynamic fields are UNKNOWN, not absent. Trigger fields are un-prefixed: `var("orderId")`.
95
+ 2. **Identity enrichment** — for every trigger-payload field (any object depth, not inside arrays) annotated `identityType: "contact"` or `"member"`, a root-level object is added, keyed by that field's `namespace` annotation when it has one, else its (deprecated) `name` annotation, else the identity type (`contact` / `member`). Shape: Get Identities Schema (`identitiesSchema.properties.contact` / `.member`). Both stay valid: `var("contactId")` and `var("contact.name.first")`; also e.g. `var("contact.email")`, `var("member.profile.nickname")`. A field annotated `name: "post_author_member"` (some Blog / File Share triggers) is enriched as `var("post_author_member.profile.nickname")` — two member ids on one trigger give two objects; use the key the field declares (`member.*` does not exist there). Other identity types (e.g. `visitor`) add no object; webhook/custom triggers (override schema) get none. The builder does not enrich identity fields of action outputs — don't read `contact.*` that only an action output would provide.
96
+ 3. **Ancestor action outputs** — for each non-skipped APP_DEFINED step ABOVE this node on its own path, under `properties[<namespace>]`: catalog `outputSchema`, with `overrideOutputSchema.properties` merged over it, and — when the action implements dynamic output — Get Action Dynamic Output Schema (called with that step's final `inputMapping`) merged over that: `var("triggered-emails-3.messageId")`.
97
+ 4. **Variables** — titled outputs (`outputSchema`) of non-skipped ancestor SET_VARIABLES / code-variable (`namespace: "setVariable"`) steps, merged under `setVariable`: `var("setVariable.<key>")` (§4 of Automations Delays Variables and Branches (not yet published)).
98
+
99
+ Scope rules:
100
+
101
+ - Only ANCESTORS. A node never sees later steps or a sibling branch (true path can't read the false path; SPLIT paths can't read each other).
102
+ - A skipped step (`skipActionExpression: "{{true}}"`) contributes nothing; never skip a step whose outputs a later step reads.
103
+ - Resolution order — finalize an upstream node before computing a descendant's schema: trigger filters → the trigger's dynamic schema → for each step top-down: its dynamic input schema (if any) → its final `inputMapping` → its dynamic output schema (if any) → add it to its children's schema.
104
+ - Every `var()` path MUST exist in this node's aggregated schema with a compatible type — never reason from a raw trigger or action schema alone, and never invent a field. Copy keys from the schema (titles/labels are not keys); arrays cannot be traversed by path ([Automations Mapping Expressions](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-mapping-expressions) §5).
105
+ - Preferred-language messages: map `var("contact.locale")` into the email's dynamic content; no separate "language" field is needed.
106
+
107
+ Syntax of expressions and the allowed function list: [Automations Mapping Expressions](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-mapping-expressions).
108
+
109
+ ## 5. Minimal valid examples
110
+
111
+ ### 5.1 Linear (trigger → two app-defined actions)
112
+
113
+ The simplest shape: one trigger and a chain of APP_DEFINED actions linked by `postActionIds`.
114
+ The trigger and action identities below are the Contacts "new contact created" trigger and the
115
+ Tasks "create task" action; confirm them, and each action's input keys, against the site's
116
+ catalog before use. Generate fresh uuid v4 action ids.
117
+
118
+ ```json
119
+ {
120
+ "automation": {
121
+ "name": "New contact welcome tasks",
122
+ "origin": "USER",
123
+ "configuration": {
124
+ "status": "INACTIVE",
125
+ "trigger": {
126
+ "appId": "74bff718-5977-47f2-9e5f-a9fd0047fd1f",
127
+ "triggerKey": "contacts-new_contact_was_created",
128
+ "filters": []
129
+ },
130
+ "rootActionIds": ["3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e01"],
131
+ "actions": {
132
+ "3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e01": {
133
+ "id": "3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e01",
134
+ "type": "APP_DEFINED",
135
+ "namespace": "createTask-1",
136
+ "displayName": "Create welcome task",
137
+ "appDefinedInfo": {
138
+ "appId": "146c0d71-352e-4464-9a03-2e868aabe7b9",
139
+ "actionKey": "createTask",
140
+ "inputMapping": {
141
+ "contactId": "{{var(\"contactId\")}}",
142
+ "title": "Welcome {{var(\"contact.name.first\")}}"
143
+ },
144
+ "postActionIds": ["3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e02"]
145
+ }
146
+ },
147
+ "3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e02": {
148
+ "id": "3f6c1d2e-8a4b-4c7d-9e1f-2a3b4c5d6e02",
149
+ "type": "APP_DEFINED",
150
+ "namespace": "createTask-2",
151
+ "displayName": "Create follow-up task",
152
+ "appDefinedInfo": {
153
+ "appId": "146c0d71-352e-4464-9a03-2e868aabe7b9",
154
+ "actionKey": "createTask",
155
+ "inputMapping": {
156
+ "contactId": "{{var(\"contactId\")}}",
157
+ "title": "Follow up with {{var(\"contact.name.first\")}}"
158
+ },
159
+ "postActionIds": []
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+ }
166
+ ```
167
+
168
+ Why it's valid: one parentless root; each action has at most one successor and one parent; ids
169
+ equal their keys; namespaces are unique per §3; inputMapping keys come from the input schema;
170
+ every `var()` path is in that node's aggregated schema; status is INACTIVE.
171
+
172
+ ### 5.2 Branching (trigger → condition → two branches)
173
+
174
+ > **Later stages only:** not available in stage 2; this section is published in stage 3.
175
+
176
+ ## 6. Persistence & update lifecycle
177
+
178
+ Create `INACTIVE` (your "draft"); activate only on request. Create procedure and read-back: [Build and Manage Wix Automations — included validation procedure](https://dev.wix.com/docs/api-reference/business-management/automations/skills/build-and-manage-wix-automations) §3; calls: [Automations API Catalog](https://dev.wix.com/docs/api-reference/business-management/automations/skills/automations-api-catalog) §2.
179
+
180
+ **Later stages only — not in stage 2:** **Update:** Get → change only what was asked, keep every other node byte-for-byte → Validate → Update with the full merged object + `revision`, `origin` and `settings` as fetched; on an ACTIVE automation the change is live — confirm first. Locks: §4 of Automations Feasibility and Planning (not yet published).
181
+
182
+ ## 7. Pre-validate self-check (do in code)
183
+
184
+ Script the graph/id/namespace/`var()` items of [Build and Manage Wix Automations — included validation procedure](https://dev.wix.com/docs/api-reference/business-management/automations/skills/build-and-manage-wix-automations) §4 (items 1–4 and 11 — the rules of §2–§4 above: one parentless root, RATE_LIMIT only as that root, ≤1 id per connection, one parent each, no cycles/orphans/MERGE/`mergeActionId`/`UNKNOWN_ACTION_TYPE`, keys = ids, globally unique uuid v4s incl. SPLIT path ids, `triggerKey` and `<id>true/false/-end`, own `*Info` only, §3 namespaces unique except `setVariable`, every `var()` in THAT node's aggregated schema). Also check that only user-requested conditions/delays exist; then Validate Automation must return no trigger or action errors.
185
+
186
+ ## 8. Anti-patterns (all wrong)
187
+
188
+ ```text
189
+ A → C ← B // join (two parents) — drawn under one parent
190
+ Condition → true: X, false: X // same id twice — duplicate X instead
191
+ Condition.mergeActionId / MERGE // not drawable — duplicate downstream steps
192
+ Trigger → [A, B] // 2 roots — use a SPLIT
193
+ A.postActionIds: [B, C] // fan-out — use a SPLIT
194
+ A → B → A // cycle
195
+ D in actions, never referenced // orphan — deleted on save
196
+ RATE_LIMIT under anything // node never finishes loading
197
+ DELAY carrying a leftover appDefinedInfo // wrong wiring
198
+ Inventing a VIP condition from email copy wording
199
+ ```