Direct Market Data (no CDN)
md.sentico-labs.xyz carries the same public market-data stream as
api.sentico-labs.xyz, without a CDN in front of it. It exists because the
detour costs measurable time: from inside the venue's facility, connection
establishment drops from 21.67 ms to 0.51 ms and frame delivery from 8.55 ms to
1.80 ms at the median. The full measurement is in the
Colocation Latency Benchmark.
The direct route carries the same frames, in the same order, with the same sequence numbers as the public route. It is available to anyone holding a read-scoped credential, on identical terms. There is no privileged channel for selected participants, and the public route is unchanged.
Endpoints
wss://md.sentico-labs.xyz:9002/api/v1/ws/public
wss://md.sentico-labs.xyz:9003/api/v1/ws/public
Both ports serve the same content from separate processes. Use one as primary and the other for failover; do not assume their frames interleave in lockstep.
The name is DNS-only and resolves to the venue host, like fix., fixp. and
bsl.. The TLS certificate is issued for md.sentico-labs.xyz; verify it as
you would any other.
Authentication
Unlike the public CDN route, the direct route requires authentication on the WebSocket upgrade. Anonymous upgrades are rejected with HTTP 401.
Use the standard SENTICORE-HMAC-V2 headers on
the upgrade request, signing method:GET and path:/api/v1/ws/public with an
empty body:
SC-Auth-Version: 2
SC-Key: <api key id>
SC-Nonce: <decimal nonce>
SC-Timestamp: <unix ms>
SC-Passphrase: <passphrase>
SC-Signature: 0x<hmac-sha256 hex>
read scopeA credential without it is rejected with HTTP 403 and
AGENT_AUTH_FAILED — "This credential lacks permission. Use a credential with
the required scope." Credentials issued for order entry alone do not
automatically carry read. Request the scope when you request the key.
Protocol
Identical to /api/v1/ws/public:
subscribe control messages, l2Book and bbo channels, snapshot followed by
sequenced deltas, seq and prev_seq on every event, and the same session
limits — 32 subscriptions and 16 markets per connection. The session frame
states the limits in force when you connect; read them rather than hardcoding
them.
Resume uses the same cursor semantics as the public route, including
cursorNamespace: "execution-v1" where applicable.
import WebSocket from "ws";
const ws = new WebSocket("wss://md.sentico-labs.xyz:9002/api/v1/ws/public", {
headers: buildMachineAuthHeadersV2({ /* ... */ method: "GET", url: "/api/v1/ws/public" }),
});
ws.on("open", () => {
ws.send(JSON.stringify({
id: "book-15",
method: "subscribe",
subscription: { type: "l2Book", marketId: 15, depth: 10 },
}));
});
Choosing a route
api.sentico-labs.xyz | md.sentico-labs.xyz | |
|---|---|---|
| Authentication | none | HMAC-V2, read scope |
| CDN in front | yes | no |
| Connection setup, measured in-facility | 21.67 ms p50 | 0.51 ms p50 |
| Frame delivery, measured in-facility | 8.55 ms p50 | 1.80 ms p50 |
| Suitable for | dashboards, browsers, casual clients | quote engines, anything that trades on it |
The measured difference above was taken from inside the venue's facility. From a distant client the network term dominates and the gap will be a smaller share of your total. Measure your own path before deciding.
Operational notes
Each port runs as its own process, so a connection problem on one does not imply the other. The route is subject to a per-source-IP rate limit at the network layer; a client that reconnects in a tight loop will be throttled before it reaches the application.
The certificate for md.sentico-labs.xyz is currently renewed manually. Treat a
certificate error as a transient condition, fail over to the other port or to
the public route, and report it.