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

Functions

Admin-defined server-side JavaScript with grpcSdk access.

The functions module runs admin-defined JavaScript in-process with full grpcSdk access. Operators upload function definitions through the Admin API; HTTP and socket handlers register on the Client API (via router), while function CRUD and execution history live on the Admin API. Treat function code like server configuration — admin-trusted, not user-supplied.

Use cases

Webhooks

Receive Stripe/GitHub callbacks at /hook/{name} and call grpcSdk.database or grpcSdk.email

Custom Client API routes

Authenticated request handlers at /{name} with declared params and returns

Event automation

React to Redis bus events — send notifications when records change

Scheduled jobs

Cron functions run on a BullMQ schedule (Redis-backed)

Socket handlers

Custom Socket.io event handlers on a dedicated namespace path

Cross-module orchestration

Chain database writes, chat system messages, and email in one handler

Capabilities

  • Six function types (request, webhook, middleware, socket, event, cron)
  • Client API route registration via router
  • node:vm sandbox (timeout + require allowlist)
  • grpcSdk access
  • BullMQ cron scheduler
  • Execution logging & metrics
  • GitOps export/import

Example: Webhook handler

Walkthrough

  1. Admin uploads a webhook function via POST /functions/upload (Admin API)
  2. Router registers POST /hook/stripeWebhook on CLIENT_BASE_URL
  3. External provider POSTs to the hook URL
  4. Function validates signature in JS, calls grpcSdk.database to update Order
  5. grpcSdk.email sends receipt; res({ ok: true }) returns the response shape
Invoke webhook (Client API)
curl -X POST http://localhost:3000/hook/stripeWebhook \
-H "Content-Type: application/json" \
-d '{"type":"payment_intent.succeeded","data":{...}}'
Upload function (Admin API)
curl -X POST http://localhost:3030/functions/upload \
-H "masterkey: YOUR_MASTERKEY" \
-H "Content-Type: application/json" \
-d '{
  "name": "stripeWebhook",
  "functionType": "webhook",
  "functionCode": "const sig = req.headers[\"stripe-signature\"]; /* verify + handle */ res({ received: true });",
  "inputs": { "method": "POST" },
  "returns": { "received": "Boolean" }
}'

How it works

Trust boundary

Function code is admin-trusted — equivalent to deploying code to the server. It runs in the same Node.js process with full grpcSdk privileges. The VM layer applies a per-invocation timeout and limits require to lodash and axios only. These are guardrails against accidents, not a security boundary for malicious code. Do not use this module for tenant-submitted scripts.

For user-facing filtered queries, use database custom endpoints at /database/function/{name} on the Client API instead.

Handler shape

Stored functionCode is the body of:

function (grpcSdk, req, res) {
  // your code
}
ParameterMeaning
grpcSdkConduit gRPC SDK — database, auth, storage, chat, communications, …
reqParsed request: HTTP params/body/query for routes; event payload for bus/cron
resCallback (data) => void — return value mapped through returns schema

console.log output is captured in execution logs.

Function types

functionTypeTriggerClient API surface
requestHTTP route/{name} (+ optional /:urlParams)
webhookHTTP route (no auth middleware by default)/hook/{name}
middlewareGlobal middlewareRegistered as named middleware on /
socketSocket.io eventNamespace path /{name}, event from inputs.event
eventRedis bus subscriptioninputs.event = bus channel name
cronBullMQ repeatable jobinputs.event = cron expression

The module waits for router to be serving before registering routes (watch: router rising).

HTTP methods and PUT mapping

inputs.method accepts GET, POST, PUT, PATCH, or DELETE. PUT maps to ConduitRouteActions.UPDATE — the same route action Hermes uses for update verbs (not GET). This matters when declaring returns and when matching routes in middleware patches.

Optional inputs.auth: true on request functions adds authMiddleware.

Declare inputs.bodyParams, inputs.queryParams, and inputs.urlParams to validate incoming data; urlParams append /:key segments to the route path.

VM sandbox

Each invocation runs inside node:vm:

  • Timeout — per-function timeout in milliseconds (default 180000 / 3 minutes)
  • require allowlist — only lodash (lodash-es) and axios; anything else throws at runtime
  • Single run — compile + invoke share one timeout budget

Syntax is validated on upload (POST /functions/upload) and update (PATCH /functions/:id).

Event functions

functionType: event subscribes to grpcSdk.bus on channel inputs.event. Payloads are passed as req (JSON-parsed when the bus message is a JSON string). Handler errors are logged; they do not block the publisher.

Cron functions (BullMQ)

functionType: cron stores a cron expression in inputs.event (for example 0 */6 * * *). The functions module registers a BullMQ repeatable job on Redis — the same job-queue infrastructure used by database and communications modules. On each tick the handler runs with an empty or minimal req payload.

Cron requires the platform Redis connection used by other BullMQ workers (grpcSdk.redisManager) — there is no separate FUNCTIONS_REDIS_* configuration. Execution history is recorded like other function types.

Returns mapping

If returns is omitted, the handler result is wrapped as { result: data }. When returns is a schema object, only declared keys are forwarded from the res(...) payload. Set returns: "String" for a plain string result.

When to use Functions vs alternatives

NeedUse
Filtered Client API queryDatabase custom endpoint
Long-running domain serviceCustom ManagedModule
Webhook, cron, bus automationFunctions
System chat message from backendgrpcSdk.chat from Function or custom module

Configure

KeyDefaultMeaning
activetrueModule serves and registers routes when router is up

Define functions via Admin panel or Admin API when the functions module is enabled. Each document stores name, functionType, functionCode, inputs, optional returns, and timeout.

On create/update/delete the module publishes to the functions bus channel and refreshes router registrations.

Client API

Functions register routes on the router (not Admin API):

TypeExample pathNotes
requestPUT /myHandlerWhen inputs.method is PUT → UPDATE action
webhookPOST /hook/stripeWebhookTypically unauthenticated
socketNamespace /{name}Event from inputs.event

App runtime code calls these URLs on CLIENT_BASE_URL like any other Client API route. request functions with inputs.auth: true require a bearer token.

Functions do not replace /database/function/{name} — those are database custom endpoints.

Admin API

Function management on ADMIN_BASE_URL/functions/...:

MethodPathPurpose
POST/functions/uploadCreate function
GET/functions/List (search, skip, limit, sort)
GET/functions/:idGet function
PATCH/functions/:idUpdate code, inputs, returns, timeout
DELETE/functions/:idDelete function
DELETE/functions/Bulk delete (ids[] query)
GET/functions/list/executionsAll execution logs
GET/functions/executions/:functionIdPer-function executions (success filter)

MCP

Enable with ?modules=functions in your MCP server URL. Admin tools manage function CRUD; uploaded functions appear on the Client API after router refresh.

Next steps

  • Router (Client API gateway)
  • Database custom endpoints
  • Communications (email from webhooks)
  • Client vs Admin API

Router

Client API gateway — REST, GraphQL, and WebSockets.

Next.js Integration

Auth vault, conduitRequest, API routes, and Client API patterns.

On this page

Use casesCapabilitiesExample: Webhook handlerHow it worksConfigureClient APIAdmin APIMCP