WP-CLI
Every important operation in the UI is mirrored as a WP-CLI subcommand under the wp 404-to-301 namespace. The CLI is the recommended path for scripted migrations, deployment pipelines, and one-off bulk fixes that would be tedious through the admin UI.
wp 404-to-301 <subcommand> [args]logs
Manage rows in the 404 log table.
wp 404-to-301 logs list [--status=<status>] [--search=<term>] [--per-page=<n>] [--page=<n>] [--format=<format>]
wp 404-to-301 logs get <id>
wp 404-to-301 logs update <id> --to=<status>
wp 404-to-301 logs delete <id|--all|--status=<status>>
wp 404-to-301 logs prune --older-than=<days>Examples
# Show the 50 most recent open 404s
wp 404-to-301 logs list --status=open --per-page=50
# Mark a log row as fixed
wp 404-to-301 logs update 1234 --to=fixed
# Delete everything older than 30 days
wp 404-to-301 logs prune --older-than=30
# Wipe the table
wp 404-to-301 logs delete --all--status accepts open, ignored, fixed (numeric codes 0, 1, 2 are also accepted by the underlying model).
redirects
Manage rows on the Redirects page.
wp 404-to-301 redirects list [--search=<term>] [--per-page=<n>] [--page=<n>] [--format=<format>]
wp 404-to-301 redirects get <id>
wp 404-to-301 redirects create --source=<path> --target=<url> [--type=<301|302|307>] [--match=<exact|prefix|regex>] [--active]
wp 404-to-301 redirects update <id> [--field=<value> …]
wp 404-to-301 redirects delete <id|--all>Examples
# Create a 301 redirect
wp 404-to-301 redirects create --source=/old --target=https://example.com/new
# Create a regex redirect
wp 404-to-301 redirects create \
--source='^/news/\d{4}/(.*)$' \
--target=https://example.com/blog/$1 \
--match=regex
# Disable a redirect without deleting it
wp 404-to-301 redirects update 42 --is-active=0
# Wipe every redirect
wp 404-to-301 redirects delete --allsettings
Read and write the plugin's stored settings.
wp 404-to-301 settings get [<key>] [--format=<format>]
wp 404-to-301 settings update <key> <value>
wp 404-to-301 settings resetExamples
# Dump every setting as JSON
wp 404-to-301 settings get --format=json
# Read one value
wp 404-to-301 settings get redirect_type
# Turn off the redirect
wp 404-to-301 settings update redirect_enabled 0
# Reset everything to defaults
wp 404-to-301 settings resetThe setting keys match the field names documented on the General, Redirect, Log, and Notification settings pages.
migrate
Drive the legacy-v3 → v4 migration from the command line — useful when upgrading a site too large to migrate through the admin UI's progress bar.
wp 404-to-301 migrate status [--format=<format>]
wp 404-to-301 migrate run [--phase=<1|2|all>] [--limit=<chunks>]
wp 404-to-301 migrate abortExamples
# See what's left to migrate
wp 404-to-301 migrate status
# Migrate everything (phase 1 + phase 2)
wp 404-to-301 migrate run
# Only migrate the redirects (phase 1) — fast, runs in one go
wp 404-to-301 migrate run --phase=1
# Migrate at most 5 chunks of logs and stop
wp 404-to-301 migrate run --phase=2 --limit=5
# Stop a long-running phase-2 migration
wp 404-to-301 migrate abortrun is safe to re-run: already-migrated rows are skipped, so a second pass after a partial run just continues from where the previous run stopped.
CLI on a fresh install
A fresh install has no legacy wp_404_to_301 table to read from. migrate run detects that and exits with Phase 1 complete — 0 custom redirects migrated. rather than erroring.
doctor
Run a health check across the plugin's cron schedule, settings, and database. Prints grouped results and exits non-zero on any FAIL, so it slots into deployment scripts and CI tripwires.
wp 404-to-301 doctor [--format=<report|table|csv|json|yaml>]Sample output
Cron
[PASS] Hook 404_to_301_run_migration_chunk next runs 2026-06-05 14:20:00 (in 5 minutes).
Settings
[FAIL] Invalid email recipient(s): not-an-email.
[PASS] Default redirect URL parses cleanly (https://example.com/sitemap).
Database
[PASS] Table wp_404_to_301_logs exists.
[PASS] Table wp_404_to_301_redirects exists.
[WARN] 12 log row(s) reference a redirect that no longer exists.
[PASS] Redirect source hashes are unique.
Summary: 5 pass, 1 warn, 1 fail.What it checks
- Cron — every scheduled event whose hook starts with
404_to_301_, with the next-run timestamp. Other prefixes can be added via the404_to_301_doctor_cron_prefixesfilter so addon-owned events show up too. - Settings — when notifications are enabled: recipient list is non-empty and every entry passes
is_email(). When the default redirect is enabled: the destination URL parses (link mode) or the destination page exists and is published (page mode). - Database — both plugin tables exist; no log rows reference a deleted redirect; no duplicate
source_hashvalues on the redirects table.
Exit codes
0 on a clean bill of health (including WARN), 1 if any check reports FAIL. WARN is a heads-up, not a failure — the count surfaces in the summary line but doesn't trip the exit code.
Extending it
Addons can register their own group via the 404_to_301_doctor_checks filter — see the developer docs.

