Config file reference

Configuration file reference

apifae.yaml is the workspace. It names the project, says where the mocks live, and configures the server that serves them. apifae init writes one; everything below is what it may contain.

Every key on this page is one the binary reads today, with one group of exceptions that says so plainly where it appears: six settings the tool accepts and stores but does not yet act on. Documenting them is the only honest option, because the tool takes them without complaint and a reader who finds one needs to know that nothing happens next.

Where the file is found

Commands look for apifae.yaml in the current directory, then in each parent, and stop at the first one. That directory is the workspace root, and every relative path in the file resolves against it.

Two things change the answer:

  • --config <path> names a file directly. A path that does not exist is an error, not a fallback.
  • --global reads ~/.apifae/config.yaml instead. Keys set there apply to every workspace that does not set them itself.

A workspace file beats the global one key by key, not file by file: setting server.port in a workspace leaves a global log_level in force.

The keys

Project

Key Type Default What it does
name string my-api Project name. Shown by status, and used as the workspace's identity.
version string 1.0.0 Project version. Yours to set; nothing derives behaviour from it.
schemas list of globs schemas/**/*.yaml Where to look for the OpenAPI spec, after the root. See Finding the spec.

Mocks

Key Type Default What it does
mocks.directory path mocks Directory holding the mock files, relative to the workspace root.
mocks.defaults.delay_ms integer 0 Delay applied to every response that does not set its own delay_ms.
mocks.validation.exclude list of globs empty Mock files withheld from spec comparison. They are still loaded and served — they are simply never checked against the spec, so they neither warn nor fail. * stops at a directory separator; ** crosses them.

Server

Key Type Default What it does
server.port integer 4000 Port up and serve bind. --port beats it.
server.host string 127.0.0.1 Interface to bind. 0.0.0.0 accepts connections from other machines.
server.cors boolean true Send permissive CORS headers, so a browser app can call the mock.
server.seed integer unset Seed the template helpers so uuid() and the fake_* helpers return the same values every run. Off unless asked for: seeding changes what every mock using a helper returns. --seed beats it.

Drift checking

Key Type Default What it does
diff.path_params map empty Values for {param} placeholders, so a parameterised endpoint can be probed rather than skipped. --path-param beats it.
auth.headers map empty Headers sent on every live request diff and patch make. This is where an API key for the real service goes. Values are used verbatim${TOKEN} is sent as those nine characters, not as the environment variable.

Recording

Key Type Default What it does
convert.denied_headers list empty Headers dropped when record --convert writes a mock, on top of the ones it always drops.
convert.body_file_threshold_kb integer 10 Bodies larger than this are written beside the mock as a body_file rather than inline.
ssl.ca_cert path unset CA certificate to trust when recording from an API with a private certificate authority.
ssl.client_cert path unset Client certificate, for an API that requires mTLS.
ssl.client_key path unset Private key for ssl.client_cert.
ssl.verify boolean true Verify the upstream certificate. Turning this off disables the check that the API is who it claims to be.

Output

Key Type Default What it does
log_level trace, debug, info, warn, error info Console log level. --verbose acts as a floor rather than an override, so it can raise this but not lower it. Re-read while up is running.
output_format text, json text Output shape for the structured commands. --json beats it.

Hosted service

These describe a hosted service that does not exist yet. status will show them if they are set; nothing else reads them, and login, logout, push and pull refuse rather than pretending to have worked. Nothing in the local workflow needs an account.

Key Type Default What it does
cloud.endpoint string unset Address of the hosted service.
cloud.project_id string unset Project to sync this workspace with.
cloud.auto_sync boolean unset Whether to push changes as they are made.

Reaching the outside

Every request the CLI makes to a live API goes through these: diff and patch when they probe, and record when it forwards to the real upstream.

Key Type Default What it does
proxy.http string unset Proxy for http:// requests.
proxy.https string unset Proxy for https:// requests.
proxy.no_proxy string unset Comma-separated hosts to reach directly, bypassing the proxy.
timeouts.connect integer (ms) 5000 How long establishing a connection may take.
timeouts.request integer (ms) 5000 How long a whole request may take. --timeout beats it.

Config replaces the environment, it does not extend it. HTTP_PROXY, HTTPS_PROXY and NO_PROXY are read when this file says nothing about proxying. The moment it names any of the three keys, the environment stops applying entirely — so a file setting only proxy.http also turns off HTTPS_PROXY. The rule is deliberate: it means the routing can be read off one file rather than assembled from a file and whichever shell launched the process.

record takes timeouts.connect and ignores timeouts.request. It forwards live traffic whose duration is the upstream's business, and cutting off a slow response mid-capture would write the fragment into the session as if it were real. The connect timeout is safe there because it bounds only reaching the upstream, not waiting for it.

A run that times out exits 2 — could not complete — rather than 1, so a slow API never reads as drift.

Mock response delays

Key Type Default What it does
timeouts.mock_delay_max integer (ms) 60000 Ceiling on a mock's own delay_ms.

A response declaring more than the ceiling is served at the ceiling, not refused: delay_ms: 300000 is almost always a misplaced zero, and turning a typo into a failed request helps nobody. Offending responses are named once when the mocks load, and again on every reload. The ceiling is fixed when the server starts, so changing it while up is running asks for a restart.

Finding the spec

Commands that need the OpenAPI spec — validate, up, diff, patch — look for it in two places, in order:

  1. The workspace root, under openapi.yaml, openapi.json or swagger.yaml.
  2. The schemas globs, resolved against the root.

Among files matched by a glob, only one declaring a top-level openapi: or swagger: key is a candidate, and the first in sorted order wins — so the same workspace resolves the same spec on a laptop and in CI.

The root wins on purpose. apifae init writes the spec to both places, and letting the copy win would mean editing the spec at the root had no effect.

Editing it

apifae config reads and writes the file without you opening it:

apifae config list
apifae config get server.port
apifae config set server.port 8080
apifae config add schemas "api/**/*.yaml"
apifae config remove schemas "api/**/*.yaml"

--global on any of them targets ~/.apifae/config.yaml instead. config list shows the keys the file actually sets and where each came from, not every key on this page.

Editing the file by hand is equally fine. up --watch re-reads it while running.

A complete file

name: orders-api
version: 1.0.0

schemas:
  - "schemas/**/*.yaml"

mocks:
  directory: mocks
  defaults:
    delay_ms: 0
  validation:
    exclude:
      - "mocks/vendor/**"

server:
  port: 4000
  host: 127.0.0.1
  cors: true

diff:
  path_params:
    id: ord_8f14e45fceea

auth:
  headers:
    Authorization: "Bearer sk_live_not_a_real_token"

log_level: info
output_format: text

This manual is generated from the repository. Every command and flag in it is checked against the binary; the marked transcripts are executed.