Creating Your First API
This guide walks you through creating your first API endpoint with flAPI using a Parquet file as the data source. You will end up with a running GET /customers/ endpoint that supports optional filtering parameters.
Prerequisites
Before starting, make sure you have:
- The
flapibinary or Docker image available (see the Quickstart Guide). - A
customers.parquetfile. The flAPI repository ships one underexamples/data/customers.parquet(TPC-H customer columns:c_custkey,c_name,c_acctbal,c_mktsegment, etc.).
Project Layout
Create the following directory layout:
my-first-api/
├── flapi.yaml
├── data/
│ └── customers.parquet
└── sqls/
├── customers.yaml # Endpoint configuration
└── customers.sql # SQL template (Mustache)
Step 1: Create the Main Configuration
Create flapi.yaml at the project root:
project-name: my-first-api
project-description: My first flAPI project
template:
path: ./sqls
environment-whitelist:
- '^FLAPI_.*'
connections:
customers-parquet:
properties:
path: ./data/customers.parquet
duckdb:
access_mode: READ_WRITE
Key points:
project-name/project-descriptionuse hyphens (this is the canonical naming convention).connections.<name>.propertiesexposes values to your SQL template as{{ conn.<key> }}.- DuckDB pass-through keys (
access_mode,db_path,threads,max_memory,default_order) keepsnake_casebecause they are forwarded verbatim to DuckDB.
Step 2: Define the Endpoint
Create sqls/customers.yaml:
url-path: /customers/
method: GET
request:
- field-name: id
field-in: query
description: Customer key (c_custkey)
required: false
validators:
- type: int
min: 1
max: 1000000
preventSqlInjection: true
- field-name: segment
field-in: query
description: Market segment
required: false
validators:
- type: enum
allowedValues: [AUTOMOBILE, BUILDING, FURNITURE, HOUSEHOLD, MACHINERY]
template-source: customers.sql
connection:
- customers-parquet
with-pagination: true
Key points:
url-path,template-source, andconnectionare required.methoddefaults toGETif omitted.- Each request field declares
field-name,field-in(query,path,header, orbody), and an optional list ofvalidators. Built-in validator types areint,string,enum,email,uuid,date, andtime. with-pagination: trueautomatically acceptslimitandoffsetquery parameters.
Step 3: Write the SQL Template
Create sqls/customers.sql. Templates use Mustache syntax — {{ params.foo }} for variables and {{#params.foo}} … {{/params.foo}} for conditional sections that render only when the parameter is present.
SELECT
c_custkey AS id,
c_name AS name,
c_acctbal AS balance,
c_mktsegment AS segment
FROM '{{{ conn.path }}}'
WHERE 1=1
{{#params.id}}
AND c_custkey = {{{ params.id }}}
{{/params.id}}
{{#params.segment}}
AND c_mktsegment = '{{{ params.segment }}}'
{{/params.segment}}
Notes on the template syntax:
{{{ ... }}}(triple braces) emits the value unescaped, which is required for SQL fragments and file paths.{{ conn.path }}reads thepathproperty of thecustomers-parquetconnection defined inflapi.yaml.{{#params.id}} … {{/params.id}}renders the inner SQL only when theidquery parameter is provided. Otherwise it is silently skipped.- Validators defined in
customers.yamlrun before the template is rendered, so by the time{{ params.id }}reaches the SQL it has already been type-checked.
Step 4: Run flAPI
Start the server pointing at your config file:
./flapi -c flapi.yaml
flAPI listens on port 8080 by default (override with -p <port> or http-port: in flapi.yaml). You can also validate the configuration without starting the server:
./flapi -c flapi.yaml --validate-config
Step 5: Call the Endpoint
In another terminal:
# All customers (first page)
curl "http://localhost:8080/customers/"
# Filter by customer key
curl "http://localhost:8080/customers/?id=42"
# Filter by market segment
curl "http://localhost:8080/customers/?segment=AUTOMOBILE"
# Combine filters with pagination
curl "http://localhost:8080/customers/?segment=BUILDING&limit=10&offset=0"
Next Steps
- Learn about global configuration options, including DuckLake caching, MCP, and authentication.
- Explore the Quickstart Guide for a condensed end-to-end walk-through.
- Read the upstream Configuration Reference and CLI Reference for the complete option list.