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.--globalreads~/.apifae/config.yamlinstead. 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:
- The workspace root, under
openapi.yaml,openapi.jsonorswagger.yaml. - The
schemasglobs, 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
Related
- Mock file reference — every key a mock file accepts.
- Scenario files — named states one workspace can serve.
- Commands — what each command does with all of this.