Getting started¶
wt is a command-line client for the Wagtail v3 API. This walkthrough drives
the API with wt from end to end: install, point it at a site, verify auth,
and publish a page with rich-text (Markdown) content.
Requirements¶
- Python 3.12 or newer.
- A Wagtail site exposing the v3 API (Wagtail 8.0 or newer). The demo site in
this repository ships with the v3 API mounted at
/api/v3/.
1. Install¶
# one-shot (no install)
uvx --from wagtail-cli wt --help
# or install permanently
uv tool install wagtail-cli
wt --help
wtinstalled in isolation (uv tool, pipx) runs outside your project's environment. Delegated Django commands (for examplewt runserver) andwt --versionautomatically prefer your project's interpreter: the active$VIRTUAL_ENV, or a.venv/venvdirectory in the current directory. Alternatively runwtinside the project environment withuv run --with wagtail-cli wt ....
2. Configure a site¶
You need two things: the API base URL and a token. Start the demo site and create a token:
# from the repo root, in the demo/ project
cd demo
.venv/bin/python manage.py migrate
.venv/bin/python manage.py runserver 0.0.0.0:9001
# in another terminal:
.venv/bin/python manage.py api_tokens create --user=demo
# → prints a token like wagtail_xxxxxxxxxxxxxxxxxxxxxxxx
The v3 API lets authenticated clients create, read, update, and manage content. Tokens are tied to user accounts; create one for a superuser or a least-privilege role.
Then configure the CLI:
# env vars (simplest; also sets it for scripts)
export WAGTAIL_CLI_BASE_URL="http://127.0.0.1:9001/api/v3"
export WAGTAIL_CLI_TOKEN="wagtail_xxxxxxxxxxxxxxxxxxxxxxxx"
# or persist it once:
wt api init
# prompts for URL + token and writes ~/.wagtail-cli.toml
See Configuration for the full precedence rules.
3. Verify authentication¶
4. Browse pages and the content model¶
wt api pages list --limit 5 # paginated, JSON when piped
wt api schema list # registered page types and snippets
wt api schema show blog.BlogPage # the raw JSON read/create/patch schema
pages list is a good sanity check: an error here usually means a bad URL,
token, or API path.
5. Publish a page written in Markdown¶
Create a local Markdown file:
cat > post.md <<'EOF'
## A Philosophy of Bread
Wagtail's v3 API accepts Markdown for rich-text fields and converts it server-side.
EOF
Create and publish a page whose body field is rich text:
wt api pages create blog.BlogPage \
--parent /blog/ \
--title "A Philosophy of Bread" \
--field body:@post.md \
--publish
What happens:
@post.mdreads the file; because of the.mdsuffix the CLI sends the value as{"format": "db_markdown", "content": "…"}— the API converts to database HTML. A.htmlfile (or a plain--field body:'<p>…</p>') is sent as-is.@-reads from stdin.--parent /blog/resolves a URL path to a page id via the API'sfindendpoint (numeric ids also work, e.g.--parent 5).--fieldis repeatable and JSON-aware: values starting with[or{are parsed as JSON, so you can set StreamField bodies and structured fields directly:--field 'tags:["bread","sourdough"]'.- Without
--publishthe page is created as a draft.
6. Verify it's live¶
Open the page in a browser if you like:
http://127.0.0.1:9001/blog/a-philosophy-of-bread/.
Mutating commands: --dry-run and confirmation¶
Every mutating command supports --dry-run, which prints the request that
would be sent without sending it:
wt api pages create blog.BlogPage --parent /blog/ \
--title "Dry" --field body:@post.md --dry-run
# POST http://127.0.0.1:9001/api/v3/pages/
# { ...payload... }
update and delete also require confirmation (--yes) on a non-interactive
terminal, to keep scripts from destructively mutating content by accident.
Next steps¶
- Usage – the full command reference, every command and flag.
- Configuration – the config cascade, dotfiles, and environment variables.
- Agent skills – point an AI agent at the published skill.