Conduit
Conduit
Docsllms.txtHostingGitHubIntroduction

Getting Started

OverviewInstall ConduitMCP SetupYour First AppStart with AI

Learn

ArchitectureClient vs Admin APIConfiguration

Modules

OverviewAuthenticationAuthorizationDatabaseStorageCommunicationsChatRouterFunctions

Guides

Next.js IntegrationReBAC Team ScopingGitOps State Export

Deployment

Deployment OverviewDocker ComposeKubernetes and HelmLocal from SourceContainer Images

Reference

CLI ReferenceClient APIAdmin APIEnvironment VariablesMCP Tools

Resources

Migration v0.16 → v0.17Legacy DocumentationChangelogFAQGlossaryContributing

Router

Client API gateway — REST, GraphQL, and WebSockets.

The router module (Hermes) is the Client API gateway. Every module that serves application traffic registers routes with router over gRPC; Hermes terminates HTTP, GraphQL, and Socket.io on the client ports and proxies each request to the owning module handler. The Admin API lives on core (:3030) — router does not expose admin routes on the client port.

Use cases

Unified API surface

One base URL for auth, database, storage, chat, and more

Realtime apps

REST on :3000, Socket.io on :3001 with shared auth middleware

GraphQL queries

Optional /graphql endpoint when modules register types

Client credentials

Router validates client id/secret context for auth flows

Public hook URLs

hostUrl config builds correct /hook/... links in emails and deep links

Capabilities

  • REST aggregation (Hermes)
  • GraphQL
  • WebSockets / Socket.io
  • gRPC route proxy to modules
  • Global middleware (CORS, rate limit, captcha, client validation)
  • Per-route middleware patching (Admin API)
  • Security client registry
  • HA route recovery via Redis bus
  • Swagger / API reference

Example: Single API surface diagram

Walkthrough

  1. Application calls CLIENT_BASE_URL (default http://localhost:3000)
  2. Router matches path and verb, runs global + route middleware
  3. Router forwards the request to the module gRPC handler that registered the route
  4. Module handler returns; router serializes the response to the client
  5. Socket.io listens on CLIENT_SOCKET_PORT (default 3001) with path /realtime
  6. Admin API (:3030) on core — operators inspect routes and patch middleware there

How it works

Client vs Admin surfaces

SurfaceHostConsumersWhat router does
Client APICLIENT_BASE_URL (:3000 REST/GraphQL)Apps, mobile, user-scoped server routesProxies registered module client routes
Client socketsSOCKET_BASE_URL (:3001)Socket.io clientsProxies module socket namespaces and events
Admin APIADMIN_BASE_URL (:3030, core)Admin panel, MCP, CIRouter module registers operator routes only (/router/*, /routes, /security/client)

Hermes powers both the router (client) and the admin package (admin). End-user apps must never call :3030. See Client vs Admin API.

Port layout

PortEnv varProtocol
3000CLIENT_HTTP_PORTREST, GraphQL, Swagger
3001CLIENT_SOCKET_PORTWebSockets / Socket.io
3030Admin (core)Admin API — not router

Request proxy flow

App → Router (Hermes) → global middleware (CORS, rate limit, client validation, …)
                      → route middleware (authMiddleware, captcha, …)
                      → gRPC call to registering module handler
                      → database, storage, chat, functions, …

At startup (and on HA recovery), each module calls registerConduitRoute over gRPC. Router stores route metadata, mounts paths in Hermes, and publishes route state to the Redis bus so peer router replicas stay in sync.

Transports

Router config toggles three transports — all default to true:

KeyDefaultEffect
transports.resttrueREST + Swagger
transports.graphqltrue/graphql
transports.socketstrueSocket.io on socket port

There is no transports.proxy flag. Older deployments that referenced a proxy transport should use rest, graphql, and sockets instead.

WebSockets

Socket.io listens on CLIENT_SOCKET_PORT with path: /realtime. Each module registers a namespace (for example /chat/). Clients connect with bearer auth in headers:

import { io } from "socket.io-client";

const socket = io(`${SOCKET_BASE_URL}/chat/`, {
  path: "/realtime",
  extraHeaders: { authorization: `Bearer ${accessToken}` },
});

Modules push events to connected clients via router's socketPush gRPC method (rooms, receivers, namespace).

Global middleware

When at least one transport is enabled, router registers:

  • rateLimiter — per-user request cap (rateLimit.maxRequests per rateLimit.resetInterval seconds)
  • corsMiddleware — configurable origins, methods, credentials
  • helmetMiddleware — security headers (relaxed for /graphql, /swagger, /reference GET)
  • clientMiddleware — optional client id/secret validation when security.clientValidation is true
  • captchaMiddleware — optional reCAPTCHA / hCaptcha / Turnstile when captcha.enabled is true

Per-route middleware (for example authMiddleware) is declared by each module and can be patched at runtime via Admin API.

Public base URL (hostUrl)

hostUrl defaults to http://localhost:{CLIENT_HTTP_PORT}. Set it via patch_config_router to your public Client API origin so modules can embed correct absolute URLs — for example chat invitation hooks at {hostUrl}/hook/chat/invitations/accept/{token}.

What router is not

Router does not replace database custom endpoints — filtered queries still need provisioned /database/function/{name} endpoints. Router does not serve the Admin API on port 3000; provisioning uses :3030 or MCP.

Configure

Router requires the database module. Enable feature modules in deployment; their Client routes appear automatically when they register with router.

Patch via MCP patch_config_router (?modules=router):

KeyDefaultMeaning
hostUrlhttp://localhost:3000Public Client API base for generated links
transports.resttrueEnable REST
transports.graphqltrueEnable GraphQL
transports.socketstrueEnable Socket.io
cors.enabledtrueCORS middleware
cors.origin*Allowed origin(s), comma-separated
security.clientValidationfalseRequire registered client credentials on auth routes
captcha.enabledfalseCaptcha on applicable routes
rateLimit.maxRequests50Max requests per interval per user
rateLimit.resetInterval1Reset interval in seconds

Environment variables:

VariableDefaultMeaning
CLIENT_HTTP_PORT3000REST/GraphQL port
CLIENT_SOCKET_PORT3001WebSocket port

See Environment variables and Architecture.

Client API

All module Client paths are relative to CLIENT_BASE_URL:

PrefixModule
/authentication/*Authentication
/database/*Database
/storage/*Storage
/chat/*Chat
/authorization/*Authorization
/hook/*Functions webhooks (and module hooks)
/{functionName}Functions request type
/graphqlGraphQL (when enabled)

Admin API

Operator routes registered by the router module on ADMIN_BASE_URL:

MethodPathPurpose
GET/routesList all registered client routes by module
GET/router/middlewaresList available middleware handlers
GET/router/route-middlewaresQuery path + action → middleware chain
PATCH/router/patch-middlewarePatch middleware on a client route
POST/security/clientCreate security client (platform + secret)
GET/security/clientList security clients
PATCH/security/client/:idUpdate security client
DELETE/security/client/:idDelete security client

MCP

Enable router in deployment for patch_config_router and route inspection tools. Feature modules are enabled separately (?modules=database,authentication,…).

Next steps

  • Architecture
  • Client vs Admin API
  • Chat (sockets)
  • Functions (hooks on router)
  • Deployment overview

Chat

Realtime rooms and messages over REST and Socket.io.

Functions

Admin-defined server-side JavaScript with grpcSdk access.

On this page

Use casesCapabilitiesExample: Single API surface diagramHow it worksConfigureClient APIAdmin APIMCP