Backend — Return Value & Methods
createConsenti(config) returns an object with framework adapters, service references, and lifecycle controls. Nothing is a class — you get a plain object you can destructure or pass around.
Quick reference
| Property | Type | Description |
|---|---|---|
| Framework adapters | ||
router | (req, res, next) => void | Express / Connect middleware. Calls next() for unmatched routes. |
handler | (req, res) => Promise<void> | Terminal Node.js HTTP handler. Does not call next. Use with raw http.createServer or as a Fastify handler. |
fastifyHandler | Fastify plugin | Drop-in Fastify plugin. Register with fastify.register(consenti.fastifyHandler). |
honoApp | { fetch: (req: Request) => Promise<Response> } | Hono / WinterCG fetch handler. Works with Cloudflare Workers, Deno, Bun, and any runtime that supports the Fetch API. |
| Services | ||
services.profile | ProfileService | Create, get, update, and delete consent profiles. |
services.consent | ConsentService | Submit, update, erase, and verify consent records. |
services.visitor | VisitorService | List and manage visitor records. |
services.user | UserService | Create and manage admin users programmatically. |
| Infrastructure | ||
storage | StorageAdapter | Raw storage adapter. Use when the service layer does not expose what you need. |
eventBus | EventEmitter | Node.js EventEmitter that fires lifecycle events. See Events. |
ready | Promise<void> | Resolves after storage connects and the bootstrap admin user is created. Await this before accepting requests. |
| Lifecycle | ||
destroy() | () => Promise<void> | Graceful shutdown — stops background jobs, runs plugin destroy() hooks. Call before process.exit(). |
router
Express / Connect compatible middleware. Handles all Consenti routes and calls next() for any path that does not match. Use this when Consenti shares a process with other Express routes.
import express from 'express'
import { createConsenti } from '@consenti/api'
const app = express()
const consenti = createConsenti({ /* ... */ })
app.use(consenti.router) // Consenti handles /consenti/…; other routes fall through
app.get('/health', (req, res) => res.json({ ok: true }))
app.listen(3000)handler
Terminal Node.js HTTP handler. Suitable for http.createServer, or as an all-routes Fastify handler. Does not call next() — if the request does not match, a JSON 404 is returned.
import { createServer } from 'node:http'
import { createConsenti } from '@consenti/api'
const consenti = createConsenti({ /* ... */ })
await consenti.ready
const server = createServer(consenti.handler)
server.listen(3000)fastifyHandler
Pre-built Fastify plugin. It catches all paths and delegates to the Consenti handler, bypassing Fastify's routing layer for maximum compatibility.
import Fastify from 'fastify'
import { createConsenti } from '@consenti/api'
const fastify = Fastify()
const consenti = createConsenti({ /* ... */ })
await fastify.register(consenti.fastifyHandler)
await fastify.listen({ port: 3000 })honoApp
WinterCG-compatible fetch handler. Conforms to the { fetch } interface expected by Hono, Cloudflare Workers, Deno, Bun, and Next.js Edge routes.
import { Hono } from 'hono'
import { createConsenti } from '@consenti/api'
const consenti = createConsenti({ /* ... */ })
const app = new Hono()
app.all('/consenti/*', (c) => consenti.honoApp.fetch(c.req.raw))// app/consenti/[...path]/route.ts
import { createConsenti } from '@consenti/api'
const consenti = createConsenti({ /* ... */ })
const handler = (req: Request) => consenti.honoApp.fetch(req)
export { handler as GET, handler as POST, handler as PUT, handler as DELETE, handler as PATCH }ready
A Promise<void> that resolves once the storage adapter has connected, migrations have run, and the bootstrap admin user has been created (first run only). Reject if storage fails to connect.
Always await ready before starting to accept requests in production — this ensures the admin user exists and the database schema is up to date.
const consenti = createConsenti({ /* ... */ })
await consenti.ready // ← guaranteed schema + admin user after this line
server.listen(3000, () => {
console.log('Consenti ready at http://localhost:3000/consenti')
})await ready is safe for fire-and-forget scripts, but in a server process it risks accepting requests before the database schema exists — causing crashes on the first query.services
Direct programmatic access to the service layer — no HTTP overhead, no auth check. Use this for server-side scripts, scheduled jobs, or integration tests.
const { services, storage } = createConsenti({ /* ... */ })
// Read a profile
const profile = await services.profile.get('profile-uuid')
// Submit consent programmatically (e.g. from a server-side form handler)
const record = await services.consent.create({
visitorId: 'visitor-uuid',
profileId: 'profile-uuid',
profileVersion: 1,
locale: 'en',
consentJson: { analytics: 'granted', marketing: 'denied', necessary: 'granted' },
gpcDetected: false,
source: 'api',
})
// List recent visitors
const visitors = await services.visitor.list({ tenantId: 'default', page: 1, limit: 50 })storage
The raw StorageAdapter instance. Use it when the service layer does not expose the operation you need, or when writing integration tests that seed data directly.
const { storage } = createConsenti({ /* ... */ })
await consenti.ready
// Stream all consent records for an export job
for await (const record of storage.streamConsents({ tenantId: 'default' })) {
await writeToWarehouse(record)
}
// Get overview stats directly
const stats = await storage.getOverviewStats('default')destroy()
Runs graceful shutdown in order: stops the data-retention background timer, stops the GVL refresh job (if TCF is enabled), and calls destroy() on each registered plugin. Call this before process.exit()or in your framework's shutdown hook.
// Express + graceful shutdown
process.on('SIGTERM', async () => {
await consenti.destroy()
server.close(() => process.exit(0))
})
// Fastify
fastify.addHook('onClose', async () => {
await consenti.destroy()
})