Public catalogue API
The machine-readable interface to KEW’s published catalogue. Intended for agents and integrators; the same public data the KEW catalogue renders.
Read-only OpenAPI contract · Product sitemap · Agent discovery notes
You can search products and prepare a list for a quote without an account or a paid integration. This does not create a quotation or submit an enquiry. The customer completes the quote basket in their browser, or contacts KEW.
No authentication. No rate-limit headers are published yet — treat the service as politely rate-limited and do not poll aggressively.
Base URL: https://kew-erp-api-dxxg3763qa-ew.a.run.app
What is visible, and what is not
A product appears here only when KEW has explicitly published it. Publication is a deliberate staff decision recorded against the SKU; it is not inferred from stock levels, from legacy import flags, or from the product simply existing.
Consequences worth understanding before you build against this:
- Absence is not evidence KEW cannot supply the line. An unpublished SKU may still be stocked. Ask for a quote rather than concluding it is unavailable.
- The catalogue can be empty. It legitimately returns
total: 0when nothing has been published yet. That is not an outage.
The following are never returned by any public endpoint, by policy: cost, sell price, supplier identity, exact stock quantities, and warehouse bin locations.
GET /catalog/search
Search or browse published products.
Parameters
| Name | Type | Default | Notes |
|---|---|---|---|
q |
string, ≤ 120 chars | "" |
Free text. Empty browses everything published. Matches SKU, name, description, brand, manufacturer, MPN, GTIN and category. |
category_code |
string, ≤ 64 chars | — | Restrict to one category. Codes come from GET /catalog/categories. |
sort |
name | sku | code |
sku |
|
limit |
integer, 1–100 | 10 |
|
offset |
integer, ≥ 0 | 0 |
Response
{
"total": 0,
"limit": 10,
"offset": 0,
"items": []
}
total is the full count matching the query, not the page size — use it to
paginate with offset.
Each entry in items carries the public-safe field set. Search omits unset fields;
detail and category responses may return optional fields as null. Treat every
field except sku as optional and handle both missing and null values:
| Field | Notes |
|---|---|
sku |
KEW’s product code. Always present. Stable identifier. |
name, description |
Human-readable copy. |
brand, manufacturer, model, mpn, gtin |
Product identity for cross-referencing. |
image_url, datasheet_url |
May be absolute or site-relative. Resolve relative values against https://kew.ie/, not the API server. |
category, category_code |
Human-readable name and the code for filtering. |
technical_description, bullet_features, layperson_description |
|
stock_status |
in_stock | low_stock | order_in. See below. |
model is an optional field in the response schema but is not currently selectable
through the standard publication workflow. Do not rely on it being populated;
use a verified mpn and the published description when identifying a product.
Stock bands
Availability is a band, never a count:
| Value | Meaning |
|---|---|
in_stock |
More than 5 units on hand |
low_stock |
1–5 units on hand |
order_in |
None on hand; KEW orders it in |
The band reflects the last stocktake for that line, not a real-time reservation. It is not a guarantee of allocation — confirm on a quote.
Examples
Search for a product (read-only):
curl --get 'https://kew-erp-api-dxxg3763qa-ew.a.run.app/catalog/search' \
--data-urlencode 'q=LED high bay' \
--data-urlencode 'limit=10'
Look up a specific SKU:
curl --get 'https://kew-erp-api-dxxg3763qa-ew.a.run.app/catalog/product' \
--data-urlencode 'sku=UFO200W'
Build customer-facing links and resolve media safely:
const productPage = new URL('/p', 'https://kew.ie');
productPage.searchParams.set('sku', product.sku);
const imageUrl = product.image_url
? new URL(product.image_url, 'https://kew.ie/').href
: undefined;
Keep the SKU exactly as returned, including punctuation and slashes. Do not construct a different SKU from the manufacturer part number. Check the product description and ask KEW about pack sizes or ordering units if they are unclear.
GET /catalog/categories
Published categories with product counts. Only categories containing at least one published product appear.
{ "total": 0, "items": [] }
Each item has code, name and product_count. Use code with the
category_code parameter on search.
GET /catalog/p/{sku} and GET /catalog/product?sku=...
Detail for a single published SKU. Returns the same public-safe field set as a search result.
Use the query-parameter form for SKUs containing / — several KEW codes do
(for example PFE/10/100), and percent-encoding them into the path is fragile
across clients.
Returns 404 when the SKU is unknown or not published. The two are
deliberately indistinguishable: whether an unpublished SKU exists is not public
information.
GET /catalog/c/{category_code}
Published products in one category. Supports limit and offset with the same
bounds as search.
POST /catalog/quote-requests
This is the existing browser quote-basket submission endpoint. It requires Cloudflare Turnstile verification and is not an unattended agent tool. Publishing these documents does not remove that requirement or grant write access.
An agent should prepare a list containing the exact SKU, product link, requested quantity and any customer notes, then hand it to the customer. The customer can open the catalogue, add the products to their quote basket and submit it, or contact KEW. Opening a product link does not automatically add the item to a basket or submit it.
The browser endpoint validates published SKUs, records the enquiry and attempts
to send an acknowledgement email. Its response distinguishes email_status: "sent" from "failed". A saved request with a failed email is still saved: do
not blindly resubmit and create duplicates. The customer should retain the
request reference and contact KEW if confirmation is unclear.
Every quote request is reviewed by a person before a price is issued. Expect a human-in-the-loop reply, not an instant automated price.
Errors
| Status | Meaning |
|---|---|
404 |
Unknown or unpublished SKU/category — or the public catalogue is disabled. |
422 |
Invalid parameters, or a quote request naming a SKU that is not published. |
429 |
Request frequency exceeded a service limit. Honour Retry-After when present and back off. |
5xx |
Temporary service failure. Retry reads with bounded backoff; never treat an error as an empty catalogue. |
The catalogue sits behind a feature flag and is fail-closed: when disabled,
catalogue routes return 404. If all reads return 404, the catalogue may be
disabled; check the base URL and contact KEW rather than concluding every
product is unavailable.
Guidance for agents
- Do not infer a price from any field. There is none, by design.
- Prefer this API over scraping HTML. It is stable and returns the same data the pages render.
- Do not treat absence as unavailability — see the visibility note above.
- Paginate with
totalandoffset. Do not assumelimitbounds the result set; it bounds the page. - Use
sort=skufor a full crawl. Request at most 100 items per page, deduplicate by SKU and advance the offset by the page size. The catalogue can change during pagination; refresh later if the total changes. Stop and investigate repeated empty pages before reaching the reported total. - Be a considerate crawler. Fetch sequentially, cache successful reads and use bounded retries with backoff. Do not repeatedly crawl the entire catalogue for a single customer enquiry.
- Separate facts from suggestions. Do not invent specifications, compatibility, certifications, pack units, delivery promises or prices when fields are missing.
- Keep the customer in control. Ask them to confirm the item list and quantities. A prepared list is not a submitted enquiry, a priced quote, an order or a stock reservation.
- Protect contact details. Do not place names, email addresses, phone numbers or account details in public URLs or search queries.