1 Why one contract
Once you learn one service, you know the rest. Health endpoints, OpenAPI, WebSocket auth, queue backends, storage backends — all identical across the suite.
2 Health and diagnostics
Every service exposes GET /up. Startup logging is verbose on purpose: config summary, dependency checks, queue/storage readiness, server startup phases.
3 API and docs
GET /openapi returns a full 3.0.3 spec. Swagger UI is served at /swagger/. UI assets are served from the same binary at /assets/*.
4 Realtime
GET /ws is the canonical WebSocket endpoint. Auth via SHARED_WS_KEY (query string, header, or Bearer). Default channels: system.events, system.logs, jobs.events, jobs.<jobID>.events. Enqueue jobs via the jobs.enqueue publish hook.
5 Queue backends
Set QUEUE_BACKEND to one of: redis, valkey, kafka, rabbitmq, activemq, sqs. Redis and Valkey use namespaced prefixes. Kafka supports TLS + SASL. SQS validates connectivity at startup.
6 Storage backends
Set STORAGE_BACKEND to local, s3, minio, or azure. Local is for development; the rest are production-grade.
7 Caches
Redis and Valkey share a code path. TLS and auth are supported. Namespace isolation prevents collisions when multiple services share a cluster.