blob: 3c6e49d7fca40d20164ddafac89f6b4a07d5d75a [file]
---
title: Connection lifecycle
---
## Protocol version
The protocol version is a semver packed into one u32, 10 bits per component (each must be below 1024):
```text
bits 31..30 reserved (zero)
bits 29..20 major
bits 19..10 minor
bits 9..0 patch
value = major << 20 | minor << 10 | patch
```
Integer 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:
```text
[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):**
```text
[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):**
```text
[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](/docs/binary-protocol/framing#evictionheader) for the frame layout.
A successful login is a normal `Reply` whose body is:
```text
[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.