Primat

Primat API

Daily per-store Swedish grocery prices — ICA, Coop, Willys, Hemköp, Lidl, City Gross. Regular, member, multibuy and campaign prices, GTIN/EAN-keyed, with change-log history since December 2025.

Primat är under utveckling. Strukturen, datat och prismodellen kan komma att ändras. Om ändringar sker så ser vi till att meddela användare via epost.
Gratisnivån förutsätter synlig attribution där datat visas: ”Prisdata från primat.nu” med länk till primat.nu. Datat får inte återförsäljas som dataset — se villkoren.

Start here

No key needed for the first taste.

# Real data, no account (25 results/call, 250 calls/day):
curl 'https://primat.nu/api/v3/demo/products?q=banan'

# Which stores serve a place? The site's own resolver:
curl 'https://primat.nu/api/v3/demo/stores/resolve?place=Uppsala'

# An API key in one call — no email round-trip to start:
curl -X POST https://primat.nu/api/v3/signup \
  -H 'Content-Type: application/json' \
  -d '{"email": "you@example.com"}'

The key is provisional (7-day TTL, tight quota). One click on the confirmation mail (POST /api/v3/confirm/request) upgrades it to the free tier. Machine-readable contract: https://primat.nu/api/v3/openapi.json — self-describing root: /api/v3.

Authentication

Authorization: Bearer <key> or X-API-Key: <key>. Two key types: secret (primat_live_…, server-side) and publishable (primat_pk_…, safe to embed in client-side apps: locked to your web origins, read-only, own quota, CORS enabled). Manage keys at primat.nu/konto.

Endpoints

v3 — the current surface. v1/v2 keep serving frozen for existing integrations.

Price semantics

Straight from the contract — the same text agents read in the OpenAPI document.

Price FACTS. regular: what everyone pays (public campaigns included). member: only set while a member price runs. multiprice/member_multiprice: PER-UNIT price when buying `quantity` (7 with quantity 5 = '5 for 35 kr'). comparison: unit price per kg/l/st computed on the REGULAR price. offer: the active campaign behind the current pricing, null when none. effective: least price a card-carrying shopper pays right now (a convenience fold; combine the facts yourself for anything serious). previous: on /deals results.

Fields: regular, member, multiprice, member_multiprice, comparison, offer, effective, previous. Timestamps: changed_at = when the price last CHANGED, confirmed_at = when the store was last checked. No change since changed_at means confirmed unchanged, not unmeasured.

Plans

Prices ex VAT. Sign up and upgrade at primat.nu/data.

PlanPriceRateRows HistoryImage URLs
Gratis free 60/min 20,000 rows/day
App 249 SEK/mo 250/min (+250 burst) 100,000 rows/day yes
Pro 1995 SEK/mo 600/min (+600 burst) 1,000,000 rows/day 12 mo yes
Byrå 7495 SEK/mo 3000/min (+3000 burst) unlimited full yes

Errors

Every non-2xx answer is {"error": {"code", "message"}} with honest Retry-After/WWW-Authenticate headers. Codes: invalid_api_key, rate_limited, daily_row_budget_exceeded, demo_limit_reached, query_required, bad_request, not_found, product_not_found, place_not_found, upgrade_required, origin_not_allowed, read_only_key, email_in_use, invalid_email, signup_limit_reached, history_timeout, service_unavailable.

Questions, bulk exports (CSV/Parquet, Byrå plan), or something missing? kontakt@primat.nu.

Tyck till