# `A2UIAgent.PayloadValidator`
[🔗](https://github.com/a2ui-elixir/a2ui/blob/v0.1.1/umbrella/apps/a2ui_agent/lib/a2ui_agent/payload_validator.ex#L1)

Checks a payload an agent is about to send the way a renderer holding
the same catalogs would.

    :ok = A2UIAgent.PayloadValidator.validate(catalogs, messages)

The check is stateless: it sees one payload, with no record of earlier
ones.

  * A surface the payload creates is checked in full: its components
    must be valid and reachable from the root, and their references
    must resolve once every message of the payload is applied (a
    component may name a child that a later message adds).
  * A surface the payload only updates may already hold components, so
    references to components outside the payload and a missing root
    are accepted. Its components must still be valid in a catalog that
    defines all of them; the surface passes if one such catalog accepts
    it. When the caller knows the catalog an earlier payload created
    the surface with (`:surface_catalog_ids`), only that one is tried.

Every message must state a `version` its catalogs accept: `v0.9` or
`v0.9.1` for v0.9 catalogs, `v1.0` for v1.0 catalogs. Messages may be
maps or `Jason.OrderedObject`s.

Failures are `A2UICore.Error`s: category `:validation` (or one of its
refinements, `:integrity` and `:recursion`) for a payload a renderer
would reject, `:catalog` for catalogs that cannot be used together.

# `validate`
*since 0.1.0* 

```elixir
@spec validate([A2UICore.Catalog.t()], term(), keyword()) ::
  :ok | {:error, A2UICore.Error.t()}
```

Validates `payload` (one message or a list of messages) against
`catalogs`. Option: `:surface_catalog_ids` — `%{surface_id =>
catalog_id}` for surfaces earlier payloads created.

---

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