---
search:
  tags:
    - Journey
    - GET
seo:
  description: >-
    WebSocket upgrade (RFC 6455) — modelled here for discoverability, not a…
    Reference for the GET /stores/{store_id}/journey/stream endpoint in the
    Sarvex V1 API.
sidebar:
  label: Subscribe to live journey updates for the store
  badge: GET
title: Subscribe to live journey updates for the store
type: openapi-operation
---
WebSocket upgrade (RFC 6455) — modelled here for discoverability, not a standard
HTTP operation. The client authenticates by sending the bearer token as a
WebSocket subprotocol (`Sec-WebSocket-Protocol: bearer, <token>`) rather than an
Authorization header, since browsers cannot set custom headers on the handshake
request; the server echoes back `bearer` as the negotiated subprotocol. Ownership
of `store_id` is verified against the resolved principal before the upgrade
completes, exactly as on `GET /stores/{store_id}`.

On every server-side journey transition (see `control.journey.updated` in
sarvex-v1-syncing-plane-async.yaml) the server pushes one
`journey_stream_message` text frame with `type: journey.updated`. The payload is
a thin signal, not the full journey record — the client is expected to re-fetch
`GET /stores/{store_id}/journey` on receipt (same "thin event, fat pull"
convention the plugin uses for change signalling).

The same connection also carries `type: task.updated` frames whenever a task
belonging to this store changes (see `control.task.updated` in
sarvex-v1-syncing-plane-async.yaml), scoped to stores that already have a
journey record. The client is expected to re-fetch the task via
`GET /tasks/{id}` (`task_id` on the frame) rather than treat the frame as
authoritative.

It also carries `type: orders.updated` frames whenever a new order is recorded
for this store (see `sync.order.created` in
sarvex-v1-syncing-plane-async.yaml) — the Path's "Agent orders this week" tile
re-reads `GET /orders` on receipt.

No message frame should be treated as authoritative on its own, and a client
that never connects (or whose connection drops) must still see current state on
next page load via the GET endpoints above — the stream is a freshness
optimization, not a dependency.

`GET /stores/{store_id}/journey/stream`
