VynnAI

Documentation

API reference

Canadian grocery price data over HTTPS. JSON in, JSON out, documented errors, and a method you can cite.

Authentication

Send your key as a bearer token on every request:

curl https://vynn.ai/v1/products/lookup?upc=0060383682057 \
  -H "Authorization: Bearer vynn_pk_your_key_here"

Keys are server-side credentials

  • Call from your server, never from browser code. We deliberately send no CORS header on authenticated endpoints, so a browser cannot call them — that is a feature, not a gap.
  • Your key is shown in full exactly once, when it is created. We store only a hash and a display prefix, so we cannot recover it for you — rotate instead.
  • Responses to authenticated requests are private, no-store and must not be put in a shared cache.

Manage keys from your dashboard. Create or rotate a server-side key, then return here for the request contract. The public index page and the downloadable observation sample need no key.

Endpoints

GET /v1/products/lookup

Resolve a UPC/GTIN to its canonical product and the latest offers observed for it by the nightly sweeps.

ParameterRequiredDescription
upcrequiredThe UPC/EAN/GTIN to look up.
provinceoptionalTwo-letter province code. Default ON.
limitoptionalMaximum offers to return.

GET /v1/prices/history

Per-SKU price series from the reference-store panel, one point per nightly observation.

ParameterRequiredDescription
upcone ofMatched as a retailer-scoped SKU today — true UPC-to-SKU resolution is not yet available. Prefer product_id from a lookup or search result.
product_idone ofRetailer-scoped SKU.
provinceoptionalTwo-letter province code.
periodoptionalLookback, e.g. 90d.

GET /v1/stores

The geocoded reference-store directory the observations come from.

ParameterRequiredDescription
provinceoptionalTwo-letter province code.
banneroptionalBanner slug.
limitoptionalMaximum results.
offsetoptionalResults to skip, for paging.

Unrecognised query parameters are ignored rather than passed through, so a typo cannot change what you are billed for or what you receive.

Errors

Every error is JSON in the same shape. There is no HTML error page on /v1.

{ "error": { "code": "rate_limit_exceeded", "message": "..." } }
StatusCodeMeaning
400invalid_requestA required parameter is missing or invalid.
401missing_api_keyNo key, or a malformed Authorization header.
403invalid_api_keyThe key is unknown, revoked, or not a Vynn key.
404not_foundNo record matches that request.
405invalid_requestMethod not supported. These endpoints are GET-only; the response carries an Allow header.
429rate_limit_exceededPlan quota exceeded. Honour the Retry-After header.
502upstream_unavailableThe data service is unavailable. Retry shortly.

A 429 carries Retry-After — back off rather than retrying immediately. A 502 means our data service, not your request; retrying is appropriate.

Rate limits

Quotas are enforced per key against your plan. Daily quotas reset at the start of each UTC day; monthly quotas reset on the first of each month (UTC). Every call that reaches the data service counts, including rejected ones; requests rejected at this boundary — a missing parameter, a malformed key — are not metered.

PlanCallsPeriod
Free100per day
Pro10,000per month
Pro 5x50,000per month
Max200,000per month
Team2,000,000per month
Enterprisecontract-defined (bounded)per month

Before you model on this data

  • A missing date means “not observed”, never “price unchanged”. Build observation-frequency controls.
  • SKUs are retailer-scoped. A UPC helps link equivalents across banners, but not every SKU is reliably matched.
  • Store identifiers do not bridge collection eras.
  • Read the methodology and the data limits first. The gaps are disclosed there, not buried.