22 "decision": "The request shape is verified live (create + readback + delete, 2026-08-16), but importSafe stays FALSE: nothing observable proves that disableNotifications actually suppresses the guest confirmation email. The flag is accepted and echoed, and the site-wide mute was on, yet neither is a proof of non-delivery — see pitfall notification-suppression-unproven for exactly what was probed and what would settle it. Any run that needs RSVPs must surface this at the approval gate."
23 },
24 "reliability": {
25 "status": "partially-reliable",
26 "flags": []
27 },
28 "safeModeContactFields": [
29 {
30 "kind": "email",
31 "targetPath": "rsvp.email",
32 "source": "target-schema",
33 "notes": "Guest email on the RSVP create body — required, format-validated, and the key Wix uses to create/match a CRM contact."
34 }
35 ],
36 "pitfalls": [
37 {
38 "code": "notifications-default-on",
39 "severity": "blocker",
40 "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."
41 },
42 {
43 "code": "notification-suppression-unproven",
44 "severity": "blocker",
45 "summary": "PROBED 2026-08-16, STILL UNPROVEN. What was established: `disableNotifications: true` is accepted on create, is persisted, and is echoed back on both the create response and a later GET (a response flag, not a delivery flag); the site was verified muted (getSiteMuteState → muted:true) before and during the probe; the guest address used a .invalid domain, so nothing could have been delivered anyway. What was NOT established: the create-rsvp docs describe the field only as \"Whether notifications are disabled\" — no statement that it covers the guest-facing confirmation email; there is no public API that lists sent emails, so non-delivery cannot be observed from the API; and the site-wide mute cannot be credited either, because its documented scope is site notifications, not proof about guest transactional mail. WHAT WOULD SETTLE IT: (a) an explicit statement from the Events team/docs that disableNotifications suppresses the guest confirmation email — the cheap owner ask, or (b) a controlled probe on a throwaway site with a real monitored mailbox, comparing disableNotifications true vs false on an UNMUTED site (the true-vs-false pair is what makes the negative observable). Until one of those exists, keep importSafe false."
46 },
47 {
48 "code": "draft-events-reject-rsvps",
49 "severity": "blocker",
50 "summary": "DISCOVERED 2026-08-16 (live): creating an RSVP against a DRAFT event fails with 400 EVENT_NOT_FOUND — RSVP V2 does not see unpublished events. The same call succeeded immediately after POST /events/v3/events/{id}/publish. This breaks the tempting 'import events as drafts, load RSVPs quietly, publish later' plan: the event must be publicly published before its guest list can be imported, which widens the notification/visibility surface of an RSVP import."
51 },
52 {
53 "code": "rsvp-creates-a-crm-contact",
54 "severity": "blocker",
55 "summary": "CORRECTED 2026-08-16 (live): the earlier claim that RSVPs do not touch CRM is wrong. Creating one RSVP produced a new contact for the guest email with sourceType WIX_EVENTS. An RSVP import therefore writes into Contacts as a side effect — it can duplicate contacts imported by crm/contact, and it means RSVP volume is contact volume. Reconcile guest emails against the contact crosswalk before importing RSVPs, and count the contact writes in the plan. (Method note: a Contacts V4 query filtered on info.emails.email returned zero rows for a contact that plainly exists — filter fields are a closed list per endpoint, so verify by listing, not by an unsupported filter.)"
56 },
57 {
58 "code": "registration-state-blocks-create",
59 "severity": "warning",
60 "summary": "A freshly created event comes back with registration.status CLOSED_AUTOMATICALLY (no sale/RSVP window open), and create-rsvp defines RSVPS_CLOSED / RSVPS_NOT_STARTED / GUEST_LIMIT_EXCEEDED / RSVP_LIMIT_EXCEEDED failures. The 2026-08-16 probe passed options.ignoreResponseStatus:true and options.ignoreLimits:true and succeeded; which of the two was strictly required was not isolated. A historical-guest import should pass both deliberately and disclose it — they override the site's own registration rules."
65 "summary": "rsvp.form.inputValues must use the input names from the event's form (GET /events/v3/events/{id}?fields=FORM), honour mandatory inputs for YES responses, and stay inside predefined options, else INVALID_FORM_RESPONSE. The probe sent firstName/lastName/email and they round-tripped. options.ignoreFormValidation exists as an escape hatch for lossy source data. Additional guests require the event form to carry a GUEST_CONTROL control."
66 },
67 {
68 "code": "one-rsvp-per-email-per-event",
69 "severity": "warning",
70 "summary": "Duplicate guest emails on one event fail with 428 MEMBER_EMAIL_ALREADY_REGISTERED (and MEMBER_ALREADY_REGISTERED when memberId repeats) — dedupe the source guest list by email per event before writing, and make retries crosswalk-guarded."
71 },
72 {
73 "code": "rsvp-only-events",
74 "severity": "blocker",
75 "summary": "The event's registration.initialType must be RSVP and is immutable — a TICKETING event can never accept RSVPs (428 INVALID_EVENT_TYPE). Choose the registration type when creating the event from the source data."
76 },
77 {
78 "code": "past-event-rsvps-unverified",
79 "severity": "warning",
80 "summary": "Still unverified whether Create Rsvp accepts already-ended events; the 2026-08-16 probe used a far-future event. Historical RSVP import may be restricted to upcoming events — verify before planning full history."
81 }
82 ],
83 "mappingGuidance": [
84 "Create the event first with registration.initialType RSVP, PUBLISH it, and use its crosswalked ID in eventId — draft events are invisible to this API.",
85 "Set disableNotifications on every create call — this is the safe-import rule for the whole registration group — and still treat the write as guarded until the suppression is proven.",
86 "Map source attendee records (e.g. Event Tickets RSVPs) to firstName/lastName/email/status (YES | NO | WAITLIST) and additionalGuestDetails.guestCount/guestNames; build form.inputValues from the event's form controls.",
87 "Plan the CRM impact: each RSVP creates or matches a contact (sourceType WIX_EVENTS), so sequence RSVPs after crm/contact and reconcile by email."
102 "note": "disableNotifications is a field on the rsvp object (not a query param); described only as \"Whether notifications are disabled\" — no statement about the guest confirmation email"
103 },
104 {
105 "type": "live-run",
106 "path": "migrations/reference-run",
107 "note": "finding #17 follow-up; RSVP import path spotted at the docs-survey sweep"
108 },
109 {
110 "type": "live-run",
111 "path": "migrations/probe-run-20260812/config/wix.env (target site 00000000-0000-0000-0000-000000000000)",
112 "note": "KB verification probe 2026-08-16, safe mode on / site muted (muted:true re-checked at call time): create against the DRAFT probe event → 400 EVENT_NOT_FOUND; after publish, create with disableNotifications:true + ignoreResponseStatus/ignoreLimits and a zzz-probe-guest@example.invalid address → 200 (rsvp 19e60538…, disableNotifications echoed true on create and on GET); a contact with sourceType WIX_EVENTS appeared for the guest email; RSVP, contact and both probe events deleted afterwards"
113 }
114 ],
115 "notes": "Authored 2026-08-11 from the docs-survey gap (RSVP V2). The write shape was promoted to verified-live on 2026-08-16, but importSafe deliberately stays FALSE — the probe could not prove that no guest email fires (see notification-suppression-unproven for the settle-it conditions). The same probe found two contradictions in the original entry: draft events reject RSVPs, and RSVP creation does create a CRM contact."