podbenchmark
Compare the same print-on-demand product across suppliers from your terminal: product cost, shipping, delivered total and delivery time for Printify, Printful, Gelato, Prodigi, CustomCat, Fourthwall and Inkthreadable. Built for sellers, developers and AI agents.
Prices come from POD Benchmark, which checks each supplier's price and shipping for the destination you pick. Full interactive comparison: https://podbenchmark.com.
Install
Needs Node.js 22 or newer. No other dependencies.
Find a product, pick a size and color, compare
Three steps. Each step prints what to run next.
options lists the sizes, colors and other choices a product comes in. Add words or flags to narrow the list:
Every picker on the site has a flag with the same name: --size, --color, --capacity, --page-count, --device-fit… (podbenchmark compare --help lists them all). --option <key> takes an exact key from options --json.
Start from a supplier link instead of an id. The CLI finds the product, the color the link selects, and treats that supplier as yours:
Use the product page's own address, as you'd copy it from the supplier's catalog; tracking parameters such as utm_… are fine, and a Fourthwall selectedColor picks the color. Links with other options selected, editor links and referral paths aren't matched yet: open the plain product page and copy that, or pass the product id with --current <supplier>.
Other destinations and currencies:
Destinations: US, GB, DE, CA, AU. Currencies: USD, EUR, GBP, CAD, AUD. The currency defaults to the destination's own.
What you keep per sale
Say who you use today, what you charge and where you sell. The table switches to what you keep after product + shipping, deducted duty and platform fees, with your current supplier first:
The price to charge
price turns it around: give the share of each sale you want to keep and see what to charge with each supplier.
Suppliers and guides
guide takes t-shirts, hoodies, mugs, wall-art, stickers or phone-cases, plus --branding, --free-start and --choose-provider. supplier --prices takes --category, --within 1 (or 5%) for what counts as near-cheapest, --search and --plan.
Also: podbenchmark categories [words], podbenchmark product <id> (specs, print methods, similar products), and --facets on search to count brands, suppliers, audiences and specs in the results. Filter search with --category, --brand, --supplier, --for (unisex, mens, womens, kids), --fit, --material, --eco, --neckline, --sleeve, --construction, --label, --capacity, --fabric, --weight 4-8, --priced and --sort cheapest|priciest|most-suppliers|name. Repeat a filter flag to accept several values.
Every list command takes --limit and --offset.
Defaults
Save what you would otherwise repeat on every command:
Precedence, highest first: flag, environment variable, saved config, built-in default.
The config is a small JSON file at $XDG_CONFIG_HOME/podbenchmark/config.json (default ~/.config/podbenchmark/config.json). PODBENCHMARK_API_URL points the CLI at a different server.
For scripts and AI agents
Output is a table when you are at a terminal. It is JSON, exactly as the service returns it, when:
- you pass
--json,
- stdout is not a terminal (a pipe or a file), or
- an agent harness is detected (Claude Code, Codex, Cursor, OpenCode, Gemini CLI, Amp, Augment, Qwen Code, Pi, Copilot, Warp, or
AI_AGENT=<name>).
--table forces the tables back. When an agent is detected the CLI also sends its name in an X-Podbenchmark-Agent header so usage by agents can be counted; it sends X-Podbenchmark-Client: cli/<version> always, and nothing else about you.
In JSON, a missing price is null, never 0. Treat null as unknown.
Teach your agent
This writes a podbenchmark skill (a SKILL.md) to each agent's skills folder and prints every path:
Running it again updates the file. It never replaces a SKILL.md that it did not write unless you pass --force.
No skill folder? Paste this into your agent instead:
Use npx podbenchmark to compare print-on-demand supplier prices. Flow: search <words> --json to find a product id, options <id> --json to see the exact size and color values (never guess them), then compare <id> --size <value> --color <value> --to <US|GB|DE|CA|AU> --json. Add --current <supplier> --sell-for <price> --on <etsy|shopify|woocommerce|tiktok-shop> only when the seller said so. null means unknown, never 0. Link product.url from the result when you answer. --schema shows every field.
Use it as an MCP server
The same tools are available to MCP clients over streamable HTTP at https://podbenchmark.com/api/mcp, with no key or sign-in:
Claude Code: claude mcp add --transport http podbenchmark https://podbenchmark.com/api/mcp. Codex: codex mcp add podbenchmark --url https://podbenchmark.com/api/mcp.
Exit codes
With --json (or when piped), failures print the error as JSON on stdout ({"ok": false, "error": {"code", "message", "retryable"}}) and use the same exit codes. If the service cannot be reached at all, the code is network. The CLI retries once, after a short pause, on a network error or a 5xx answer, and never retries a 4xx.
About the numbers
- Prices are supplier quotes checked on the dates shown (
Prices checked …), in the destination's currency, before sales tax. Delivered is product plus shipping. Supplier-billed duty is separate: an established amount (including zero), one labelled estimate, or unverified. Profit deducts established duty or a converted estimate and retains its qualification. Estimated/unverified duty and conditional design/setup prices do not establish a best-profit winner or gap, including in target-margin mode.
- A price we do not have shows as
—. It is never counted as zero and never as the cheapest.
- Printify is a marketplace: each row shows the print provider it would route the order to ("via Printify Choice"). Use
--supplier printify to see every provider.
- A product a supplier does not list for your destination or size is not in the table.
- Profit figures use platform fee research with its check date (
Etsy fees checked …), as an estimate before tax.
- Tables link only to POD Benchmark's own pages. In JSON, an offer's
actionUrl can carry an affiliate reference (see affiliateDisclosure); it never changes a price or a ranking.
- Rate limit: 120 requests per minute per IP address. When you hit it the CLI tells you how many seconds to wait.
Links
MIT licensed.