FedEx — Printing Press CLI
Prerequisites: Install the CLI
This skill drives the fedex-pp-cli binary. You must verify the CLI is installed before invoking any command from this skill. If it is missing, install it first:
- Install via the Printing Press installer. It defaults binaries to
$HOME/.local/binon macOS/Linux and%LOCALAPPDATA%\Programs\PrintingPress\binon Windows:npx -y @mvanhorn/printing-press-library install fedex --cli-only - Verify:
fedex-pp-cli --version - Ensure the reported install directory is on
$PATHfor the agent/runtime that will invoke this skill.
If the npx install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.6 or newer):
go install github.com/mvanhorn/printing-press-library/library/commerce/fedex/cmd/fedex-pp-cli@latest
If --version reports "command not found" after install, the runtime cannot see the binary directory on $PATH. Do not proceed with skill commands until verification succeeds.
When to Use This CLI
Use fedex-pp-cli when you run a small-to-medium shipping operation and want to programmatically interact with the FedEx REST API. Right fit for: e-commerce stores creating labels from order CSVs, customer-service teams generating return labels, ops teams tracking in-flight shipments, and SMB owners who want a local ledger of every shipment and rate quote for accounting. The local SQLite archive makes it the right tool for analytical queries over historical shipments. Choose this CLI over multi-carrier SaaS (ShipStation, Shippo) when you only need FedEx, want to own your data, and prefer terminal/agent automation over web UIs.
Unique Capabilities
These capabilities aren't available in any other tool for this API.
Save money, save time
rate shop— Quote rates across every applicable service type in parallel and rank by cost, transit days, or cost-per-day.When picking the cheapest viable service for a shipment, this collapses 6+ API calls into one ranked answer. The headline cost-saving command for SMB shippers.
fedex rate shop --from 90210 --to 10001 --weight 5lb --json --select rates.serviceType,rates.totalNetCharge,rates.transitTimeship bulk— Create labels for a CSV of orders with adaptive rate limiting, per-row PASS/FAIL accounting, and resume-from-last-success.The 'I ship 30 packages a day' workflow. Replaces clicking through FedEx Ship Manager one label at a time.
fedex ship bulk --csv orders.csv --service GROUND --output labels/ --resumereturn create— Generate a Ground Call Tag (return label) against an existing tracking number with one command, optionally emailing it to the recipient.E-commerce customer-service workflow. Issuing a return label is the most common post-sale interaction.
fedex return create --tracking 794633071234 --reason damaged --email customer@example.comaddress validate— SHA-256-keyed local cache prevents re-billing the FedEx Address Validation API for repeat lookups.Direct cost savings — the only feature with a quantifiable per-call $ impact.
fedex address validate --street '1600 Amphitheatre Pkwy' --city 'Mountain View' --state CA --zip 94043 --country US --cacheship etd— Single-command Electronic Trade Documents shipping: uploads commercial invoice, captures docId, and stitches it into the shipment create call.International shipments require ETD; this collapses an error-prone multi-step into one atomic action.
fedex ship etd --invoice invoice.pdf --orig CN --dest US --recipient-name 'Acme' --weight 2kg --service FEDEX_INTERNATIONAL_PRIORITY
Local state that compounds
address save— Save frequently-used recipients to a local address book; reference them by name in ship commands.Ergonomic parity with paid SaaS competitors. Eliminates retyping addresses for repeat customers.
fedex address save acme --street '500 Main St' --city Denver --state CO --zip 80202 --country UStrack diff— Show only the tracking events that have appeared since the last poll for each tracking number in the local store.Replaces tracking-poll dedupe glue agents would otherwise write.
fedex track diff --since 1h --jsontrack watch— Continuously poll a set of tracking numbers and emit new events to stdout, a webhook, or a file as they arrive. Polling alternative to FedEx push notifications.Most SMBs don't have provisioned push webhooks. Polling daemon is the universal alternative.
fedex track watch --tracking 794633071234 --interval 10m --webhook https://example.com/hookarchive— SQLite FTS5 search across every shipment in the local archive — recipient name, address, reference, tracking number, service.'Did we ship to ACME last week?' — a question SMBs ask constantly.
fedex archive 'warehouse 47' --service GROUND --jsonspend report— Sum of net charges per service type, lane, or account from the local rate-quote and shipment ledger.'How much did I spend on FedEx last month?' — the question every SMB owner asks.
fedex spend report --since 30d --by service --jsonexport— Dump shipments + charges + tracking events as CSV or JSON for QuickBooks/Xero reconciliation.Closes the loop on accounting reconciliation without manual data entry.
fedex export --format csv --since 30d --output fedex-april.csvmanifest— Generate a printable PDF/text summary of every shipment created today from the local archive, optionally invoking the Ground EOD close API.Closes the warehouse-day workflow loop in one command.
fedex manifest --date 2026-05-02 --close --output manifest.mdsql— Direct SQLite SELECT queries against shipments, rate_quotes, tracking_events, address_validations, addresses tables.Escape hatch for arbitrary analytics over the local ledger.
fedex sql "select serviceType, count(*) as n, sum(net_charge) as spend from shipments where created_at > date('now','-30 days') group by serviceType order by spend desc"
Setup smoothness
doctor— Verifies OAuth auth, sandbox/prod routing, account-number format, label-format compatibility, and surfaces BAG (Bar Code Analysis Group) approval status.Avoids the most common 'why won't my labels print' failure mode for first-time users.
fedex doctor
Command Reference
addresses — Address validation
fedex-pp-cli addresses— Validate one or more addresses (resolved/standardized form, classification, optional resolved coordinates)
availability — Service availability, special-service options, and transit times
fedex-pp-cli availability services— Get available services for an origin/destination pairfedex-pp-cli availability special_services— Get available special-service options (alcohol, dangerous goods, signature requirements, etc.)fedex-pp-cli availability transit_times— Get transit times for an origin/destination pair across services
consolidations — Consolidate multiple shipments into one fulfillment (advanced; for high-volume 3PLs)
fedex-pp-cli consolidations add_shipment— Add shipments to a consolidationfedex-pp-cli consolidations confirm— Confirm a consolidation (locks rates and triggers shipping)fedex-pp-cli consolidations confirm_results— Get results of a consolidation confirmationfedex-pp-cli consolidations create— Create a consolidationfedex-pp-cli consolidations delete— Delete a consolidationfedex-pp-cli consolidations delete_shipment— Remove a shipment from a consolidationfedex-pp-cli consolidations modify— Modify a consolidationfedex-pp-cli consolidations results— Get consolidation resultsfedex-pp-cli consolidations retrieve— Retrieve a consolidation
endofday — Submit and modify Ground end-of-day close (daily manifest)
fedex-pp-cli endofday close— Submit Ground end-of-day close (manifest packages shipped today)fedex-pp-cli endofday modify— Re-submit or modify a previous end-of-day close
freight_pickups — Schedule, check, and cancel freight (LTL) pickups
fedex-pp-cli freight_pickups availability— Check freight pickup availabilityfedex-pp-cli freight_pickups cancel— Cancel a freight pickupfedex-pp-cli freight_pickups create— Schedule a freight (LTL) pickup
freight_shipments — Create freight (LTL) shipments (for industrial shippers)
fedex-pp-cli freight_shipments— Create a freight (LTL) shipment
globaltrade — Global trade regulatory details (HS codes, restrictions)
fedex-pp-cli globaltrade— Get regulatory details (HS codes, harmonized system, country restrictions)
locations — Find FedEx Office, dropoff, and pickup locations
fedex-pp-cli locations— Find FedEx locations near an address or postal code
openship — Build multi-piece shipments progressively before confirming (advanced; not needed for typical SMB workflows)
fedex-pp-cli openship add_package— Add a package to an open shipmentfedex-pp-cli openship create— Create an open (uncommitted) multi-piece shipmentfedex-pp-cli openship delete— Delete an open shipmentfedex-pp-cli openship delete_package— Delete a package from an open shipmentfedex-pp-cli openship modify— Modify an open shipmentfedex-pp-cli openship modify_package— Modify a package in an open shipmentfedex-pp-cli openship results— Get results of a confirmed open shipmentfedex-pp-cli openship retrieve— Retrieve an open shipment by indexfedex-pp-cli openship retrieve_package— Retrieve a specific package from an open shipment
pickups — Schedule, check availability, and cancel Express/Ground pickups
fedex-pp-cli pickups availability— Check whether pickup is available for a postal code on a datefedex-pp-cli pickups cancel— Cancel a previously-scheduled Express/Ground pickupfedex-pp-cli pickups create— Schedule an Express or Ground pickup at a specified address
postal — Postal code validation and country servicing
fedex-pp-cli postal— Validate that FedEx services a postal code in a country
rates — Rate quotes for Express, Ground, Home, Ground Economy, and freight
fedex-pp-cli rates quote— Quote rates for a shipment (Express/Ground/Home/Ground Economy)fedex-pp-cli rates quote_freight— Quote rates for freight (LTL) shipments
shipments — Create, validate, cancel, and retrieve shipments
fedex-pp-cli shipments cancel— Cancel a shipment by tracking numberfedex-pp-cli shipments create— Create a shipment and generate label(s)fedex-pp-cli shipments results— Retrieve results of an asynchronous shipment jobfedex-pp-cli shipments tag— Create a Ground Call Tag (return label) for an existing shipmentfedex-pp-cli shipments tag_cancel— Cancel a Ground Call Tagfedex-pp-cli shipments validate— Validate a shipment package without creating a label (catches rejections before billing)
track — Track shipments by tracking number, reference, TCN, or associated shipment; retrieve documents and configure notifications
fedex-pp-cli track associated— Track shipments associated with a master tracking number (multi-piece)fedex-pp-cli track documents— Retrieve tracking documents (signature proof of delivery, etc.)fedex-pp-cli track notifications— Configure tracking notifications (email/SMS) for a shipmentfedex-pp-cli track number— Track up to 30 tracking numbers in one call (returns full event timeline per shipment)fedex-pp-cli track reference— Track by reference number (PO/customer ref/RMA)fedex-pp-cli track tcn— Track by Transportation Control Number (military/government use)
Hand-written commands
fedex-pp-cli auth login [--client-id <id>] [--client-secret <secret>] [--env sandbox|prod]— Mint an OAuth2 bearer token via client_credentials and cache it on diskfedex-pp-cli auth logout— Clear the cached bearer tokenfedex-pp-cli auth status— Show the cached token's expiry and which env vars were detectedfedex-pp-cli rate shop --from <zip> --to <zip> --weight <n>[lb|kg]— Quote rates across every applicable service type in parallel and rank by cost or transitfedex-pp-cli ship bulk --csv <path> --service <type> [--output <dir>] [--resume] [--concurrency N]— Create labels for a CSV of orders with adaptive rate limiting and resumable on partial failurefedex-pp-cli ship etd --invoice <pdf> --orig <country> --dest <country> ...— Single-command Electronic Trade Documents shipping (upload + reference + ship in one call)fedex-pp-cli address save <name> --street <s> --city <c> --state <s> --zip <z> --country <c>— Save a recipient to the local address bookfedex-pp-cli address list— List saved recipients in the local address bookfedex-pp-cli address delete <name>— Delete a saved recipient from the local address bookfedex-pp-cli track diff [--since <duration>] [--tracking <num>...]— Show only tracking events that have appeared since the last pollfedex-pp-cli track watch --tracking <num> [--interval <duration>] [--webhook <url>]— Long-poll daemon: continuously poll tracking and emit new eventsfedex-pp-cli return create --tracking <orig-tracking> [--reason <reason>] [--email <addr>]— Generate a return label (Ground Call Tag) for an existing shipmentfedex-pp-cli spend report [--since <duration>] [--by service|account|lane]— Sum net charges per service type from the local shipment ledgerfedex-pp-cli archive <query>— FTS5 search across shipments in the local archivefedex-pp-cli export [--format csv|json] [--since <duration>] [--output <file>]— Export shipment history for accounting reconciliationfedex-pp-cli manifest [--date YYYY-MM-DD] [--close] [--output <file>]— Generate end-of-day manifest report from local archive; optionally fire Ground EOD closefedex-pp-cli doctor— Verify auth, sandbox/prod routing, account-number format, label-format compatibility, BAG approval status
Finding the right command
When you know what you want to do but not which command does it, ask the CLI directly:
fedex-pp-cli which "<capability in your own words>"
which resolves a natural-language capability query to the best matching command from this CLI's curated feature index. Exit code 0 means at least one match; exit code 2 means no confident match — fall back to --help or use a narrower query.
Recipes
Rate-shop and select cheapest service
fedex rate shop --from 90210 --to 10001 --weight 5lb --json --select rates.serviceType,rates.totalNetCharge,rates.transitTime
Returns every applicable service type with cost and transit time so the agent (or human) picks the right balance.
Bulk ship with resume
fedex ship bulk --csv orders.csv --service GROUND --output labels/ --resume --concurrency 2
Creates labels for every row in orders.csv, respects the FedEx 1 req/s burst limit via cliutil.AdaptiveLimiter, and resumes from the last successful row if interrupted.
Save a recipient and ship to them
fedex address save acme --street '500 Main St' --city Denver --state CO --zip 80202 --country US
Address book lookup avoids retyping recipient details across every shipment.
Issue a return label
fedex return create --tracking 794633071234 --reason damaged --json
Generates a Ground Call Tag against the original tracking; PDF/ZPL label is emitted for the customer.
Monthly spend report by service
fedex spend report --since 30d --by service --json --select service,total_net_charge,shipment_count
Joins shipments + rate quotes from the local ledger; answers 'where did I spend money on FedEx this month'.
Auth Setup
FedEx uses OAuth2 client_credentials. Run fedex auth login once with your sandbox or production Client ID and Client Secret; the CLI mints a 1-hour bearer token, caches it on disk, and refreshes proactively before expiry. Production label printing requires per-project Bar Code Analysis Group (BAG) approval from FedEx — fedex doctor surfaces approval status before you hit it.
Run fedex-pp-cli doctor to verify setup.
Agent Mode
Add --agent to any command. Expands to: --json --compact --no-input --no-color --yes.
Pipeable — JSON on stdout, errors on stderr
Filterable —
--selectkeeps a subset of fields. Dotted paths descend into nested structures; arrays traverse element-wise. Critical for keeping context small on verbose APIs:fedex-pp-cli addresses --agent --select id,name,statusPreviewable —
--dry-runshows the request without sendingNon-interactive — never prompts, every input is a flag
Agent Feedback
When you (or the agent) notice something off about this CLI, record it:
fedex-pp-cli feedback "the --since flag is inclusive but docs say exclusive"
fedex-pp-cli feedback --stdin < notes.txt
fedex-pp-cli feedback list --json --limit 10
Entries are stored locally at ~/.fedex-pp-cli/feedback.jsonl. They are never POSTed unless FEDEX_FEEDBACK_ENDPOINT is set AND either --send is passed or FEDEX_FEEDBACK_AUTO_SEND=true. Default behavior is local-only.
Write what surprised you, not a bug report. Short, specific, one line: that is the part that compounds.
Output Delivery
Every command accepts --deliver <sink>. The output goes to the named sink in addition to (or instead of) stdout, so agents can route command results without hand-piping. Three sinks are supported:
| Sink | Effect |
|---|---|
stdout |
Default; write to stdout only |
file:<path> |
Atomically write output to <path> (tmp + rename) |
webhook:<url> |
POST the output body to the URL (application/json or application/x-ndjson when --compact) |
Unknown schemes are refused with a structured error naming the supported set. Webhook failures return non-zero and log the URL + HTTP status on stderr.
Named Profiles
A profile is a saved set of flag values, reused across invocations. Use it when a scheduled agent calls the same command every run with the same configuration - HeyGen's "Beacon" pattern.
fedex-pp-cli profile save briefing --json
fedex-pp-cli --profile briefing addresses
fedex-pp-cli profile list --json
fedex-pp-cli profile show briefing
fedex-pp-cli profile delete briefing --yes
Explicit flags always win over profile values; profile values win over defaults. agent-context lists all available profiles under available_profiles so introspecting agents discover them at runtime.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 2 | Usage error (wrong arguments) |
| 3 | Resource not found |
| 4 | Authentication required |
| 5 | API error (upstream issue) |
| 7 | Rate limited (wait and retry) |
| 10 | Config error |
Argument Parsing
Parse $ARGUMENTS:
- Empty,
help, or--help→ showfedex-pp-cli --helpoutput - Starts with
install→ ends withmcp→ MCP installation; otherwise → see Prerequisites above - Anything else → Direct Use (execute as CLI command with
--agent)
MCP Server Installation
- Install the MCP server:
go install github.com/mvanhorn/printing-press-library/library/commerce/fedex/cmd/fedex-pp-mcp@latest - Register with Claude Code:
claude mcp add fedex-pp-mcp -- fedex-pp-mcp - Verify:
claude mcp list
Direct Use
- Check if installed:
which fedex-pp-cliIf not found, offer to install (see Prerequisites at the top of this skill). - Match the user query to the best command from the Unique Capabilities and Command Reference above.
- Execute with the
--agentflag:fedex-pp-cli <command> [subcommand] [args] --agent - If ambiguous, drill into subcommand help:
fedex-pp-cli <command> --help.