Liksy Enterprise API
Real-time price intelligence,
sourced from the ground.
Query millions of verified price points, run aggregate statistics, detect anomalies, and chart trends — all from supermarkets, pharmacies, fuel stations, and markets across 150+ countries. Updated continuously by a global network of data collectors who earn a share of every query you make.
730K+
live data points
150+
countries covered
11
production endpoints
50%
revenue to collectors
Quickstart
Make your first API call in under a minute. Replace lk_live_YOUR_KEY with your actual API key, which we send after approval.
The response includes a meta object (pagination + quota info) and a data array (the prices themselves):
Authentication
All API requests require an API key passed via the Authorization header as a bearer token. Keys look like lk_live_... and are tied to a specific tier and quota.
Key security
- Keep your key secret. Never commit it to a public repo or expose it in client-side code.
- Use environment variables. Store the key in your deployment's env vars, not in source.
- Rotate if compromised. Revoke a leaked key immediately from your dashboard — contact us to revoke yours.
- Revocation is permanent. A revoked key cannot be restored. You'll get a new one.
Endpoints
The API exposes four production endpoints. Each costs a different number of credits based on the computational work involved. Your monthly quota is denominated in credits, so a Starter plan with 10,000 credits gets you 10,000 /prices calls, or 5,000 /stats calls, or any mix.
| Endpoint | Cost | Tier required | What it does |
|---|---|---|---|
| /api/v1/prices | 1 credit | All | Raw price record query with filters |
| /api/v1/stats | 2 credits | Starter+ | Aggregate statistics (median, percentiles, trends) |
| /api/v1/timeseries | 3 credits | All (capped) | Time-bucketed series for charts |
| /api/v1/anomalies | 5 credits | Growth+ | Detect significant price changes vs baseline |
| /api/v1/export | 1 / 1K rows credits | All (capped) | Bulk download — csv, ndjson, json (streamable) |
| /api/v1/inflation | 3 credits | All | Liksy Food Inflation Index — monthly, country-specific, baseline-normalized |
| /api/v1/risk/country | 5 + 1/compare credits | All | Composite 0-100 food-risk score with letter grade (AAA-D) |
| /api/v1/correlation | 4 + 1/matrix credits | All | Pearson correlation between countries — pair or matrix mode |
| /api/v1/coverage | 1 credit | All | Data availability — global snapshot, country drill, or filtered query |
| /api/v1/supply-chain/stress | 6 credits | All | Cross-country anomaly clusters with severity rating and per-country breakdown |
| /api/v1/webhooks | free credits | All | Real-time event delivery — register URL, receive HMAC-signed POSTs on anomaly + supply-chain stress events |
✓ Outlier filtering is on by default
/stats, /anomalies, and /timeseries apply Tukey IQR filtering (1.5× interquartile range) to remove extreme values before aggregation. Each response includes outliers_excluded for transparency. Set include_outliers=true if you need raw aggregates (research, debugging, or custom downstream filtering).
/api/v1/pricesLIVE1 creditAll tiersQuery individual price records with rich filters. Supports pagination, sorting, and CSV export. Use this when you want raw data — for storage, custom analysis, or feeding your own pipeline.
Example: Hungarian dairy, last 30 days, sorted newest first
Sample response:
See for the complete filter list and for every field in a record.
/api/v1/statsLIVE2 creditsStarter+Aggregate statistics over the price database — median, average, percentiles, standard deviation, and a 7-day trend signal. Returns a single object (or grouped breakdown when group_by is set). Cheaper than fetching all records and aggregating client-side.
Parameters
All /prices filters work here, plus:period (7d, 30d, 90d, all), group_by (none, country, city, store_chain, subcategory, category — Growth+ for non-none), include_outliers (default false; set to true for raw stats including extreme values).
Example
Sample response — global aggregate over the last 30 days:
The trend_7d_vs_prior_pct field compares the median of the last 7 days against the prior 23 days. Useful as an early inflation signal.
/api/v1/anomaliesLIVE5 creditsGrowth+Detect significant price changes by comparing a recent window against a baseline. Aggregates at the subcategory + country [+ city] level — surfaces regional inflation signals, supply disruptions, and competitive pricing shifts.
Parameters
recent_days (1-90, default 7), baseline_days (7-365, default 30, must be > recent_days), threshold_pct (1-100, default 10), direction (up, down, both), min_sample (default 5), group_by_city (default true), include_outliers (default false). Plus the standard filters: country, category, subcategory, city, store_chain.
Example
Sample response — a real US anomaly detected in our database:
Results are sorted by absolute change_pct descending. The recent_samples and baseline_samples fields let you assess statistical significance.
/api/v1/timeseriesLIVE3 creditsAll (capped by tier)Time-bucketed aggregates ready for direct charting. Each bucket contains median, average, percentiles, and sample count. Choose daily, weekly, or monthly granularity.
Tier caps: Starter 90 buckets · Growth 365 · Pro 730 · Enterprise 1,825. Requesting beyond your cap automatically trims the period — no error, just a cap_applied: true flag in the response.
Parameters
period_days (1-1825), granularity (daily/weekly/monthly), min_sample (default 1, exclude buckets with fewer samples), include_outliers (default false; per-bucket IQR filter applied). Plus the standard filters: country, category, subcategory, city, store_chain.
Example
Sample response — Hungarian dairy, weekly for 180 days:
Buckets without samples are omitted (not zero-filled). Use min_sample=N to require minimum statistical significance per bucket.
/api/v1/exportLIVE1 per 1K rows creditsAll (capped by tier)Bulk download for analysis pipelines, hedge fund backtests, and academic research. Supports csv, ndjson (newline-delimited JSON, streamable), and json. Streams chunked — millions of rows without buffering memory.
Tier limits (max rows per call): Starter 10K · Growth 100K · Pro 1M · Enterprise 5M. JSON format capped at 100K rows; use ndjson or csv for larger exports.
Parameters
format (csv/ndjson/json), country, city, category, subcategory, data_source (collector/wfp/scrape/openfoodfacts), since, until, min_price_usd, max_price_usd, limit.
Example
Cost: 1 credit per 1,000 rows returned (rounded up, minimum 1). A 75K-row export = 75 credits.
/api/v1/inflationLIVE3 creditsAllLiksy Food Inflation Index — a monthly, country-specific basket cost normalized to a January 2020 baseline of 100. Methodology mirrors the WFP Minimum Food Basket framework with country-specific weight overrides, IQR outlier filtering, and unit normalization. Read the full methodology at liksy.app/methodology.
Coverage: 12 countries with WFP institutional data — KE, NG, ET, EG, YE, SY, LB, UA, JO, IQ, GH, TR. Each returns up to 130+ monthly index points. New countries added as ingestion expands.
Parameters
country (required, ISO2), months (history depth, default 24, max 360).
Example
Sample response — Kenya, 24 months:
Index returns null when basket coverage falls below 40% (insufficient subcategory data). Always check basket_components.effective_weight for the subcategory share actually measured.
/api/v1/risk/countryLIVE5 + 1 per compare creditsAllComposite 0–100 food-risk score with S&P-style letter grade (AAA→D). Designed for trade credit insurance, sovereign macro analysis, and EM hedge fund overlays. Combines inflation volatility (40%), absolute inflation (30%), anomaly density (20%), and data freshness (10%) over a 24-month rolling window.
Use compare to benchmark: add up to 9 additional countries with compare=NG,ET,YE. Returns the same risk breakdown for every country in a single call. 1 extra credit per compared country.
Parameters
country (required, ISO2), compare (comma-separated ISO2 list, max 9).
Example
Sample response — Kenya benchmarked against 4 EM/crisis countries:
Countries with insufficient data (<6 months in 24-month window) return letter_grade: "NR" (Not Rated). Full methodology at liksy.app/methodology.
/api/v1/correlationLIVE4 + 1/matrix country creditsAllPearson correlation coefficient between two countries' monthly median prices for a given subcategory. Reveals price passthrough (supply chain coupling), regional cohesion, and crisis dissociation. Two modes: pair (A ↔ B) and matrix (A vs many).
Real example: UA ↔ NG grains correlation = −0.81 over 24 months. When Ukraine grain exports tighten, Nigerian markets compensate through alternative sourcing — a negative correlation signals shock absorption, not transmission. Hedge fund alpha signal.
Parameters
Pair mode: country_a, country_b, subcategory, months (default 24, max 60).
Matrix mode: country, matrix (comma-separated ISO2 list, max 9), subcategory, months.
Example
Sample response — Ukraine grains vs 8 EM countries, sorted by coupling strength:
Each month requires at least 3 IQR-trimmed samples per country to be included in the correlation. Minimum 6 overlapping months required for meaningful interpretation — fewer returns insufficient_data.
/api/v1/coverageLIVE1 creditAllInstant answer to "what data do you have?" — designed for pre-sales demos, self-service prospect evaluation, and internal monitoring. Three modes:
- Global (no params): platform snapshot — total records, top countries, category breakdown, 30/7-day momentum.
- Country drill (
?country=XX): subcategory + city + data_source breakdown with freshness status. - Filtered (any combination): record count + status + sample rows for your exact query.
Coverage status labels: strong (5K+ records, active), partial (100-5K), sparse (<100), stale (no updates in 90 days), no_coverage (none). Honest signaling — we flag gaps explicitly.
Parameters
All optional: country, city, category, subcategory, product. No params = global snapshot (served from hourly cache, <200ms).
Example
Sample response — Türkiye country drill (stale status demonstration):
Cheapest endpoint at 1 credit — designed to be queried freely during evaluation. Global mode served from hourly materialized cache for <200ms latency.
/api/v1/supply-chain/stressLIVE6 creditsAllSupply Chain Stress Index. Detects when the same subcategory shows statistically significant price moves across multiple countries simultaneously — a leading indicator of upstream supply shocks, trade disruption, or regional commodity stress.
Real example: Current run detects oils surge in JO +16.7%, LB +13.0%, KE -13.5% — Middle East / East Africa price decoupling signal. Hedge fund pair trade setup, Lloyd's cargo risk repricing trigger.
Methodology
For every country × subcategory pair we compute the z-score of the recent median vs a preceding baseline distribution. When |z| exceeds the threshold in N+ countries simultaneously, the subcategory is flagged as a cluster and ranked by severity (avg |z| × countries affected).
Parameters
All optional: recent_days (14-365, default 90), baseline_days (60-1825, default 540), min_z (0.5-5.0, default 1.0), min_countries (2-10, default 2). Defaults tuned for WFP monthly-cadence data.
Example
Severity scale: critical (avg |z| ≥ 3.0 AND ≥ 5 countries), high, elevated, moderate. Each cluster includes per-country z-scores and automated interpretation narrative.
/api/v1/index2 CREDITSNEW
External authoritative index series — currently FAO Consumer Price Indices (food + general CPI) for 151 countries, January 2000 to present. Liksy serves upstream values verbatim under CC-BY-4.0. Use this to cross-check Liksy-computed inflation against official reference data, or as a standalone time-series feed for research dashboards.
Parameters
| Param | Type | Description |
|---|---|---|
country | string | ISO2, required (e.g. TR, HU, KE) |
series | string | Optional: food_cpi or general_cpi. Returns both if omitted. |
source | string | Optional data_source filter. Currently faostat_cp; more sources coming. |
from | date | YYYY-MM-DD, default 36 months ago |
to | date | YYYY-MM-DD, default today |
limit | integer | Max points returned, default 360, max 1000 |
list_series | boolean | true → returns the catalog of available series for the country (no time-series payload) |
Example — Turkey food CPI, last 36 months
curl -H "Authorization: Bearer lk_live_YOUR_KEY" \ "https://liksy.app/api/v1/index?country=TR&series=food_cpi"
Example response (truncated)
{
"meta": {
"tier": "starter",
"cost_credits": 2,
"total_points": 29,
"series_returned": 1,
"response_ms": 142
},
"country": "TR",
"time_window": { "from": "2023-04-24", "to": "2026-04-24" },
"series": [{
"data_source": "faostat_cp",
"series_code": "food_cpi",
"series_label": "FAO Food Consumer Price Index",
"unit": "index",
"base_period": "2015=100",
"cadence": "monthly",
"points": [
{ "period": "2023-05", "value": 660.90, "flag": "X", "confidence": 0.95 },
{ "period": "2024-09", "value": 1181.23, "flag": "X", "confidence": 0.95 },
{ "period": "2025-09", "value": 1607.19, "flag": "X", "confidence": 0.95 }
],
"latest": { "period": "2025-09", "value": 1607.19 },
"yoy_pct": 36.06
}],
"methodology": {
"note": "External authoritative index series — Liksy serves upstream values verbatim, no recomputation.",
"sources": {
"faostat_cp": "FAO Consumer Price Indices, monthly, 2015=100. License CC-BY-4.0."
},
"docs": "https://liksy.app/methodology"
}
}Discover what's available for a country
curl -H "Authorization: Bearer lk_live_YOUR_KEY" \ "https://liksy.app/api/v1/index?country=KE&list_series=true"
Use cases
- Validate Liksy-computed inflation against FAO official series for the same country
- Standalone time-series feed for academic, policy, or central-bank research dashboards
- Multi-country food vs general CPI comparison for emerging-market macro strategy
- Pair with
/inflation(Liksy basket) for ground-truth benchmarking
/api/v1/webhooksFREE MGMTNEW
Real-time event delivery via HMAC-signed POST callbacks. Register a URL once, then receive push notifications when Liksy detects price anomalies or supply-chain stress clusters that match your filters — no polling, no missed events, no stale data.
Why webhooks instead of polling /anomalies every minute? You don't pay credits for empty polls, you receive events within a minute of detection (vs your polling interval), and Liksy's HMAC-SHA256 signature proves the payload originated from us so you can trust it.
How it works
Liksy runs a trigger every 15 minutes that recomputes anomalies and stress clusters across the database. Matching events are queued for each webhook subscription whose filters apply. A separate delivery worker drains the queue every minute, signing each payload with your webhook's secret and POSTing to your URL. Failed deliveries retry with exponential backoff (1m, 5m, 30m); after 3 failures the delivery is marked dead and the event is visible in your audit log.
Register a webhook
The response contains a one-time secret (32-byte hex) — store it securely. You'll need it to verify signatures on incoming deliveries. Liksy never returns this secret again.
Sample response
List your webhooks
Returns all your subscriptions with delivery counters (total_deliveries, total_failures, last_triggered_at) but never the secret. Revoked subscriptions remain visible with is_active: false for audit.
Revoke a webhook
Soft delete — the subscription is marked inactive immediately, no new events are queued, but pending deliveries already in the queue will still be sent before the worker picks up the revocation. Idempotent: revoking an already-revoked webhook returns 200.
Filtering
| Field | Type | Description |
|---|---|---|
| event_types | array | Array of "anomaly_detected", "supply_chain_stress", or both. Default: both. |
| filter_country | string? | ISO2 (e.g. "TR"). For stress events, matches if any country in the cluster matches. null = all countries. |
| filter_subcategory | string? | e.g. "dairy", "grains". null = all subcategories. |
| min_severity | enum | One of moderate, elevated, high, critical. Default: elevated. |
Incoming delivery — request headers
Every delivery POST to your URL includes these headers:
| Header | Description |
|---|---|
| X-Liksy-Signature | sha256=<hex> — HMAC-SHA256 of the raw request body, using your webhook secret. Always verify before processing. |
| X-Liksy-Event | anomaly_detected or supply_chain_stress |
| X-Liksy-Delivery-Id | Unique UUID per delivery attempt. Use as your idempotency key — we may retry on transient failures. |
| X-Liksy-Attempt | Integer, 1-3. Anything >1 means we're retrying. |
Sample payload — anomaly_detected
Sample payload — supply_chain_stress
Verifying the signature — Node.js
Verifying the signature — Python (Flask)
Retry policy
Liksy considers a delivery successful only on a 2xx response within 8 seconds. Any other status (including 5xx, redirects, timeouts) triggers a retry. Backoff schedule is +1 min, then +5 min, then +30 min. After 3 failed attempts the delivery is marked dead and surfaced in your operator console. For idempotency, dedupe on X-Liksy-Delivery-Id — the same delivery may arrive twice if your server times out after processing but before responding.
Idempotency & deduplication
The same anomaly cluster (e.g. "TR dairy high") can recur across multiple 15-minute trigger runs while the underlying condition persists. Liksy fingerprints each event by (country, subcategory, severity, direction, day) and de-duplicates within a 24-hour window — you receive at most one notification per webhook per event-day. The fingerprint key is internal; you should still dedupe on X-Liksy-Delivery-Id for retry safety.
Webhook management endpoints (POST/GET/DELETE) do not consume credits and do not count against your monthly quota. Event deliveries are also free — you only pay for queries you issue against the data API.
Query Parameters
The table below covers /prices. Most filters (category, country, city, store_chain, etc.) also work on /stats, /anomalies, and /timeseries. Endpoint-specific parameters are documented in each endpoint's section above.
| Parameter | Type | Description |
|---|---|---|
| category | string | Filter by category: grocery, electronics, fuel, pharma, clothing, restaurant, hardware, services, commodity, realestate |
| subcategory | string | Filter by subcategory (e.g., dairy, bakery, phones, gasoline) |
| country | string | ISO 3166-1 alpha-2 code (HU, TR, US, GB, DE, etc.) |
| city | string | City name (case-insensitive, partial match) |
| product | string | Product name search (case-insensitive, partial match) |
| store_type | string | supermarket, convenience, market, pharmacy, gas_station, restaurant, online |
| store_chain | string | Specific chain (Tesco, Migros, Auchan, Walmart, etc.) |
| barcode | string | EAN/UPC barcode exact match |
| date_from | ISO date | Earliest captured date (YYYY-MM-DD) |
| date_to | ISO date | Latest captured date (YYYY-MM-DD) |
| min_price | number | Minimum price in USD |
| max_price | number | Maximum price in USD |
| min_confidence | number | Minimum OCR confidence (0–1). Default: 0.75 |
| verified | boolean | Return only human-verified records |
| limit | integer | Max results per request (capped by tier). Default: 100 |
| offset | integer | Pagination offset. Default: 0 |
| sort | enum | price_asc, price_desc, date_asc, date_desc. Default: date_desc |
| format | enum | json (default) or csv for direct spreadsheet export |
Example: Hungarian dairy prices, last 30 days
Response Schema
Each price record in the data array of /prices has the following shape. Fields marked with ? may be null. Other endpoints return aggregated shapes — see their sections above.
| Field | Type | Description |
|---|---|---|
| id | bigint | Unique record identifier |
| product_name | string | Product name as captured |
| product_brand | string? | Brand name if detected |
| product_size | string? | Size/volume (e.g., 500g, 1L) |
| barcode | string? | EAN/UPC barcode if captured |
| category | string | Top-level category |
| subcategory | string? | More specific category |
| price | number | Price in local currency |
| currency | string | ISO 4217 currency code |
| price_usd | number | Price normalized to USD (daily FX rate) |
| country | string | ISO 3166-1 alpha-2 country code |
| city | string | City name |
| district | string? | District/neighborhood within city |
| lat | number | Latitude of capture point |
| lng | number | Longitude of capture point |
| store_name | string | Store name as captured |
| store_type | string | Store type classification |
| store_chain | string? | Chain name if part of a chain |
| confidence | number | OCR/extraction confidence (0–1) |
| source | string | scan, receipt, supplier, external |
| captured_at | ISO datetime | When the price was captured in-store |
Meta fields
The meta object on every response helps you manage pagination and monitor quota usage:
| Field | Type | Description |
|---|---|---|
| total | integer | Total records matching the query (across all pages, /prices only) |
| returned | integer | Number of records in this response |
| limit | integer | The limit used for this request (clamped to tier max) |
| offset | integer | The offset used for this request |
| tier | string | Your API tier (starter, growth, pro, enterprise, research) |
| credits_used | integer | Credits this request consumed (1-5 depending on endpoint) |
| remaining | integer | Remaining credits this billing period |
| response_ms | integer | Server-side response time in milliseconds |
Rate Limits & Pricing
Each tier has a monthly credit quota, per-minute rate limit, and result caps. Endpoints consume different amounts of credits: /prices = 1, /stats = 2, /timeseries = 3, /anomalies = 5. Exceeding your quota returns 429 insufficient_credits; exceeding the rate limit returns 429 Too Many Requests.
Research
for academic use
5,000 credits / month
60 / min
100 records / 100 anomalies
- ✓Academic research only
- ✓Attribution required
- ✓All 7 endpoints
- ✓Manual approval
Starter
per month
10,000 credits / month
60 / min
100 records, 90 buckets
- ✓/prices, /stats, /timeseries, /export
- ✓/inflation index + /risk score
- ✓JSON + CSV + NDJSON export
- ✓Email support
- ✓99.5% uptime SLA
Growth
per month
100,000 credits / month
300 / min
500 records / 365 buckets
- ✓All 7 endpoints incl. /anomalies + /risk
- ✓Priority email support
- ✓99.9% uptime SLA
- ✓Daily usage reports
Pro
per month
1,000,000 credits / month
1,200 / min
5,000 records / 730 buckets
- ✓Everything in Growth
- ✓Dedicated Slack channel
- ✓Custom subcategory filters
- ✓Anomaly webhooks (beta)
Enterprise
volume pricing
Unlimited credits
6,000 / min
50,000 records / 1,825 buckets
- ✓Everything in Pro
- ✓Dedicated infrastructure
- ✓5-year history access
- ✓Revenue-share partnerships
- ✓On-premise deployment
Error Codes
Errors use standard HTTP status codes. The response body includes a structured error object with code and message fields. Some errors include extra context (e.g., upgrade_to, credits_remaining).
| Status | Name | When it happens |
|---|---|---|
| 200 | OK | Request successful, data returned. |
| 400 | Bad Request | Invalid query parameter. Check country code format, date format, or numeric fields. |
| 401 | Unauthorized | API key missing or invalid. Include it as 'Authorization: Bearer lk_live_...' |
| 403 | Forbidden | Tier required (e.g., /anomalies needs Growth+) or key revoked. Check the upgrade_to field in the response. |
| 429 | Too Many Requests | Rate limit hit, or insufficient credits for the endpoint cost. Slow down or upgrade. |
| 500 | Server Error | Something went wrong on our side. We've been notified. Retry with exponential backoff. |
Handling rate limits and quota
When rate-limited (429), use exponential backoff in production clients. When credits are insufficient, the response includes credits_required and credits_remaining so you can decide whether to retry, switch to a cheaper endpoint, or upgrade.
Ready to get started?
Tell us briefly what you're building. We'll reply within a day with your API key, the right tier for your use case, and pricing.
Request API access →Or email us directly: emir@delmundo.hu