> ## Documentation Index
> Fetch the complete documentation index at: https://api.nektir.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Exact lookups and inventory matrices

> Resolve one or many products or stores and retrieve bounded product-store inventory without N+1 requests.

Use the collection endpoints for both single and bulk exact lookup. This keeps one response shape as an application grows from one identifier to several.

## Resolve products

Supply either Utah DABS SKUs or Nektir product IDs. Each selector accepts up to 25 unique values, and identifiers remain strings so leading zeroes survive.

```bash theme={"dark"}
curl "$NEKTIR_API_BASE/v1/products?skus=061213,017956&sort=sku&limit=25"
curl "$NEKTIR_API_BASE/v1/products?product_ids=<product-id>&limit=25"
```

Do not combine `skus`, `product_ids`, or the legacy singular `sku` parameter. Exact lookup remains a normal product collection: results use deterministic sorting and cursor pagination, not request order. The detail URLs remain available when an application needs raw source fields, aggregate quantities, family members, or retained history.

Exact SKU lookup also recognizes unambiguous historical mappings. The returned product always carries its current SKU in `source_ids.utah_dabs_sku`; `identifier_matches` records the requested value and whether it was `current`, an `active_alias`, or `historical`. Conflicted or ambiguous mappings do not resolve.

## Resolve stores

Store collections likewise accept one or many stable Nektir IDs or four-digit DABS inventory codes:

```bash theme={"dark"}
curl "$NEKTIR_API_BASE/v1/stores?inventory_store_codes=0001,0002&sort=store_number&limit=25"
curl "$NEKTIR_API_BASE/v1/stores?store_ids=<store-id>&limit=25"
```

Unknown identifiers simply do not appear in collection results. Compare the requested set with returned `id` or `source_ids` values when every identifier must resolve. The inventory matrix and availability comparison instead fail with `404` if any requested exact resource is unpublished, preventing silent partial calculations.

## Retrieve a dense inventory matrix

`GET /v1/inventory` accepts one to 25 products and one to 25 stores. It returns at most 625 product-store observations in a single response.

```bash theme={"dark"}
curl "$NEKTIR_API_BASE/v1/inventory?skus=061213,017956&inventory_store_codes=0001,0002&inventory_age=within_policy"
```

Alternatively, let Nektir choose the nearest published consumer stores within a radius. `store_limit` is capped at 25, so the matrix remains bounded:

```bash theme={"dark"}
curl "$NEKTIR_API_BASE/v1/inventory?skus=061213,017956&lat=40.7608&lng=-111.8910&radius_m=50000&store_limit=10"
```

Coordinate scope is mutually exclusive with exact store IDs and inventory codes. `meta.coverage.scope` records the origin, radius, and cap. Zero nearby stores returns an empty matrix with coverage status `none`; it does not mean the products have no stock elsewhere.

Products and stores are returned once in `data.products` and `data.stores`. Each item in `data.observations` references `product_id` and `store_id`, avoiding repeated resource metadata. Product and store input order is preserved; observations are product-major and store-minor.

The matrix is deliberately dense. Every requested pair has a row:

* `reported_positive` is a DABS-reported positive quantity, not a purchase guarantee.
* `reported_zero` is an explicit reported zero.
* `row_absent` means a validated product detail omitted that store row; it is not rewritten as zero.
* `unchecked` means no observation qualified for the requested retrieval-age policy.

An `unchecked` row has `quantity_reported: null`, null observation times, and `meets_retrieval_policy: false`. Never translate it to zero or unavailable.

```json theme={"dark"}
{
  "data": {
    "products": [{"id": "<product-1>", "source_ids": {"utah_dabs_sku": "061213"}}],
    "stores": [{"id": "<store-1>", "source_ids": {"inventory_store_code": "0001"}}],
    "observations": [{
      "product_id": "<product-1>",
      "store_id": "<store-1>",
      "observation_state": "unchecked",
      "quantity_reported": null,
      "purchase_eligibility": "unknown",
      "meets_retrieval_policy": false,
      "upstream_age_known": false,
      "times": {"source_updated_at": null, "retrieved_at": null, "published_at": null}
    }]
  },
  "meta": {
    "coverage": {
      "expected_pair_count": 1,
      "checked_pair_count": 0,
      "unchecked_pair_count": 1,
      "denominator_definition": "requested_published_products_x_requested_published_stores"
    }
  }
}
```

Values are illustrative. Use `inventory_age=within_policy` for customer-facing freshness. `any_age` is useful for investigation or an explicitly labeled fallback, but it does not establish current upstream stock.

## Choose matrix or comparison

Use the matrix when the application needs raw observations for a known product and store set. Use `/v1/availability/comparison` when it needs Nektir to search stores near coordinates and rank single-store or fewest-stop plans. Both read one stored publication and never trigger an upstream refresh.
