# `Macaw.Data.Source.Request`
[🔗](https://github.com/dcoai/macaw_data/blob/v0.5.3/lib/macaw/data/source/request.ex#L1)

What a reader asks a source for (spec/01 §2.3).

- `params`: the parameters, by name, checked against the description's before the call
  (`Macaw.Data.Parameter.validate/2`);
- `window`: `[from, to]` over a `:time` or `:number` window field, either bound `nil` for
  open, or `nil`;
- `box`: `%{west: w, south: s, east: e, north: n}` over a `:point` window field, in
  degrees, or `nil`;
- `region`: ranges over named fields, `%{field => [from, to]}`, each over a `:time` or
  `:number` field, or `nil` (visualize's region, kept so a region-supporting feed has an
  equivalent; the owner's decision, 2026-10-27);
- `latest`: `true` asks for each identity's latest row (spec/01 §1.4);
- `budget`: the most rows the reader wants, or `nil`;
- `as_of`: the `DateTime` the answer is as of, for a source supporting `:as_of`, or `nil`;
- `viewer`: the host's viewer, **opaque** here, passed to the source and never stored;
  `nil` is the anonymous viewer;
- `now`: the instant, given by the surface; a source never reads a clock.

`new/1` builds one and reports every fault at once. A request asks; a source may not
honor every part, and Macaw finishes what it does not (spec/01 §2.4).

# `t`

```elixir
@type t() :: %Macaw.Data.Source.Request{
  as_of: DateTime.t() | nil,
  box:
    %{west: number(), south: number(), east: number(), north: number()} | nil,
  budget: pos_integer() | nil,
  latest: boolean(),
  now: DateTime.t(),
  params: map(),
  region: %{required(term()) =&gt; [term()]} | nil,
  viewer: term(),
  window: [term()] | nil
}
```

# `box?`

```elixir
@spec box?(term()) :: boolean()
```

Whether a value is a box: four bounds in degrees, latitudes from −90 to 90 with `south`
at most `north`, longitudes from −180 to 180; `west` east of `east` crosses the
antimeridian.

# `new`

```elixir
@spec new(keyword() | map()) :: {:ok, t()} | {:error, [{list(), term()}, ...]}
```

A request of the given fields (a keyword list or a map), `now` required: `{:ok, request}`
or every fault, `{[field], reason}`, ordered by field.

    iex> {:ok, r} = Macaw.Data.Source.Request.new(now: ~U[2026-10-27 12:00:00Z], budget: 100)
    iex> {r.budget, r.latest, r.viewer}
    {100, false, nil}
    iex> Macaw.Data.Source.Request.new(budget: 0)
    {:error, [{[:budget], {:type, :pos_integer}}, {[:now], :required}]}

# `new!`

```elixir
@spec new!(keyword() | map()) :: t()
```

As `new/1`, raising `ArgumentError` naming every fault.

---

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