Docs · Reference
Read the relay field by field.
Every request the shipped clients make, with the exact shapes the server reads — and, field by field, what it can never read.
Point at the base URL
https://api.qeryx.com/api/v1
Authorization: Bearer <jwt> # on every authenticated request
This reference documents the surface the shipped clients speak today, mirrored from the server's own request structures. A field that is not listed is not read — the server rejects unknown fields on credential payloads rather than silently accepting them.
Authenticate
An account is a Serpent ID and a password. The register payload has two fields; that is the complete identity surface the relay ever learns.
POST /auth/register — request and response
{
"serpent_id": "string — 3–64 chars: letters, digits, - and _",
"password": "string — 8–128 chars"
}
// 200 —
{
"token": "<jwt>",
"user_id": "<uuid — internal routing id>",
"profile_id": "PROFILE-XXXXXXXX-XXXXXXXX"
}
The password is stored as an Argon2id hash (m=512 MiB, t=2, p=4 — RFC 9106). The Profile ID is derived on your device; the server stores it verbatim and routes by it.
Publish and fetch keys
Everything under /keys is public material. The relay is a
bulletin board for public keys; private keys never appear in any
payload on this page.
Why you can trust a fetched bundle
Bundles are signed (the signed-prekey binding closes the classic substitution attack), identity keys are appended to the KTS transparency log, and the safety-number ritual in Key verification lets two humans confirm the relay served the same keys to both sides.
Open a session
A session opens with one round trip: init carries the
hybrid handshake, respond completes it. The server
validates structure and bindings; the secrets are born on the two
devices.
POST /sessions/init — request shape
{
"responder_id": "<uuid>",
"handshake_init": "<base64 — serialized hybrid HandshakeInit>",
"bell_transcript": "<base64 — canonical Q-Entangle-Bell v1 bytes>",
"bell_transcript_hash": "<base64 — SHA3-256 of the canonical bytes>",
"bell_op_sig": "<base64 — ML-DSA-87 operator signature>"
}
The server recomputes SHA3-256 over the transcript bytes and rejects the request if the hash binding does not hold — a session cannot be persisted around the check.
This is not QKD. Not quantum networking. Not quantum teleportation. We do not violate the no-communication theorem. We bind a key-derivation function to a verifiable physical measurement no classical adversary can fabricate in advance.
Send a message
The envelope the relay carries is ciphertext plus routing. Group names, subjects, avatars, and all content are end-to-end encrypted; the relay holds only opaque routing identifiers; sender identifiers are stripped from the stored message row (sealed-sender v2), though the relay still authenticates the sender at send time. Undelivered messages queue with routing metadata under a published retention ladder.
POST /messages — request shape
{
"recipient_id": "PROFILE-… or <uuid>",
"encrypted_content": "<base64 — ciphertext; opaque to the relay>",
"nonce": "<base64>",
"message_type": "text | image | video | file | location | voice",
"reply_to_id": "<uuid, optional>",
"conversation_id": "<string, optional — group routing>",
"idempotency_key": "<string, optional — client-side dedup>"
}
encrypted_content and nonce are opaque
bytes to the relay. message_type is a routing hint for
notifications; the content behind it is indistinguishable
ciphertext.
Audit the transparency log
The endpoints an auditor uses. Inclusion proofs, auditor keys, signed audit receipts, and the current build attestation are readable without any special access — verification is a public capability, not a support ticket.
What the log guarantees today
KTS is an append-only key log anchored by a 2-of-3 multi-witness quorum (verify-only today — operator equivocation is detected, not prevented) plus three external Ed25519 auditor slots that ship dormant: all three hold placeholder keys, so no external cosignature is carried yet. Registry expansion is release-gated.
Hold the socket open
GET /ws
Authorization: Bearer <jwt>
# ?token=<jwt> is accepted as a fallback and deprecated —
# tokens in URLs end up in logs.
One socket carries typed frames, dispatched on
msg_type: delivery (delivered,
delivery_ack, read), call signaling
(call_ready, call_accept,
call_reject, call_end and their video
variants), group media control, and transparency gossip. Message
payloads inside frames are the same opaque ciphertext as the REST
surface.
08The developer questions — answered against the shipped server
Push on the reference.
Is there a third-party app program or API keys?
Not today. This reference exists so you can verify what the shipped clients send — and what the relay can read — not to onboard bots. There are no bots and no server-side AI in the core product, by design.
Why document an API nobody can register apps for?
Because the API surface is the privacy claim. Anyone can read these shapes, capture their own traffic, and confirm the two match. A privacy policy asks for trust; a field list can be checked.
Where are rate limits documented?
The relay enforces per-route rate limits (auth endpoints are the strictest). Exact thresholds are operational tuning and move with load; the error you get is HTTP 429 with a retry hint.