Command line¶
api-contract has five commands. Options such as --format and --config go
after the command: api-contract check --format markdown.
| Command | What it does |
|---|---|
snapshot |
Write the normalized current schema to the snapshot file |
check |
Compare the current schema with the snapshot, apply the allowlist |
diff |
Compare any two specs, snapshots or sources |
allow |
Add an allowlist entry |
changelog |
Write a consumer-facing Markdown changelog |
usage: api-contract [-h] [--version] COMMAND ...
Detect breaking changes between OpenAPI documents.
positional arguments:
COMMAND
snapshot write the normalized schema snapshot
check diff the current schema against the snapshot
diff compare any two specs or snapshots
allow acknowledge a change in the allowlist
changelog
consumer-facing changelog (Markdown)
options:
-h, --help show this help message and exit
--version show program's version number and exit
--version prints api-contract 0.1.0a1 (the installed version).
Options shared by several commands:
| Option | Commands | Meaning |
|---|---|---|
--config PATH |
all | Use this pyproject.toml or api-contract.toml instead of discovering one |
--source SOURCE |
all | Override the configured source for this run |
--format {text,markdown,json} |
check, diff |
Report format, default text. See Reports |
--fail-on {breaking,potentially-breaking} |
check, diff |
Lowest severity that fails. Default: the config's fail_on, else breaking |
--output FILE, -o FILE |
snapshot, check, diff, changelog |
Write to this file instead of stdout (for snapshot, instead of the configured snapshot path) |
--no-group |
check, diff |
List every change separately. See grouping |
snapshot¶
Loads the schema from the source, normalizes it and writes it to the snapshot
file (snapshot in the config, default api-contract.json). Commit the file.
Prints Wrote <path>.
usage: api-contract snapshot [-h] [--config PATH] [--source SOURCE]
[--output FILE]
options:
-h, --help show this help message and exit
--config PATH pyproject.toml or api-contract.toml
--source SOURCE override the configured source, e.g.
"file:openapi.json"
--output FILE, -o FILE
default: the configured snapshot path
check¶
Compares the current schema (from source) with the snapshot, applies the
allowlist, prints the report and exits 0 or 1. A missing
snapshot is an error (exit 2).
usage: api-contract check [-h] [--config PATH] [--source SOURCE]
[--format {json,markdown,text}]
[--fail-on {breaking,potentially-breaking}]
[--output FILE] [--no-group]
options:
-h, --help show this help message and exit
--config PATH pyproject.toml or api-contract.toml
--source SOURCE override the configured source, e.g.
"file:openapi.json"
--format {json,markdown,text}
--fail-on {breaking,potentially-breaking}
lowest severity that fails (default: config fail_on,
else breaking)
--output FILE, -o FILE
write the report here, not stdout
--no-group text/markdown: list every change separately instead of
grouping changes that differ only by endpoint or media
type (json is never grouped)
diff¶
Compares any two documents, without a snapshot. Each side is a file path or a
source string, so diff old.json fastapi:app.main:app compares a saved spec
with the live app. The allowlist is not applied unless you pass
--allowlist PATH.
usage: api-contract diff [-h] [--config PATH] [--source SOURCE]
[--format {json,markdown,text}]
[--fail-on {breaking,potentially-breaking}]
[--output FILE] [--no-group] [--allowlist PATH]
old new
positional arguments:
old file path or source string (e.g. fastapi:app.main:app)
new file path or source string
options:
-h, --help show this help message and exit
--config PATH pyproject.toml or api-contract.toml
--source SOURCE override the configured source, e.g.
"file:openapi.json"
--format {json,markdown,text}
--fail-on {breaking,potentially-breaking}
lowest severity that fails (default: config fail_on,
else breaking)
--output FILE, -o FILE
write the report here, not stdout
--no-group text/markdown: list every change separately instead of
grouping changes that differ only by endpoint or media
type (json is never grouped)
--allowlist PATH apply this allowlist (not applied by default)
Attribution (the at: lines) comes from the loader of the second argument.
allow¶
Adds an entry to the allowlist (creating the file if needed). --reason and
--expires are both required, and the reason cannot be empty. Prints
Allowed <id> until <date> in <path>. The id is canonicalized first, so an id
copied with real path parameter names ({id}) is stored as {}.
usage: api-contract allow [-h] [--config PATH] [--source SOURCE] --reason
REASON --expires YYYY-MM-DD [--allowlist PATH]
id
positional arguments:
id change id, as printed by check
options:
-h, --help show this help message and exit
--config PATH pyproject.toml or api-contract.toml
--source SOURCE override the configured source, e.g.
"file:openapi.json"
--reason REASON
--expires YYYY-MM-DD
--allowlist PATH default: the configured allowlist
See Allowlist for the file format and wildcards.
changelog¶
Writes a Markdown changelog for the consumers of your API, without ids or
attribution. With no arguments it compares the snapshot with the current
source; with OLD NEW it compares two documents. Giving only one of them is an
error. It always exits 0 when it succeeds, whatever the changes are.
usage: api-contract changelog [-h] [--config PATH] [--source SOURCE]
[--title TITLE] [--output FILE]
[old] [new]
positional arguments:
old default: the snapshot
new default: the configured source
options:
-h, --help show this help message and exit
--config PATH pyproject.toml or api-contract.toml
--source SOURCE override the configured source, e.g.
"file:openapi.json"
--title TITLE
--output FILE, -o FILE
See Reports for an example.
Exit codes¶
| Code | Meaning |
|---|---|
| 0 | No failing changes |
| 1 | Failing changes, or an expired allowlist entry |
| 2 | Configuration or load error: no snapshot yet, bad config, app failed to import, framework not installed |
snapshot, allow and changelog return 0 on success and 2 on error.
Argument errors (a missing --expires, an unknown --format) also return 2.
Errors are printed to stderr as api-contract: error: <message>, for example:
Django: manage.py api_contract¶
With "api_contract.contrib.django" in INSTALLED_APPS, every command is also
available as a management command. It runs the same CLI, so the options are the
same:
python manage.py api_contract snapshot
python manage.py api_contract check --format markdown
python manage.py api_contract allow "GET /api/orders/:response:200:total:type-changed" \
--reason "..." --expires 2026-12-01
Differences from the plain CLI:
manage.pyhas already set Django up, so you do not needDJANGO_SETTINGS_MODULEin the environment. (The plainapi-contractCLI has no--settingsflag and needs the variable.)- If neither
--sourcenor your config names a source,snapshot,checkandchangelogdefault tosource = "django". -
Flags go after the subcommand, because everything after it is forwarded unchanged:
-
Django's own options (
--settings,--pythonpath) go before the subcommand: -
Messages say
manage.py api_contractinstead ofapi-contract, including the suggestedallowcommand in the report. - A non-zero result exits the process with the same code (1 or 2).