# `AshHooks.InboundDelivery`
[🔗](https://github.com/baselabs/ash_hooks/blob/v2.0.3/lib/ash_hooks/inbound_delivery.ex#L1)

Turns the consumer's resource into the inbound webhook ledger — the
durable deduplication record used by `AshHooks.Ingress`.

Attach next to the consumer's own data layer:

    use Ash.Resource,
      data_layer: AshSqlite.DataLayer,
      extensions: [AshHooks, AshHooks.InboundDelivery]

    inbound_delivery do
      scope_identity([:account_id])
    end

The extension injects the ledger fields (provider, external ids, payload +
digest, the fenced state machine's status/token/lease/attempts), the
`unique_ingest` identity spanning provider + external event id + the
declared scope slots, and the action primitives used by
`AshHooks.Ingress`. These include ingest, claim/finalize/renew, payload
redaction, bounded retention, and explicit legacy identity adoption.

The uniqueness identity must be backed by a unique index on the
consumer's data layer. Storage-level uniqueness preserves one ledger row
under concurrent ingests; the lease and token govern handler ownership.
Scope slots
must be non-nullable attributes: a nullable slot would make `nil` scope
values distinct on SQL unique indexes and silently break dedup for
scope-less redeliveries.

Provider identity upgrades use
`AshHooks.Ingress.plan_legacy_identity_adoption/3` and
`AshHooks.Ingress.adopt_legacy_identity/3`. Adoption keeps one deterministic
representative per canonical identity and marks every retained sibling
terminal `:superseded`; those rows cannot be reaped into handler execution.
Applying adoption requires a transaction-capable data layer and quiesced
ingress and reapers. See the ordered upgrade in `UPGRADING.md`.

The injected actions are low-level primitives: the conditional gates
(claim only from `:received` or an expired lease; mark/renew only by the
current token under an unexpired lease) live in the query filters that
`AshHooks.Ingress` builds. Call the driver APIs to preserve those
conditions; restrict direct access to the generated machine actions.

This ledger stores decoded provider payloads, the signed-body digest,
event IDs, and scope keys. Payloads can contain personal information.
Define read policies in your domain; the extension does not inject them.
The README's Security section shows an example.

# `inbound_delivery`
*macro* 

# `statuses`

```elixir
@spec statuses() :: [atom()]
```

The fenced state machine's statuses, including terminal `:superseded` rows
retained by legacy identity adoption.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
