TL;DR: To configure WooCommerce shipping from the command line, use the 1TeamSoftware plugins, which expose their full config and fulfillment surface through WP-CLI: run wp wc-shippo-shipping settings set to write origin, credentials, and services, wp wc-shippo-shipping validate to gate a deploy, and wp wc-shippo-shipping rates quote to prove a live rate comes back. The same commands ship as a Claude Code skill, so an AI agent can run them too.
This is the terminal how-to; every command is real and uses the Shippo namespace. It assumes you're comfortable with WP-CLI and know your way around WooCommerce shipping zones and methods. You don't need prior carrier-API knowledge.
Run more than one WooCommerce store and you've met the problem already: shipping setup doesn't survive scale.
You configure zones, boxes, and carrier credentials by clicking through wp-admin. It works. Then you do it again on staging, then again for the next client, each pass a little different because a settings screen won't let you repeat yourself exactly. The failure mode is the bad part. A customer hits checkout, sees no shipping options at checkout, and leaves. Nothing in the logs says why. You find out from a support email three days later.
I wanted shipping to behave like the rest of my infrastructure: text I can diff, commit, replay across environments, and gate in CI. That's what the 1TeamSoftware shipping plugins give you. It all runs through WP-CLI, and the same commands are wrapped in a Claude Code skill so an agent can drive them.
This is the developer tour. Every command below is real, copy-pasteable, and uses the Shippo namespace (wc-shippo-shipping). Swap the namespace for your carrier and the rest holds. For the complete reference with every flag and output shape, see the full pillar: configuring WooCommerce shipping with AI and WP-CLI.
Prefer to watch first? Here's the whole setup running end to end from the terminal, then handed to an AI agent. Every command below is in the video.
One prerequisite, said plainly
A lot of "official" carrier integrations import orders and print labels but never quote a price at checkout. If your current tool can't return a rate to the cart, no CLI command will make one appear there.
The plugins here quote woocommerce live shipping rates at cart and checkout, validate addresses, pack boxes, buy labels, and pull tracking. All of it is scriptable. The rest of this assumes you've got that.
The command shape
Everything follows one pattern:
wp <namespace> <command> [<subcommand>] [--flags]
The namespace is the plugin slug with -pro dropped, so Shippo is wc-shippo-shipping for both the free and PRO editions. Not sure what yours is?
wp help | grep shipping
wc-shippo-shipping Manage Shippo shipping configuration and fulfillment.
One thing the command list won't hand you: the exact setting keys. Credential fields, service IDs, and box types differ per carrier, so discover them instead of guessing.
wp wc-shippo-shipping settings list
+----------------------+---------------------+
| key | value |
+----------------------+---------------------+
| testApiToken | [REDACTED] |
| liveApiToken | [REDACTED] |
| sandbox | yes |
| priceAdjustmentPercent | 1.00 |
| maxShippingRates | 0 |
+----------------------+---------------------+
settings list is your map. It prints every stored setting with secrets shown as [REDACTED], which is also how you find a carrier's credential keys before you write them. Shippo uses testApiToken and liveApiToken; other carriers name theirs differently. Read first, write second.
Start with status and validate
Before touching anything, check what the plugin actually sees.
wp wc-shippo-shipping status --format=json
wp wc-shippo-shipping validate
wp wc-shippo-shipping zones
status --format=json returns something like:
{
"version": "2.4.10",
"carrier": "Shippo",
"sandbox": true,
"debug": false,
"live_rates": true,
"origin": "San Francisco, CA, US",
"method_instances": 2
}
status reports version, carrier, sandbox and debug flags, live-rate state, origin, and method-instance count. Watch what it doesn't report: API connectivity. There's no "connected: true" field, because the only honest connectivity test is asking the carrier for a real quote.
validate is the one to put in your pipeline. It runs every config check and reports PASS, FAIL, WARN, INFO, or PENDING, and it exits non-zero on any FAIL:
PASS Origin address is complete
PASS API token is set
WARN No box presets configured; falling back to per-item packing
FAIL Plugin not attached to zone "Rest of World"
That non-zero exit is what makes it a clean deploy gate:
wp wc-shippo-shipping validate --format=json 2>/dev/null \
| jq -e 'all(.[]; .status != "FAIL")' >/dev/null \
|| { echo "Shipping config has failures"; wp wc-shippo-shipping validate; exit 1; }
WARN doesn't break the build; only FAIL does. Drop this in your release script and a broken shipping config stops a deploy before customers ever see it.
zones shows which WooCommerce shipping zones the plugin is attached to, with plugin_active, instance_id, and method_id per zone:
+---------+-----------------+---------------+-------------+
| zone_id | zone_name | plugin_active | instance_id |
+---------+-----------------+---------------+-------------+
| 1 | US Domestic | yes | 4 |
| 2 | Rest of World | no | - |
+---------+-----------------+---------------+-------------+
Remember this one. It's behind most "no rates" tickets: zone 2 above quotes nothing because the method was never added.
Reading and writing settings
Anything stored is readable and writable from the CLI, credentials and origin included.
wp wc-shippo-shipping settings get origin
wp wc-shippo-shipping settings set origin '{"name":"Co","address":"123 Main St","city":"SF","state":"CA","postcode":"94105","country":"US"}'
Associative settings flatten with bracket notation (origin[city], services[usps_priority][enabled]). Read a single value with settings get <key>, add --raw to reveal a secret, write with settings set <key> <value>, and target one zone with --instance=<id>. Your origin address now lives in a provisioning script instead of someone's memory.
Proving rates actually come back
This is the test that matters. A green validate tells you the config is internally consistent. A real quote tells you the carrier is reachable and the route is actually served.
wp wc-shippo-shipping rates quote --products="9405:2" --destination="500 5th Ave, New York, NY 10001, US"
wp wc-shippo-shipping rates get --order=12345
After the human log line, the JSON array looks like:
[
{ "service": "USPS Ground Advantage", "amount": "8.45", "currency": "USD", "days": 3 },
{ "service": "USPS Priority Mail", "amount": "11.20", "currency": "USD", "days": 2 }
]
rates quote asks the carrier for a live quote on an ad-hoc product and destination. It needs at minimum a ZIP or postcode plus a country; a full street address sharpens accuracy. One scripting gotcha: it prints a human log line before the JSON, so when you parse it, extract the array from the first [ to the matching ] rather than leaning on 2>/dev/null. rates get does the same for an existing order by ID.
If a complete product on a covered route returns nothing, that tells you something real: either a connectivity failure or a route the carrier doesn't serve. Either way you now know, instead of guessing from a blank checkout.
How do I fix "no shipping options at checkout"?
When a store shows no rates for some customers but not others, it's almost always one of two things: a zone the plugin isn't attached to, or products with no weight. Here's the workflow I reach for.
The zone case is sneaky because rates work for you and not for the buyer in another region. The plugin only returns rates on zones where it's attached as a shipping method, so a missing zone is a silent dead end. You won't see it from your own checkout.
wp wc-shippo-shipping zones
wp wc shipping_zone_method create --zone_id=2 --method_id=wc-shippo-shipping --user=1
zones shows each zone's plugin_active. Where it reads plugin_active: no, add the method. In zone-based mode, being absent from a zone means no rates there; in global mode it's fine.
The product-data case is the other half. Rates drop silently when an item has no weight, because the carrier can't quote a parcel that has no size.
wp wc-shippo-shipping products audit --detailed --format=json --limit=0
{
"total_products": 412,
"completeness_percent": 87,
"missing_weight_products": [1842, 1907],
"missing_dimensions_products": [1842, 1907, 2003],
"suspicious_data_products": [1559]
}
products audit gives a completeness percentage and flags missing weight, missing dimensions, and suspicious values. The per-product arrays (missing_weight_products, missing_dimensions_products, suspicious_data_products) only appear with --format=json. Pass --limit=0 so a big catalog isn't capped at 500. Fix the flagged products with wp wc product update, re-quote, and the rates come back.
Sizing boxes to what you actually ship
Rates look high for a boring reason more often than you'd think: parcels get quoted in oversized boxes nobody matched to the catalog.
wp wc-shippo-shipping products stats --format=json
wp wc-shippo-shipping products orders --since=2025-12-01 --format=json
wp wc-shippo-shipping products fit-box --length=12 --width=8 --height=6
products stats returns weight and dimension stats plus a size distribution. products orders analyzes completed and processing orders: items per order, top destination states, domestic versus international. products fit-box takes box dimensions (all three required) and reports what percentage of your catalog fits, rotation handled automatically. Together they tell you whether a candidate box set covers what leaves your warehouse before you commit it.
Tuning rates: markup, floors, and which services show
Same complaint, three flavors: undercharging, too many options at checkout, or a $1.50 Media Mail rate leaking through. All of these adjustment fields live in the free plugin.
wp wc-shippo-shipping settings set priceAdjustmentPercent 1.15
wp wc-shippo-shipping settings set priceAdjustment 2.00
wp wc-shippo-shipping settings set minRateCost 5.00
wp wc-shippo-shipping settings set maxShippingRates 3
wp wc-shippo-shipping services --format=json
wp wc-shippo-shipping settings set services '{"usps_ground_advantage":{"enabled":true,"name":"USPS Ground Advantage"}}'
Watch priceAdjustmentPercent. It's a multiplier, so 1.15 adds 15%. Set it to 15 and you multiply every rate fifteenfold, which makes for a funny bug report after the fact. Adjustments apply in order: carrier rate, then percent, then fixed, then floor and ceiling, then the max-count cap. To control which services quote at all, discover real IDs with services first and write them with settings set services. Never invent service IDs.
The PRO half: labels, tracking, manifests
Once a license is active, fulfillment is on the CLI too, and it behaves the same whether a person, an agent, or a cron job runs it.
wp wc-shippo-shipping labels purchase --orders=1240,1241,1242
wp wc-shippo-shipping labels pdf --orders=1240,1241,1242 --output=/var/labels/2026-06-11.pdf
wp wc-shippo-shipping track abc123 --order=1240 --format=json
wp wc-shippo-shipping manifest create --shipments=abc123,def456 --ship-date=2026-06-11
wp wc-shippo-shipping license activate YOUR-KEY
labels purchase buys a batch and auto-creates shipments if they're missing, but it logs label counts, not tracking numbers, so pull those from track or shipments get. labels pdf merges many orders into one print-ready file and errors if the target already exists, so dated filenames are the safe move. manifest create builds a carrier SCAN form from shipment IDs. And license activate takes the key as a positional argument, not --key=.
So a nightly fulfillment run is a five-line script: collect the day's processing order IDs, buy labels in one batch, merge to a dated PDF for the print station.
Handing it to Claude Code
The commands above are stable enough to script directly. There's a second mode too: install a skill and let an AI agent drive the same CLI from plain language.
npx skills add https://github.com/1TeamSoftware/skills --skill 1teamsoftware-wc-shipping
Under the hood the skill is a small library of playbooks. Ask it to fix box coverage and it reaches for the box-sizing routine instead of guessing at flags. It runs the exact same WP-CLI a human would, and it pauses to ask for secrets rather than inventing them. No hidden API layer, no magic. The free plugin ships 6 skills; PRO adds 4.
In practice you describe the job with real constraints and let it work one step at a time:
"Customers in some regions say no shipping options appear. Make the plugin active for both my US domestic zone and Rest of World, then show me the zone coverage table so I can confirm it's attached where it needs to be."
"Set up Shippo from scratch. Sandbox key is
shippo_test_abc123, we ship from 215 Clayton St, San Francisco 94117. Audit my catalog for missing weight or dimensions, recommend a starter box set from what I actually sell, and prove rates come back with a real quote. Ask one question at a time and don't touch my live key yet."
The security model helps anyone managing a fleet: hand the agent a sandbox key during setup, rotate to the live key yourself, and it never needs to see the real one. Secrets stay redacted in CLI output, and you can store credentials in wp-config.php constants so they never touch the database at all.
Which carriers does this work with?
The same engine, settings model, and command set run across eight carrier plugins: Shippo, EasyPost, FedEx, ShipStation, ShipEngine, Shipmondo, ChitChats, and Stallion Express. Only the namespace and a few setting keys change. Run wp help | grep shipping to find the namespace, then settings list to discover the keys.
One catch worth knowing: the current ShipStation plugin runs on the carrier's API v2, so its namespace is wc-shipstation-shipping-v2, not the legacy wc-shipstation-shipping. When in doubt, trust what wp help prints.
Trade-offs: what this doesn't do
The CLI isn't free of edges, so here they are:
- Free vs PRO is gated. Configuration, diagnostics, and live rate quotes work in the free plugin. Labels, tracking, and manifests need an active PRO license, and those commands fail without one.
- An agent can't invent secrets. Hand Claude Code a store with no API token and it stops to ask. By design it never fabricates a credential or a service ID, so first-run setup still needs you in the loop for keys.
- There's a CLI learning curve. If you've never touched WP-CLI, the first hour is slower than clicking through wp-admin. The payoff shows up on store two, not store one.
-
No connectivity check shortcut.
validateconfirms the config is internally consistent, not that the carrier is reachable. The only real proof is arates quote, which costs an API round-trip. -
priceAdjustmentPercentis a multiplier, not a percent field.1.15means +15%. Pass15and you've multiplied every rate fifteenfold. Easy to fat-finger.
Why bother, if a settings screen works?
For one store you set up once, it doesn't. The UI is fine.
The CLI earns its keep the moment shipping becomes something you operate: multiple stores, staging-to-production parity, agency work that repeats per client, audits you can re-run on demand, a deploy gate that blocks releases on a broken config, and increasingly a workflow you can hand to an agent. That's the same engine already running on thousands of WooCommerce stores, so this is a well-worn path, not an experiment.
Try it
The free Shippo plugin covers configuration and live rate quotes; PRO adds labels, tracking, and manifests. Install the skill, point Claude Code at a staging store, and run a validate plus a rates quote to watch the whole loop work:
npx skills add https://github.com/1TeamSoftware/skills --skill 1teamsoftware-wc-shipping
If you've ever debugged a blank checkout at 11pm, shipping you can diff and replay is worth the ten minutes it takes to set up. The full command reference and AI-agent walkthrough live in the WooCommerce shipping WP-CLI and AI pillar.
Further reading
- Configuring WooCommerce shipping with AI and WP-CLI: the full command reference with every flag and output shape
- 1TeamSoftware agent skills repo: read the playbooks before you install one
- Free Shippo plugin on the product page: configuration plus live rate quotes at no cost
-
WP-CLI handbook: if the
wpcommand itself is new to you - WooCommerce shipping zones documentation: the zone model these commands attach to
Top comments (0)