Skip to main content

Configuration

Configure the client with createTogglyClient({ ... }) or initToggly({ ... }). Options match TogglyServerConfig.

Required / common​

import { createTogglyClient } from '@ops-ai/toggly-node-core'

const client = createTogglyClient({
appKey: process.env.TOGGLY_APP_KEY!,
environment: 'Production',
baseUrl: 'https://definitions.toggly.io',
refreshInterval: 180_000, // ms; 0 disables polling
timeout: 10_000,
identity: 'default-service-user', // optional default for all evals
featureDefaults: { 'critical-feature': true },
debug: false,
})
await client.init()
OptionTypeDefaultDescription
appKeystring—Application key (required for API mode)
environmentstring'Production'Environment name
baseUrlstring'https://definitions.toggly.io'Definitions API base URL
identitystring—Default identity when a call omits context
featureDefaultsRecord<string, boolean>—Fallback when a flag is missing / offline
refreshIntervalnumber180000Poll interval in ms (0 disables)
timeoutnumber10000HTTP timeout in ms
debugbooleanfalseDebug logging
useEtagbooleantrueConditional fetches via If-None-Match
hooksHook[]—Lifecycle hooks

Identity, groups, claims, traits​

Adapters (preferred): configure ambient EvalContext once on Express / Fastify / Hono / Koa middleware with getIdentity / getGroups / getClaims (or getContext). Then req.toggly.isFeatureOn('X') (or the adapter equivalent) uses that request-scoped context — see Express, Fastify, Hono, Koa.

Core / per-call: pass an EvaluationContext on each isFeatureOn / evaluateFeatureGate call when you are not using an adapter (or when overriding ambient fields):

import type { EvaluationContext } from '@ops-ai/toggly-node-core'

const context: EvaluationContext = {
identity: 'user-123', // stable rollouts / Percentage
groups: ['beta-testers'], // group targeting
claims: { // UserClaims filters
role: 'admin',
tenant: 'acme',
},
traits: { // custom attributes (not UserClaims)
plan: 'enterprise',
},
}

await client.isFeatureOn('MyFeature', context)
await client.setIdentity('user-456') // updates default identity (no forced refresh)

Filter types and parameters: Feature filters.

HTTP segment filters + fromHttpRequest​

Segment identity filters (BrowserFamily, BrowserLanguage, Country, DeviceType, OS / OperatingSystem) read from EvaluationContext.request:

request?: {
userAgent?: string
acceptLanguage?: string
country?: string
}

fromHttpRequest (re-exported from @ops-ai/toggly-node-core, implemented in @ops-ai/toggly-eval) maps common headers:

HeaderField
User-Agentrequest.userAgent
Accept-Languagerequest.acceptLanguage
cf-ipcountry, x-vercel-ip-country, or cloudfront-viewer-countryrequest.country
import { createTogglyClient, fromHttpRequest } from '@ops-ai/toggly-node-core'

const client = createTogglyClient({ appKey: process.env.TOGGLY_APP_KEY! })
await client.init()

// In a request handler:
const context = fromHttpRequest(req.headers, {
identity: user.id,
groups: user.roles,
claims: { role: user.role },
})

await client.isFeatureOn('MobileCheckout', context)

UserClaims uses context.claims (not HTTP headers). Wire JWT / principal claims yourself.

Adapters: Express, Fastify, Hono, and Koa middleware call fromHttpRequest by default and accept ambient getIdentity / getGroups / getClaims (or getContext). Missing request keys are still filled from headers even when getContext is used. The adapters bind key-only request helpers. For a per-check override, call request.toggly.client.isFeatureOn(key, { ...request.toggly.context, ...overrides }) (using the equivalent object in your framework); merge nested claims or request fields explicitly if needed.

Signed definitions​

const client = createTogglyClient({
appKey: process.env.TOGGLY_APP_KEY!,
verifySignatures: true,
allowedKeyIds: [], // empty / omitted = allow all kids
maxSignatureAgeSeconds: 3600, // optional freshness; omit / <=0 disables
onError: (error, context) => {
console.error(context, error)
},
})

Verification uses the exact raw defs JSON bytes (never re-serialized). See Server-side reliability.

Live updates (WebSocket)​

Set enableStreaming: true to connect a WebSocket for flag refresh and signing-key rotation. Optional streamingUrl overrides the URL derived from baseUrl + appKey.

const client = createTogglyClient({
appKey: process.env.TOGGLY_APP_KEY!,
enableStreaming: true,
// streamingUrl: 'wss://...',
})

While connected, client.state.wsConnected is true. Protocol notes: WebSocket sync. Always call client.close() on shutdown.

Caching​

By default the client uses an in-memory DefinitionsCache. For disk persistence:

import { createTogglyClient, createFileCache } from '@ops-ai/toggly-node-core'

const client = createTogglyClient({
appKey: process.env.TOGGLY_APP_KEY!,
enableFileCache: true,
fileCachePath: '.toggly-cache',
// or: cacheProvider: createFileCache('.toggly-cache'),
})

await client.clearCache() // definitions + JWKS snapshots

Custom backends implement CacheProvider (get / set / delete / has). Shared caching concepts: Client-side caching.

Entity schema registration​

OptionDefaultDescription
registerContextsOnStartuptruePUT registered entity schemas after init

Opt out with registerContextsOnStartup: false if you register kinds only in the dashboard. See Entity context.

Singleton helpers​

import { initToggly, getToggly, closeToggly } from '@ops-ai/toggly-node-core'

await initToggly({ appKey: process.env.TOGGLY_APP_KEY! })
const client = getToggly()
closeToggly()

Usage & metrics​

Optional gRPC usage statistics and business metrics (enableUsageTracking, enableMetrics, metricsBaseUrl, flush intervals): Usage & metrics.