Commands

Commands

Every command the binary answers to, what it is for, and when to reach for it.

This page is an index, not a reference: it says what each command is for. The exhaustive flag-by-flag reference — every option, its default and its value name, plus what each exit code means — is generated from the binary's own argument declaration and lives in reference.md.

APIFae ships fifteen commands. Eleven do work. Four name a hosted service that does not exist yet and refuse rather than pretending — they are listed at the bottom, under Commands that refuse, and are the honest edge of the tool rather than a gap in this page.

Exit codes follow one rule everywhere: 0 succeeded, 1 the command ran and found a problem, 2 you asked for something impossible — an unknown flag, a missing argument. Where a command means something more specific by 1, its entry says so.


The daily loop

init

Turns a directory into an APIFae workspace. It looks for an OpenAPI 3.x or Swagger spec where you are — openapi.yaml, swagger.json, api/*.yaml and friends — copies it to schemas/, and writes one mock per documented path, populated from the spec's own example: values.

Reach for it once, first. The point is that init then up serves the documented API immediately, rather than leaving you a directory of stubs to fill in.

$ apifae init -N
EXIT: 0

-N is the non-interactive form and imports the spec exactly as the prompt does. It is what a Dockerfile or a CI step runs.

With no spec in the directory, init writes a single commented example mock instead, and the workspace still serves.

up

Starts the mock server, watching for changes. This is the command you leave running in a terminal all day; edit a mock and the next request reflects it.

$ apifae up

up does not return: it serves until you stop it. There is no exit status to gate on, which is why a pipeline runs validate or diff rather than this.

serve

The same mock server as up. up is the quick-start spelling and serve the explicit one; they run the same code.

Reach for serve in scripts and CI, where the more descriptive name reads better, and for up when you are typing it yourself.

validate

Checks every mock in the workspace: that it loads, that its templates render, and that what it renders agrees with the spec.

Reach for it before you commit, and in CI. It exits 1 on an error — a mock that disagrees with the spec, or a file that will not load. Mocks the spec does not describe are warnings and exit 0, unless you pass --strict.

$ apifae validate
EXIT: 0

If there is no spec in the workspace, validate says so and checks the mocks on their own terms rather than refusing.

status

Reads the workspace you are standing in and reports it: project, mock and schema counts, defined scenarios, and whether a server is currently serving this workspace.

Reach for it when you are not sure what a directory contains, or from a script — --json gives the same reading in a machine-readable form.

$ apifae status
EXIT: 0

Keeping a mock honest

diff

Compares your mocks against a live API, and the live API against your spec. Two independent questions, which is the point: a mock can match production perfectly while both have drifted away from the contract the spec describes.

Reach for it as a CI gate, and whenever you suspect the real API has moved.

$ apifae diff https://api.example.com

Its exit codes carry more meaning than the general rule:

Exit Meaning
0 clean
1 drift, a contract violation, or both
2 the run could not complete — connection refused, timeout, 401, 403

Separating 1 from 2 is what makes it usable as a gate: a network problem must not read as a passing contract, and it does not.

Every response variant is probed. A response carrying a when: block is compared against a request built to satisfy that block, and reported under its own label; see the FAQ for what it cannot build a request for.

Endpoints and variants that could not be checked are reported but do not fail the run unless you pass --fail-on-skip.

patch

Applies what diff found, rewriting only the fields that actually changed.

Reach for it after a diff you believe. It edits in place and preserves the file around the change — comments, quoting and key order all survive — so the resulting commit shows the drift and nothing else. --dry-run changes nothing; every applied change leaves a timestamped .bak.

$ apifae patch https://api.example.com --dry-run

Under --dry-run it exits 1 when it finds drift — finding it is the whole point, and the exit code is what a CI gate reads. A real run exits 0 once it has applied everything it found, and 1 only when something it found could not be written. Either way, a 1 from patch is not a failure to run; that is 2.

It will not write a value the spec forbids unless you pass --accept-violations.

record

Proxies a real API and captures the traffic through it into mock definitions, including HTTPS by way of a generated CA certificate.

Reach for it when the API already exists and writing mocks by hand is the wrong way to spend an afternoon — and when you want a replayable capture of what production actually returned.

$ apifae record https://api.example.com

ca

Inspects and removes the recording CA certificates APIFae has written on this machine. record asks you to trust a root certificate; this is how you see what that left behind and take it back out.

It reads what APIFae wrote on disk. It cannot see your system trust store, and says so rather than implying otherwise.

ca list

Lists the recording CAs APIFae has written on this machine.

$ apifae ca list
EXIT: 0

ca remove

Deletes a recording CA and prints how to untrust it. Removing the file does not untrust the certificate — that needs your system's own tooling, which the command spells out for you.


Scenarios

scenario

Named states one workspace can be in — empty, forbidden, slow — so the same mocks can stand in for several API conditions without a second workspace.

Reach for scenarios when you are testing what your client does when things go wrong, which is most of the interesting testing.

scenario list

Lists the scenarios this workspace defines.

$ apifae scenario list
EXIT: 0

scenario set

Activates a scenario on a running server.

scenario reset

Returns to the default state, with no scenario active.

scenario create

Writes a new scenario file.


Configuration

config

Reads and writes the workspace's apifae.yaml.

Reach for config rather than editing the file when you want the effective value — the one the tool will actually use once defaults, the config file and any --config override have been resolved.

config list

Shows the effective configuration, annotated with where each value came from.

$ apifae config list
EXIT: 0

config get

Shows one key's effective value and its source.

config set

Sets a value.

config add

Appends to a list key, such as schemas.

config remove

Removes a list item, or deletes a map entry such as auth.headers.X-Api-Key.


Commands that refuse

login, logout, push and pull name APIFae's hosted service. That service does not exist yet. These commands are on the surface because the names are real intentions and part of the intended workflow, but each exits non-zero with a message saying so.

They used to print a and exit 0 having done nothing. That was worse than useless, so it is gone: a command that refuses honestly is not a false claim.

Nothing in the local workflow needs an account. init, up, record, diff, patch, validate and scenario all work against files in your workspace. Sharing a workspace with your team today means committing it to git.

login

Would authenticate against APIFae cloud.

$ apifae login
EXIT: 1

logout

Would end that session.

push

Would upload local schemas to a hosted workspace.

pull

Would download them.

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