Everything below describes the TOML config files. Run npx apimock --init (or
apimock --init) once to scaffold apimock.toml and apimock-rule-set.toml
into the current directory, then tweak to taste.
[listener]
ip_address = "127.0.0.1" # interface to bind
port = 3001 # plaintext HTTP port
[listener.tls] # optional — enables HTTPS
cert = "./cert.pem"
key = "./key.pem"
# port = 3002 # optional — if omitted, HTTPS replaces HTTP on the port above
[log]
verbose = { header = true, body = true }
[service]
strategy = "first_match" # only value supported today
rule_sets = ["apimock-rule-set.toml"] # paths, resolved relative to this file
middlewares = [] # Rhai scripts, resolved relative to this file
fallback_respond_dir = "." # folder served when no rule matches
Section / field
Required
Default
Notes
listener.ip_address
no
127.0.0.1
Bind address. 0.0.0.0 to accept from other machines.
listener.port
no
3001
Plaintext HTTP port.
listener.tls.cert / .key
yes if [listener.tls] set
—
PEM files. Any key format rustls-pki-types accepts (PKCS#8, PKCS#1, SEC1).
listener.tls.port
no
same as listener.port
When omitted, the single port serves HTTPS only — no plaintext listener is started.
log.verbose.header
no
false
Log each request’s headers.
log.verbose.body
no
false
Log each request’s URL query and JSON body (pretty-printed).
service.strategy
no
first_match
Currently the only strategy — the first rule that matches wins.
service.rule_sets
no
[]
See Rule-set schema below. Paths relative to this file.
service.middlewares
no
[]
Rhai script paths, relative to this file.
service.fallback_respond_dir
no
.
Folder served when nothing in rule_sets or middlewares handled the request.
Exactly one of file_path / text / status must be present. (text may be combined with status to set the response code.)
Field
Type
Purpose
file_path
string
File under prefix.respond_dir (or the working dir if no prefix). Extension decides content type; .json / .json5 / .csv served as JSON, other text types served verbatim with an inferred Content-Type, binary types (images, audio, video, .pdf, .zip) served with the corresponding binary Content-Type.
text
string
Return this string verbatim. Content type text/plain; charset=utf-8.
status
integer (100–999)
HTTP status code. With text, sets the status; alone, returns an empty body with that status. Cannot be combined with file_path.
headers
{ name = value } map
Extra response headers.
delay_response_milliseconds
integer
Sleep this long before responding — useful for simulating slow backends in UI tests.
csv_records_key
string
Only meaningful when file_path points at a .csv. The JSON response wraps the rows as { "<key>": [...] } using this value; defaults to "records".
The JSONPath support is deliberately minimal — only the “object key” and “array index” forms, joined by .. This covers every real-world body-match need without exposing a full jsonpath engine that users would then have to learn.
Input
Meaning
user
Top-level key user
user.id
user → id (nested object)
items.0
First element of array items
orders.2.total
Array index 2 of orders, then key total
a.b.c
Three-level nested object lookup
If any segment is missing or has the wrong shape (e.g. a numeric segment against an object), the rule simply does not match — no error, because “missing” is a useful matchable condition.
Prepended to every rule’s when.request.url_path before matching. Leading/trailing slashes are normalised. The contains operator deliberately ignores the prefix — it matches against the raw url_path value — because “contains” usually means “substring anywhere in the full request path”, and re-applying a prefix there would be surprising.
respond_dir
Prepended to every rule’s respond.file_path. Resolved relative to the rule-set file’s directory, not the working dir — so configs travel cleanly between machines.