session.create, then send each frame as raw image bytes. Each frame gets one reply event, and a frame the session cannot read now is dropped, never queued.
When to use a session
Use a session when you read many frames from one source with the same model and method: a camera, a screen, or a decoded video. Use aPOST for single images, documents, and anything you read once.
We drop instead of queue because a queued frame answers for a moment you have already moved past. A drop tells you to send fewer frames, or to raise
max_inflight on the session.
Session lifecycle
Both sockets share this lifecycle. Only thesession.create fields and the reply event differ.
- Upgrade. Open the socket with
Authorization: Bearer <VLMRUN_API_KEY>on the upgrade request. A request with no key, or withBearer vlmrun, is refused with401before the socket opens. session.create. Send it as the first JSON text message. The Gateway checks your plan, model access, credit, and capacity once, then repliessession.createdwith the session’s bounds. A refusal is anerrorevent, then a close.- Frames. Send each frame as one binary message of raw JPEG, PNG, WebP, or GIF bytes. Each frame gets one event back: its reply,
frame.dropped, or anerrorthat names the frame. session.close. Reads in flight finish and return. The server sendssession.statswith the session’s counts and cost, then closes with1000.
WebSocket API cannot set request headers, so a browser cannot send Authorization. Open sessions from a server. The Node.js samples use the ws package, which takes headers. The Python samples pass the header to websockets.connect as additional_headers.
Close codes
The server explains a refusal or a cut with anerror event before it closes. The error_type values are listed on each socket’s reference page.
A replica restart can also cut the connection with no close frame. Reconnect and open a new session. A session does not resume: frames, counts, and spend start again from zero.
Supported models
A model must opt in to realtime. On/v1/ws, a model without realtime support is refused at session.create with invalid_request_error and close 1008.
max_fps is the read rate the model allows, on average. A frame that arrives sooner than that after the last read is dropped with reason: "rate". A short burst bank absorbs network jitter.
Billing
On
/v1/ws, idle time bills like streaming time, so close the session when you stop sending frames. On /v1/ws/systemone, dropped frames and failed reads bill nothing.
On /v1/ws, a session open for 10 minutes bills 600 seconds at $3 / hour, which is $0.50, on either model. The session total is in session.stats.cost, and its id reads back with GET /v1/completions/{id}.
Limits
Sessions are limited per organization plan, not per request. A session does not spend the per-minute request budget.- Sessions at once: 1 on Free, up to 5 on paid plans. Then
rate_limit_errorand close1013. - Per session: 10 minutes, 30 seconds idle, $5 of spend, and 2 MiB per frame.
- Capacity: the Gateway and some models cap open sessions. A full cap is
capacity_errorwith close1013.
Next steps
Realtime Frames
Stream frames to a pose model in Python or Node.js.
Realtime System One
Ask the same System One questions of every frame.
WS /v1/ws reference
Every event, field, and error type on the frames socket.
Rate Limits
Sessions per plan, per-session bounds, and capacity refusals.