## Launch stream (WSS)

Receive an initial view of indexed Solana launches, followed by changes over one WebSocket connection. This is a changing launch view, not a stream of individual trades.

```
wss://api.dexra.dev/new_launches/stream
```

### Access and authentication

Create an [API key](https://dexra.dev/app/keys) and use an active, non-trial subscription with `launch_stream` enabled. Access and limits are managed per plan; a plan name alone does not grant access. Delivery is included in the subscription and updates do not consume tool credits.

Check `GET https://api.dexra.dev/billing/plans` for `launch_stream`, `stream_connections`, `stream_max_launches` and `stream_interval_seconds`. The `ready` event reports the effective limits for this connection. Global service capacity can also limit connections.

Currently enabled plans: Scale, Business, Scale, Business. [View plans](https://dexra.dev/app/plans).

Send the auth frame within five seconds of opening the connection. Server clients may instead send `Authorization: Bearer dxr_…` or `X-Api-Key` during the upgrade. Use an API key, not the cabinet session token. Keep keys out of URLs and public frontend bundles.

```json
{"type":"auth","api_key":"dxr_YOUR_KEY","client":"my-bot/1.0"}
```

### Connect from Node.js

Save as `stream.mjs`, set `DEXRA_API_KEY` in the server environment, then run `node stream.mjs`. Node.js 22 or later includes WebSocket; no package is needed.

```ts
// Node.js 22+. Set DEXRA_API_KEY in your server environment.
const apiKey = process.env.DEXRA_API_KEY;
if (!apiKey) throw new Error('Set DEXRA_API_KEY first');

const launches = new Map();
const ws = new WebSocket("wss://api.dexra.dev/new_launches/stream");

ws.onopen = () => ws.send(JSON.stringify({
  type: 'auth', api_key: apiKey, client: 'my-bot/1.0'
}));

ws.onmessage = ({ data }) => {
  const event = JSON.parse(data);
  switch (event.type) {
    case 'ready':
      console.log('Connected', event);
      break;
    case 'snapshot_start':
      launches.clear();
      break;
    case 'upsert':
      launches.set(event.launch.pool, event.launch);
      break;
    case 'remove':
      launches.delete(event.pool);
      break;
    case 'snapshot_end':
      console.log('Initial view ready', [...launches.values()]);
      break;
    case 'status':
    case 'error':
      console.log(event);
      break;
  }
};

ws.onerror = () => console.error('WebSocket connection failed');
ws.onclose = ({ code, reason }) => {
  console.log('Disconnected', code, reason);
  // Fix auth, access or filters before retrying 4401, 4403 or 4400.
  // For temporary failures, reconnect with capped exponential backoff.
  // Every reconnect sends a new snapshot; discard the previous view.
};
```

### Events and reconnects

| Event | How to handle it |
| --- | --- |
| `ready` | Authentication succeeded. Read protocol, plan, maximum launches and delivery interval here. |
| `snapshot_start` | Clear the local view before accepting a new snapshot. |
| `upsert` | Insert or replace `event.launch`, keyed by `event.launch.pool`. |
| `snapshot_end` | The initial view is complete. Later upserts and removals update it. |
| `remove` | Delete `event.pool` from the view. A removal can mean the pool left the window or filtered selection; it does not prove a token failed. |
| `status` / `error` | Read source coverage or the error and its `retryable` flag. |

Every reconnect starts a new snapshot. There is no durable replay cursor or exactly-once delivery. Use capped exponential backoff with jitter for temporary failures and replace the old view. Standard WebSocket clients handle protocol ping/pong automatically; no JSON heartbeat is needed.

### Optional filters

Add query parameters to the endpoint before connecting. Omit `limit` to use your plan's default. To change filters, reconnect.

| Parameter | Meaning |
| --- | --- |
| `platforms` | Comma-separated platform IDs, for example `pump_fun,pump_swap`. |
| `min_liquidity_usd` | Minimum liquidity in USD, from 0 to 10¹⁵. |
| `include_collapsed` | Whether to include collapsed pools: `true` or `false`. |
| `limit` | 1 to the effective plan maximum: the smaller of `stream_max_launches`, `max_batch` and 200. |

The shared source covers the latest 200 indexed pools within a rolling 60-minute window. Filters operate inside that bounded source. Read source freshness and coverage from stream events; delivery frequency does not guarantee every on-chain launch has been indexed.

### Connection failures

| Close code | Next step |
| --- | --- |
| `4401` | Supply a valid API key within the auth deadline. |
| `4403` | Check subscription, trial status, key access and service settings before reconnecting. Access is rechecked while connected. |
| `4400` | Correct filters or reduce the requested limit. |
| `4429` | Close unused connections or wait for capacity, then retry with backoff. |
| `1013` | Consume messages faster; reconnect for a fresh snapshot. |
| `1001` | Heartbeat timeout; check connectivity and reconnect with backoff. |

Header authentication can return HTTP 401 or 403 before upgrade; exhausted service capacity can return HTTP 429. Fix the cause before retrying.

Source: https://dexra.dev/docs/launch-stream
