API - System, Federation, and WebSocket
Source of truth:
d3chat/backend/app/main.pyd3chat/backend/app/federation/inbox.pyd3chat/backend/app/websocket/router.py
System Routes
GET /health
Returns:
{ "status": "ok" }GET /api/v1/config
Public config consumed by frontend branding/login/register views.
Fields:
app_nameapp_descriptionregistration_modebrand_primary_colorbrand_accent_color
GET /.well-known/d3chat-server
Federation identity descriptor:
domainsigning_key_publicapi_base_urlprotocol_version
Federation Routes
POST /federation/inbox
Single ingress endpoint for signed server-to-server events.
Required headers:
X-D3Chat-OriginX-D3Chat-TimestampX-D3Chat-Signature
Validation flow:
- header presence
- replay-window check (5 minutes)
- per-origin Redis rate limit (100 req/min)
- origin discovery + public key lookup
- signature verification
- event dedup by
event_id(Redis NX with 24h TTL) - dispatch by
type
Supported event families include:
message.relaysender_key.distributechannel.invitechannel.joinchannel.leave
GET /federation/user-lookup?username=<name>
Signed endpoint for remote servers to resolve local users.
Returns:
{ "found": true, "username": "alice", "user_id": "<uuid>", "server_domain": "chat.example.com"}or { "found": false }.
WebSocket Route
GET /ws?ticket=<one-time-ticket>
Auth model:
- ticket issued from
POST /api/v1/auth/ws-ticket - ticket consumed atomically (
getdel) and expires quickly
On connect:
- subscribes user to all channel topics where user is member
Client message types handled:
typing.starttyping.stoppresence.updatesubscribe
Server pub/sub fan-out includes:
message.newmessage.editmessage.delete- typing events
- key-health events like
keys.low_otp - channel creation notices like
channel.new
Invalid/expired ticket closes socket with code 4001.