Protocol invariants & edge cases
Non-obvious rules and behaviors you must implement for robust clients and SDK generation.
Protocol invariants & edge cases
This page documents behaviors that are easy to miss when you only look at payload structs. If you implement these rules, your client stays compatible across releases and handles real-world server responses.
Envelope is always {type, payload}
Every WebSocket JSON message uses the same envelope:
typeis an integer usecase identifier.payloadis the request or response body for that usecase type.
If you receive JSON without type or without payload, treat it as a protocol violation and close the socket.
Packet id is uint64
Many payloads contain id (packet id). Treat it as an unsigned 64-bit integer:
- C++:
uint64_tis safe. - JavaScript/TypeScript: do not assume it fits into
numbersafely. Preferstringorbigint.
status can be omitted
Some responses omit status. Do not require it to consider a response valid.
Recommended rule:
- If the server returns a well-formed response for your request and the socket stays open, treat it as success unless an explicit non-OK
statusis present.
time_left is an expiration timestamp
time_left is a Unix timestamp (seconds) of the license expiration moment, not "seconds remaining".
- If the license has no expiration, the server may return
0. - To show remaining time, compute
max(0, time_left - now).
levels is a string array
levels is always an array of strings, for example:
["admin", "pro", "noob"]
Do not parse it as a single string or as an object.
transfer_file is JSON header + binary frame
A file chunk is transferred as two WebSocket messages:
- A JSON request (type
8) with metadata (transfer_id, offsets, chunk size, checks). - A binary frame with raw bytes of the chunk.
Important rules:
- If
chunk_size = 0, do not send a binary frame. This is used to finalize the transfer. - The response may include
file_size,checks, andstatusonly on the final chunk. Intermediate responses can be empty besides structural fields.
stop_file_transfer and resume tokens
stop_file_transfer can optionally return resume_token only when you request it:
- Set
issue_token = trueto receive a token. - Store the token together with
transfer_id. resume_file_transferrequires bothtransfer_idandresume_token.
Blacklist may terminate your session
If you call blacklist, be prepared that:
- the server can close the socket after applying the rule,
- the response may not include a "success"
statuseven when the operation is applied.
Treat a clean close after a successful blacklist request as an expected outcome.
Panel events are server-push messages
Panel events are pushed by the server as a JSON message of type 18.
These are not responses to a request; your client must handle them out of band.
Reserved endpoints
panel_event_subscribe exists but is currently reserved. Implement it as a no-op on the client side, but keep it in your SDK surface for forward compatibility.
Compatibility rules for SDK generation
When generating SDKs or clients:
- Keep the envelope model stable (
type,payload). - Model
idasuint64orstringto avoid precision loss. - Treat omitted fields as defaults.
- Do not hard-fail on unknown fields inside payloads.
- Unknown
typeshould be ignored or logged, not crash the client.