Kraken: Four Reliability Fixes in the WebSocket and Futures REST Clients | eSeGeCe Blog

Kraken: Four Reliability Fixes in the WebSocket and Futures REST Clients

· Components
Kraken: Four Reliability Fixes in the WebSocket and Futures REST Clients

Four separate Kraken defects went into 2026.9, and none of them were the kind you catch by reading the code once. Each one only shows up under a specific condition: the wrong endpoint at connect time, a request body that never leaves the machine, a reconnect that happens a few hundred milliseconds too early. All four are fixed, and all four are worth understanding, because the failure mode in each case looks like something else entirely.

The spot client was speaking v1 to a v2 endpoint

TsgcWSAPI_Kraken builds and parses the v1 schema: event, pair, subscription, subscriptionStatus, systemStatus. That schema exists for a reason, it is what every subscribe call and every event handler on this component is written against. The endpoint it connected to, however, defaulted to Kraken's v2 WebSocket, which speaks a different schema entirely: method, params, channel, type. The connection opened without error. It just never produced a single subscription acknowledgement or status event, because the server was answering in a shape the client never parses.

Kraken.Version now defaults to 1, and the component picks the matching v1 endpoint:

uses
  sgcWebSocket, sgcWebSocket_APIs;

var
  oKraken: TsgcWSAPI_Kraken;
begin
  oKraken := TsgcWSAPI_Kraken.Create(nil);
  oKraken.Client := oClient;
  // Version defaults to 1, matching the event/pair/subscription
  // schema this component already builds and parses.
  oKraken.Kraken.Version := 1;
  oClient.Active := True;
  oKraken.SubscribeTicker('XBT/USD');
end;

If your application was somehow relying on the old, silently-wrong default, that means it was never actually receiving v1 events either, so there is nothing working today to preserve. Setting Kraken.Version := 2 explicitly still connects to the v2 endpoint, with RawMessages enabled and the payload handled in OnKrakenData or OnMessage, for anyone building against that schema on purpose.

Futures orders sent as GET, body discarded

This one is quieter and more serious. Every private request on the Kraken Futures REST client, sending an order, editing one, cancelling one, a transfer, a withdrawal, went out as an HTTP GET. The signed request body was built correctly, computed, formatted, ready to send, and then discarded, because a GET request has no body to put it in. Kraken received a GET with no parameters and rejected or ignored it. None of these calls worked.

uses
  sgcHTTP_API_Kraken;

var
  oKraken: TsgcHTTP_API_Kraken_Futures_Rest;
  oOrder: TsgcHTTPKrakenFuturesOrder;
begin
  oKraken := TsgcHTTP_API_Kraken_Futures_Rest.Create(nil);
  oKraken.KrakenOptions.ApiKey := 'your_api_key';
  oKraken.KrakenOptions.ApiSecret := 'your_api_secret';

  oOrder := TsgcHTTPKrakenFuturesOrder.Create;
  try
    oOrder.OrderType := kotfLMT;
    oOrder.Symbol := 'PF_XBTUSD';
    oOrder.Side := kosfBuy;
    oOrder.Size := 1;
    oOrder.LimitPrice := 30000;
    // SendOrder now posts through DoHTTP_POST_PRIVATE, body included.
    ShowMessage(oKraken.SendOrder(oOrder));
  finally
    oOrder.Free;
  end;
end;

SendOrder, EditOrderByOrderId, EditOrderByCliOrderId, CancelOrderByOrderId, CancelOrderByCliOrderId, Transfer and WithdrawalToSpotWallet now all route through the private POST path, with the signed body actually attached to the request.

Private subscriptions lost on reconnect

The WatchDog reconnects, the log shows a clean reconnection, and from that point on your orders, balance and fills channels are simply gone. Nothing errors. Nothing logs. The reconnect looked entirely successful, because the connection itself did succeed, it was only the private subscriptions issued before the disconnect that were never replayed afterwards. This affected Kraken spot and Kraken Futures alike, along with several other exchange clients fixed in the same pass. It is now part of the standard resubscribe replay, the same path that already restores your public market data subscriptions after a reconnect.

Futures resubscribing before the session was authenticated

A closely related defect, specific to Kraken Futures: after a reconnect, the replay of active subscriptions could run before the authentication handshake had actually completed. The subscribe requests went out on a session Kraken had not yet authenticated, so the private ones were rejected, again with nothing in the client pointing at why. The replay now waits for authentication to finish before it resubscribes.

Upgrading

All four fixes are drop-in, there is no API to migrate. The one behavioural change to be aware of is the Kraken.Version default flip from the previous, effectively non-functional value to 1; if your code explicitly sets Version := 2 already, nothing changes for you.

Questions, feedback or migration help? Get in touch — you will get a reply from the people who wrote the code.