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

# List a product's reported inventory across stores

> Returns materialized product/store states. Warehouse and on-order values are
deliberately excluded from rows and remain separate on product detail.




## OpenAPI

````yaml /openapi/v1.yaml get /products/{product_id}/inventory
openapi: 3.1.0
info:
  title: Independent Utah DABS API
  version: 1.0.0
  summary: Database-backed product, store, and reported-inventory reads
  description: >
    Version 1 pilot contract. All requests read a locally published database
    revision;

    no public request waits for or triggers Utah DABS. Reported quantities are

    observations, not purchase guarantees. This service is independent and is
    not

    affiliated with or endorsed by Utah DABS. The current local seed contains

    historical inventory fixtures; clients must inspect response warnings and

    coverage metadata.
servers:
  - url: http://127.0.0.1:5185/v1
    description: Local development only; set MINTLIFY_API_BASE_URL before publishing
security: []
tags:
  - name: Products
  - name: Stores
  - name: Metadata
paths:
  /products/{product_id}/inventory:
    get:
      tags:
        - Products
      summary: List a product's reported inventory across stores
      description: >
        Returns materialized product/store states. Warehouse and on-order values
        are

        deliberately excluded from rows and remain separate on product detail.
      operationId: listProductInventory
      parameters:
        - $ref: '#/components/parameters/ProductIdPath'
        - $ref: '#/components/parameters/StoreIds'
        - $ref: '#/components/parameters/Latitude'
        - $ref: '#/components/parameters/Longitude'
        - $ref: '#/components/parameters/RadiusMeters'
        - $ref: '#/components/parameters/ObservationStates'
        - $ref: '#/components/parameters/PurchaseEligibility'
        - $ref: '#/components/parameters/InventoryAge'
        - $ref: '#/components/parameters/InventorySort'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/CoverageDetails'
        - $ref: '#/components/parameters/IfNoneMatch'
        - $ref: '#/components/parameters/IfModifiedSince'
      responses:
        '200':
          description: Inventory page from one immutable publication revision.
          headers:
            ETag:
              $ref: '#/components/headers/ETag'
            Last-Modified:
              $ref: '#/components/headers/LastModified'
            Cache-Control:
              $ref: '#/components/headers/InventoryCacheControl'
            X-Publication-Revision:
              $ref: '#/components/headers/PublicationRevision'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InventoryListResponse'
        '304':
          $ref: '#/components/responses/NotModified'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '410':
          $ref: '#/components/responses/CursorExpired'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/Unavailable'
components:
  parameters:
    ProductIdPath:
      name: product_id
      in: path
      required: true
      description: Stable API-owned product UUID.
      schema:
        type: string
        format: uuid
    StoreIds:
      name: store_ids
      in: query
      style: form
      explode: false
      description: Comma-separated stable store UUIDs, mutually exclusive with coordinates.
      schema:
        type: array
        maxItems: 25
        uniqueItems: true
        items:
          type: string
          format: uuid
    Latitude:
      name: lat
      in: query
      description: WGS84 latitude; must be paired with `lng`.
      schema:
        type: number
        format: double
        minimum: -90
        maximum: 90
    Longitude:
      name: lng
      in: query
      description: WGS84 longitude; must be paired with `lat`.
      schema:
        type: number
        format: double
        minimum: -180
        maximum: 180
    RadiusMeters:
      name: radius_m
      in: query
      description: Radius in meters; valid only with coordinates.
      schema:
        type: integer
        minimum: 1
        maximum: 500000
        default: 50000
    ObservationStates:
      name: observation_states
      in: query
      style: form
      explode: false
      schema:
        type: array
        uniqueItems: true
        maxItems: 4
        items:
          $ref: '#/components/schemas/ObservationState'
    PurchaseEligibility:
      name: purchase_eligibility
      in: query
      description: Independent policy classification for ordinary consumer purchase.
      schema:
        $ref: '#/components/schemas/PurchaseEligibility'
    InventoryAge:
      name: inventory_age
      in: query
      description: Whether inventory predicates require the current retrieval-age policy.
      schema:
        type: string
        enum:
          - within_policy
          - any_age
        default: within_policy
    InventorySort:
      name: sort
      in: query
      description: >-
        `distance` requires coordinates. Every sort ends with store UUID
        ascending.
      schema:
        type: string
        enum:
          - distance
          - store_number
          - quantity
          - '-quantity'
        default: store_number
    Limit:
      name: limit
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 25
    Cursor:
      name: cursor
      in: query
      description: >-
        Signed opaque keyset cursor, valid for 15 minutes and only with the
        original query.
      schema:
        type: string
        maxLength: 2048
    CoverageDetails:
      name: include
      in: query
      description: >-
        Set to `coverage_details` to add pair-state accounting to the compact
        default coverage summary. Product search requires an inventory scope or
        predicate when this is supplied.
      schema:
        type: string
        enum:
          - coverage_details
    IfNoneMatch:
      name: If-None-Match
      in: header
      description: Strong entity tag from an earlier response.
      schema:
        type: string
    IfModifiedSince:
      name: If-Modified-Since
      in: header
      description: HTTP-date fallback validator. ETag takes precedence.
      schema:
        type: string
  headers:
    ETag:
      description: >-
        Strong validator for the response representation. A new publication may
        retain the validator when this response is unchanged.
      schema:
        type: string
      example: '"v1-018f2fd0-a3d4-7d20-9c11-9482722f6b26-a91c"'
    LastModified:
      description: >-
        Newest relevant publication time in HTTP-date format; not an upstream
        update time.
      schema:
        type: string
      example: Tue, 15 Sep 2026 16:31:00 GMT
    InventoryCacheControl:
      schema:
        type: string
      example: public, max-age=30, stale-while-revalidate=120
    PublicationRevision:
      description: Immutable API publication revision used for this representation.
      schema:
        type: string
        format: uuid
    RetryAfter:
      description: Seconds until retry or an HTTP-date.
      schema:
        type: string
    RequestId:
      description: >-
        Server-generated identifier for correlating a response with private
        operational logs.
      schema:
        type: string
        format: uuid
  schemas:
    InventoryListResponse:
      type: object
      additionalProperties: false
      required:
        - data
        - meta
        - links
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/InventoryItem'
        meta:
          $ref: '#/components/schemas/CollectionMeta'
        links:
          $ref: '#/components/schemas/Links'
    ObservationState:
      type: string
      enum:
        - reported_positive
        - reported_zero
        - row_absent
        - unchecked
    PurchaseEligibility:
      type: string
      enum:
        - any
        - eligible
        - restricted
        - unavailable
        - unknown
      default: any
    InventoryItem:
      type: object
      additionalProperties: false
      required:
        - product_id
        - store
        - observation_state
        - quantity_reported
        - quantity_semantics
        - purchase_eligibility
        - eligibility_reason_code
        - retrieval_policy_id
        - meets_retrieval_policy
        - upstream_age_known
        - times
        - last_refresh_attempt
      properties:
        product_id:
          type: string
          format: uuid
        store:
          $ref: '#/components/schemas/StoreSummary'
        observation_state:
          $ref: '#/components/schemas/ObservationState'
        quantity_reported:
          type:
            - integer
            - 'null'
          minimum: 0
        quantity_semantics:
          type: string
          const: dabs_reported_unverified
        purchase_eligibility:
          $ref: '#/components/schemas/PublishedPurchaseEligibility'
        eligibility_reason_code:
          type: string
        retrieval_policy_id:
          type: string
        meets_retrieval_policy:
          type:
            - boolean
            - 'null'
        upstream_age_known:
          type: boolean
          const: false
        times:
          $ref: '#/components/schemas/NullableObservationTimes'
        last_refresh_attempt:
          $ref: '#/components/schemas/RefreshAttemptSummary'
    CollectionMeta:
      type: object
      additionalProperties: false
      required:
        - page
        - warnings
      properties:
        page:
          $ref: '#/components/schemas/PageMeta'
        coverage:
          $ref: '#/components/schemas/Coverage'
        warnings:
          type: array
          items:
            $ref: '#/components/schemas/Warning'
    Links:
      type: object
      additionalProperties: false
      required:
        - self
        - next
      properties:
        self:
          type: string
          format: uri-reference
        next:
          type:
            - string
            - 'null'
          format: uri-reference
    Problem:
      type: object
      additionalProperties: false
      required:
        - type
        - title
        - status
        - detail
        - instance
        - code
        - request_id
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
          minimum: 400
          maximum: 599
        detail:
          type: string
        instance:
          type: string
          format: uri-reference
        code:
          type: string
        request_id:
          type: string
          format: uuid
        invalid_params:
          type: array
          items:
            $ref: '#/components/schemas/InvalidParameter'
    StoreSummary:
      type: object
      additionalProperties: false
      required:
        - id
        - source_ids
        - name
        - address
        - phone
        - contact_links
        - location
        - distance_m
        - access_type
        - regular_hours_available
        - directory_presence
        - details_times
      properties:
        id:
          type: string
          format: uuid
        source_ids:
          $ref: '#/components/schemas/StoreSourceIds'
        name:
          type: string
        address:
          $ref: '#/components/schemas/PostalAddress'
        phone:
          type:
            - string
            - 'null'
          description: E.164 when normalization is verified.
        contact_links:
          $ref: '#/components/schemas/ContactLinks'
        location:
          oneOf:
            - $ref: '#/components/schemas/GeoPoint'
            - type: 'null'
        distance_m:
          type:
            - integer
            - 'null'
          minimum: 0
        access_type:
          $ref: '#/components/schemas/StoreAccessType'
        regular_hours_available:
          type: boolean
        directory_presence:
          oneOf:
            - $ref: '#/components/schemas/SourcePresenceSummary'
            - type: 'null'
        details_times:
          $ref: '#/components/schemas/ObservationTimes'
    PublishedPurchaseEligibility:
      type: string
      enum:
        - eligible
        - restricted
        - unavailable
        - unknown
    NullableObservationTimes:
      type: object
      additionalProperties: false
      required:
        - source_updated_at
        - retrieved_at
        - published_at
      properties:
        source_updated_at:
          type:
            - string
            - 'null'
          format: date-time
        retrieved_at:
          type:
            - string
            - 'null'
          format: date-time
        published_at:
          type:
            - string
            - 'null'
          format: date-time
    RefreshAttemptSummary:
      type: object
      additionalProperties: false
      required:
        - attempted_at
        - status
      properties:
        attempted_at:
          type:
            - string
            - 'null'
          format: date-time
        status:
          type: string
          enum:
            - succeeded
            - failed
            - skipped
            - rate_limited
            - schema_rejected
            - never_attempted
    PageMeta:
      type: object
      additionalProperties: false
      required:
        - has_more
        - next_cursor
      properties:
        has_more:
          type: boolean
        next_cursor:
          type:
            - string
            - 'null'
        cursor_expires_at:
          type: string
          format: date-time
          description: Present only when `next_cursor` is non-null.
    Coverage:
      type: object
      additionalProperties: false
      description: >-
        Compact inventory coverage summary. Request `include=coverage_details`
        to add the optional pair-state fields. The denominator is candidate
        products after non-inventory filters multiplied by reviewed stores in
        scope.
      required:
        - status
        - candidate_product_count
        - checked_product_count
        - unchecked_pair_count
        - retrieved_at_min
        - retrieved_at_max
      properties:
        status:
          type: string
          enum:
            - complete_for_retrieval_policy
            - partial
            - none
            - not_applicable
        candidate_product_count:
          type: integer
          minimum: 0
        scope_store_count:
          type: integer
          minimum: 0
        expected_pair_count:
          type: integer
          format: int64
          minimum: 0
        checked_product_count:
          type: integer
          minimum: 0
        within_policy_product_count:
          type: integer
          minimum: 0
        reported_positive_pair_count:
          type: integer
          format: int64
          minimum: 0
        reported_zero_pair_count:
          type: integer
          format: int64
          minimum: 0
        row_absent_pair_count:
          type: integer
          format: int64
          minimum: 0
        unchecked_pair_count:
          type: integer
          format: int64
          minimum: 0
        retrieved_at_min:
          type:
            - string
            - 'null'
          format: date-time
        retrieved_at_max:
          type:
            - string
            - 'null'
          format: date-time
    Warning:
      type: object
      additionalProperties: false
      description: >-
        Machine-readable data qualification. Current codes include FIXTURE_DATA,
        INVENTORY_COVERAGE_PARTIAL, SOURCE_REFRESH_DELAYED,
        UPSTREAM_PRODUCT_UNAVAILABLE, SOURCE_SCHEMA_QUARANTINED, and
        CATALOG_BATCH_OLD.
      required:
        - code
      properties:
        code:
          type: string
          examples:
            - INVENTORY_COVERAGE_PARTIAL
    InvalidParameter:
      type: object
      additionalProperties: false
      required:
        - name
        - reason
      properties:
        name:
          type: string
        reason:
          type: string
    StoreSourceIds:
      type: object
      additionalProperties: false
      required:
        - inventory_store_code
        - directory_id
      properties:
        inventory_store_code:
          oneOf:
            - $ref: '#/components/schemas/StoreInventoryCode'
            - type: 'null'
        directory_id:
          type:
            - string
            - 'null'
    PostalAddress:
      type: object
      additionalProperties: false
      required:
        - line1
        - line2
        - city
        - region
        - postal_code
        - country
      properties:
        line1:
          type: string
        line2:
          type:
            - string
            - 'null'
        city:
          type: string
        region:
          type: string
          examples:
            - UT
        postal_code:
          type: string
        country:
          type: string
          const: US
    ContactLinks:
      type: object
      additionalProperties: false
      required:
        - telephone_uri
        - geo_uri
      properties:
        telephone_uri:
          type:
            - string
            - 'null'
          description: Neutral `tel:` URI, present only when the phone was normalized.
        geo_uri:
          type:
            - string
            - 'null'
          description: Neutral RFC 5870 `geo:` URI derived from published coordinates.
    GeoPoint:
      type: object
      additionalProperties: false
      required:
        - latitude
        - longitude
      properties:
        latitude:
          type: number
          format: double
          minimum: -90
          maximum: 90
        longitude:
          type: number
          format: double
          minimum: -180
          maximum: 180
    StoreAccessType:
      type: string
      enum:
        - consumer_state_store
        - licensee_only
        - package_agency
        - unknown
    SourcePresenceSummary:
      type: object
      additionalProperties: false
      description: Compact presence state for collection rows.
      required:
        - state
        - last_seen_at
      properties:
        state:
          type: string
          enum:
            - present
            - suspect_missing
            - retirement_review_required
            - reviewed_retired
        last_seen_at:
          type:
            - string
            - 'null'
          format: date-time
    ObservationTimes:
      type: object
      additionalProperties: false
      required:
        - source_updated_at
        - retrieved_at
        - published_at
      properties:
        source_updated_at:
          type:
            - string
            - 'null'
          format: date-time
          description: Null when the source supplies no update timestamp.
        retrieved_at:
          type: string
          format: date-time
        published_at:
          type: string
          format: date-time
    StoreInventoryCode:
      type: string
      pattern: ^[0-9]{4}$
      examples:
        - '0002'
  responses:
    NotModified:
      description: Representation has not changed for the supplied validator.
      headers:
        ETag:
          $ref: '#/components/headers/ETag'
        Cache-Control:
          description: Cache policy for the validated representation.
          schema:
            type: string
        X-Publication-Revision:
          $ref: '#/components/headers/PublicationRevision'
    BadRequest:
      description: Invalid parameters, incompatible scope, or cursor/query mismatch.
      headers:
        Cache-Control:
          schema:
            type: string
          example: no-store
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotFound:
      description: Published resource or source mapping not found.
      headers:
        Cache-Control:
          schema:
            type: string
          example: no-store
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    CursorExpired:
      description: Cursor expired or its publication revision was retired.
      headers:
        Cache-Control:
          schema:
            type: string
          example: no-store
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    RateLimited:
      description: Public read-rate limit exceeded.
      headers:
        Cache-Control:
          schema:
            type: string
          example: no-store
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    InternalError:
      description: >-
        An unexpected server failure. Details are withheld; report the response
        request identifier.
      headers:
        Cache-Control:
          schema:
            type: string
          example: no-store
        X-Request-ID:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unavailable:
      description: No safe published database revision is currently readable.
      headers:
        Cache-Control:
          schema:
            type: string
          example: no-store
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'

````