Find a bottle
Everything in vabc follows the same three-step loop:
- Search the live catalog to get a product code.
- Check inventory at a store near you (or statewide).
- Investigate further — warehouse stock, nearby alternatives, lottery events.
Every command hits a live Virginia ABC endpoint. There is no local cache; results reflect the current state of the website.
Step 1 — Search the catalog
product search queries the site’s Coveo index. It covers the full catalog, including new and online-only SKUs that the downloadable price list omits.
vabc product search "crown royal"vabc product search oftdNarrow by product category or type with --type:
vabc product search bourbon --type ryevabc product search "" --type gin # browse all ginsShow only allocated / limited-availability products:
vabc product search "" --allocatedvabc product search bourbon --allocatedBoth filters can be combined. --type matches against the product name, category, and type fields (case-insensitive).
Reading the results
Every result row carries a productCode — a six-digit, zero-padded string:
productCode name retailPrice953714 Planteray O.F.T.D. 49.99010807 Crown Royal Regal Apple 29.99That productCode is the key for every other command. Copy it exactly as shown (with leading zeros if present).
Fetch one product by code
If you already know the code, skip the search:
vabc product get 010807vabc product get 953714Step 2 — Check inventory near you
inventory check takes a product code and a location. It returns the anchor store’s quantity plus nearby stores that carry the product, ranked by distance.
Using —near
--near accepts a 5-digit ZIP, a street address, or a lat,lng pair. vabc resolves the point, finds the nearest store, and uses that as the anchor.
vabc inventory check 953714 --near 22182vabc inventory check 953714 --near "1100 Bank St, Richmond VA"vabc inventory check 953714 --near "38.9072,-77.0369"vabc prints the resolved location and the anchor store number to stderr so you know what it picked:
resolved "22182" to ZIP 22182 centroid; nearest store is 219Using —store
If you already know your preferred store number, pass it directly:
vabc inventory check 010807 --store 219Store 219 is Vienna. You can find other store numbers with store list or store near (see below).
Reading the inventory result
{ "productCode": "953714", "store": { "storeNumber": 219, "address1": "...", "city": "Vienna", "quantity": 3, "distance": 0.4 }, "nearbyStores": [ { "storeNumber": 230, "quantity": 1, "distance": 2.1 }, { "storeNumber": 410, "quantity": 0, "distance": 3.7 } ]}quantity: 0 means the store does not have the product in stock; it still appears in nearbyStores because the endpoint returned it.
Warehouse stock
inventory warehouse checks the statewide central warehouse — useful for gauging whether a product is being restocked at all.
vabc inventory warehouse 953714vabc inventory warehouse 010807The API returns the count as a string internally; vabc normalizes it to a number. A zero means the warehouse has none on hand; it does not confirm whether the product is discontinued.
Finding stores
Nearest stores to a location
vabc store near 22182vabc store near "1100 Bank St, Richmond VA"vabc store near "38.9072,-77.0369" --limit 10--limit controls how many stores come back (default 50). Results are sorted by great-circle distance from the resolved point.
Get one store by number
vabc store get 219List all stores
vabc store listReturns all ~394 Virginia ABC stores. Combine with --json and jq to filter by city or region.
Lottery and allocated releases
lottery check hits the limited-availability events endpoint and returns any active lottery or allocated events for a product. It also sets an allocated flag from the product’s catalog record.
vabc lottery check 953714vabc lottery check 010807Event titles are CMS-authored free text. By default vabc wraps them in untrusted-content markers so a downstream agent cannot be prompted by embedded instructions:
⟦UNTRUSTED⟧ Fall Allocated Bourbon Release 2026 ⟦/UNTRUSTED⟧To suppress the markers (for human-only use):
vabc lottery check 953714 --no-wrap-untrustedScripting with JSON and jq
Pass --json (or --format json) to get machine-readable output on stdout. Errors go to stderr in the same structured format.
Find the closest in-stock store for a product:
vabc --json inventory check 953714 --near 22182 \ | jq '[.store, .nearbyStores[]] | map(select(.quantity > 0)) | sort_by(.distance) | first'List store numbers where warehouse stock is nonzero (illustrative — warehouse returns a single count, not per-store):
vabc --json inventory warehouse 010807 | jq '.warehouseInventory'Get product codes for all allocated bourbons:
vabc --json product search bourbon --allocated \ | jq -r '.[].productCode'For a more complete scripting reference, see Scripting with JSON.
Throttle behavior
vabc keeps a cross-process throttle so it does not hammer Virginia ABC’s endpoints. If you hit the rate limit, the default behavior is to fail fast with exit code 7 and print a retry hint:
error: rate limited — try again in 4s code: RATE_LIMITED fix: re-run with --wait to wait it out, or wait 4s and retryPass --wait to let vabc wait instead of failing (up to --max-wait, default 30 s):
vabc --wait inventory check 953714 --near 22182