Viewer URL parameters & transport
Query parameters you can append to a Wallflower.tv watch or broadcast URL, and how the
origin → edge transport hint (xport) works. Developer reference.
Watch / broadcast selectors
| Parameter | Example | Meaning |
|---|---|---|
stream | ?stream=ab5ki |
Broadcast as a given 5-char stream id (broadcaster path). |
node | ?node=<52-char key> |
Watch a broadcast by its stream key — the broadcaster's Ed25519 public key
rendered as base32(publicKey), minted in the browser. Your browser resolves the key to a live
origin off the public Mainline DHT (a signed pkarr record; no directory server). The key
is itself the capability to watch (a legacy ?luke= alias resolves the same DHT path). Access
is token-gated at the relay, but the Worker auto-mints your subscribe token from the key
— you never handle a token. This is distinct from the origin relay's own iroh EndpointId, which is a
transport address, not the stream name. |
publish | ?publish=1 |
Go live as a node id: the browser mints an Ed25519 key, assigns an origin, and
self-publishes a signed pkarr record to the Mainline DHT so ?node= viewers can resolve it.
The broadcaster connects with a publish-scoped token (put:[key]) — the origin is gated. |
viewer-cdn direct-mode only | ?viewer-cdn=ams.moqcdn.net |
A direct-mode override that forces which provisioning fleet serves this viewer's edge (a
cross-cluster edge pulling from the origin, Mode B). Ignored on the brokered production
deployment (wallflower.tv / multicast.video): there the broker (cdnadmin) owns box selection and
geo-routes the viewer to its nearest fleet automatically — and as of 2026-07-19 makes a non-origin fleet
cluster-pull the origin with no override needed (the brokered viewer path returns before this param is read).
Use ?geo= to exercise steering on the brokered path; viewer-cdn only takes effect where
the app runs in direct mode (calling its own fleet box's /assign). |
publisher-cdn direct-mode only | ?publisher-cdn=ams.moqcdn.net |
A direct-mode override for which provisioning fleet the broadcaster's origin is assigned on
(broadcaster path, incl. ?publish=1). Ignored under brokered (wallflower.tv /
multicast.video) — the broker geo-places the origin on the broadcaster's nearest fleet. Must be an allowed
fleet host where it does apply (direct mode). |
geo | ?geo=47.60,-122.33 |
Testing override for the viewer/broadcaster location, forwarded to the broker as hints.geo
so geo-nearest routing can be exercised from anywhere (normally derived from request.cf). Works
on the origin-placement, fleet-watch, and ?node= edge-placement paths. Since 2026-07-19
this drives real cross-fleet playback: geo-steering a fleet-watch (Model A) viewer to a fleet that isn't the
broadcaster's origin makes that fleet cluster-pull the origin over host:port and play —
so cross-cluster edge (Mode B) is now automatic under geo routing, no longer only under
?viewer-cdn=. |
origin | ?origin=host:port |
Testing override on the fleet watch path: force the host:port origin the edge pulls from
(normally derived by the Worker). The old &origin=HOST:PORT browser form of the retired
luke directory gateway is gone; on the ?node= path the origin comes from the signed DHT record,
not this param. |
xport transport hint | ?xport=iroh |
Selects the origin → edge transport. See below. |
xport — origin → edge transport hint
On a cross-cluster (?viewer-cdn=) or enterprise watch URL, xport tells the
TinyMoQ CDN how the edge should pull the stream from the origin:
| Value | Effect |
|---|---|
iroh | The edge pulls from the origin over iroh — mainline-DHT discovery, NAT-friendly, so the origin needs no public host:port. |
| (absent / any other value) | Default: the edge pulls over native
QUIC by host:port. The request is byte-identical to a URL with no
xport at all. |
Gated-origin caveat (2026-07). Origins are now token-gated, and the edge's
pull token reaches the origin only over the
host:port QUIC connect. So on the live fleet a cross-box
pull uses host:port even when ?xport=iroh is requested — the iroh transport does not
yet carry the pull token to a gated origin. Iroh origin-pull stays the design target for NAT'd origins (the current
fleet is publicly reachable); the fix is deferred.How the hint travels (it is forwarded verbatim, never interpreted client-side):
Mode B (?viewer-cdn=):
browser URL ?xport=iroh
-> GET /api/streams/<id>/route?viewer-cdn=…&xport=iroh (player)
-> Worker /route reads xport, calls assignRelay(…, xport)
-> GET https://<edge>/assign?broadcast=…&xport=iroh (server-side)
Mode C (enterprise, on-net edge):
browser URL ?xport=iroh
-> GET https://<relay>/assign?broadcast=…&xport=iroh (browser preflight)
Two things people get wrong:
- The
Connected: <edge>:<port>/Mode: WebTransportline is the browser ↔ edge hop, and it is always WebTransport — regardless ofxport. It is not a fallback indicator.xportonly affects the separate origin → edge hop. xportis a non-secret transport hint. It changes no tokens and no auth. Access is still gated by the per-broadcast token, andxportnever affects media encryption (the MoQplay fleet path stays end-to-end encrypted with a content key no relay ever sees; the?node=path stays not media-encrypted).
"Origin link" stats line
For a cross-cluster watch, the player confirms the actual origin → edge transport
by polling a public, read-only endpoint on the edge (~1.5 s after connect, re-polling every 5 s;
the line is hidden on unknown or any error):
GET https://<edge-host>/edge_xport?broadcast=<rawBroadcastId>
(port 443, no auth, CORS *; the broadcast id is substring-matched)
-> { "xport": "iroh" | "quic" | "unknown", "origin": "<host:port>" }
It renders one of:
xport | Stats line shown |
|---|---|
iroh | Origin link: iroh / DHT |
quic | Origin link: <origin> (QUIC) |
unknown / error | (line hidden) |
See also
Full architecture (PDF) — infrastructure, routing & the
three-hop transport model that xport plugs into.