> ## 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.

# Compare multi-product availability

> Find one store or a small store set for an exact product list without making one API request per product.

Use the comparison endpoint after an application has exact product IDs. It reads one published Nektir database revision and returns product, store, and plan information together. It never calls Utah DABS while the user waits.

```bash theme={"dark"}
curl "$NEKTIR_API_BASE/v1/availability/comparison?product_ids=<product-1>,<product-2>,<product-3>&lat=40.7608&lng=-111.8910&radius_m=50000"
```

The default `purchase_eligibility=eligible` requires both a reported-positive observation and Nektir's ordinary-consumer eligibility classification. Use `purchase_eligibility=any` only when the application wants all reported-positive observations and can explain restrictions itself.

## Choose a strategy

Omit `strategies` to calculate all five options in one request:

* `best_single_store` returns the store covering the most requested products, using distance as the tie-breaker.
* `closest_store_with_any` returns the nearest store covering at least one requested product.
* `closest_complete_store` returns the nearest single store covering every requested product, or an explicit no-solution result.
* `fewest_stores_complete` minimizes stops, then the farthest store's distance, then total origin distance.
* `best_partial_plan` maximizes covered products within `max_stops`, then prefers fewer and closer stores.

`max_stops` is bounded from one to three in v1. Every distance is straight-line distance from the supplied coordinates. Nektir does not claim driving distance, route order, travel time, or that a product will still be purchasable on arrival.

Request only the plans an interface needs:

```bash theme={"dark"}
curl "$NEKTIR_API_BASE/v1/availability/comparison?product_ids=<product-1>,<product-2>&lat=40.7608&lng=-111.8910&strategies=closest_complete_store,fewest_stores_complete"
```

## Render an actionable plan

Each plan embeds store summaries. `assigned_product_ids` assigns each covered product to one selected store, even if multiple selected stores report it. `reported_product_ids` and `eligible_product_ids` keep reported stock separate from purchase eligibility.

```json theme={"dark"}
{
  "strategy": "fewest_stores_complete",
  "result_state": "complete",
  "completeness_required": true,
  "no_solution_reason": null,
  "plan": {
    "stop_count": 2,
    "farthest_store_distance_m": 8240,
    "total_origin_distance_m": 13310,
    "distance_metric": "straight_line_from_supplied_coordinates",
    "covered_product_count": 3,
    "requested_product_count": 3,
    "covered_product_ids": ["<product-1>", "<product-2>", "<product-3>"],
    "uncovered_product_ids": [],
    "stores": [
      {
        "store": {"id": "<store-1>", "name": "Example store", "distance_m": 5070},
        "assigned_product_ids": ["<product-1>", "<product-2>"],
        "covered_product_ids": ["<product-1>", "<product-2>"],
        "reported_product_ids": ["<product-1>", "<product-2>"],
        "eligible_product_ids": ["<product-1>", "<product-2>"],
        "covered_product_count": 2,
        "selected_coverage_mode": "purchase_eligible_reported_positive"
      }
    ]
  }
}
```

The example is illustrative. Actual store summaries include address, coordinates, status, services, and detail timestamps.

## Handle incomplete knowledge

`result_state: no_solution` means no plan satisfied that strategy inside the requested radius, retrieval policy, eligibility mode, and stop limit. It does not necessarily mean the products are unavailable.

Inspect `meta.coverage` before presenting a conclusion:

* `uncovered_product_ids` are not covered under the selected eligibility mode anywhere in scope.
* `uncertain_product_ids` are uncovered and have at least one unchecked product-store pair.
* `restricted_product_ids` were reported positive as restricted somewhere in scope but nowhere as purchase-eligible.
* `unchecked_pair_count` is the precise number of missing observations in the product-by-store denominator.
* `retrieved_at_min` and `retrieved_at_max` are Nektir retrieval times. Upstream data age remains unknown.

Prefer `inventory_age=within_policy`. `any_age` can help investigations or graceful fallback, but the response may describe old observations and still does not establish current upstream stock.
