YAML Syntax & Structure
flAPI extends standard YAML with section includes, environment-variable substitution, and a fixed set of top-level keys per endpoint. This guide covers the extended syntax, the supported endpoint shapes (REST + 3 MCP variants), and path resolution rules.
Extended YAML Features
flAPI's YAML parser supports standard YAML plus these extensions:
1. Section Includes
flAPI's include directive copies one named section out of another YAML file. The syntax is:
{{include:section_name from path/to/file.yaml}}
No quotes around the path. The path is resolved relative to the including file.
Includable sections (anything else is rejected):
requestauthrate-limitconnectiontemplate-sourcecacheheartbeat
Example — a shared customer-common.yaml:
# common/customer-common.yaml
request:
- field-name: id
field-in: query
validators:
- type: int
min: 1
auth:
enabled: true
type: basic
users:
- username: admin
password: '${ADMIN_PASSWORD}'
roles: [admin, read]
rate-limit:
enabled: true
max: 100
interval: 60
connection:
- customers-parquet
template-source: customers.sql
cache:
enabled: true
table: customers_cache
schema: analytics
schedule: 5m
Endpoint that pulls them in:
# customers-rest.yaml
url-path: /customers/
method: GET
{{include:request from common/customer-common.yaml}}
{{include:auth from common/customer-common.yaml}}
{{include:rate-limit from common/customer-common.yaml}}
{{include:connection from common/customer-common.yaml}}
{{include:template-source from common/customer-common.yaml}}
{{include:cache from common/customer-common.yaml}}
with-pagination: true
You can also keep multiple variants of a section under different top-level keys in the source file (auth, auth-dev, auth-prod, ...) and choose which to include:
{{include:auth-prod from common/customer-common.yaml}}
This works because the include directive grabs the value of whatever top-level key you name.
2. Environment Variables
Reference environment variables anywhere a value is expected. Two equivalent forms exist:
auth:
jwt-secret: '${JWT_SECRET}'
jwt-issuer: '{{env.JWT_ISSUER}}'
${VAR}— shell-style.{{env.VAR}}— Mustache-style, also works inside SQL templates.
Environment variables must be whitelisted in flapi.yaml (template.environment-whitelist). Unknown / unwhitelisted variables cause a load-time error.
3. Template Variables
These context variables are available inside SQL templates (not in endpoint YAML):
params.*— validated request parametersconn.*— properties of the first connection listed underconnection:auth.*— authenticated user (auth.username,auth.roles,auth.email,auth.type,auth.authenticated)cache.*— cache metadata (in cache-refresh templates)env.*— whitelisted environment variables
See SQL Templating for the full reference.
Endpoint YAML Structure
Each YAML file defines one endpoint of one of four kinds. flAPI decides which kind by inspecting the top-level keys:
| Top-level key present | Endpoint kind |
|---|---|
url-path | REST |
mcp-tool | MCP tool |
mcp-resource | MCP resource |
mcp-prompt | MCP prompt |
url-path can also coexist with mcp-tool / mcp-resource when the same query should be exposed both ways.
Basic REST Endpoint
# sqls/customers.yaml
url-path: /customers/
method: GET
request:
- field-name: segment
field-in: query
description: Market segment to filter by
required: false
validators:
- type: enum
allowedValues: [AUTOMOBILE, BUILDING, FURNITURE, HOUSEHOLD, MACHINERY]
- field-name: min_balance
field-in: query
description: Minimum account balance
required: false
validators:
- type: int
min: 0
max: 1000000
template-source: customers.sql
connection:
- customers-parquet
with-pagination: true
cache:
enabled: true
table: customers_cache
schema: analytics
schedule: 5m
primary-key: [id]
Full-Featured REST Endpoint
# sqls/orders.yaml
url-path: /orders/:order_id
method: GET
request:
- field-name: order_id
field-in: path
description: Order ID
required: true
validators:
- type: int
min: 1
- field-name: status
field-in: query
description: Order status filter
required: false
default: "completed"
validators:
- type: enum
allowedValues: [pending, completed, cancelled, refunded]
- field-name: start_date
field-in: query
description: Start of the date range (YYYY-MM-DD)
required: false
validators:
- type: date
min: "2020-01-01"
- field-name: end_date
field-in: query
description: End of the date range (YYYY-MM-DD)
required: false
validators:
- type: date
template-source: orders/detail.sql
connection:
- bigquery-warehouse
- customers-parquet
with-pagination: true
request-fields-validation: true
auth:
enabled: true
type: bearer
jwt-secret: '${JWT_SECRET}'
jwt-issuer: 'my-auth-server'
rate-limit:
enabled: true
max: 1000
interval: 60
cache:
enabled: true
table: orders_cache
schema: analytics
schedule: 15m
primary-key: [order_id]
cursor:
column: updated_at
type: timestamp
retention:
keep-last-snapshots: 5
max-snapshot-age: 14d
Top-Level Keys Reference
| Key | Type | Default | Notes |
|---|---|---|---|
url-path | string | – | Required for REST endpoints. Path parameters use :name. |
method | string | GET | Single HTTP method: GET, POST, PUT, PATCH, DELETE. Use one string, not a list. |
template-source | string | – | Required for REST + MCP-tool + MCP-resource. Path to .sql file. |
connection | list[string] | – | Required when a template is used. First entry exposes conn.* in templates. |
request | list | [] | Request parameter definitions. |
with-pagination | bool | true | Wraps responses in {data, next, total_count} and accepts limit/offset. |
request-fields-validation | bool | false | Reject requests containing parameters not declared in request:. |
auth | mapping | inherits global | Per-endpoint auth override — see Authentication. |
rate-limit | mapping | inherits global | Per-endpoint rate-limit override. |
cache | mapping | – | DuckLake cache configuration. |
operation | mapping | auto | type: Read / type: Write, plus returns-data, transaction, validate-before-write. |
heartbeat | mapping | – | Endpoint heartbeat config. |
mcp-tool | mapping | – | Declares an MCP tool. |
mcp-resource | mapping | – | Declares an MCP resource. |
mcp-prompt | mapping | – | Declares an MCP prompt. |
Note:
methodis a single string. There is nomethods: [GET]list form.
MCP Endpoint Variants
flAPI exposes the same YAML configuration as three MCP shapes for AI agents.
MCP Tool
A callable tool that runs an SQL query. Only these three keys are recognised:
| Key | Type | Default | Description |
|---|---|---|---|
mcp-tool.name | string | required | Unique tool name (alphanumeric / underscore) |
mcp-tool.description | string | required | Tool description for the LLM |
mcp-tool.result-mime-type | string | application/json | MIME type sent back to the model |
# sqls/customers-mcp.yaml
mcp-tool:
name: search_customers
description: |
Search and retrieve customer information with flexible filtering
by segment, balance, name, or registration date.
result-mime-type: application/json
request:
- field-name: segment
field-in: query
required: false
validators:
- type: enum
allowedValues: [AUTOMOBILE, BUILDING, FURNITURE, MACHINERY, HOUSEHOLD]
- field-name: min_balance
field-in: query
required: false
validators:
- type: int
min: 0
max: 1000000
- field-name: name
field-in: query
required: false
validators:
- type: string
min: 2
max: 50
regex: '^[A-Za-z ]+$'
template-source: customers/search.sql
connection:
- customers-parquet
MCP Resource
A readable resource — e.g. an introspection query exposed as data.
| Key | Type | Default | Description |
|---|---|---|---|
mcp-resource.name | string | required | Unique resource name |
mcp-resource.description | string | required | Description shown to the model |
mcp-resource.mime-type | string | application/json | Content MIME type |
mcp-resource:
name: customer_schema
description: Customer table schema and field definitions
mime-type: application/json
template-source: customers/schema.sql
connection:
- customers-parquet
MCP Prompt
A reusable, parameterised Mustache prompt. Prompts have an inline template (no template-source) and do not need a connection.
| Key | Type | Default | Description |
|---|---|---|---|
mcp-prompt.name | string | required | Unique prompt name |
mcp-prompt.description | string | required | Description shown to the model |
mcp-prompt.template | string | required | Inline Mustache template body |
mcp-prompt.arguments | list[string] | [] | Template argument names |
mcp-prompt:
name: customer_analysis
description: Generate a customer analysis prompt
template: |
You are a data analyst. Analyse this customer:
{{#customer_id}}Customer ID: {{customer_id}}{{/customer_id}}
{{#segment}}Segment: {{segment}}{{/segment}}
Provide insights on purchasing patterns and recommendations.
arguments:
- customer_id
- segment
File Structure Best Practices
Recommended Directory Layout
project/
├── flapi.yaml # Main configuration
├── common/ # Shared section definitions
│ ├── customer-common.yaml
│ └── _shared/
│ └── auth.yaml
│
└── sqls/ # Endpoint definitions + SQL templates
├── customers/
│ ├── list.yaml # GET /customers/
│ ├── list.sql
│ ├── detail.yaml # GET /customers/:id
│ ├── detail.sql
│ └── search.yaml # MCP search tool
│
├── orders/
│ ├── list.yaml
│ ├── list.sql
│ ├── create.yaml # POST /orders/
│ └── create.sql
│
└── analytics/
├── revenue.yaml
└── revenue.sql
Naming Conventions
sqls/customers/list.yaml -> GET /customers/
sqls/customers/detail.yaml -> GET /customers/:id
sqls/customers/search.yaml -> GET /customers/search/
sqls/orders/create.yaml -> POST /orders/
sqls/analytics/revenue.yaml -> GET /analytics/revenue/
Path Resolution
Includes
Includes resolve relative to the including file:
# flapi.yaml (project root) — main config does not use the include directive,
# it lives only inside endpoint YAML files.
# sqls/customers-rest.yaml
{{include:request from ../common/customer-common.yaml}}
# Resolves to: common/customer-common.yaml
Template Source
template-source: resolves relative to the directory configured as template.path in flapi.yaml. Sub-paths are honoured:
# template.path: sqls/
template-source: customers.sql
# -> sqls/customers.sql
template-source: customers/list.sql
# -> sqls/customers/list.sql
Absolute paths and remote (s3://, https://, ...) paths are used as-is.
Cache Template Override
cache:
template-file: customers_cache.sql
# Same resolution rules as template-source.
YAML Best Practices
1. Consistent indentation
# 2 spaces throughout
request:
- field-name: status
field-in: query
validators:
- type: enum
allowedValues: [active, inactive]
2. Comment intent, not mechanics
# Customer search endpoint
# Cached every 5 minutes, basic auth, read-only.
url-path: /customers/search/
3. Use descriptive field names
- field-name: customer_segment
description: Market segment classification
- field-name: minimum_account_balance
description: Minimum balance in USD
4. Group related configuration with separators
# -- Endpoint -----------------------------------------------
url-path: /customers/
method: GET
# -- Request ------------------------------------------------
request:
- field-name: id
field-in: query
# -- Caching ------------------------------------------------
cache:
enabled: true
5. Pull shared config out into common files
{{include:auth from ../common/_shared/auth-basic.yaml}}
{{include:rate-limit from ../common/_shared/rate-limit-standard.yaml}}
6. Always validate enums and ranges
validators:
- type: enum
allowedValues: [pending, completed, cancelled]
7. Multi-line descriptions for MCP tools
mcp-tool:
name: search_orders
description: |
Search orders by status, customer, and date range.
Returns up to 100 orders per page (use limit/offset for more).
8. Keep secrets out of YAML
auth:
jwt-secret: '${JWT_SECRET}' # not a literal
Validation & Testing
Validate YAML syntax
flapii endpoints validate /customers/
Inspect resolved paths and includes
flapii config paths sqls/customers/list.yaml
Export resolved configuration
flapii config export sqls/customers/list.yaml
Troubleshooting
YAML syntax errors
Check indentation and quoting; YAML is whitespace-sensitive.
Include not found
Error: Include file not found: common/missing.yaml
Verify the file exists at the path relative to the including YAML, and that the section name on the left of from matches a top-level key in that file.
Environment variable not resolved
Error: Environment variable 'DB_HOST' not found
Export the variable and add it to template.environment-whitelist in flapi.yaml.
Template path not found
Error: Template file not found: customers.sql
Confirm template-source resolves against template.path from flapi.yaml.
Next Steps
- Endpoints Overview — complete configuration tutorial
- SQL Templating — Mustache syntax
- Parameters — query/path/header/body
- Validation — the seven validator types
- Authentication — basic, JWT, bearer, OIDC
- Write Operations — POST/PUT/PATCH/DELETE