Config Field Reference
Complete reference for every field in config.json. This file controls runtime product behavior — plan limits, billing, webhooks, and feature flags. It is separate from .env, which holds secrets and infrastructure wiring.
Starter Example
This is the recommended starting point for a self-hosted deployment with no billing configured. All limits are set to null (unlimited), and billing features are disabled. Replace [email protected] with your own address.
admins#
An array of email addresses that are granted site admin access. Admins can access privileged pages such as the batch process scheduler and system-wide usage dashboards.
| Field | Type | Required | Description |
|---|---|---|---|
| admins | string[] | Required | List of email addresses with admin access. Must match the email associated with the user's Clerk account. |
features#
Feature flags that control which parts of the product UI are active. For simple self-hosted deployments, you can disable all billing features and leave only the scheduler flag if needed.
| Field | Type | Required | Description |
|---|---|---|---|
| subscriptionEnforcementEnabled | boolean | Required | When true, users can view and upgrade to paid plans. When false, the upgrade UI shows a billing coming soon placeholder instead. |
| workspaceBillingEnabled | boolean | Required | When true, billing tiers and plan information appear in the sidebar and workspace settings. Set to false to hide all billing UI entirely. |
| batchSchedulerEnabled | boolean | Required | When true, the batch process scheduler is active and admin-accessible. Requires Redis and BullMQ to be running. |
| customMCPServerTokens | boolean | Required | When false, the MCP server authenticates using the standard OAuth/Clerk token. When true, self-managed API tokens are used instead — useful for environments without Clerk MCP support. |
limits#
An array of limit sets that control resource usage. Each entry can be tied to a billing tier via billingTier, or set to null to apply to all users regardless of plan. For simple deployments with no billing, a single entry with "billingTier": null is sufficient. null values for numeric limits mean unlimited.
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Unique identifier for this limit set (e.g. free, pro, default). |
| maxTrackableItems | number | Required | Maximum number of trackable items (forms + API endpoints) a user can create per workspace. |
| maxResponsesPerSurvey | number | null | Required | Maximum number of responses allowed per survey/form. null means unlimited. |
| maxWorkspaceMembers | number | null | Required | Maximum number of members in a workspace. null means unlimited. |
| maxApiLogsPerMinute | number | Required | Maximum number of log events that can be ingested per minute per trackable item. Excess requests are rate-limited. |
| maxApiPayloadBytes | number | Required | Maximum size in bytes of a single log payload. Requests larger than this are rejected. |
| logRetentionDays | number | Required | Number of days log entries are retained before being purged. Applies to all logs within this tier. |
| maxCreatedWorkspaces | number | null | Required | Maximum number of workspaces a single user can create. null means unlimited. |
| billingTier | string | null | Required | The billing tier ID this limit applies to. Must match an id in the billing.tiers array. Set to null to apply this limit to all users regardless of plan. |
billing#
Optional billing configuration for Lemon Squeezy integration. If you are not using paid plans, set lemonSqueezyStoreId and manageUrl to null and leave tiers as an empty array. Tier id values are referenced by limits[].billingTier — they must match exactly.
| Field | Type | Required | Description |
|---|---|---|---|
| lemonSqueezyStoreId | string | null | Optional | Your Lemon Squeezy store ID. Required if you are processing payments through Lemon Squeezy. |
| manageUrl | string | null | Optional | URL to the billing management page shown to users. Typically your Lemon Squeezy customer portal URL. |
billing.tiers[]
Array of billing tiers displayed in the upgrade UI. Each tier must have a unique id that matches a corresponding entry in limits[].billingTier.
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | Required | Unique tier identifier. Referenced by limits[].billingTier. |
| name | string | Required | Display name shown to users (e.g. Pro, Team). |
| priceLabel | string | Required | Price string shown in the UI (e.g. $25). |
| priceInterval | string | Required | Billing interval shown below the price (e.g. per month). |
| description | string | Required | Short description of what this tier includes. |
| tone | "neutral" | "accent" | "strong" | Required | Visual theme of the tier card. accent and strong are highlighted styles; neutral is the default. |
| mostPopular | boolean | Required | When true, shows a Most Popular badge on this tier card. |
| lemonSqueezyVariantId | string | null | Optional | Lemon Squeezy product variant ID for this tier. Required for checkout to work. |
| enabled | boolean | Required | When false, this tier is hidden from the upgrade UI even if billing is enabled. |
usage#
Global API usage controls that apply across all workspaces and users.
| Field | Type | Required | Description |
|---|---|---|---|
| invalidApiKeyRateLimitPerMinute | number | Required | Maximum number of requests with an invalid API key allowed per minute per IP before the source is rate-limited. Helps prevent credential stuffing. |
| maxBodyBytes | number | Required | Maximum size in bytes for a log request body at the API gateway level. Requests exceeding this are rejected before reaching the service layer. |
| pageSize | number | Required | Number of log entries fetched per page when loading the log viewer. |
webhooks#
Controls the outbound webhook delivery queue backed by Redis and BullMQ. Rate limiting here applies to the queue consumer, not to inbound log ingestion.
| Field | Type | Required | Description |
|---|---|---|---|
| queue.enabled | boolean | Required | When true, outbound webhooks are queued in Redis and delivered asynchronously. Requires Redis to be running. |
| queue.rateLimitMs | number | Required | Minimum milliseconds to wait between consecutive webhook deliveries from the queue. |
| queue.rateLimitMax | number | Required | Maximum number of webhook events that can be sent within the rateLimitMs window. |
batch#
Configuration for the background batch scheduler. The scheduler must also be enabled via features.batchSchedulerEnabled.
| Field | Type | Required | Description |
|---|---|---|---|
| schedulerTimeZone | string | Required | IANA timezone string used for scheduling batch jobs (e.g. UTC, America/New_York). Affects when cron-based jobs trigger. |