Skip to content

Getting Started

brookie edited this page Oct 8, 2026 · 4 revisions

Getting Started

This page installs API Dock, creates a config folder, adds one remote API and one database backed by a local Parquet file, and starts the server. The CLI reference is at the end.

Install

API Dock needs Python 3.11 or later.

pip install api-dock                    # core package
pip install 'api-dock[postgres]'        # also installs the PostgreSQL driver and pool

With conda or pixi (conda-forge):

conda install -c conda-forge api_dock
pixi add api_dock

You only need the postgres extra if your configs define PostgreSQL connections. See PostgreSQL.

Create a config folder

Run api-dock init in the directory you will start the server from:

api-dock init

It creates api_dock_config/ and copies in the bundled example files:

api_dock_config/
├── config.yaml              # the main config
├── databases/
│   ├── config.yaml          # optional shared database config (all commented out)
│   └── example_db.yaml      # an example database
└── remotes/
    ├── config.yaml          # optional shared remote config (all commented out)
    └── example_remote.yaml  # an example remote API

The example files point at placeholder addresses (https://api.example.com, s3://your-bucket/...) and contain commented-out examples of most features. Replace or delete them before you use the server.

init stops with an error if api_dock_config/ already has .yaml files at its top level. --force runs it anyway and replaces existing files with the example's (since api_dock 0.10.0; before, it only added missing files). Every example file is copied, keeping its folders.

A first remote

A remote is an HTTP API that API Dock forwards requests to. Replace api_dock_config/remotes/example_remote.yaml with a file for httpbin.org:

# api_dock_config/remotes/httpbin.yaml
name: httpbin
description: HTTP request and response service
url: https://httpbin.org

Requests to /httpbin/<path> are now forwarded to https://httpbin.org/<path>. The URL prefix comes from the file's name (the file name is used if name is missing). Allow-lists, restrictions and route remapping are covered in Routing and Restrictions.

A first database

A database is a set of tables plus routes that map URLs to SQL. Create a small Parquet file (DuckDB is installed with API Dock):

mkdir -p data
python -c "import duckdb; duckdb.sql(\"COPY (SELECT * FROM (VALUES (1, 'Oakland', 'US'), (2, 'Lyon', 'FR')) t(id, name, country)) TO 'data/places.parquet' (FORMAT parquet)\")"

Then describe it:

# api_dock_config/databases/places.yaml
description: Example places table
tables:
  places: data/places.parquet
routes:
  - route: places
    sql: SELECT [[places]].* FROM [[places]]
    query_params:
      - country:
          sql: "[[places]].country = {{country}}"
  - route: places/{{id}}
    sql: SELECT [[places]].* FROM [[places]] WHERE [[places]].id = {{id}}
  • tables maps a name to a file path or URI. Relative paths such as data/places.parquet are read by DuckDB relative to the directory you start the server from.
  • [[places]] refers to that table. After FROM it becomes 'data/places.parquet' AS places; elsewhere it becomes places.
  • {{id}} is a path variable and {{country}} a query parameter. Both reach DuckDB as bound parameters.

The URL prefix of a database is its entry in the main config's databases: list (which is also the file name). See SQL Database Support and Query Parameters for everything a database config can hold.

The main config

List the remote and the database in api_dock_config/config.yaml:

# api_dock_config/config.yaml
name: my-api
description: My first API Dock
authors:
  - Your Name

remotes:
  - httpbin          # remotes/httpbin.yaml

databases:
  - places           # databases/places.yaml

settings:
  add_trailing_slash: false

add_trailing_slash defaults to true, which turns /httpbin/get into a request for https://httpbin.org/get/, and httpbin answers that with 404. Many APIs expect the slash, some (like httpbin) don't. See Configuration for every setting.

Start the server

api-dock start

API Dock checks every database config at startup and refuses to start if one is invalid, naming the database, version and route. By default it binds 0.0.0.0:8000; if the port is taken it tries the next four ports and prints the one it used.

Try it

curl http://localhost:8000/
# {"name":"my-api","description":"My first API Dock","authors":["Your Name"],"endpoints":["/"],"remotes":["httpbin","places"]}

curl http://localhost:8000/places/
# {"routes": ["places", "places/{{id}}"]}

curl http://localhost:8000/places/places
# [{"id": 1, "name": "Oakland", "country": "US"}, {"id": 2, "name": "Lyon", "country": "FR"}]

curl "http://localhost:8000/places/places?country=FR"
# [{"id": 2, "name": "Lyon", "country": "FR"}]

curl http://localhost:8000/places/places/1
# [{"id": 1, "name": "Oakland", "country": "US"}]

curl http://localhost:8000/httpbin/get
# httpbin's own JSON response
  • / returns the metadata from the main config. Databases are listed under remotes too.
  • /<database>/ lists the database's routes. For a versioned database it lists the versions instead (see Versioning).
  • An unknown route returns 404 with a JSON body, e.g. {"error": "Route 'nope' not found in database 'places'"}.

CLI reference

Command What it does
api-dock Lists the configs in api_dock_config/ and the bundled examples, plus the commands
api-dock init [--force/-f] Creates api_dock_config/ and copies the example files; --force replaces existing ones
api-dock start [CONFIG_NAME] Starts the server with api_dock_config/<CONFIG_NAME>.yaml (default config)
api-dock describe [CONFIG_NAME] Prints the config's name, description, authors, remotes, databases (tables and route SQL) and endpoints
api-dock generate-key Writes a new local encryption key file with permissions 600
api-dock encrypt PLAINTEXT Encrypts a value for use in a config file
api-dock decrypt CIPHERTEXT Decrypts a value (for testing)
api-dock lookups [CONFIG_NAME] Runs the config's lookups and prints their rows; with --url shows or --refreshes them on a running server

start options:

Option Default Meaning
--host 0.0.0.0 Address to bind
--port 8000 Port to bind; if it's in use, the next four ports are tried
--backbone, -b fastapi fastapi or flask. Flask buffers responses and refuses configs with PostgreSQL connections
--log-level info critical, error, warning, info, debug or trace. With Flask, debug turns on Flask's debug mode

CONFIG_NAME may include or omit .yaml. If api_dock_config/<CONFIG_NAME>.yaml doesn't exist, start and describe fall back to the bundled example config of that name. See Configuration.

describe builds the API the way start does (running lookups and the startup checks, so a bad config is reported), then prints every remote/version with its URL and every database/version with its schema, its own tables and each route's SQL with [[...]] references expanded (? marks a bound request value; query-param filters aren't shown). Before api_dock 0.10.0 it printed SQL as written and failed on versioned databases.

generate-key options: --output/-o (default .api_dock_key) and --force/-f to overwrite an existing key file.

encrypt and decrypt options:

Option Default Meaning
--method, -m local_key local_key, env_key or aws_kms
--key-file .api_dock_key Key file for local_key
--key-env API_DOCK_ENCRYPTION_KEY Environment variable holding the key for env_key
--key-id none KMS key ID, required for aws_kms
--region us-east-1 AWS region for aws_kms

How encrypted values are used is covered in Authentication and Cookies.

Next steps

Clone this wiki locally