Connection lifecycle
Protocol version
The protocol version is a semver packed into one u32, 10 bits per component (each must be below 1024):
bits 31..30 reserved (zero)
bits 29..20 major
bits 19..10 minor
bits 9..0 patch
value = major << 20 | minor << 10 | patchInteger order equals semver order. The value tracks the iggy_binary_protocol crate release. Under 0.x the compatibility gate is minor-scoped: the server accepts a client whose packed version is at least the server's minimum and whose major.minor is at most the server's. Patch releases never change the wire, so the upper bound ignores patch. Past 1.0.0 the gate follows strict semver (major bump = incompatible).
Login-register
The only way to authenticate is the register handshake: command code 40 (LOGIN_REGISTER, username and password) or 45 (LOGIN_REGISTER_WITH_PAT, personal access token). Both ride operation = 1 (Register) with session = 0 and a freshly minted non-zero client id.
Both request bodies begin with the ClientVersionInfo prefix, so the server can gate on the version before touching credentials:
[protocol_version: u32]
[sdk_name_len: u8][sdk_name: UTF-8, 1-255 bytes]
[sdk_version_len: u8][sdk_version: UTF-8, 1-255 bytes]protocol_version is the packed version of the protocol the client was built against. sdk_name identifies the SDK (for example rust-sdk, go-sdk). sdk_version is the SDK's own build version.
After the prefix:
LOGIN_REGISTER (code 40):
[ClientVersionInfo]
[username_len: u8][username: N]
[password_len: u8][password: N]
[context_len: u32][context: N, only when context_len > 0]LOGIN_REGISTER_WITH_PAT (code 45):
[ClientVersionInfo]
[token_len: u8][token: N]
[context_len: u32][context: N, only when context_len > 0]An incompatible protocol version is answered with a 256-byte Eviction frame, reason 14 (IncompatibleProtocol), carrying the accepted window at bytes 144 (max) and 148 (min) as packed u32 versions. A body without a decodable ClientVersionInfo prefix gets reason 15 (MalformedLogin) with a zero window. Bad credentials get reasons 9-11. See EvictionHeader for the frame layout.
A successful login is a normal Reply whose body is:
[user_id: u32]
[session: u64]
[server_protocol_version: u32]
[server_version_len: u8][server_version: N]The client stores session and echoes it in every subsequent request header. Logout is command code 39 (LOGOUT_USER), operation = 3 (Logout), empty body.
The legacy login commands 38 (LOGIN_USER) and 44 (LOGIN_WITH_PERSONAL_ACCESS_TOKEN) are refused: the server answers them with an Eviction frame, reason 15 (MalformedLogin). Only PING is accepted before login. Every other command on an unauthenticated connection is denied.