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

An outbound event: its identity, type, exact payload bytes, and optional context.

    {:ok, event} = AshHooks.Event.new(
      id: "msg_order-" <> to_string(order.id),
      type: :order_paid,
      payload: Jason.encode!(%{order_id: order.id})
    )

    AshHooks.dispatch(OrderResource, :order_paid, event)

Choose a deterministic `id` for each logical event when a producer can run
again. Reusing that ID lets dispatch recognize an existing delivery and lets
receivers deduplicate `webhook-id`. A generated ID makes each invocation a
new event, which can produce a duplicate POST for the same business change.
If a record can emit several changes, include the change's stable identity
or revision rather than using the record ID alone.

  * `id` is generated with a `msg_` prefix when omitted or `nil`. Supplied
    IDs do not require that prefix. They must be nonempty UTF-8 binaries,
    at most 255 bytes, without dots, spaces, or control characters. Dots
    delimit the Standard Webhooks signing string. Dispatch also validates
    IDs supplied through direct struct construction before persistence.
  * `type` is an atom or nonempty binary, at most 255 bytes. Construction
    converts atoms to strings, the representation used by subscriptions
    and the delivery ledger.
  * `payload` is a nonempty binary containing the exact bytes to sign and
    send. Serialize once; maps and structs are rejected.
  * `metadata` is a map of unsigned application context, defaulting to `%{}`.

# `t`

```elixir
@type t() :: %AshHooks.Event{
  id: String.t(),
  metadata: map(),
  payload: binary(),
  type: String.t()
}
```

# `new`

```elixir
@spec new(keyword() | map()) :: {:ok, t()} | {:error, String.t()}
```

Builds a validated event. Returns `{:ok, %AshHooks.Event{}}` or
`{:error, reason}` — never raises on caller input.

---

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