# /azure/prices/search

`POST /api/azure/prices/search`

Price: 10 credits

Search the Azure retail price catalogue. Every row is one meter priced in one region, carrying the retail and unit price, the billing unit, the tier the price starts at, whether it is a pay-as-you-go, dev/test or reservation rate, the reservation term where there is one, the date the price takes effect, and the service, product, SKU and meter it belongs to. Narrows by service, service family, region, ARM SKU name whole or by prefix, SKU name whole or by suffix, meter id, meter name whole or by substring, product name whole, product, SKU and service ids, rate kind, reservation term, billing unit and primary-region rows, and converts the prices to any of the currencies Microsoft publishes rates in.

## How to use it

Spot and low-priority machines are not a rate kind — they are separate meters, so reach them through `sku_name_ends_with` set to `Spot` rather than through `price_type`. One meter is priced in many regions and in several rate kinds at once, so without `region` and `price_type` the same machine comes back many times; `meter_id` alone does not identify a row either. `effective_from` can be a future date, because announced price changes are published ahead of time and the superseded row stays in the catalogue — pick by date yourself rather than taking the first row. At least one filter is required.

## Parameters

- `access-token` (string, required)

## Request body

- `timeout` (integer) — Max scrapping execution timeout (in seconds) (default: 300; min: 20; max: 1500)
- `service_name` (string, nullable) — Keep only meters of this Azure service, matched exactly (examples: "Virtual Machines", "Storage", "Azure Kubernetes Service"; minLength: 1)
- `service_family` (string, nullable) — Keep only meters in this service family (one of: "AI + Machine Learning", "Analytics", "Azure Communication Services", "Azure Stack", "Blockchain", "Compute", "Containers", "Data", "Databases", "Developer Tools", "Gaming", "Integration", "Internet of Things", "Management and Governance", "Microsoft Syntex", "Networking", "Other", "Quantum Computing", "Security", "Storage", "Web")
- `service_id` (string, nullable) — Keep only meters of the service with this id (examples: "DZH313Z7MMC8"; minLength: 1)
- `region` (string, nullable) — Keep only meters priced for this region, given as the ARM region name (examples: "eastus", "westeurope", "japaneast"; minLength: 1)
- `location` (string, nullable) — Keep only meters priced for this location, given as the display name (examples: "US East", "EU West"; minLength: 1)
- `arm_sku_name` (string, nullable) — Keep only meters for this ARM SKU, matched exactly (examples: "Standard_D2s_v5", "Standard_B2s"; minLength: 1)
- `arm_sku_name_starts_with` (string, nullable) — Keep only meters whose ARM SKU name begins with this text (examples: "Standard_D2s", "Standard_E"; minLength: 1)
- `sku_name` (string, nullable) — Keep only meters with this SKU name, matched exactly (examples: "Standard_D2s_v5 Spot", "Hot LRS"; minLength: 1)
- `sku_name_ends_with` (string, nullable) — Keep only meters whose SKU name ends with this text (examples: "Spot", "Low Priority"; minLength: 1)
- `meter_id` (string, nullable) — Keep only rows of this meter (examples: "2e1c40e1-df96-5494-80f5-52d91a411a5d"; minLength: 1)
- `meter_name` (string, nullable) — Keep only meters with this name, matched exactly (examples: "D2 v3", "LRS Data Stored"; minLength: 1)
- `meter_name_contains` (string, nullable) — Keep only meters whose name contains this text (examples: "D2s v5", "Data Stored"; minLength: 1)
- `product_id` (string, nullable) — Keep only meters of the product with this id (examples: "DZH318Z08M9T"; minLength: 1)
- `product_name` (string, nullable) — Keep only meters of this product, matched exactly (examples: "Virtual Machines Dv3 Series"; minLength: 1)
- `sku_id` (string, nullable) — Keep only rows of the SKU with this id (examples: "DZH318Z08M9T/00K0"; minLength: 1)
- `price_type` (string, nullable) — Keep only pay-as-you-go, dev/test or reservation rates. Unset returns all three, so one meter comes back several times (one of: "Consumption", "DevTestConsumption", "Reservation")
- `reservation_term` (string, nullable) — Keep only reservation rates on a commitment of this length (one of: "1 Year", "3 Years")
- `unit_of_measure` (string, nullable) — Keep only meters billed in this unit, matched exactly (examples: "1 Hour", "1 GB/Month"; minLength: 1)
- `primary_meter_region_only` (boolean, nullable) — True keeps only rows whose region is the meter's primary one. Unset returns primary and secondary rows together
- `currency` (string) — Currency the prices are converted to before they are returned (default: "USD"; one of: "AED", "ARS", "AUD", "BRL", "CAD", "CHF", "CNY", "CZK", "DKK", "EUR", "GBP", "HKD", "HUF", "IDR", "ILS", "INR", "JPY", "KRW", "MXN", "MYR", "NOK", "NZD", "PLN", "RUB", "SAR", "SEK", "SGD", "THB", "TRY", "TWD", "USD", "ZAR")
- `count` (integer, required) — Max number of results to return (min: 1; max: 50000)

## Response

### 200 — Successful Response

- `@type` (string) (default: "AzurePrice")
- `id` (string, required)
- `meter_id` (string, nullable)
- `meter_name` (string, nullable)
- `sku_id` (string, nullable)
- `sku_name` (string, nullable)
- `arm_sku_name` (string, nullable)
- `product_id` (string, nullable)
- `product_name` (string, nullable)
- `service_id` (string, nullable)
- `service_name` (string, nullable)
- `service_family` (string, nullable)
- `region` (string, nullable)
- `location` (string, nullable)
- `is_primary_meter_region` (boolean, nullable)
- `price_type` (string, nullable)
- `reservation_term` (string, nullable)
- `retail_price` (number, nullable)
- `unit_price` (number, nullable)
- `currency` (string, nullable)
- `unit_of_measure` (string, nullable)
- `tier_minimum_units` (number, nullable)
- `effective_from` (string, nullable)

## Errors

### 422 — Validation Error

Azure rejected the filter, or no filter was given.

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

No published meter 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.

