56 "summary": "sendSmsReminder has 'Default: true' on both Create Booking and Bulk Create Booking (read 2026-08-16). This is the inverse of every other notification control the KB has met - events/rsvp's disableNotifications and this API's own participantNotification.notifyParticipants both default to OFF, so a generated payload built from the required-field list alone is SAFE there and UNSAFE here. Omitting the flag opts every migrated customer into an SMS to their real phone number. Every create call in the generated script must set sendSmsReminder:false explicitly, and the script's own test must assert its presence on every element of a bulk request, not just the first."
64 "summary": "Create Add On declares durationInMinutes and maxQuantity as a required ONE-OF: every add-on is EITHER duration-based (durationInMinutes 1..1440, i.e. max 24 hours) OR quantity-based (maxQuantity 1..9999), never both and never neither. A source extra that is conceptually both ('add 30 minutes, up to 3 times') cannot be expressed as one add-on and must be split or ledgered. The two kinds also behave differently at booking time: for duration-based add-ons quantity is not applicable - passing quantity 1 is accepted but silently cleared, and any other value returns INVALID_ARGUMENT with the message 'Invalid AddOn details: either duration or quantity must be set correctly'."
72 "summary": "Wix Bookings is not present on a fresh headless site, and neither `/bookings/v2/services` nor `/bookings/v2/resources/query` reveal that by erroring — both answer with ordinary 200s/validation errors regardless. Create Service instead fails with a plain 'form Form with id 00000000-0000-0000-0000-000000000000 doesn't exist', which reads like a form problem but is actually the app-install gap. Install with appDefId 13d21c63-b5ec-5912-8397-c3a5ddb27a97 (see rp-execute-setup SKILL.md) before the first Create Service call; this also auto-provisions the default booking form and one default 'Business Owner' staff resource."
149 "summary": "WooCommerce shipping zones (location rules + per-zone methods) and Wix delivery profiles/regions do not map one-to-one; carrier-calculated Woo methods (e.g. a real UPS/FedEx/USPS integration plugin) have no data equivalent and become reconfigure-in-Wix decisions — shipping-build.js's classifyMethod flags these as a gap rather than guessing a rate."
153 "displayName": "eCommerce Discount Rule (\"Automatic Discounts\" in the dashboard)",
154 "classification": "native",
155 "reliabilityStatus": "partially-reliable",
156 "reliabilityFlags": [
157 "not-yet-live-verified"
158 ],
159 "summary": "The Wix dashboard calls this feature 'Automatic Discounts'; the API/data model name is DiscountRule (`ecom/v1/discount-rules`). Distinct from the Coupons API (stores/coupon.json) — coupons need a customer-entered code, discount rules apply automatically when their trigger is met. Do not conflate the two when a source plugin (e.g. WooCommerce Discount Rules) models automatic, no-code discounting."
163 "displayName": "eCommerce Order Applied Discount",
164 "classification": "native",
165 "reliabilityStatus": "reliable",
166 "reliabilityFlags": [],
167 "summary": "Applied discounts import as historical fact via the merchantDiscount variant — Wix never re-evaluates them as live discount rules, and Import Order stores all money values as-is without recalculating priceSummary. The mapper must therefore keep the source order's totals internally consistent itself; nothing on the Wix side reconciles appliedDiscounts against priceSummary.discount. VERIFIED LIVE 2026-08-16: an order carrying appliedDiscounts totalling 8.00 with priceSummary.total 22.00 on a 30.00 subtotal was stored exactly as sent — and a control order with the same appliedDiscounts but NO priceSummary.discount kept total == subtotal, proving Wix applies nothing."
171 "displayName": "eCommerce Order Line Item Options (Description Lines)",
172 "classification": "native-plus-cms",
173 "reliabilityStatus": "reliable",
174 "reliabilityFlags": [],
175 "summary": "lineItems[].modifierGroups is READ-ONLY on import: it is absent from the Import Order writable request body and marked read-only (maxItems 10) on the returned Order object — addon values can never be recreated as structured modifiers on historical orders. descriptionLines[] is the import-time carrier. VERIFIED LIVE 2026-08-16: an imported line item carrying descriptionLines and catalogReference.options read back with modifierGroups: [] — the field stays empty even when the referenced catalog product genuinely has modifiers attached."
187 "displayName": "eCommerce Order Merchant Note (Activity)",
188 "classification": "native",
189 "reliabilityStatus": "reliable",
190 "reliabilityFlags": [],
191 "summary": "Order.activities[] is read-only on Create/Import Order — a merchant note can NEVER ride the order import payload. It must be a separate Add Activities call AFTER Import Order creates the order, using the crosswalked Wix order id."
199 "summary": "Verify whether the selected order write shape preserves refund amounts, reasons, dates, and line references."
200 },
201 "order": {
202 "path": "domains/ecom/entities/order.json",
203 "displayName": "eCommerce Order",
204 "classification": "native-plus-cms",
205 "reliabilityStatus": "partially-reliable",
206 "reliabilityFlags": [],
207 "summary": "Never route historical orders through createOrder — it decrements inventory, emails the buyer, and auto-creates contacts; importOrder is the only import-safe writer."
215 "summary": "CRITICAL, LIVE-DISCOVERED 2026-08-15 (not documented on any Delivery Profile/Delivery Carrier doc page -- found only via dev.wix.com's 'Fix Shipping Coverage Gaps' skill article, a separate doc tree from shipping-delivery/delivery-profiles/*): DeliveryCarrier.backupRate does NOT create a ShippingOption, and does NOT clear Wix's own 'This region is missing rates. Add them so customers can complete checkout.' dashboard warning. VERIFIED on the reference store: 'Europe'/'Israel' (created by this pipeline via addDeliveryRegion + addDeliveryCarrier with a correctly-shaped, active backupRate) still showed the warning and had ZERO linked ShippingOptions, while 'Domestic'/'International' (Wix's own auto-created defaults, never touched by this pipeline) each already had a real ShippingOption. A region migration that only calls addDeliveryCarrier is INCOMPLETE -- it appears fully successful (the write returns 200, the read-back matches exactly what was sent) while silently leaving the region non-functional at checkout. Always create a matching ShippingOption (via createShippingOption) for every DeliveryRegion this pipeline creates, from the SAME classified method used for that region's DeliveryCarrier.backupRate -- see shipping-build.js's buildShippingOptionInput."
216 }
217 }
218 },
219 "events": {
220 "path": "domains/events/domain.json",
221 "displayName": "Wix Events",
222 "ownerHint": "Events, registration, RSVP, and ticketing domain owners",
230 "summary": "Wix Events categories are flat; a hierarchical source event taxonomy (tribe_events_cat is hierarchical) flattens on import — faithfulness-ledger entry required."
231 },
232 "event": {
233 "path": "domains/events/entities/event.json",
234 "displayName": "Event",
235 "classification": "native",
236 "reliabilityStatus": "partially-reliable",
237 "reliabilityFlags": [],
238 "summary": "Backdating is not documented either way. Historical events are the common migration case, so confirm a past startDate is accepted before promising event history; if rejected, past events fall back to CMS."
246 "summary": "The form is per-event configuration (an ordered list of controls), not standalone records: there is no create — controls are added/updated on the event's existing form. Historical submissions do not live here; they arrive as RSVP/order data."
247 },
248 "rsvp": {
249 "path": "domains/events/entities/rsvp.json",
250 "displayName": "Event RSVP",
251 "classification": "native",
252 "reliabilityStatus": "partially-reliable",
253 "reliabilityFlags": [],
254 "summary": "RSVP creation emails the guest a confirmation unless disableNotifications is set — the domain's registration-notifications-default-on pitfall. An import that forgets the flag mass-mails migrated guests. importSafe is false until the generated script provably sets it on every call AND the suppression itself is proven."
262 "summary": "A ticket definition is the purchasable ticket type (name, price, limits) — importing it does not carry sold tickets. Past ticket sales remain not importable (domain pitfall ticket-order-history-not-importable, owner tracker EVNT-01)."
263 }
264 }
265 },
266 "forms": {
267 "path": "domains/forms/domain.json",
268 "displayName": "Wix Forms",
269 "ownerHint": "Wix Forms (form schemas, form submissions) domain owners — the Forms APIs sit under the CRM docs tree, not Business Solutions",
277 "summary": "OBSERVED 2026-08-16, full method-parameter list of Create Submission read end to end: the call accepts exactly `submission`, `additionalMetadata` and `captchaToken`. There is NO disableNotifications, no suppressNotifications, no flowControlSettings, no participantNotification, and no `sendEmail`-style toggle anywhere on the Form Submissions surface; the words 'notification' and 'email' do not appear on the Create Submission, Submission Object, Confirm Submission or Form Submissions Introduction pages at all. What IS documented: creating a submission fires the `Submission Created` domain event, and the Form Schemas glossary defines 'post-submission trigger' as 'automated actions that are executed after a form submission is received' — i.e. the Wix Automations hook that the default 'new form submission' owner email rides on. Suppression therefore cannot be proven from the docs, so importSafe stays false, exactly as for events/rsvp. The only control we have is the site-wide MuteSite policy, which is not a per-call flag, is applied by default only to newly created target sites, and has not been verified to cover the Automations email path."
278 },
279 "form": {
280 "path": "domains/forms/entities/form.json",
281 "displayName": "Wix Form (form schema)",
282 "classification": "native",
283 "reliabilityStatus": "unknown",
284 "reliabilityFlags": [],
285 "summary": "THE TWO DOCS PAGES CONTRADICT EACH OTHER on this field and both readings are recorded here, because either one is bad enough to matter. About Form Fields says the mild version: 'Wix Forms uses `identifier` to render submissions in the submission table, so a field with a missing or non-standard identifier may display incorrectly there, even though the form itself works and the API accepts the request.' The Form Object page says the severe version: 'An unrecognized value, such as a custom string or a GUID, is dropped rather than rejected: the request still succeeds, but the field doesn't appear in the response's formFields, and neither the field nor its submitted values appear in the Wix dashboard.' Both agree the request returns success, so neither failure mode surfaces as an error at import time. Behave as if the severe reading holds until a live probe settles it: map every source field type onto a known identifier from the Field types table, ledger anything forced to a generic TEXT_INPUT/TEXT_AREA as a fidelity loss, never invent an identifier or pass a source GUID through — and after creating a schema, DIFF the returned formFields against what was sent, which detects the drop directly. Note also that the identifier list is per-namespace: apps owning their own namespace may define additional identifiers, so the table applies to `wix.form_app.form` only."
286 }
287 }
288 },
289 "gift-cards": {
290 "path": "domains/gift-cards/domain.json",
291 "displayName": "Wix Gift Cards",
292 "ownerHint": "Gift cards, stored value, and store credit domain owners",
300 "summary": "A site supports a MAXIMUM OF ONE gift card product (documented as a temporary limitation; second create → 409 GIFT_CARD_PRODUCT_ALREADY_EXISTS). A source shop with several gift-card products (different designs, different denomination sets, seasonal variants) CANNOT be migrated one-to-one: collapse them into a single product whose presetVariants union the denominations, and ledger the lost designs/descriptions as fidelity_loss. Check for an existing product before creating — on a non-empty destination the create will fail rather than merge."
308 "summary": "Omit `giftCard.notificationInfo` entirely on import. Including it emails the recipient — immediately when `notificationDate` is empty — so a historical import would re-mail every card holder."
354 "summary": "This surface defines the profile field (name, fieldType, defaultPrivacy); per-member values are written on the member profile. Import definitions before members or the value writes have no field to land in."
372 "summary": "VERIFIED LIVE 2026-08-16: safe mode cannot import members at all today. `mockEmailForEntity` (rp-target-wix/lib/wix-writers.js) mints `replatform+<type>_<id>@wix.com`, and POST /members/v1/members rejects that domain with 400 INVALID_EMAIL_DOMAIN — so a safe-mode member import fails wholesale on the first record. The bug hid because Contacts V5 ACCEPTS @wix.com (existing test contacts use it), so only the Members surface trips it. A reserved-TLD address (RFC 2606 `.invalid`) was accepted by other surfaces in the same probe session and is the obvious candidate, but changing the safe-mode address format alters what gets written to a customer's site on every entity, not just members — it needs an explicit decision, not a silent lib patch. Until then: treat safe mode + member import as unsupported and say so in the plan rather than discovering it mid-run."
387 "summary": "STILL UNPROVEN after a live probe (2026-08-16) — importSafe deliberately stays false. Create Offline Order documents no member-notification behavior and has no suppress/silent flag (the request is only planId, memberId, paid, startDate, couponCode, submissionId), while the sibling Mark As Paid explicitly documents that offline payments 'trigger events and emails'. The 2026-08-16 probe created a real offline order with paid:true and observed NOTHING that indicates an email either way — but the observation is worthless as proof of silence for two independent reasons: (a) the target site was under a site-wide notification mute for the whole probe, which by design suppresses all notifications to all recipients on all channels, so no email could have been sent regardless of the API's default behavior; and (b) the probe member's address was deliberately undeliverable (example.invalid), and there is no Wix read API that lists emails a site has sent, so even unmuted there would have been nothing to inspect. Absence of evidence here is an artifact of the method, not a finding. See notification-proof-requirements for what would actually settle it."
395 "summary": "plan.status is REQUIRED on create and is NOT listed among the docs' required parameters. VERIFIED LIVE 2026-08-16: omitting it 400s with REQUIRED_FIELD on plan.status; 'ACTIVE' is accepted. Any generated create payload built strictly from the documented required-field list will fail on the first call."
396 }
397 }
398 },
399 "sales-channels": {
400 "path": "domains/sales-channels/domain.json",
401 "displayName": "Wix Sales Channels",
402 "ownerHint": "Stores multichannel/marketplace integrations — the \"Sales Channels\" section of the Wix Stores dashboard (Catalog > Sales Channels)",
412 "summary": "Public support docs describe the original \"Amazon by Wix\" app as deprecated since 2025-05-04, with Wix recommending a third-party app (Koongo) as the replacement. But a live internal service, wix.stores_channels.amazon.v1.amazon_passive_feed, was created 2026-06-17 and last updated 2026-07-20 — well after that deprecation — and implements an automatic feed-push mechanism (AMAZON_XML format, pushed to an Amazon-owned S3 bucket). This suggests Wix has since built a newer native Amazon integration distinct from the deprecated app, but the exact current merchant click-path was not independently confirmed against a live dashboard this session. Re-verify the steps below (and whether the current \"Amazon\" sidebar entry is this newer service or a third-party app) against a live site before relying on them for a real migration report."
423 "summary": "No FQDN matching \"ebay\" was found anywhere in the internal Business Schema registry this session (docs-schema MCP fqdn_lookup), unlike every other channel in this domain (Google, Facebook, TikTok, Pinterest, and Amazon all resolved to a real internal wix.stores_channels.* service). The mechanism below is sourced from support.wix.com only — treat it as lower confidence than the other entities in this domain until an internal service is located or a live site is checked."
431 "summary": "This channel is the most automated of the group: after the one-time connect, sync is push-based and continuous — there is no feed link for the merchant to copy anywhere, unlike Meta/TikTok/Pinterest."
439 "summary": "The connect flow below reproduces the sync OUTCOME, not the plugin's per-product configuration. Meta for WooCommerce's fb_visibility, _wc_facebook_product_image_source, _wc_facebook_google_product_category, _wc_facebook_gender, and _wc_facebook_color_attribute have no receiving field: wix.stores_channels.marketplace_overrides.v1.product_override (the live, GA per-product channel-override mechanism) implements only googleProductOverrides/youtubeProductOverrides in its oneof — no facebookProductOverrides variant exists (verified via docs-schema MCP fqdn_schema, 2026-08-16). Report these as accepted, reported loss."
447 "summary": "Unlike Meta/TikTok, Pinterest requires a site-ownership verification step (a Pinterest-issued HTML tag pasted into Wix Custom Code) BEFORE the catalog-link step. A runbook that skips straight to \"Get Catalog Link\" will fail — the merchant must verify the site first."
470 "summary": "An item is addressed by `{itemType}:{itemId}` where itemId is the WIX GUID of an already-created item (a page, a Blog post, a Stores product). SEO tags therefore import in a SECOND pass, after the owning entity has been written and its id recorded in the crosswalk. There is no create-by-source-id path here, which is why crosswalkRequired is true."
478 "summary": "POST /promote/seo/v1/seo-patterns/{pageType} fails with 409 PATTERN_ALREADY_EXISTS when the site already has its own pattern for that page type, and PATCH on the same path fails with 404 PATTERN_NOT_FOUND when it does not. `source` on the object says which is the case (the site's own pattern versus the Wix default). Read first, then branch; do not retry the other verb blindly."
486 "summary": "A `robots` tag with `noindex` or `none` at site level stops search engines indexing the WHOLE site. A WordPress source in staging almost always carries site-wide noindex (blog_public = 0; verified live on the reference store 2026-08-16, where every yoast_head_json.robots reported index: noindex). Copying the source's site-level robots value across would silently de-index the new Wix site. Never carry noindex; treat indexability as a launch decision, not migrated data."
497 "displayName": "Back In Stock Notification Request",
498 "classification": "native",
499 "reliabilityStatus": "partially-reliable",
500 "reliabilityFlags": [
501 "target-write-not-yet-live-verified"
502 ],
503 "summary": "Creating a request 428s with REQUEST_COLLECTION_DISABLED unless Start Collecting Requests has been called for the site first. This is a one-time setup step, not a per-record concern — emit it as a setup requirement, not a per-row retry."
504 },
505 "brand": {
506 "path": "domains/stores/entities/brand.json",
507 "displayName": "Stores Brand",
508 "classification": "native",
509 "reliabilityStatus": "reliable",
510 "reliabilityFlags": [],
511 "summary": "The Wix Brand object is {id, name, revision, dates} only; source brand logos and descriptions have no native home and are dropped unless preserved via the CMS fallback. Record the loss in the faithfulness ledger."
543 "summary": "Attaching an existing customization to a product by id ALONE fails. VERIFIED LIVE 2026-08-16: product.modifiers[] = [{ id: <customization GUID>, mandatory: false }] → 400 REQUIRED_ONE_OF_FIELD 'freeTextSettings or choicesSettings must not be empty', and adding freeTextSettings without a title → 400 MIN_LENGTH on modifiers[0].modifierSettings.freeTextSettings.title. A ConnectedModifier must restate name, modifierRenderType, and the full settings block (title included) next to the id. Note the field renames between the two surfaces: the standalone customization uses freeTextInput/customizationRenderType, the product-side modifier uses freeTextSettings/modifierRenderType — a transform that reuses the create payload verbatim will fail."
567 "summary": "CORRECTED 2026-08-16 (this entity previously claimed the opposite). A Wix Stores promotion is 'a visual banner displayed on store category pages, including their product gallery sections' — it is a MERCHANDISING IMAGE with a name, a required media asset, an optional destinationUrl, and category placements. It carries NO discount, NO percentage, NO scope, NO date window, and NO price effect of any kind; the create schema has no such fields and a body containing them is rejected. Discount-rule plugin campaigns therefore DO NOT map here — route them to stores/coupon, to native discount rules, or to per-product pricing on stores/product. Mapping a source discount campaign to this entity would produce a decorative banner and silently lose the discount."
575 "summary": "Every review needs a contact: Bulk Create requires reviews.author.contactId, and the Create Review introduction states the single-create method requires a contact ID too. Importing reviews therefore CREATES OR RESOLVES A CONTACT PER DISTINCT REVIEWER — a CRM side effect well beyond the catalog, and reviewers are frequently not customers. Resolve each reviewer by email through Query Contacts first, create only on miss, and disclose the contact count at the execution gate."
583 "summary": "Subscription expiry/length, initial signup price, and free trial have NO product.subscriptionDetails field. Decided by Spec Owner 2026-08-16: these are reported loss — ledger them as fidelity_loss entries in the migration report; they are NOT CMS-carried. Do not invent an extended-field or CMS home for them."
584 }
585 }
586 },
587 "tax": {
588 "path": "domains/tax/domain.json",
589 "displayName": "Wix Tax",
590 "ownerHint": "eCommerce tax domain owners (Tax Groups / Tax Regions / Manual Tax Mappings)",
606 "summary": "Create/Query/Delete Tax Group are all `/billing/v1/tax-groups...`, not `/ecom/v1/...` (unlike sibling Discount Rules) or `/stores/v2/...` (unlike Coupons)."
622 "summary": "There is exactly one TaxSettings object per site (Get returns defaults if never set; Upsert creates-or-updates the same singleton). Treat this as ordinary setup/config work, never a per-record write with a crosswalk."