← All Reports

Barcode Discovery Spike Report

Spike 2026-03-31 Barcode + Price Lookup for SA Retailers Complete
5
Retailers Probed
1
Working Endpoint
2
Service Scripts
3
Test Barcodes

Overview

This spike investigated whether South African grocery retailers expose public APIs for barcode-based product lookup or catalog search with pricing. The goal was to determine which retailers can serve as data sources for the Pantry App's barcode scan feature, enabling users to scan a product barcode and retrieve its name, price, and retailer availability.

Five retailers were probed (Woolworths, Checkers/Sixty60, Pick n Pay, SPAR, Makro) along with two international barcode databases (Open Food Facts, UPC Item DB). The investigation also covered third-party aggregators and community scraping projects.

Deliverables

ID Title Effort Status Owner
BD-1 Probe Woolworths product API 2h Done Backend Dev
BD-2 Probe Checkers/Sixty60 API 2h Blocked (WAF) Backend Dev
BD-3 Probe Pick n Pay API 2h Blocked (SPA) Backend Dev
BD-4 Probe SPAR API 1h No API exists Backend Dev
BD-5 Test Open Food Facts for SA barcodes 1h Low coverage Backend Dev
BD-6 Test UPC Item DB for SA barcodes 1h Zero coverage Backend Dev
BD-7 Build Woolworths search service script 2h Done Backend Dev
BD-8 Build Open Food Facts lookup service script 1h Done Backend Dev
BD-9 Research third-party aggregators (Trundler) 1h Done Backend Dev
BD-10 Document findings and recommendations 2h Done Business Analyst
BD-11 Create spike report 1h Done Business Analyst

Retailer Results

Retailer Barcode Lookup Catalog Search Price (ZAR) Auth Confidence
Woolworths No Yes Yes None High
Checkers/Sixty60 No Blocked N/A WAF + Auth Low
Pick n Pay No Blocked N/A SPA Auth Low
SPAR No No No N/A None
Open Food Facts Partial Yes No None Low
UPC Item DB No Yes No None Low

Key Decisions

Technical Notes

Woolworths Constructor.io Integration

The Woolworths search API is powered by Constructor.io. Two endpoints are available:

Response data includes: product name, brand, ratings, images, and price fields (p10, p30, p60). No authentication is required. The API key is embedded in the Woolworths public frontend.

Proposed Data Model

barcodes
  - id (uuid)
  - ean (text, unique)         -- EAN-13 barcode
  - product_name (text)        -- canonical product name
  - brand (text, nullable)
  - category (text, nullable)
  - source (text)              -- "user", "openfoodfacts", "manual"
  - created_at, updated_at

prices
  - id (uuid)
  - barcode_id (fk)
  - retailer (text)            -- "woolworths", "pnp", etc.
  - price_zar (numeric)
  - unit (text, nullable)      -- "each", "per kg", "per litre"
  - fetched_at (timestamptz)
  - source (text)              -- "constructor_io", "trundler", "manual"

price_history
  - id (uuid)
  - barcode_id (fk)
  - retailer (text)
  - price_zar (numeric)
  - recorded_at (timestamptz)

Barcode Scan Flow (Proposed)

  1. Camera captures barcode image
  2. Client-side barcode detection (ZXing or QuaggaJS) extracts EAN-13
  3. Query local barcodes table for product name
  4. If found: search Woolworths API for current price, display to user
  5. If not found: prompt user for product name, save mapping, then fetch price
  6. Cache price in prices table with 24-hour TTL

Outcomes

What We Learned

Recommendation Summary

For MVP, use Woolworths Constructor.io as the primary price source. Build a local barcode mapping cache seeded with Open Food Facts data. Let users contribute barcode-to-product mappings via the scan flow. Plan for Trundler integration in Sprint 2+ for multi-retailer comparison.

Open Issues