Skip to content

.ws files

.ws files define WebSocket sessions. A file starts with a connection block (settings before the first ###), followed by message blocks separated by ###.

@url = wss://api.example.com/ws
@headers
Authorization: Bearer {{API_TOKEN}}
X-Client-Id: sendpad
@protocol graphql-ws
@reconnect off
@timeout 5000
DirectiveDescription
@urlWebSocket URL (required)
@headersUpgrade handshake headers — one per line, indented
@protocolSec-WebSocket-Protocol value
@reconnect on|offAuto-reconnect with exponential backoff (default: off)
@timeout <ms>Connection timeout in milliseconds

Use > to send and < to expect a received message:

### Authenticate
# @name auth
> {"type": "auth", "token": "{{API_TOKEN}}"}
# @expect within 5000
< {"type": "auth_ok"}
# @extract sessionId = $.session_id
# @assert body contains "auth_ok"
### Subscribe to channel
> {"type": "subscribe", "channel": "prices"}
# @expect within 3000
< {"type": "subscribed"}
DirectiveDescription
# @name <label>Name this step
# @expect within <ms>Timeout for the next < receive (default: 5000ms)
# @extract var = $.pathExtract value from the received message body
# @assert body contains "text"Assert received message content
# @assert body matches ^regexAssert against a regex pattern
# @close [code] ["reason"]Send a WebSocket close frame
# @binary <path>Send a binary frame from a file
# @pause <ms>Wait before the next step

Bearer token (most common)

@url = wss://api.example.com/ws
@headers
Authorization: Bearer {{API_TOKEN}}

API key header

@url = wss://api.example.com/ws
@headers
X-Api-Key: {{API_KEY}}

Query-string ticket

@url = wss://api.example.com/ws?token={{API_TOKEN}}

Subprotocol-based auth

@url = wss://api.example.com/ws
@protocol bearer.{{API_TOKEN}}

First-message auth

@url = wss://api.example.com/ws
### Authenticate via first message
> {"type":"auth","token":"{{API_TOKEN}}"}
# @expect within 3000
< "auth_ok"

WebSocket connections share the same cookie jar as .http requests. Cookies set by a prior HTTP login are automatically attached to the WS upgrade handshake.

login.http
### Sign in
POST https://api.example.com/login
Content-Type: application/json
{"email":"{{USER_EMAIL}}","password":"{{USER_PASSWORD}}"}
# chat.ws — no auth headers needed; the login cookie rides along
@url = wss://api.example.com/chat
### Say hi
> {"type":"hello"}
# @expect within 3000
< "welcome"

To opt out of cookie injection:

# @cookies off
@url = wss://public.example.com/feed
@url = wss://api.example.com/ws
@reconnect on

Global reconnect defaults live in Settings → WebSocket: initial delay, max delay, max attempts (0 = infinite). While reconnecting, the Session Panel shows a live countdown and a Cancel button.

Press ⌘Enter to connect. Use the compose bar at the bottom of the Session Panel to send messages. Incoming messages appear in real time.

Connections persist when you switch files — background messages are buffered. The header badge shows active connection count.

Press ⌘⇧Enter to run all message blocks sequentially as a scripted test. Assertions and extractions work exactly like .flow files.

KeyAction
⌘EnterConnect / Disconnect
⌘⇧EnterRun all steps (scripted mode)
EnterSend message from compose bar
⇧EnterNewline in compose bar