Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.proof.community/llms.txt

Use this file to discover all available pages before exploring further.

Subscribe to one transaction at a time and receive push updates as its status changes.

Connection

wss://DOMAIN/ws?tx_id=<merchant_transaction_id>

Authentication

Authenticate with the same client_token you use for HTTP. Send it in the Authorization header on the upgrade request:
GET /ws?tx_id=550e8400-... HTTP/1.1
Host: DOMAIN
Authorization: Bearer <client_token>
Upgrade: websocket
Connection: Upgrade
Open WebSocket connections from your backend server, not the browser. Browsers cannot send custom headers on the upgrade request, and client_token must not be exposed to the frontend. Your backend subscribes and pushes status updates to the browser through your own channel (SSE, polling your API, or a WebSocket relay).

Query parameters

ParameterRequiredDescription
tx_idYesA single merchant_transaction_id to subscribe to
One connection subscribes to one transaction. To watch multiple transactions, open multiple connections.

Events

tx.update

Fired on every status change for the subscribed transaction.
{
  "event": "tx.update",
  "merchant_transaction_id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "buy",
  "status": "completed",
  "payment_method": "card",
  "currency": "USDT",
  "fiat_currency": "EUR",
  "fiat_amount": "100.00",
  "crypto_amount": "99.50",
  "occurred_at": "2026-04-01T10:03:45Z"
}
FieldTypeNotes
eventstringAlways "tx.update"
merchant_transaction_idstringEcho of the subscription
typestring"buy" or "sell"
statusstringNormalized status — see Transaction Status
payment_methodstringOmitted if unknown
currencystringCrypto currency
fiat_currencystringFiat currency
fiat_amountstringFiat amount
crypto_amountstringCrypto amount (may be empty before processing)
occurred_atstringISO 8601 timestamp of the status-change event

Code examples

Node.js
const WebSocket = require("ws");

const ws = new WebSocket(
  "wss://DOMAIN/ws?tx_id=550e8400-e29b-41d4-a716-446655440000",
  { headers: { Authorization: "Bearer <client_token>" } }
);

ws.on("message", (data) => {
  const msg = JSON.parse(data);
  if (msg.event === "tx.update") {
    console.log(msg.status);
    if (["completed", "failed", "cancelled"].includes(msg.status)) {
      ws.close();
    }
  }
});

ws.on("close", () => {
  // Reconnect with exponential backoff
});

Reconnection

Always implement reconnection with exponential backoff and a cap:
let attempt = 0;

function connect(txId) {
  const ws = new WebSocket(
    `wss://DOMAIN/ws?tx_id=${txId}`,
    { headers: { Authorization: "Bearer <client_token>" } }
  );

  ws.on("open", () => { attempt = 0; });

  ws.on("close", () => {
    const delay = Math.min(1000 * Math.pow(2, attempt++), 30000);
    setTimeout(() => connect(txId), delay);
  });

  ws.on("message", (data) => handleMessage(JSON.parse(data)));
}

connect("550e8400-e29b-41d4-a716-446655440000");

Fallback to polling

If your environment cannot use WebSocket (proxy, ad blocker, browser without backend support), fall back to polling GET /widget/transactions/{id} every 5–10 seconds.