---
title: "Reconcile Optout Event"
method: POST
path: "/sms-consent/optout-events/{event_id}/reconcile"
tags: ["sms-consent"]
---

# Reconcile Optout Event

`POST /sms-consent/optout-events/{event_id}/reconcile`

## Request

- Base URL: `https://api.verdun.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.verdun.ai/sms-consent/optout-events/{event_id}/reconcile`
- Auth: HTTP bearer

Offer a CANDIDATE number for an unattributed opt-out.

THE NUMBER IS NOT ACCEPTED, IT IS PROVEN. The finalizer runs a live lookup
and resolves only if the candidate's single matching Surge contact IS this
event's contact. A typo returns `unverified`, suppresses nothing, resolves
nothing, and leaves SMS paused — which is the entire point: accepting an
owner's word would suppress the wrong number and lift the account-wide
refusal for the real subscriber.

## Path parameters

- `event_id` string, required

## Request body

- ReconcileOptOutRequest
  - `candidate_phone` string, required: A CANDIDATE number for the opt-out, never an assertion. The server proves it belongs to the event's Surge contact with a live lookup before suppressing anything; an unprovable candidate resolves nothing and suppresses nothing.

## Response `200`

Successful Response

- ReconcileOptOutResponse
  - `outcome` string, required: resolved | already_resolved | unverified. `unverified` means the candidate number could NOT be proven to belong to this contact: nothing was suppressed, nothing was resolved, and SMS stays paused.
  - `event` OptOutEventResponse, required: One durable STOP event, for the owner's reconcile view. An UNRESOLVED row here is why SMS may be refusing every send: we know someone opted out but not which number, so no destination can be proven unrelated to them.
    - `id` string, uuid, required: Unique identifier of the opt-out event.
    - `webhook_id` string, required: Surge's signed webhook-id; the replay key.
    - `surge_contact_id` string, required: The Surge contact that opted out.
    - `event_ts` string, date-time, required: When the opt-out occurred, frozen at first insert.
    - `phone_number` string, nullable: The number, once PROVEN to belong to the contact. NULL until then.
    - `resolved_at` string, date-time, nullable: When it was reconciled.
    - `resolution_error` string, nullable: Why the last resolution attempt proved nothing.
    - `attempt_count` integer, required: Resolution attempts so far.
    - `last_attempt_at` string, date-time, nullable: Most recent attempt.
    - `escalated_at` string, date-time, nullable: When this was escalated for human attention.
    - `created_at` string, date-time, nullable: Row creation time.
    - `updated_at` string, date-time, nullable: Row last-update time.

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/verdun/apis/verdun-api.md) - [All operations](https://skmtc.dev/verdun/apis/verdun-api/llms.txt) - [OpenAPI document](https://skmtc.dev/verdun/apis/verdun-api/revisions/00252d8227c1?raw)
