WebSocket Events

Receive real-time position updates via WebSocket. All position state changes are delivered as events over a persistent Socket.IO connection.

SDK note: The @dimes-dot-fi/sdk package does not include a WebSocket client. Use Socket.IO directly alongside the SDK for real-time updates. The REST hooks (usePositions, useMarkets) handle polling; use WebSocket events to trigger cache invalidation for instant updates.

Two WebSocket gateways are available. Both deliver the same event types and payload shapes — they differ only in authentication and scope.

Gateway
Namespace
Auth
Scope

Partner

/v1/ws/prediction-markets/positions

API key

All positions for the partner

Customer

/v1/ws/prediction-markets/customer-positions

User JWT

Only positions for the authenticated customer


Partner gateway

Namespace:

Environment
WebSocket URL

Production

wss://api.dimes.fi/v1/ws/prediction-markets/positions

Sandbox

wss://api-sandbox.dimes.fi/v1/ws/prediction-markets/positions

Sandbox emits the same event types and payload shapes as production — only the host and the key prefix differ. See Environments.

Transport: Socket.IO

Auth: Partner API key, passed as either:

  • Socket.IO auth payload (recommended): auth: { apiKey: "dm_live_skey_..." } (or dm_sbx_skey_... in sandbox). Transmitted in the handshake body — never appears in URLs, server logs, or browser history.

  • HTTP header: Authorization: Api-Key dm_live_skey_... (or dm_sbx_skey_... in sandbox). For Socket.IO clients, set this via the extraHeaders option.

On successful auth, the connection is scoped to the partner. All events for positions created through that partner's API keys are delivered.

import {io} from "socket.io-client";

const socket = io("wss://api.dimes.fi/v1/ws/prediction-markets/positions", {
  auth: {apiKey: process.env.DIMES_API_KEY},
});

socket.on("connect", () => {
  console.log("Connected to position events");
});

socket.on("position.opened", (event) => {
  console.log("Position opened:", event.data.id);
});

socket.on("error", (error) => {
  console.error("WebSocket error:", error);
});

Customer gateway

Environment
WebSocket URL

Production

wss://api.dimes.fi/v1/ws/prediction-markets/customer-positions

Sandbox

wss://api-sandbox.dimes.fi/v1/ws/prediction-markets/customer-positions

Transport: Socket.IO

Auth: User JWT (the same token from POST /tokens), passed as either:

  • Socket.IO auth payload (recommended): auth: { token: "<jwt>" }.

  • HTTP header: Authorization: Bearer <jwt>. For Socket.IO clients, set this via the extraHeaders option.

On successful auth, the connection is scoped to the authenticated customer. Only events for positions belonging to that specific wallet address and partner are delivered — other customers' positions are never visible.


Authentication errors

If authentication fails on either gateway, the server emits an error event and disconnects:


Event envelope

All events follow the resource.action naming pattern with a consistent envelope:

Field
Type
Description

id

string

Unique event identifier (prefixed evt_)

type

string

Event type in resource.action format

created_at

string (ISO 8601)

When the event was emitted

data

object

Event payload — always contains the full position object matching the REST API shape

The data object contains the same representation you would get from GET /positions/{id}. This means event consumers can reuse the same types/parsers as their REST integration.


Event types

Event Type
Trigger

position.created

On-chain position account created (user submitted tx)

position.opening

Finalize-open tx confirmed on-chain (early signal, before indexer picks up)

position.opened

Position finalized on-chain, tokens acquired (indexer confirmed)

position.close_requested

User submitted close request

position.closed

Close finalized, proceeds distributed

position.settled

Market resolved, position settled

position.liquidated

Position liquidated due to insufficient margin

position.force_unwound

Position partially unwound to reduce leverage (position remains open)

position.reverted

Position open failed, collateral refunded

position.cancelled

Position cancelled before opening (EVM only)


Event payloads

The data field in every event is a full position object — the same shape returned by the REST API. See the Positions section of the API Reference for complete field definitions.

Event

status

Position shape

position.created

pending

Open shape (entry, current, risk, fees, timing)

position.opening

pending

Open shape (early signal — position not yet indexed)

position.opened

open

Open shape

position.close_requested

closing

Open shape

position.closed

closed

Closed shape — close_reason: "closed", entry, result, fees

position.settled

settled

Closed shape — close_reason: "settled", entry, result, fees

position.liquidated

liquidated

Closed shape — close_reason: "liquidated", entry, result, fees

position.force_unwound

open

Open shape (reduced size — current values reflect new position)

position.reverted

cancelled

Closed shape — close_reason: "reverted", entry, result, fees

position.cancelled

cancelled

Closed shape — close_reason: "reverted", entry, result, fees

Open positions include current, risk, fees, and timing sections. Closed, settled, and liquidated positions replace those with close_reason and result (including collected_liquidation_fee_* for liquidations).

position.opening vs position.opened

position.opening fires as soon as the finalize-open transaction is confirmed on-chain — before the event indexer picks it up. This gives the UI an early signal (~5-15 seconds faster) that the position is about to open.

position.opened fires later when the indexer delivers the confirmed PositionOpened event.

Recommended UI behavior: On position.opening, show a "finalizing" state. On position.opened, transition to the full open position view with live data. If position.reverted arrives instead, the open failed — show the error state.


Listening to events

Subscribe to specific event types using Socket.IO's standard event listeners:


Best practices

Deduplicate on event id. Store processed event IDs and skip duplicates. The same event may be delivered more than once.

Handle events out of order. A position.closed event could arrive before position.close_requested due to network timing. Use the created_at timestamp and the position status from the REST API as the source of truth if ordering matters.

Reconnect on disconnect. Configure your client's reconnection settings for production reliability.

Use REST API as fallback. If your WebSocket connection drops, use GET /positions to catch up on any missed state changes.

Last updated