# /energystar/products/search

`POST /api/energystar/products/search`

Price: 20 credits

Search ENERGY STAR certified products within one certification category. Narrows by brand, model name and number, sub-type, certifying partner, UPC, the market a model is certified for, whether it meets the Most Efficient criteria, free text across the record, and exact or numeric bounds on any of the measured columns the category is certified on. Orders by any of those columns. Returns the full certification record for every match, with the measured performance figures under the programme's own column names.

## How to use it

One `product_category` per call — categories are separate datasets and their measured columns barely overlap, so `filters`, `min_values`, `max_values` and `sort` all take column names that only exist within the chosen one; call energystar/product_types first to read them. A column the category does not have is rejected rather than ignored, and `product_type` exists on only about half of them. Residential and commercial versions of the same appliance are different categories (residential_clothes_washers against commercial_clothes_washers), and heat pumps and central air conditioners share one very large category. Every value is text, so a numeric comparison has to go through `min_values` and `max_values` rather than `filters`. `market` matches a model certified for several markets, and almost the whole register is certified for the United States, so it separates usefully only for Canada and the smaller markets.

## Parameters

- `access-token` (string, required)

## Request body

- `timeout` (integer) — Max scrapping execution timeout (in seconds) (default: 300; min: 20; max: 1500)
- `product_category` (string, required) — Certification category to search. Each category is a separate dataset with its own measured columns, and a search never spans more than one (one of: "boilers", "ceiling_fans", "commercial_boilers", "commercial_clothes_washers", "commercial_coffee_brewers", "commercial_dishwashers", "commercial_electric_cooktops", "commercial_fryers", "commercial_griddles", "commercial_hot_food_holding_cabinet", "commercial_ice_machines", "commercial_ovens", "commercial_refrigerators_and_freezers", "commercial_steam_cookers", "commercial_water_heaters", "computers_v9_0", "data_center_storage_block_i_o", "data_center_storage_file_i_o", "dehumidifiers", "displays", "electric_vehicle_supply_equipment_ac_output", "electric_vehicle_supply_equipment_dc_output", "enterprise_servers", "furnaces", "geothermal_heat_pumps", "heat_pumps", "imaging_equipment", "laboratory_grade_refrigerators_and_freezers", "large_network_equipment", "light_commercial_hvac", "light_fixtures_downlights", "medical_imaging_equipment", "pool_pumps", "residential_clothes_dryers", "residential_clothes_washers", "residential_dishwashers", "residential_electric_cooking_products", "residential_freezers", "residential_refrigerators", "room_air_cleaners_v3_0", "room_air_conditioners", "smart_thermostats", "storm_windows", "telephones", "televisions", "uninterruptible_power_supplies", "vending_machines", "ventilating_fans", "water_coolers", "water_heaters"; examples: "residential_clothes_washers", "heat_pumps", "displays")
- `brand` (string, nullable) — Brand name, matched exactly (examples: "GE"; minLength: 1)
- `model_name` (string, nullable) — Model name, matched exactly (minLength: 1)
- `model_number` (string, nullable) — Model number, matched exactly (examples: "GTW490ACJ4WS"; minLength: 1)
- `product_type` (string, nullable) — Sub-type within the category, matched exactly. About half the categories record a sub-type at all; the rest reject this field. energystar/product_types shows which, under columns (examples: "Printers", "Vented Gas"; minLength: 1)
- `energy_star_partner` (string, nullable) — Certifying partner organisation, matched exactly (minLength: 1)
- `upc` (string, nullable) — UPC barcode, matched exactly (minLength: 1)
- `text` (string, nullable) — Free-text search across every column of the category (examples: "Beko"; minLength: 1)
- `market` (string, nullable) — Keep models certified for this market. A model is often certified for several (one of: "United States", "Canada", "Taiwan", "Japan", "Switzerland", "Europe", "Australia", "New Zealand")
- `most_efficient` (boolean, nullable) — Keep only models meeting the year's Most Efficient criteria, or only those that do not. Unset returns both
- `filters` (object, nullable) — Exact-match filters on any column of the category, keyed by the certification programme's own column name. energystar/product_types lists the columns each category publishes, and a column the category does not have is rejected (examples: {"connected":"Yes","load_configuration":"Front Load"})
  - `*` (string)
- `min_values` (object, nullable) — Lower bounds on numeric columns of the category (examples: {"volume_cubic_feet":5})
  - `*` (number)
- `max_values` (object, nullable) — Upper bounds on numeric columns of the category (examples: {"annual_energy_use_kwh_year":120})
  - `*` (number)
- `sort` (string, nullable) — Column of the category to order by. Unset orders by product id, which is what makes paging stable (examples: "annual_energy_use_kwh_year"; minLength: 1)
- `order` (string) — Direction for sort (default: "ASC"; one of: "ASC", "DESC")
- `count` (integer, required) — Max number of results to return (min: 1; max: 150000)

## Response

### 200 — Successful Response

- `@type` (string) (default: "EnergystarProduct")
- `id` (string, required)
- `product_category` (string, nullable)
- `product_type` (string, nullable)
- `dataset_id` (string, nullable)
- `dataset_name` (string, nullable)
- `brand` (string, nullable)
- `model_name` (string, nullable)
- `model_number` (string, nullable)
- `energy_star_model_identifier` (string, nullable)
- `energy_star_partner` (string, nullable)
- `additional_model_information` (string, nullable)
- `upc` (string, nullable)
- `markets` (array) (default: [])
- `is_most_efficient` (boolean, nullable)
- `available_on_market_date` (string, nullable)
- `qualified_date` (string, nullable)
- `certified_date` (string, nullable)
- `attributes` (object) (default: {})

## Errors

### 422 — Validation Error

A column name the chosen product_category does not have. energystar/product_types lists them.

What to do: Check the fields against this schema. A URN with the wrong prefix is the most common cause.

- `detail` (array)
  - `loc` (array, required)
  - `msg` (string, required)
  - `type` (string, required)
  - `input` (any)
  - `ctx` (object)

### 408

The request ran past its time limit

What to do: Raise `timeout` in the request body, up to the maximum this endpoint documents. Lowering `count` or turning off the `with_*` flags also helps, because less work finishes sooner.

### 412

Nothing in that category matched the filters.

What to do: Retrying will not help: either the entity does not exist, or the input points at a different one.

### 429

Too many requests: a rate limit or a usage window is exhausted

What to do: When the response carries an X-Retry-After header, wait that many seconds and retry: the same number is in the body as `detail.retry_after`, and the limit clears once that window passes. The message in the body names the limit that was hit.

### 500

Something broke on our side

What to do: Retrying will not help. If it keeps happening, send us the X-Request-ID from the response headers.

### 529

Rate limit reached, or the endpoint is overloaded

What to do: Wait at least 30 seconds, then retry.

## Response envelope

Success: Array of objects (may be empty if no results)

Error: Error may coexist with partial results if it occurs mid-execution. Check X-Error header and status code.

Every response carries these headers:

- `X-Error` — Error message text (present only on error)
- `X-Request-ID` — Unique request identifier
- `X-Execution-Time` — Execution time in seconds
- `X-Result-Count` — How many records the body carries. 0 means an empty result, which is a normal answer and not by itself an error. A non-zero count can come back together with X-Error when the failure happened partway through — read this header and X-Error independently.
- `X-Total-Available-Results` — How many records exist for this query, when the endpoint can say. On a `dry_run` request this is the answer and the body is empty. It saturates: the endpoint's documented maximum means 'at least that many', any smaller number is exact.
- `X-Warning` — Present when the request body carried keys this endpoint does not document. They were ignored, so any filter you meant to apply through them did not apply. Check the spelling against this schema and retry.
- `X-Retry-After` — Seconds to wait before retrying. Present only on 429.

