API reference

Public API endpoints

Complete reference for every endpoint the Haszno hosted demo serves without credentials.

The Haszno API is in developer preview. All data returned by the hosted demo at https://haszno.com is synthetic sample data unless noted otherwise. See Conventions for null semantics, currency, and timestamp formats.

Summary

Every endpoint in this table is callable against https://haszno.com without an Authorization header or any other credential. For endpoints that require credentials, see Protected endpoints.

Method Path Returns
GET /api/health Liveness check
GET /api/geo Visitor country and suggested UI language
GET /api/categories Category taxonomy with product counts
GET /api/products Product catalogue with pricing and market data
GET /api/products/supplier-counts Product count per supplier
GET /api/suppliers Configured supplier list
GET /api/stats Dashboard summary numbers
GET /api/settings Active pricing rules
GET /api/impact Profit impact attributed to Haszno
GET /api/orders Last 50 orders (empty array on demo)
GET /api/proposals Price proposals (empty array on demo)
GET /api/peers/invites Peer invite codes (empty array on demo)
GET /api/peers/links Established peer links (empty array on demo)
GET /api/import-list Import list staging items
GET /api/blog Published market insight posts (real data)
GET /api/blog/:slug Single published post (real data)
GET /api/blog/rss.xml RSS feed of posts
GET /api/blog/feed.json JSON Feed of posts
GET /llms.txt LLM-readable site summary

System

GET/api/health

Returns a liveness indicator. Use this to verify that the API is reachable before making other calls.

Public Read-only

Parameters

None.

Request

curl --fail-with-body https://haszno.com/api/health

Response (200)

Field Type Description
ok boolean Always true when the server is up.
{"ok":true}

GET/api/geo

Returns the visitor's country code and the suggested UI language. The country is derived from request headers set by the edge network (x-vercel-ip-country or cf-ipcountry). The API server never stores or logs IP addresses.

Public Read-only

Parameters

None.

Request

curl --fail-with-body https://haszno.com/api/geo

Response (200)

Field Type Description
country string | null Two-letter ISO 3166-1 country code, or null if the country cannot be determined.
lang "hu" | "en" Suggested UI language: "hu" for Hungary or unknown, "en" for all other countries.
{"country":"HU","lang":"hu"}

Cache-Control: private, no-store is set on this response; do not cache it on a shared layer.


Demo catalogue data

The following endpoints return synthetic sample data. The response body includes "demo": true where applicable. partnerCount is always 0 in the demo — no real suppliers are connected.


GET/api/categories

Returns the full category taxonomy used to organise products. Each entry includes counts for the demo data set.

Public Read-only

Parameters

None.

Request

curl --fail-with-body https://haszno.com/api/categories

Response (200)

Returns an array of category objects. All 14 categories are always returned; there is no filtering or pagination.

Field Type Description
key string Internal category key used in filter parameters, e.g. "kert".
label string Hungarian display name, e.g. "Kert és növény".
emoji string Emoji icon for the category.
partnerCount integer Number of real connected suppliers. Always 0 on the demo.
exampleCount integer Number of demo/example suppliers.
productCount integer Total products in the category across all suppliers.
[
  {
    "key": "auto",
    "label": "Autó, gumi és motor",
    "emoji": "🛞",
    "partnerCount": 0,
    "exampleCount": 1,
    "productCount": 100
  },
  {
    "key": "kert",
    "label": "Kert és növény",
    "emoji": "🌿",
    "partnerCount": 0,
    "exampleCount": 1,
    "productCount": 100
  }
]

Notes

  • partnerCount: 0 is expected on the demo — no real suppliers are connected.
  • Use the key value as the cats parameter when filtering products or stats.

GET/api/products

Returns the product catalogue with gross prices, net costs, market price comparisons, and pricing recommendations. This is the primary read endpoint for integration work.

Public Read-only

The demo returns synthetic products only. sku values follow the pattern DEMO-{id}. Market prices have "source": "mock". Pricing parameters (undercutPct, minMarginPct, vatPct) are accepted but do not persist — they affect only the current response.

Parameters

Name In Type Required Default Description
cats query comma-separated string No (all) Category keys to include, e.g. kert,sport.
supplier query comma-separated integers No (all) Supplier IDs to include.
all query "1" No omit Real instances only; the demo ignores it. When set to "1", includes catalogue-only (unlisted) products.
shippingMarkets query comma-separated ISO 3166-1 alpha-2 No HU Demo only. Countries for which to return market price comparisons. Valid values: HU SK DE AT CZ PL RO. A real instance uses the shop's saved shippingMarkets setting.
undercutPct query number No 1 Demo only. Percentage to undercut the market minimum when computing the recommended price. Does not persist.
minMarginPct query number No 10 Demo only. Minimum net margin percentage enforced by the pricing engine. Does not persist.
vatPct query number No 27 Demo only. VAT rate used for gross/net conversion in recommended. Does not persist.

Request

curl --fail-with-body \
  'https://haszno.com/api/products?cats=kert&shippingMarkets=HU,SK'

Response (200)

Returns an array. Each item represents one product.

Field Type Description
id integer Internal product ID.
sku string Supplier SKU. DEMO-{id} on the demo.
name string Product name (Hungarian).
supplierId integer Supplier ID.
supplierName string Supplier display name.
category string Category key (matches GET /api/categories).
costNet integer (HUF) Net wholesale cost excluding VAT.
priceGross integer (HUF) Current gross selling price including VAT.
rrpGross integer | null Supplier's recommended retail price, gross. null if not provided.
marketMinGross integer | null Cheapest gross price found across monitored markets. null if no data.
marketShop string | null Shop name that holds the cheapest offer.
stock integer Stock units available.
listed boolean Whether the product is actively listed.
example boolean true for demo/example supplier products. Present on real instances only; absent from the synthetic demo response.
current object {marginNet, marginPct} — margin at the current price; both null when costNet is unknown.
recommended object Pricing suggestion — see sub-fields below.
marketByCountry object Fixed keys hu, sk and eu. Each slot: market offer object or null.
bestMarket object | null {market, ratio}: the market ("hu", "sk" or "eu") with the highest minGross / priceGross ratio; a ratio above 1 means the shop is already the cheapest there. Always null on the demo.
markets array Market offer records: on the demo one per requested country, on a real instance one per market (hu, sk, eu) that has price data.
trendKeyword string | null Hungarian trend search keyword for the product. Present on real instances only; absent from the synthetic demo response.
trendKeywordEn string | null English trend keyword. Present on real instances only; absent from the synthetic demo response.
updatedAt ISO-8601 string | null Timestamp of last update. Present on real instances only; absent from the synthetic demo response.

recommended sub-fields

Field Type Description
priceGross integer (HUF) Suggested gross selling price.
floorGross integer (HUF) Lowest gross price that still keeps minMarginPct; 0 when costNet is unknown. Formula in Conventions.
marginNet integer (HUF) | null Net margin at the recommended price. null when costNet is unknown.
marginPct number | null Margin percentage at the recommended price. null when costNet is unknown.
status string Pricing status — see enum below.

recommended.status enum

Value Meaning
"versenykepes" Competitive — a market price is known, and the recommended price undercuts it by undercutPct (rounded to a price ending in 90 Ft) while staying at or above floorGross.
"nem_versenykepes" Not competitive — beating the market price would break the minimum margin, so the recommended price stays at floorGross.
"nincs_piaci_ar" No market price is known. The recommended price is rrpGross when it is at or above floorGross, otherwise floorGross.
"nincs_besz_ar" The purchase cost (costNet) is unknown, so no pricing recommendation can be made: priceGross keeps the current price, floorGross is 0, and marginNet and marginPct are null.

Market offer object (each slot in marketByCountry and each item in markets)

Field Type Description
market string Market key: "hu", "sk" or "eu".
country string | null Two-letter ISO country code of the cheapest offer, e.g. "DE" for the eu market.
minGross integer (HUF) Cheapest gross price found in this market.
shop string Shop name for the cheapest offer.
url string | null URL of the cheapest listing. null on the demo.
source string Data source: "dataforseo" or "mock". Always "mock" on the demo.
fetchedAt ISO-8601 string When the market price was fetched.
isCheapest boolean Whether this market holds the overall cheapest offer.

The demo returns this full object in both places. On a real instance, marketByCountry slots have no market or isCheapest field, and markets items have no fetchedAt.

{
  "id": 101,
  "category": "kert",
  "supplierId": 2,
  "sku": "DEMO-101",
  "name": "Kerti napernyő · 1. változat",
  "supplierName": "Példa-partner · Kert és növény",
  "costNet": 1121,
  "priceGross": 2190,
  "rrpGross": 2190,
  "marketMinGross": 2124,
  "marketShop": "Példa-bolt · HU",
  "stock": 0,
  "listed": true,
  "current": {"marginNet": 603, "marginPct": 35},
  "recommended": {
    "priceGross": 2090,
    "floorGross": 1590,
    "status": "versenykepes",
    "marginNet": 525,
    "marginPct": 31.9
  },
  "marketByCountry": {
    "hu": {
      "market": "hu",
      "country": "HU",
      "minGross": 2124,
      "shop": "Példa-bolt · HU",
      "url": null,
      "source": "mock",
      "fetchedAt": "2026-11-10T00:00:00.000Z",
      "isCheapest": true
    },
    "sk": {
      "market": "sk",
      "country": "SK",
      "minGross": 2650,
      "shop": "Példa-bolt · SK",
      "url": null,
      "source": "mock",
      "fetchedAt": "2026-11-10T00:00:00.000Z",
      "isCheapest": false
    },
    "eu": null
  },
  "bestMarket": null,
  "markets": [
    {"market":"hu","country":"HU","minGross":2124,"shop":"Példa-bolt · HU",
     "url":null,"source":"mock","fetchedAt":"2026-11-10T00:00:00.000Z","isCheapest":true},
    {"market":"sk","country":"SK","minGross":2650,"shop":"Példa-bolt · SK",
     "url":null,"source":"mock","fetchedAt":"2026-11-10T00:00:00.000Z","isCheapest":false}
  ]
}

Notes

  • null on a price field means unknown or unavailable, not zero.
  • source: "mock" on market prices means the price is not a verified live market result.
  • On the public demo, current.marginPct is a fixed placeholder (35) that does not follow from the prices, while current.marginNet is computed as round(priceGross / 1.27 − costNet), always at 27 % VAT. Only recommended reflects the undercutPct, minMarginPct and vatPct parameters.
  • Returns all matching products in a single array. There is no pagination on this endpoint.

GET/api/products/supplier-counts

Returns the number of products per supplier. Useful for displaying a supplier breakdown without loading the full catalogue.

Public Read-only

Parameters

On the demo, the same filtering parameters as GET /api/products: cats, supplier. A real instance ignores them and counts the listed products of every supplier.

Request

curl --fail-with-body 'https://haszno.com/api/products/supplier-counts?cats=kert'

Response (200)

Returns an array. Only suppliers with at least one matching product are included.

Field Type Description
id integer Supplier ID.
name string Supplier display name.
count integer Number of products matching the filter.
[
  {"id": 2, "name": "Példa-partner · Kert és növény", "count": 100}
]

GET/api/suppliers

Returns the list of suppliers configured in the shop. On the demo, returns synthetic example suppliers.

Public Read-only

Parameters

None.

Request

curl --fail-with-body https://haszno.com/api/suppliers

Response (200)

Returns an array of supplier objects.

Field Type Description
id integer Supplier ID.
name string Supplier display name.
category string Primary category key.
visibility string "private" or "network".
network boolean Whether the supplier is part of the shared network.
orderMode string How orders are forwarded (e.g. "email").
email string | null Supplier contact email, or null.
[
  {
    "id": 1,
    "name": "Példa-partner · Autó, gumi és motor",
    "category": "auto",
    "visibility": "private",
    "network": false,
    "orderMode": "email",
    "email": null
  }
]

GET/api/stats

Returns dashboard summary numbers. These are computed across all products matching the optional filters.

Public Read-only

Parameters

Name In Type Required Default Description
cats query comma-separated string No (all) Filter by category keys.
supplier query comma-separated integers No (all) Filter by supplier IDs.

Request

curl --fail-with-body https://haszno.com/api/stats

Response (200)

Field Type Description
products integer Number of actively listed products.
losing integer Products with a negative net margin at the current price.
overMarket integer Products priced above the cheapest known competitor.
toFix integer Products where the current price differs from the recommended price.
orders integer Total order count (not window-scoped).
{"products":1400,"losing":0,"overMarket":1400,"toFix":1400,"orders":0}

Notes

  • orders: 0 is expected on the demo — no real orders exist.
  • overMarket: 1400 on the demo reflects that all 1 400 synthetic products are above their (synthetic) market minimum.

GET/api/settings

Returns the current pricing rule configuration for the shop.

Public Read-only

The demo response contains "demo": true and "automationPaused": true. The undercutPct, minMarginPct, and vatPct fields shown here are read-only on the demo; write them via PUT /api/settings on a real instance.

Parameters

None.

Request

curl --fail-with-body https://haszno.com/api/settings

Response (200)

Field Type Description
id integer Always 1. Settings are a singleton per shop. Absent in the hosted demo response.
undercutPct number Percentage to undercut the market minimum when computing the recommended price.
minMarginPct number Minimum net margin percentage enforced by the floor price.
vatPct number VAT rate used for all gross/net conversions.
shippingMarkets string[] ISO country codes for which market prices are monitored.
automationPaused boolean Whether the automation engine is paused.
shopId integer | null Owning shop. Present on real instances only.
demo boolean Present and true on the hosted demo.
{
  "undercutPct": 1,
  "minMarginPct": 10,
  "vatPct": 27,
  "shippingMarkets": ["HU"],
  "automationPaused": true,
  "demo": true
}

GET/api/impact

Returns the extra profit attributed to Haszno's repricing and new-listing engine over a configurable time window.

Public Read-only

Demo values are computed from synthetic order history. arfutarImpact may exceed profitNet on the demo — this is expected when the attribution formula compares against a hypothetical baseline using synthetic data.

Parameters

Name In Type Required Default Description
days query integer 1–365 No 30 Attribution window in days, counting back from now.
cats query comma-separated string No (all) Restrict to these category keys.

Request

curl --fail-with-body 'https://haszno.com/api/impact?days=30'

Response (200)

Field Type Description
days integer Requested window length.
from ISO-8601 string Window start.
to ISO-8601 string Window end.
orders integer Order count within the window.
revenueGross integer (HUF) Total gross revenue in the window.
profitNet integer (HUF) Total net profit across all orders in the window.
arfutarImpact integer (HUF) Extra profit attributed to Haszno (sum of fromRepricing and fromNewProducts).
fromRepricing integer (HUF) Impact from repriced products.
fromNewProducts integer (HUF) Impact from newly listed products.
lossProductsFixed integer Loss-making products corrected by repricing.
autoForwardedOrders integer Orders forwarded or fulfilled automatically.
minutesPerOrder number Estimated manual minutes saved per order.
items array Per-product attribution breakdown — see sub-fields below.
demo boolean Present and true on the hosted demo.

items sub-fields

Field Type Description
productId integer Product ID.
name string Product name.
kind string "arazas" (repricing) or "felvetel" (new listing).
oldPriceGross integer (HUF) | null Gross price before the change. null for new listings.
newPriceGross integer (HUF) Gross price after the change.
unitsBeforePerDay number Average units sold per day at the old price, before the change.
unitsAfter integer Total units sold after the change within the attribution window.
actualProfit integer (HUF) Actual net profit from units sold after the change.
expectedProfit integer (HUF) Baseline profit at the old price and old sales pace. 0 for new listings.
impact integer (HUF) Profit impact attributed to this product (actualProfit − expectedProfit). 0 when insufficientHistory is true.
insufficientHistory boolean true when there is not enough order history for a reliable calculation. Such items are excluded from the totals.
{
  "days": 30,
  "from": "2026-10-13T14:08:40.424Z",
  "to": "2026-11-12T14:08:40.424Z",
  "orders": 80,
  "revenueGross": 383700,
  "profitNet": 92996,
  "arfutarImpact": 110647,
  "fromRepricing": 66658,
  "fromNewProducts": 43989,
  "lossProductsFixed": 2,
  "autoForwardedOrders": 64,
  "minutesPerOrder": 6,
  "items": [
    {
      "productId": 3,
      "name": "Ablaktörlő · 1. változat",
      "kind": "felvetel",
      "oldPriceGross": null,
      "newPriceGross": 3990,
      "unitsBeforePerDay": 0,
      "unitsAfter": 40,
      "actualProfit": 43989,
      "expectedProfit": 0,
      "impact": 43989,
      "insufficientHistory": false
    }
  ],
  "demo": true
}

GET/api/orders

Returns the last 50 orders, most recent first. The public demo returns an empty array.

Public Read-only

Returns [] on the hosted demo. No synthetic orders are generated for public access. A real instance returns order objects with items and events arrays.

Parameters

None on the demo. A real instance accepts cats (comma-separated category keys) to return only orders with at least one item from those categories.

Request

curl --fail-with-body https://haszno.com/api/orders

Response (200)

Returns an array of order objects (empty on the demo), newest first. Each real order contains: id, externalId, customerName, customerEmail, address, status, supplierOrderId, trackingNumber, totalGross (HUF), events (array of {at, text}), createdAt, forwardingStartedAt, shopId, and items (array of {orderId, qty, priceGross, name, sku}).

[]

GET/api/proposals

Returns price proposals generated by the pricing engine. The public demo returns an empty array.

Public Read-only

Returns [] on the hosted demo.

Parameters

None on the demo. A real instance accepts status (default pending), limit (default 50, max 200) and cats.

Request

curl --fail-with-body https://haszno.com/api/proposals

Response (200)

Returns an array of proposal objects (empty on the demo). Each item: id, productId, productName, productSku, productImage, supplierName, oldPriceGross, proposedPriceGross, reason, source, status ("pending", "approved", "rejected", "rolled_back", "stale"), batchId, createdAt, decidedAt.

[]

GET/api/peers/invites

Returns the shop's outbound peer invite codes. The public demo returns an empty array.

Public Read-only

Parameters

None.

Request

curl --fail-with-body https://haszno.com/api/peers/invites

Response (200)

Returns an array of invite objects (empty on the demo). Each item: id, code, createdBy, supplierId, supplierName, expiresAt, acceptedBy, acceptedAt, revokedAt, createdAt.

[]

Returns established peer links between shops. The public demo returns an empty array.

Public Read-only

Parameters

None.

Request

curl --fail-with-body https://haszno.com/api/peers/links

Response (200)

Returns an array of link objects (empty on the demo). Each item: id, supplierId, partner, createdAt, supplierName, supplierCategory.

[]

GET/api/import-list

Returns the import list — products staged from the partner catalogue before they are pushed to a connected webshop.

Public Read-only

Parameters

Name In Type Required Default Description
status query string No (all) Filter by status: varakozik (waiting), feltoltve (pushed to shop), elvetve (discarded).
q query string No — Case-insensitive substring search on the product name (a real instance also matches the category).

Request

curl --fail-with-body 'https://haszno.com/api/import-list?status=varakozik'

Response (200)

Returns an array of import list items.

Field Type Description
id integer Import list entry ID.
addedAt ISO-8601 string When the item was added to the list.
status string "varakozik", "feltoltve", or "elvetve".
note string | null Optional note added during import.
pushedProductId integer | null ID of the shop product created when this item was pushed.
networkProduct object The source catalogue product — see sub-fields below.

networkProduct sub-fields

Field Type Description
id integer Catalogue product ID.
name string Product name.
imageUrl string | null Product image URL.
sku string Supplier SKU.
wholesaleNet integer (HUF) | null Net wholesale cost.
rrpGross integer (HUF) | null Supplier's recommended retail price.
stock integer Available stock.
category string Category display name (Hungarian label, e.g. "Kert és növény").
supplierName string Supplier display name.
example boolean true for demo/example items.
marginNet integer (HUF) | null Net margin at the RRP: round(rrpGross / (1 + vatPct / 100) − wholesaleNet). null when either price is unknown.
marginPct number | null Margin percentage at the RRP. On the public demo this is the same fixed placeholder (35) as current.marginPct in GET /api/products.
[
  {
    "id": 1,
    "addedAt": "2026-11-10T08:00:00.000Z",
    "status": "varakozik",
    "note": null,
    "pushedProductId": null,
    "networkProduct": {
      "id": 1,
      "name": "Autós telefontartó · 1. változat",
      "imageUrl": null,
      "sku": "DEMO-1",
      "wholesaleNet": 1019,
      "rrpGross": 1990,
      "stock": 0,
      "category": "Autó, gumi és motor",
      "supplierName": "Példa-partner · Autó, gumi és motor",
      "example": true,
      "marginNet": 548,
      "marginPct": 35
    }
  }
]

Blog and market insights

The blog endpoints return real data — published market insight posts generated from aggregated (anonymised, ≥ 5 shops) trend data. No "demo": true flag is present in these responses.


GET/api/blog

Returns all published market insight posts, most recent first.

Public Read-only

Parameters

Name In Type Required Default Description
page query integer ≥ 1 No 1 Page number.
period query "het" | "honap" No (all) Filter to weekly ("het") or monthly ("honap") posts only.

Request

curl --fail-with-body https://haszno.com/api/blog

Response (200)

Field Type Description
posts array Published post summaries — see item fields below.
total integer Total number of published posts matching the filter.
page integer Current page number.
perPage integer Fixed page size (always 10).

Post item fields

Field Type Description
id integer Post ID.
slug string URL slug used in GET /api/blog/:slug.
period "het" | "honap" Aggregation period type: "het" = weekly, "honap" = monthly.
periodStart ISO-8601 date string Start date of the aggregation window (e.g. "2026-11-02").
periodEnd ISO-8601 date string End date of the aggregation window (e.g. "2026-11-08").
title string Post title (Hungarian).
summary string Short summary paragraph.
publishedAt ISO-8601 string Publication timestamp.
coverImageUrl string | null Cover image URL, or null.
{
  "posts": [
    {
      "id": 2,
      "slug": "2026-het45-toplista",
      "period": "het",
      "periodStart": "2026-11-02",
      "periodEnd": "2026-11-08",
      "title": "2026/45. hét — Legjobban fogyó termékek",
      "summary": "A 45. héten párásítók és LED-es világítástechnikai termékek forgalma emelkedett...",
      "publishedAt": "2026-11-09T08:00:00.000Z",
      "coverImageUrl": null
    }
  ],
  "total": 3,
  "page": 1,
  "perPage": 10
}

GET/api/blog/:slug

Returns a single published post by its slug.

Public Read-only

Path parameters

Name Type Description
slug string The post slug from the slug field in GET /api/blog.

Request

curl --fail-with-body https://haszno.com/api/blog/2026-het45-toplista

Response (200)

Returns a single post object. It has no coverImageUrl, unlike the list items.

Field Type Description
id integer Post ID.
slug string URL slug.
period "het" | "honap" Aggregation period type: "het" = weekly, "honap" = monthly.
periodStart ISO-8601 date string Start date of the aggregation window.
periodEnd ISO-8601 date string End date of the aggregation window.
title string Post title (Hungarian).
summary string Short summary paragraph.
bodyMd string Full post content in Markdown.
data object Aggregated figures behind the post: shopsCount, rankedProducts and rankedCategories. Each ranked item has name, units, shopsCount and an optional trend ("emelkedo", "stabil" or "csokkeno"); ranked products may also have imageUrl.
ogTitle string | null Open Graph title; null means the title is used.
publishedAt ISO-8601 string | null Publication timestamp.
status string Always "publikalt" (published) on this endpoint.
createdAt ISO-8601 string When the post was created.
updatedAt ISO-8601 string When the post was last updated.

Append .md to the slug (/api/blog/2026-het45-toplista.md) to get only bodyMd, as text/markdown; charset=utf-8.

Error responses

Status When
404 Slug not found or post is not published.

GET/api/blog/rss.xml

Returns an RSS 2.0 feed of published posts. The response content type is application/rss+xml; charset=utf-8.

Public Read-only

Request

curl --fail-with-body https://haszno.com/api/blog/rss.xml

GET/api/blog/feed.json

Returns a JSON Feed (version 1.1) of published posts. The response content type is application/feed+json; charset=utf-8.

Public Read-only

Request

curl --fail-with-body https://haszno.com/api/blog/feed.json

Utility endpoints

GET/llms.txt

Returns the LLM-readable site summary following the llms.txt convention. Content type: text/plain.

Public Read-only

Request

curl --fail-with-body https://haszno.com/llms.txt