Zoro APIzoro.com ↗
Search Zoro.com's industrial supply catalog via API. Returns product titles, prices, brand, ratings, and availability for up to 36 results per query.
What is the Zoro API?
The Zoro.com API exposes one endpoint — search_products — that queries the Zoro industrial supply catalog and returns up to 36 matching products per call, each with 9 response fields including price, brand, manufacturer part number, rating status, and discount data. It covers millions of SKUs across industrial, maintenance, and safety categories, making it practical for price monitoring, procurement tooling, and catalog aggregation.
curl -X GET 'https://api.parse.bot/scraper/2915cc70-1ba8-4286-88f9-ab5ed6cc8f84/search_products?query=drill' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace zoro-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: Zoro.com industrial supply search — bounded, re-runnable."""
from parse_apis.zoro_com_api import Zoro, InputFormatInvalid
client = Zoro()
# Search for products and iterate the first page (limit= caps total items)
for product in client.products.search(query="drill", limit=5):
print(product.title, product.brand, f"${product.price}")
# Scalar wrapper exposes search metadata the paginator discards
search = client.product_searches.search(query="safety glasses")
print(f"Total results: {search.total_results}, has more: {search.has_more}")
if search.corrected_query:
print(f"Corrected to: {search.corrected_query}")
# Drill into one result for full field access
product = client.products.search(query="safety glasses", limit=1).first()
if product is not None:
print(product.zoro_no, product.title, product.rating)
print("Category:", " > ".join(product.category_path))
print(f"Min order: {product.min_order_quantity}, lead time: {product.lead_time_days}d")
# Wildcard queries are rejected by the site
try:
client.products.search(query="drill*", limit=1).first()
except InputFormatInvalid:
print("Wildcard queries are not supported")
print("exercised: products.search / product_searches.search")
Searches Zoro.com for products matching a free-text query and returns the first page of results (up to 36 products, in the site's default relevance order). Each product carries its Zoro item number, title, brand, manufacturer number, price (USD, per price_unit), first product image, product page URL, minimum order quantity, package quantity, country of origin, lead time and category path. Some queries are redirected by the site to a category landing page (e.g. 'safety glasses'); in that case the category's listing is returned and redirected_category_code names the category, otherwise it is null. Ratings come from the site's review service in one extra round trip: rating and review_count are null for products with no reviews, and ratings_available is false when that service did not answer (all ratings null). total_results is the site's total match count; has_more is true when the site holds more than the first page. seller_name is always Zoro (single-seller store) and location is always null (the site does not expose a per-product location; country_of_origin is provided instead). Queries containing wildcard characters are rejected by the site and return a 422. A query with no matches returns an empty products list with total_results 0.
| Param | Type | Description |
|---|---|---|
| queryrequired | string | Free-text search term, e.g. a product type, brand or part number. |
{
"type": "object",
"fields": {
"query": "echo of the search term",
"has_more": "boolean, true when total_results exceeds the returned products",
"products": "array of product records: zoro_no, title, brand, mfr_no, price (number), original_price (number before discount or null), currency, price_unit, product_url, image_url, rating (number 0-5 or null), review_count (integer or null), seller_name, min_order_quantity (integer), package_qty, location (always null), country_of_origin (ISO-2), is_discontinued, lead_time_days, category_path (array of category names)",
"page_size": "integer, maximum products returned (36)",
"did_you_mean": "array of alternative query suggestions from the site",
"total_results": "integer, site's total number of matching products",
"corrected_query": "site's spelling correction applied to the search, or null",
"ratings_available": "boolean, false when the review service did not answer and every rating is null",
"redirected_category_code": "category code the site redirected this query to, or null when a plain search was served"
},
"sample": {
"data": {
"query": "safety glasses",
"has_more": true,
"products": [
{
"brand": "Mcr Safety",
"price": 1.39,
"title": "BearKat (BK1), Safety Glasses, Uncoated, Clear Lens, Non-Slip Temple, Frameless",
"mfr_no": "26G909",
"rating": 5,
"zoro_no": "G3600129",
"currency": "USD",
"location": null,
"image_url": "https://www.zoro.com/static/cms/product/full/Z-u5xtqcpEx_.JPG",
"price_unit": "EA",
"package_qty": 1,
"product_url": "https://www.zoro.com/mcr-safety-bearkat-bk1-safety-glasses-uncoated-clear-lens-non-slip-temple-frameless-26g909/i/G3600129/",
"seller_name": "Zoro",
"review_count": 7,
"category_path": [
"Safety",
"Personal Protective Equipment (PPE)",
"Safety Glasses"
],
"lead_time_days": 1,
"original_price": null,
"is_discontinued": false,
"country_of_origin": "TW",
"min_order_quantity": 12
}
],
"page_size": 36,
"did_you_mean": [],
"total_results": 3342,
"corrected_query": null,
"ratings_available": true,
"redirected_category_code": "6214"
},
"status": "success"
}
}About the Zoro API
What the API Returns
The search_products endpoint accepts a free-text query string — a product type, brand name, or part number — and returns a structured result set. Each product record includes zoro_no (Zoro's internal item identifier), title, brand, mfr_no (manufacturer part number), price in USD, original_price (the pre-discount price, or null when no discount applies), and currency. The response also surfaces total_results so you know the full catalog match count, and has_more (boolean) to indicate when the first page does not exhaust all matches.
Query Correction and Navigation Signals
The response includes two search-intelligence fields that mirror the site's own query handling: corrected_query returns the site's spelling correction if one was applied, or null for an unmodified query; did_you_mean is an array of alternative query suggestions. If the site resolved the query to a specific product category rather than a plain keyword search, redirected_category_code carries that category code — useful for detecting when a broad term maps to a single department.
Ratings and Coverage Notes
A ratings_available boolean signals whether the review service responded for that request. When it is false, every per-product rating field will be null, so dependent logic should check this flag before relying on review data. The endpoint returns up to 36 products per call (page_size: 36) in Zoro's default relevance order; there is no page or offset parameter, so the API covers only the first page of results for any given query.
The Zoro API is a managed, monitored endpoint for zoro.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when zoro.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official zoro.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Monitor list and sale prices for specific industrial part numbers using
priceandoriginal_pricefields. - Build a procurement comparison tool by querying multiple suppliers and matching on
mfr_no. - Populate an internal catalog with
title,brand, andzoro_nofor MRO inventory management. - Detect query spelling errors or category redirects via
corrected_queryandredirected_category_codein search UX tooling. - Track whether a product category has active discounts by comparing
pricevsoriginal_priceacross a batch of queries. - Validate brand and manufacturer part number coverage on Zoro before setting up supplier integrations using
brandandmfr_no.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Zoro.com have an official developer API?+
Can I retrieve results beyond the first page of search results?+
search_products endpoint returns only the first page of results — up to 36 products in Zoro's default relevance order. The has_more field tells you when additional results exist beyond that page, but pagination parameters are not currently supported. You can fork this API on Parse and revise it to add offset or page-based pagination.What does the `ratings_available` field tell me, and when will rating data be null?+
ratings_available boolean indicates whether Zoro's review service returned rating data for the request. When it is false, all per-product rating fields in the response will be null. You should check this flag before using rating values in any ranking or display logic.Can I look up a single product by its Zoro item number or get detailed product specs?+
query parameter; it does not expose a dedicated product-detail endpoint. Spec sheets, detailed descriptions, and dimension data are not returned. You can fork this API on Parse and revise it to add a product-detail endpoint using a zoro_no as input.