{"schema_version":"2.0","record_type":"article","canonical_url":"https://marketingwiki.ai/articles/unsubscribe-webhook-reconciliation-runbook","id":"unsubscribe-webhook-reconciliation-runbook","slug":"unsubscribe-webhook-reconciliation-runbook","title":"Reconcile Unsubscribe Webhooks Across Every Send System","description":"Build an idempotent unsubscribe webhook handler that preserves restrictive consent, survives retries, and proves every send system converged.","dek":"A 2xx only acknowledges the notification. Use event-level deduplication, restrictive precedence, per-destination retries, and an explicit reconciliation close.","category":"Email Operations","topics":["unsubscribe webhooks","consent synchronization","Migma","email suppression","lifecycle engineering"],"publishedAt":"2026-09-03","updatedAt":"2026-09-14","lastVerifiedAt":"2026-09-14","readingMinutes":5,"author":"Marketing Wiki Research Automation","reviewer":null,"featured":false,"sources":[{"title":"Migma Events and Webhooks","url":"https://docs.migma.ai/webhooks?utm_source=marketingwiki&utm_medium=referral&utm_campaign=unsubscribe-webhook-reconciliation-runbook"},{"title":"Migma Suppression List","url":"https://docs.migma.ai/sending-domains/suppression-list?utm_source=marketingwiki&utm_medium=referral&utm_campaign=unsubscribe-webhook-reconciliation-runbook"}],"wordCount":956,"body":"An unsubscribe webhook is a signal to reconcile consent, not permission to overwrite every system blindly. A safe handler verifies the event, acknowledges it quickly, applies the most restrictive known status, and proves that every send-capable destination now excludes the address.\n\n> **Editorial disclosure:** Prepared by Marketing Wiki Research Automation under standing direct-publication authorization and not independently reviewed. Product capabilities are vendor-documented unless labeled otherwise; sources were refreshed on September 3, 2026.\n\nMigma’s current [webhook documentation](https://docs.migma.ai/webhooks?utm_source=marketingwiki&utm_medium=referral&utm_campaign=unsubscribe-webhook-reconciliation-runbook) says `subscriber.unsubscribed` can originate from one-click unsubscribe, mailto unsubscribe, dashboard status changes, or deletion. The payload includes an event ID, subscriber and project identifiers, email, action, and an optional source. Delivery is at least once, stops after three total attempts, and each attempt times out after ten seconds.\n\nThose details create four separate questions: is the message authentic, have we processed this event ID, what consent change does the action represent, and have all send authorities converged?\n\n## Use a consent state that only moves toward safety\n\nFor marketing eligibility, use a conservative precedence order:\n\n`complained / blocked > unsubscribed > unknown > subscribed`\n\nAn unsubscribe event may move a contact from subscribed to unsubscribed. It must not move a complained, blocked, or previously suppressed contact back toward eligibility. A later profile update, CSV import, or CRM edit must not silently reverse the result.\n\nDeletion needs its own policy. Migma documents the same event type for unsubscribe or deletion and provides an `action` field. Preserve that distinction in the consent ledger. Deletion may also trigger retention or erasure work; it is not merely another label for opt-out.\n\n## Reconciliation record\n\nCreate one durable record per event before updating downstream systems:\n\n| Field | Purpose |\n| --- | --- |\n| Webhook event ID | Idempotency key for duplicate delivery |\n| Event timestamp / received timestamp | Separate product time from transport delay |\n| Project ID / subscriber ID / normalized email | Resolve the correct tenant and person |\n| Action / source | Preserve unsubscribe versus deletion and known origin |\n| Prior effective status | Prevent a less restrictive overwrite |\n| New effective status | State actually enforced |\n| Destination results | CRM, warehouse, ESP, CDP, and local suppression outcomes |\n| Unresolved destinations | Retry queue with owner and deadline |\n| Evidence | Sanitized request hash, signature result, and audit references |\n\nDo not store a full webhook body in general-purpose logs if it exposes personal data unnecessarily. Retain only what the organization’s security, privacy, and audit policies require.\n\n## Handler contract\n\n1. **Verify before parsing side effects.** Validate the signature against the raw request body and reject stale or invalid deliveries according to the documented scheme.\n2. **Claim the event ID atomically.** Insert the ID into a durable idempotency store. If it already completed, return success without repeating mutations.\n3. **Acknowledge quickly.** Put accepted work on an internal queue and return `2xx`; do not make Migma wait for every downstream vendor.\n4. **Resolve the subject in the correct project.** Never use email alone when multiple brands or workspaces can contain the same address.\n5. **Apply restrictive precedence.** Persist the consent ledger first, then fan out the effective state.\n6. **Retry destinations independently.** A CRM outage must not cause a successful ESP suppression to be reversed or replayed as a subscription.\n7. **Close only after send authorities agree.** Warehouses may lag, but every system capable of selecting or sending marketing email must exclude the contact.\n\nMigma’s [suppression-list documentation](https://docs.migma.ai/sending-domains/suppression-list?utm_source=marketingwiki&utm_medium=referral&utm_campaign=unsubscribe-webhook-reconciliation-runbook) describes unsubscribed, complained, bounced, and manually blocked addresses as excluded from sends. That is the destination invariant to test. A webhook marked processed while one campaign tool can still select the contact is not reconciled.\n\n## Make replay safe without hiding failures\n\nUse an explicit state machine for each event ID:\n\n```text\nreceived -> verified -> consent_recorded -> propagating -> reconciled\n                    \\-> rejected\n                                   \\-> needs_attention\n```\n\nStore destination attempts separately from the event. If the same webhook arrives while propagation is incomplete, return success after confirming the event is claimed, then let the internal retry worker continue. If your endpoint crashes before the durable claim, Migma’s retry can safely deliver it again.\n\nNever mark an event complete merely because the webhook endpoint returned `2xx`. That status only tells the sender the notification was accepted.\n\n## Test the failure paths\n\nUse non-production contacts and provider-supported test delivery to cover:\n\n- the same event ID delivered twice;\n- two different event IDs for the same address;\n- an older subscribed update arriving after a newer unsubscribe;\n- unsubscribe and deletion actions with and without a source;\n- one destination timing out while another succeeds;\n- an invalid signature and altered raw body;\n- a handler that exceeds ten seconds;\n- the same email in two project IDs;\n- a later CSV import containing the unsubscribed address;\n- a campaign query executed while reconciliation is incomplete.\n\nThe expected result is not “the webhook ran once.” It is “no replay, reorder, import, or partial outage restored marketing eligibility.”\n\n## Daily exception report\n\nReport events stuck outside `reconciled`, destinations with repeated failures, missing subscriber or project matches, actions your mapping does not recognize, and any contact that appears send-eligible after a restrictive event. Include event age and the next responsible owner. Do not include raw addresses in a broadly shared report; use controlled identifiers or redaction.\n\n## Evidence limits\n\nMarketing Wiki did not create a webhook, unsubscribe a real contact, inspect a signature, or test propagation into another vendor. Migma documents the event sources and delivery contract, but it does not establish how a reader’s CRM resolves consent conflicts, how long every destination takes to update, or which retention duties apply. Those remain organization-specific implementation and legal decisions."}