> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashnet.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming (SSE)

Server-Sent Events stream of order status changes. One connection per order; the server pushes each status transition as it happens, so you never poll.

## GET /v1/sse/operations/:id

`:id` is the order ID (`ord_...`). Connections are rate limited to 30 per minute per IP.

### Authentication

`EventSource` cannot set headers, so the API key goes in the `token` query parameter instead of `Authorization`.

* **Server keys** (`fn_`): `?token=fn_...` streams any order owned by your partner. Do not embed server keys in browser code.
* **Client keys** (`fnp_`): require the `orders:sse` scope and a second query parameter, `readToken`, the order-scoped token returned in the `/submit` or `/onramp` response that created the order with that client key. The readToken is bound to the partner, the client key, and the order ID, and expires 24 hours after issuance. A missing or invalid readToken returns `403`.

An order that does not exist or belongs to another partner returns `404`.

### Events

| Event       | Data                     | When                                                                 |
| ----------- | ------------------------ | -------------------------------------------------------------------- |
| `status`    | `{"status": "swapping"}` | Immediately on connect (current status), then on every status change |
| `heartbeat` | empty                    | Every 15 seconds while the stream is open                            |

Status values match [`GET /v1/orchestration/status`](/products/orchestration/api/quotes-and-orders#get-v1orchestrationstatus); internal `paused` states stream as `processing`.

### Close semantics

The server ends the stream when the order reaches `completed`, `failed`, or `refunded`. If the order is already terminal at connect time, you get one `status` event and the stream closes.

`unfulfilled` does not close the stream: a late deposit can revive the order, so keep listening. If your connection drops, reconnect to the same URL; the first event replays the current status, so no transition is lost.

### Browser example (client key + readToken)

```javascript theme={null}
const url = `https://orchestration.flashnet.xyz/v1/sse/operations/${orderId}` +
  `?token=${clientKey}&readToken=${readToken}`;
const es = new EventSource(url);
es.addEventListener("status", (e) => {
  const { status } = JSON.parse(e.data);
  render(status);
  if (["completed", "failed", "refunded"].includes(status)) es.close();
});
es.onerror = () => {
  // EventSource auto-reconnects; close and resubscribe if the readToken expired
};
```

### curl example (server key)

```bash theme={null}
curl -N "https://orchestration.flashnet.xyz/v1/sse/operations/ord_...?token=fn_..."
```

### When to use SSE

Use SSE for end-user progress UIs: the browser holds one connection per visible order and updates the moment the status changes. For server-to-server delivery, use [webhooks](/products/orchestration/webhooks) instead; they are durable, signed, and retried, while an SSE connection only exists while the client holds it open. For turning status updates into a good payment UX, see [deeplink best practices](/products/orchestration/deeplink-best-practices).
