Skip to main content

Configuration Service

flAPI's configuration story has two layers:

  1. The flapi.yaml file — declarative configuration loaded at server start. Supports environment variable substitution, hierarchical YAML, and modular includes.
  2. The Configuration Service API — an optional HTTP API (/api/v1/_config/*) the server exposes when started with --config-service. The flapii CLI is a thin client over this API and lets you inspect and modify configuration without restarting the server.

This page covers both layers.

Configuration Architecture

Hierarchical Configuration

Main Configuration File

flapi.yaml is the entry point. Canonical keys use kebab-case (project-name, project-description), with a few snake_case keys for DuckDB pass-through settings.

# flapi.yaml
project-name: my-api-project
project-description: Production API for customer data

# Template configuration
template:
path: './sqls'
environment-whitelist:
- '^FLAPI_.*'
- '^DB_.*'
- '^GOOGLE_.*'

# Include external configuration files
connections: {{include from 'config/connections.yaml'}}

# DuckDB engine settings (snake_case keys pass through to DuckDB)
duckdb:
db_path: ./cache/flapi.db
access_mode: READ_WRITE
threads: 8
max_memory: 8GB

Modular Configuration with Includes

Break large configurations into modules:

config/connections.yaml:

bigquery-warehouse:
init: |
INSTALL 'bigquery';
LOAD 'bigquery';
properties:
project_id: '${GOOGLE_CLOUD_PROJECT}'
credentials_path: '${GOOGLE_APPLICATION_CREDENTIALS}'

postgres-db:
init: |
INSTALL postgres;
LOAD postgres;
properties:
host: '${DB_HOST}'
port: 5432
database: '${DB_NAME}'
username: '${DB_USER}'
password: '${DB_PASSWORD}'

customers-parquet:
properties:
path: './data/customers.parquet'

Environment Variables

${VAR} substitution in YAML

flAPI substitutes ${VAR_NAME} references at load time. A default value can follow a |:

connections:
production-db:
properties:
host: '${DB_HOST}'
port: ${DB_PORT|5432}
username: '${DB_USER}'
password: '${DB_PASSWORD}'
ssl_mode: '${DB_SSL_MODE|require}'

Inside SQL templates (Mustache), use {{env.VAR_NAME}} to read whitelisted environment variables.

Only the two interpolation forms above are supported. There is no built-in ${vault:...} or ${aws-secrets:...} resolver — wire those secrets in via environment variables sourced from your deployment platform.

Environment Variable Whitelist

Control which variables are visible to templates:

template:
environment-whitelist:
- '^FLAPI_.*'
- '^DB_.*'
- '^GOOGLE_.*'
- '^AWS_.*'
- 'JWT_SECRET'

Only whitelisted variables are accessible from {{env.VAR_NAME}} in templates. This prevents accidental exposure of unrelated environment variables.

Environment-aware includes

Vary the configuration by environment by interpolating into the include path:

environment: '${FLAPI_ENV|development}'

connections: {{include from 'config/connections-${FLAPI_ENV}.yaml'}}

Then maintain config/connections-development.yaml, config/connections-staging.yaml, etc.

Configuration Validation

From the command line (server)

The server can validate and exit without starting:

./flapi --validate-config -c flapi.yaml
echo $? # 0 = valid, 1 = invalid

Use this in CI to fail builds on broken configuration.

From the command line (CLI client)

When the server is already running with --config-service, you can validate the active configuration via the CLI:

flapii config validate

Common Validation Errors

Missing Environment Variable:

Error: Environment variable 'DB_PASSWORD' is required but not set
Fix: export DB_PASSWORD='your-password'

Invalid YAML Syntax:

Error: YAML parse error on line 23
Expected ':' after key, got '-'
Fix: Check indentation and YAML syntax

Missing Include File:

Error: Include file not found: config/missing.yaml
Fix: Create the file or fix the include path

Configuration Reference (abbreviated)

For the full set of keys, see docs/CONFIG_REFERENCE.md. Selected highlights:

# Project metadata
project-name: my-api-project
project-description: API for business intelligence

# SQL template root
template:
path: './sqls'
environment-whitelist:
- '^FLAPI_.*'
- '^DB_.*'

# DuckDB engine (snake_case pass-through)
duckdb:
db_path: ./cache/flapi.db
access_mode: READ_WRITE
threads: 8
max_memory: 8GB

# Data connections
connections:
bigquery-warehouse:
init: |
INSTALL 'bigquery';
LOAD 'bigquery';
properties:
project_id: '${GOOGLE_CLOUD_PROJECT}'
credentials_path: '${GOOGLE_APPLICATION_CREDENTIALS}'

postgres-db:
init: |
INSTALL postgres;
LOAD postgres;
properties:
host: '${DB_HOST}'
port: 5432
database: '${DB_NAME}'
username: '${DB_USER}'
password: '${DB_PASSWORD}'

# Server (selected keys)
server:
http-port: 8080
http-host: 0.0.0.0
log_level: info # debug, info, warning, error

# Authentication
auth:
default_required: true
jwt_secret: '${JWT_SECRET}'
allowed_roles: [admin, user]

# Global rate limiting
rate_limit:
enabled: true
max: 100 # requests per interval
interval: 60 # seconds

The Configuration Service API

The Configuration Service exposes runtime endpoints under /api/v1/_config/* for listing, inspecting, mutating, and reloading endpoints, templates, and caches.

Enable it

The API is off by default. Enable it on the server:

./flapi -c flapi.yaml \
--config-service \
--config-service-token "$FLAPI_CONFIG_SERVICE_TOKEN"
  • If --config-service is set without a token, the server generates a random one at startup and logs it.
  • The token can also be supplied via the FLAPI_CONFIG_SERVICE_TOKEN environment variable.

Authentication

Every request to /api/v1/_config/* must present the token in one of:

Authorization: Bearer <token>

or

X-Config-Token: <token>

Reload an endpoint without restart

The dedicated reload endpoint applies updated YAML or template changes:

POST /api/v1/_config/endpoints/{slug}/reload

This is what flapii endpoints reload <path> calls under the hood. flAPI does not poll the filesystem; reloads are explicit and gated by authentication.

For the full API surface (endpoints, templates, caches, schema, MCP, ping), see docs/CONFIG_SERVICE_API_REFERENCE.md and the flapii CLI overview.

Scaffolding a project

Use the CLI to scaffold a working flapi.yaml plus directory layout:

flapii project init my-first-api

Supported flags:

  • -f, --force — overwrite existing files
  • --skip-validation — skip post-scaffold validation
  • --no-examples — only create directories and flapi.yaml
  • --advanced — include additional template files
  • --ai — use Gemini-assisted setup (requires FLAPI_GEMINI_KEY)

There is no built-in --template <preset> switch. Pick a starter from the examples directory and copy the relevant flapi.yaml if you need a specific data-source preset.

Best Practices

Use includes for organization

# Good: modular and maintainable
connections: {{include from 'config/connections.yaml'}}
auth: {{include from 'config/auth.yaml'}}

# Bad: everything in one 1000-line file

Provide defaults for optional values

# Good: fallback when env var is unset
port: ${DB_PORT|5432}
max_memory: ${FLAPI_MAX_MEMORY|8GB}

# Bad: hard failure when env var is missing
port: ${DB_PORT}

Keep secrets out of YAML

# Good: secrets via environment
password: '${DB_PASSWORD}'

# Bad: hardcoded secret in version control
password: 'my-secret-password'

Validate before deploying

# Fast check, no server start
./flapi --validate-config -c flapi.yaml

# Same against a running server
flapii config validate

Troubleshooting

Configuration not loading

Error: Failed to load configuration file
  1. ls -la flapi.yaml — does the file exist where the server runs?
  2. ./flapi --validate-config -c flapi.yaml — exact parser error.
  3. Check the working directory used by your process supervisor.

Environment variable not resolved

Error: Environment variable 'DB_HOST' not found
  1. echo $DB_HOST in the same shell that launches flapi.
  2. Confirm the variable matches the environment-whitelist if it is referenced from a template.

401 Unauthorized from the Configuration Service

The server received a request to /api/v1/_config/* without a valid token. Set FLAPI_CONFIG_SERVICE_TOKEN for both the server and flapii, or pass -t/--config-service-token explicitly.

Next Steps

🍪 Cookie Settings