# `Mead.Deck.Plug`
[🔗](https://github.com/albertosca/mead/blob/main/lib/mead/deck/plug.ex#L1)

The HTTP side of the deck: the two routes under `/deck`.

  * `POST /deck/ticket` - with the deck bearer token, creates a session (no body) or attaches to
    one (`{"session_id": "<uuid>"}`: running, or stopped with a stored history that is resumed)
    and answers `{"ticket", "session_id", "expires_in_ms"}`. The ticket is single use and short
    lived, so the token never travels in a URL.
  * `GET /deck/socket?ticket=...` - redeems the ticket and upgrades to a WebSocket served by
    `Mead.Deck.Socket`.

Each check runs only if the previous ones passed: the route (404, or 405 with `allow`), the
bearer token on the ticket route (401, checked in constant time before the body is read), the
`Origin` header (403, the same rule and setting as MCP), then the request itself. Refusals are
`{"error": "<reason>"}` and never repeat a header, a ticket or a body. No cookies and no CORS
headers are set.

## Options

  * `:configuration` - the `Mead.Deck.Configuration` (required).
  * `:allowed_origins` - exact `Origin` values accepted besides loopback; defaults to `[]`.
  * `:session_options` - options for the session a ticket creates or resumes (`:handler`,
    `:turn_timeout`); defaults to the router as handler.
  * `:storage_directory` - where the event logs live; defaults to the session storage directory.
  * `:tickets` - the ticket table; defaults to `Mead.Deck.Tickets`.

---

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