Headers: Which One Do I Use?
Every RAIDA request starts with a header whose size and layout depend on one byte. This page tells you which encryption type your command needs, and therefore which header to build.
Header Version 2 is a different layout
This page describes Header Version 1: byte 0 is 0x00 or 0x01, and byte 16 still chooses size and offsets. Header Version 2 (byte 0 = 0x02) is a single 64-byte map. Encryption type selects the cipher only. Do not send HV=2 to a RAIDA that has not advertised it.
Byte 16 decides everything
On Header Version 1, header byte 16 carries the encryption type. It is the first thing a receiver reads after the version byte, and everything else follows from it: the size of the header, where the body length field sits and how wide it is, how long the nonce is, and how the response proves it came from a genuine server.
Build your HV=1 parser accordingly. Read byte 16 before you read anything else in that header — including the body length, which does not sit at a fixed offset across types. On Header Version 2 the offsets never move; see Header Version 2.
The encryption types
| Type | Security | Name | Request header | Cipher | Key source | Response header |
|---|---|---|---|---|---|---|
| 0 | Low | None | 32 bytes | plaintext | — | 32 bytes |
| 1 | Low | AES-128 | 32 bytes | AES-128-CTR | one coin's 16-byte AN | 32 bytes |
| 2 | Low | Locker | 32 bytes | AES-128-CTR | locker AN by 5-byte prefix | 32 bytes |
| 8 | High | AES-256-GCM | 64 bytes | AES-256-GCM | two coins' ANs, concatenated | 32 bytes |
| 9 | High | Session GCM | 64 bytes | AES-256-GCM | session key by 5-byte handle | 32 bytes |
Every one of these shares the same body framing: the decrypted body begins with a 16-byte challenge, and the command payload starts at body offset 16.
Two security levels
The types divide cleanly into two groups, and the division is the one that matters when you are choosing:
| Level | Types | Encryption | What it protects |
|---|---|---|---|
| Low Security | 0, 1, 2 | none, or AES-128 | Confidentiality only. A CRC32 catches accidental corruption; nothing detects deliberate tampering, and the header is unprotected. |
| High Security | 8, 9 | AES-256-GCM | Confidentiality and integrity, for the body and the header alike. Any altered byte is detected and the request rejected. |
Within High Security, the two types differ only in where the key comes from, which follows from what you are addressing: type 8 keys from two coins and talks to a RAIDA; type 9 keys from a session and talks to a Content Server.
Prefer High Security for new work
Most live RAIDA traffic is type 1 today, and a few commands still require it — the routing table below marks those. Everywhere you have a choice, type 8 is the better one: same commands, same body layout, authenticated encryption instead of a checksum.
Type 9 goes to a Content Server, not a RAIDA
Types 0, 1, 2 and 8 address a RAIDA. Type 9 addresses a Content Server, which is a different kind of host: it holds no coin database, authenticates callers by session rather than by coin ownership, and a RAIDA will not accept type 9 at all. It is documented alongside the others because the framing is shared, but the command routing table below covers RAIDA commands only.
The unlisted type numbers
Encryption types 3, 4, 5, 6 and 7 are not available to client software and are not documented here.
Types 3 and 6 are not implemented — a request carrying either is rejected. Types 4 and 5 are an earlier AES-256 design that was superseded by type 8 and is not supported by the client library. Type 7 carries server-to-server traffic keyed by secrets that no client possesses.
If you are writing client software, the five types in the table above are the complete set.
| Page | Covers |
|---|---|
| Low Security Requests | Header Version 1 types 0, 1 and 2. Complete byte diagrams for each. |
| High Security Requests | Header Version 1 types 8 and 9. Complete byte diagrams for each. The two are not layout-compatible. |
| Header Version 2 | Byte 0 = 0x02. One 64-byte map for EN 0, 1, 2, 8 and 9. Offsets never move. Content commands (QMail, DRD, Beacon) to a RAIDA or a Content Server. |
| Response Headers | The 32-byte HV=1 response frame and how each type authenticates it. HV=2 uses the same frame with echo restored; those rules are on the Version 2 page. |
| Identity Block | The 32 bytes of body that say who is calling. |
Command routing table
Find your command group. The Accepts column lists every encryption type the server will process for that command. Where a type is marked ONLY, the server actively rejects all others — those are hard gates, not conventions.
| Group | Commands | Accepts | Notes |
|---|---|---|---|
| 0 | Status (00 echo, 01 version, 02 show_stats, 03 audit) | 1 | Type 0 works only if the operator enabled it. |
| 1 | Authentication (10 detect, 11 detect_sum, 20 pown, 21 pown_sum) | 1 | |
| 2 | Healing (40 get_ticket, 50 validate_ticket, 60 find, 61 fix2, 80 fix) | 1 | Some healing traffic between servers uses a non-public type; clients use type 1. |
| 6 | QMail 70 upload, 71 tell, 72 ping, 73 peek, 74 download | 1 | |
| 6 | 76–84 object transfer | 1 ONLY | TCP only. Any other encryption type returns ERROR_UNSUPPORTED_PROTOCOL (219); UDP returns ERROR_TCP_REQUIRED (218). |
| 8 | Locker (80 store, 83 peek, 84 remove, 87 buy, …) | 1, 2 | Type 2 keys from the locker index rather than a coin. |
| 9 | Change (90 make_change, 92 break, 93 join) | 1 | |
| 15 | RKE 1 preload, 2 get_key_share, 3 get_share_and_ticket, 4 redeem_identity_ticket | 8 ONLY | Every other type is refused. These commands handle key material, so they require authenticated encryption. |
| 16 | DRD (directory, white/black lists) | 1 | Pre-production. Its caller-identity layout is still changing — see the Identity Block page. |
Commands are pinned to their encryption types
You cannot freely upgrade a command to a stronger encryption type
The ONLY markings above are real. QMail large upload and the object transfer commands require type 1 and reject type 8 — not because type 8 is weaker, but because those commands overload header bytes that type 8 uses for something else, so the server would be reading a length from the wrong field. Conversely the RKE commands require type 8 and reject type 1.
The exclusivity runs in both directions, so this is not a migration with a legacy tail that will eventually be cleaned up. Check this table before assuming a command will accept the type you want to send.
One structural reason sits underneath all of this. Every command handler computes its payload length as body_length − 18 — sixteen challenge bytes plus a two-byte terminator. That arithmetic is baked into every command, which is why type 8 was deliberately designed to keep the older challenge-framed body layout: a 256-bit AEAD cipher wearing an older body format on purpose, so existing handlers would accept it unchanged.
Where request and response bodies are documented
They are not on these pages. Every command has a different body, so a shared "request body" page could only describe the parts that happen to be common — which is how earlier versions of this documentation ended up presenting a QMail-specific structure as though it were universal.
- Command payloads are documented on each command's own page.
- The identity block — the 32 bytes after the challenge that say who is calling — is on the Identity Block page, because several command families share it. It is body content, not header content, and it is not universal.
Keeping this page true
This table encodes gates from several different source files
The routing table above is assembled from encryption-type checks scattered across the server: request validation, the QMail command handlers, and each RKE handler separately. Maintained by hand, it will drift out of date within a couple of releases — which is how the documentation this page replaces came to describe a protocol that no longer existed.
Whoever owns this page should either generate it from the server source or add a build check that fails when an encryption gate changes without this table changing. Until then, re-verify it whenever a release touches request validation.