# `Agentic.LLM.AdminUsage`

Pollers for provider organization-level usage / cost APIs.

These endpoints require **separate** admin-tier keys distinct from
the regular API keys the agent uses for inference:

  * Anthropic — `sk-ant-admin-...`, organization-tier accounts only.
  * OpenAI — `sk-admin-...`, minted by an org Owner; available on
    all paid tiers.

Worth surfaces these as a separate "Connect organization for usage
reporting" flow in settings — they're strictly read-only billing
endpoints, but they are more sensitive than regular keys (read all
org usage, list members, manage keys).

Both providers split usage and cost across two endpoints. We return
a normalized shape here; SpendTracker reconciles against
gateway-derived rows for the same period.

# `bucket`

```elixir
@type bucket() :: %{
  period_start: DateTime.t(),
  period_end: DateTime.t(),
  model: String.t() | nil,
  input_tokens: non_neg_integer(),
  output_tokens: non_neg_integer(),
  cache_read_tokens: non_neg_integer(),
  cache_write_tokens: non_neg_integer(),
  request_count: non_neg_integer(),
  actual_cost: Money.t() | nil
}
```

# `opts`

```elixir
@type opts() :: [
  since: DateTime.t(),
  until: DateTime.t(),
  bucket_width: :daily | :hourly,
  group_by: [String.t()]
]
```

# `poll_anthropic`

```elixir
@spec poll_anthropic(String.t(), opts()) :: {:ok, [bucket()]} | {:error, term()}
```

Poll Anthropic Admin API for usage and cost over `opts[:since]..opts[:until]`.

Returns `{:ok, [bucket]}` or `{:error, reason}`. The two endpoints
(usage_report/messages and cost_report) are merged on
`(period_start, model, service_tier)`.

# `poll_openai`

```elixir
@spec poll_openai(String.t(), opts()) :: {:ok, [bucket()]} | {:error, term()}
```

Poll OpenAI Admin API for completion usage and total costs.

Returns `{:ok, [bucket]}`. The two endpoints
(`/usage/completions` and `/costs`) are merged on `period_start`.
Other modality endpoints (embeddings, images, audio) are ignored —
add them when there's a use case.

---

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