{"openapi":"3.1.0","info":{"title":"Lianex public read API","version":"1.0.0","description":"Lianex provides a free, cache-only read API over its stored shopping catalogue. No API key,\naccount or authentication is required. These endpoints do not fetch live marketplace data.\n\nAvailable now: Australia (prices in AUD). Other marketplaces are in progress. Prices are never converted: a search filtered to a `currency` that is not served returns `result: \"miss\"` with `emptied_by: [\"currency\"]`, `available_regions` and a `retry_url` without the filter.\n\nRunnable examples:\n- https://api.lianex.ai/api/public/search?q=iphone&limit=5\n- https://api.lianex.ai/api/public/search?q=laptop&currency=AUD&max_price=1500&compact=true\n- https://api.lianex.ai/api/public/browse\n\nRate limit: **120 requests per minute per caller**. Read `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (seconds until a slot frees). On `429`, wait the `Retry-After` seconds before retrying. The limit can change.\n\n## Using the results\n\n- Search returns `result: \"hit\"` with products, `\"miss\"` with an empty list, or `\"not_searched\"`\n  when no searchable term was supplied. `not_searched` omits `products` and `has_more`.\n  An empty answer means \"not in our cache\" for that query or page, not that a product does not exist.\n- Use `offset`, `limit` and `has_more` for paging. Results may change between requests; pagination\n  is not a saved snapshot. Search covers a bounded result set, not the entire marketplace.\n  `/products` and `/vs` return their full published index when `limit` is omitted.\n- No catalogue-wide match total is provided. Search `count` and category-browse `total` count only\n  products in that response.\n- Return product `url` links unchanged. They may contain affiliate tracking that supports this free\n  API at no extra cost to shoppers. Disclosure: https://lianex.ai/disclosure\n- Product IDs use `<provider>~~<marketplace-id>`, for example `amazon~~B09B2RL8CG`.\n  IDs without `~~` are eBay IDs, for example `v1~178119112778~0`.\n  Product pages are at `https://lianex.ai/p/<id>`.\n- Additional response fields may appear. Ignore unknown fields and handle missing or null values.\n  Search and category results can omit unavailable fields; product detail can return explicit nulls.\n\nThis public API is best-effort, with no SLA or deprecation policy. The conversational chat API is\noutside this contract. Human documentation: https://lianex.ai/developers\n"},"paths":{"/api/public/browse":{"get":{"summary":"List the published browse categories","description":"List published browse categories with their slug, display name and updated_at freshness. Use a slug with /api/public/browse/{slug} to retrieve its cached products. updated_at is null when no listing is cached. Cache-only.","operationId":"public_browse_index_api_public_browse_get","responses":{"200":{"description":"The published category set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrowseIndexResponse","additionalProperties":true,"type":"object","title":"Response Public Browse Index Api Public Browse Get"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}},"/api/public/browse/{slug}":{"get":{"summary":"Cached products in one published category","description":"Return ranked cached products for a published category. Unknown or unpublished slugs return 404. A renamed slug returns 200 with redirect_to; request that current slug. An empty category returns found: false, noindex: true and products: []. Otherwise found is true; total counts the products in this response, not all marketplace matches. Cache-only.","operationId":"public_browse_category_api_public_browse__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"The category's cached page data, OR — for a slug an admin renamed away from — an object carrying only `redirect_to`.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response 200 Public Browse Category Api Public Browse  Slug  Get","anyOf":[{"$ref":"#/components/schemas/BrowseCategoryPage"},{"$ref":"#/components/schemas/SlugRedirect"}]}}}},"404":{"description":"Unknown or unpublished slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}},"/api/public/product/{safe_id}":{"get":{"summary":"One cached product by permalink id","description":"Return one cached product and any stored cross-marketplace offers. safe_id is the provider-qualified permalink ID, or a provider-less eBay ID. Unknown IDs return 404; removed public products return 410. Unavailable fields may be null. Each offer entry is one marketplace: its matched hits and last_checked, when we last checked that marketplace (ISO 8601). A hit includes in_stock: true only when its stock was confirmed. eBay listings also carry `shipping` (last-seen shipping cost and delivery window) and `return_terms` (returns accepted, window in days, who pays return postage); `gtin` appears when the listing's barcode passes its check digit. Cache-only.","operationId":"public_product_api_public_product__safe_id__get","parameters":[{"name":"safe_id","in":"path","required":true,"schema":{"type":"string","title":"Safe Id"}}],"responses":{"200":{"description":"The cached public product record, plus any stored cross-marketplace offers.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Public Product Api Public Product  Safe Id  Get","$ref":"#/components/schemas/ProductResponse"}}}},"404":{"description":"We hold nothing for that id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"410":{"description":"The product was deliberately removed from our public set.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}},"/api/public/products":{"get":{"summary":"The published product-permalink index","description":"List published product permalink IDs and their updated_at freshness. Use the IDs to request individual products. Omitting limit returns the full published index; otherwise offset, page_size and has_more describe the page. ignored lists unusable paging parameters. Results can change between requests. Cache-only.","operationId":"public_products_api_public_products_get","parameters":[{"name":"offset","in":"query","required":false,"schema":{"type":"string","description":"How many permalinks to skip. Unusable values are ignored and named in `ignored`; a negative value is clamped to 0.","default":"","title":"Offset"},"description":"How many permalinks to skip. Unusable values are ignored and named in `ignored`; a negative value is clamped to 0."},{"name":"limit","in":"query","required":false,"schema":{"type":"string","description":"How many permalinks to return, clamped to 50. OMIT IT and you get the whole index — this is the sitemap's own source, so it is never truncated by default.","default":"","title":"Limit"},"description":"How many permalinks to return, clamped to 50. OMIT IT and you get the whole index — this is the sitemap's own source, so it is never truncated by default."}],"responses":{"200":{"description":"One page of the published `/p/` permalink index.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Public Products Api Public Products Get","$ref":"#/components/schemas/ProductIndexResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}},"/api/public/search":{"get":{"summary":"Search the cached catalogue by free text","description":"Search cached products using query words and, when recognized, their product category. Category matching can include titles that omit the category word; insufficient category evidence falls back to title matching. An explicit category filter replaces automatic category selection. Cache-only: no live marketplace fetch.\n\nRead result first: not_searched omits products and has_more; miss returns products: []; hit returns ranked products. An offset beyond the result set also returns miss. Check filters.applied and filters.ignored to see which inputs were used.\n\nFilters apply before selecting a bounded result pool. A filtered request can return products absent from an unfiltered response. Results are ranked again for each request and may change between pages; offset pagination is not a snapshot. No catalogue-wide total is available.\n\nUse compact or fields to reduce returned product fields without changing matching or ordering. Available now: Australia (prices in AUD); other marketplaces are in progress. Use currency with price bounds when you need prices in one currency. Prices are never converted: a currency that is not served returns miss with emptied_by, available_regions and retry_url. dedupe keeps the first result for each provider and normalized title, so variants with identical titles can be combined.","operationId":"public_search_api_public_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","description":"Search words. Matching uses recognized product categories and title words, with a title-match fallback. Without a searchable term the response is not_searched, even if filters are supplied.","default":"","title":"Q"},"description":"Search words. Matching uses recognized product categories and title words, with a title-match fallback. Without a searchable term the response is not_searched, even if filters are supplied."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum products per page. Values are clamped to the range 1–50. The response echoes the applied page_size. A non-integer value returns 422.","default":24,"title":"Limit"},"description":"Maximum products per page. Values are clamped to the range 1–50. The response echoes the applied page_size. A non-integer value returns 422."},{"name":"min_price","in":"query","required":false,"schema":{"type":"string","description":"Minimum price in each listing's stored currency. Available now: Australia (prices in AUD). Accepts 1500 or $1,500.00. Supply currency to restrict prices to one currency. Invalid values are ignored.","default":"","title":"Min Price"},"description":"Minimum price in each listing's stored currency. Available now: Australia (prices in AUD). Accepts 1500 or $1,500.00. Supply currency to restrict prices to one currency. Invalid values are ignored."},{"name":"max_price","in":"query","required":false,"schema":{"type":"string","description":"Maximum price, parsed like min_price. Available now: Australia (prices in AUD). Supply currency to restrict prices to one currency. A minimum above the maximum yields no matches.","default":"","title":"Max Price"},"description":"Maximum price, parsed like min_price. Available now: Australia (prices in AUD). Supply currency to restrict prices to one currency. A minimum above the maximum yields no matches."},{"name":"condition","in":"query","required":false,"schema":{"type":"string","description":"One of new, refurbished or used. Products with no recorded condition do not match. Invalid values are ignored.","default":"","title":"Condition"},"description":"One of new, refurbished or used. Products with no recorded condition do not match. Invalid values are ignored."},{"name":"marketplace","in":"query","required":false,"schema":{"type":"string","description":"Marketplace: ebay, amazon, aliexpress, jbhifi or shein. Stored locale labels such as EBAY_AU are accepted. Takes precedence over provider.","default":"","title":"Marketplace"},"description":"Marketplace: ebay, amazon, aliexpress, jbhifi or shein. Stored locale labels such as EBAY_AU are accepted. Takes precedence over provider."},{"name":"provider","in":"query","required":false,"schema":{"type":"string","description":"Alias for marketplace. Ignored when marketplace is also supplied.","default":"","title":"Provider"},"description":"Alias for marketplace. Ignored when marketplace is also supplied."},{"name":"brand","in":"query","required":false,"schema":{"type":"string","description":"Exact brand, case-insensitive. Products with no stored brand do not match.","default":"","title":"Brand"},"description":"Exact brand, case-insensitive. Products with no stored brand do not match."},{"name":"fresher_than","in":"query","required":false,"schema":{"type":"string","description":"Only products checked since this relative age (7d, 24h, 30m) or ISO-8601 date/time. Times without a timezone use UTC. Invalid values are ignored.","default":"","title":"Fresher Than"},"description":"Only products checked since this relative age (7d, 24h, 30m) or ISO-8601 date/time. Times without a timezone use UTC. Invalid values are ignored."},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"best_match (default), price (cheapest first) or price_desc (most expensive first). Invalid values use best_match and are listed in filters.ignored.","default":"","title":"Sort"},"description":"best_match (default), price (cheapest first) or price_desc (most expensive first). Invalid values use best_match and are listed in filters.ignored."},{"name":"offset","in":"query","required":false,"schema":{"type":"string","description":"Number of ranked products to skip. Negative values use zero; invalid values use zero and appear in filters.ignored. Results may change between requests.","default":"","title":"Offset"},"description":"Number of ranked products to skip. Negative values use zero; invalid values use zero and appear in filters.ignored. Results may change between requests."},{"name":"compact","in":"query","required":false,"schema":{"type":"string","description":"Set true for title, price, currency, condition, permalink and id only. False or empty returns full products. Invalid values are ignored. The applied selection appears in fields.","default":"","title":"Compact"},"description":"Set true for title, price, currency, condition, permalink and id only. False or empty returns full products. Invalid values are ignored. The applied selection appears in fields."},{"name":"fields","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated product fields, e.g. title,price,url. Overrides compact; id and permalink are always included. Unknown names are dropped. If none are valid, the full projection is returned and fields appears in filters.ignored.","default":"","title":"Fields"},"description":"Comma-separated product fields, e.g. title,price,url. Overrides compact; id and permalink are always included. Unknown names are dropped. If none are valid, the full projection is returned and fields appears in filters.ignored."},{"name":"category","in":"query","required":false,"schema":{"type":"string","description":"Published browse slug (mobile-phones) or numeric eBay category ID (9355), not a display name. Replaces automatic category selection. filters.applied echoes the supplied category and resolved ID.","default":"","title":"Category"},"description":"Published browse slug (mobile-phones) or numeric eBay category ID (9355), not a display name. Replaces automatic category selection. filters.applied echoes the supplied category and resolved ID."},{"name":"currency","in":"query","required":false,"schema":{"type":"string","description":"ISO-4217 currency code. Available now: Australia (prices in AUD); other marketplaces are in progress. Filters to prices stored in that currency and never converts prices. A currency that is not served returns miss with emptied_by, available_regions and retry_url. Use with min_price and max_price.","default":"","title":"Currency"},"description":"ISO-4217 currency code. Available now: Australia (prices in AUD); other marketplaces are in progress. Filters to prices stored in that currency and never converts prices. A currency that is not served returns miss with emptied_by, available_regions and retry_url. Use with min_price and max_price."},{"name":"dedupe","in":"query","required":false,"schema":{"type":"string","description":"Set true to keep the first result for each provider and normalized title, using the selected sort order. Off by default. Variants with identical titles may be combined. deduped counts removed rows in the ranked pool before paging.","default":"","title":"Dedupe"},"description":"Set true to keep the first result for each provider and normalized title, using the selected sort order. Off by default. Variants with identical titles may be combined. deduped counts removed rows in the ranked pool before paging."}],"responses":{"200":{"description":"One of THREE outcomes, discriminated on `result`. Read `result` before you read `products` — `not_searched` omits the `products` key entirely.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response 200 Public Search Api Public Search Get","oneOf":[{"$ref":"#/components/schemas/SearchNotSearched"},{"$ref":"#/components/schemas/SearchMiss"},{"$ref":"#/components/schemas/SearchHit"}],"discriminator":{"propertyName":"result","mapping":{"not_searched":"#/components/schemas/SearchNotSearched","miss":"#/components/schemas/SearchMiss","hit":"#/components/schemas/SearchHit"}}},"examples":{"not_searched":{"summary":"No searchable term — we did NOT look, so `products` is ABSENT (filters do not make a search)","value":{"query":"","cache_only":true,"page_size":24,"offset":0,"sort":"best_match","filters":{"applied":{},"ignored":[]},"searched":false,"result":"not_searched","message":"No search term was supplied, so the cached catalogue was not queried. Pass ?q=<what you are looking for>."}},"miss":{"summary":"We looked — with the filters applied — and hold nothing: `products` is present and EMPTY, plus a message","value":{"query":"iphone 15 pro under a dollar","cache_only":true,"page_size":24,"offset":0,"sort":"best_match","filters":{"applied":{"max_price":1.0},"ignored":[]},"searched":true,"result":"miss","count":0,"has_more":false,"products":[],"message":"Nothing in the Lianex cache matches this search. This endpoint answers from the cached catalogue only and never triggers a live marketplace search, so an empty result means 'not in our cache', not 'this product does not exist'."}},"hit":{"summary":"We hold matches — `products` holds up to `page_size` ranked products in the requested order, `has_more` says whether another page follows, no `message`","value":{"query":"iphone 15 pro","cache_only":true,"page_size":24,"offset":0,"sort":"price","filters":{"applied":{"max_price":2000.0,"condition":"new"},"ignored":[]},"searched":true,"result":"hit","count":1,"has_more":false,"products":[{"id":"v1~178119112778~0","permalink":"/p/v1~178119112778~0","item_id":"v1|178119112778|0","provider":"ebay","title":"Apple iPhone 15 Pro 256GB Natural Titanium — Unlocked","price":"1649.00","currency":"AUD","condition":"New","url":"https://www.ebay.com.au/itm/178119112778","image":"https://i.ebayimg.com/images/g/example/s-l1600.jpg"}]}},"miss_unserved_currency":{"summary":"A currency that is not served — still a `miss`, but it says why: `emptied_by`, `available_regions` and a `retry_url` without the filter","value":{"query":"laptop","cache_only":true,"page_size":2,"offset":0,"sort":"best_match","filters":{"applied":{"currency":"EUR"},"ignored":[]},"searched":true,"result":"miss","count":0,"has_more":false,"products":[],"message":"Nothing in the Lianex catalogue is priced in EUR. Other marketplaces are in progress. Available now: Australia (prices in AUD). Prices are never converted: retry without currency (see retry_url), or with a currency listed in available_regions.","emptied_by":["currency"],"available_regions":[{"country":"AU","name":"Australia","currency":"AUD"}],"retry_url":"/api/public/search?q=laptop&limit=2"}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}},"/api/public/resolve-compare":{"get":{"summary":"Resolve permalink ids to comparable listings","description":"Resolve up to 3 comma-separated product permalink IDs into cached listings for comparison. Each listing includes url, marketplace and item_id, plus title, price and condition when available. Unresolvable IDs and IDs beyond the limit are omitted; an empty set returns listings: []. Cache-only.","operationId":"resolve_compare_api_public_resolve_compare_get","parameters":[{"name":"ids","in":"query","required":false,"schema":{"type":"string","default":"","title":"Ids"}}],"responses":{"200":{"description":"The listings behind the ids we could resolve; unresolvable ids are dropped.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Resolve Compare Api Public Resolve Compare Get","$ref":"#/components/schemas/ResolveCompareResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}},"/api/public/vs":{"get":{"summary":"The published product-comparison index","description":"List published comparisons whose products remain cached, ordered by slug, with updated_at freshness. Omitting limit returns the full published index. Otherwise use offset, page_size and has_more; ignored lists unusable paging parameters. Results may change between requests. Cache-only.","operationId":"public_vs_index_api_public_vs_get","parameters":[{"name":"offset","in":"query","required":false,"schema":{"type":"string","description":"How many pairs to skip. Unusable values are ignored and named in `ignored`; a negative value is clamped to 0.","default":"","title":"Offset"},"description":"How many pairs to skip. Unusable values are ignored and named in `ignored`; a negative value is clamped to 0."},{"name":"limit","in":"query","required":false,"schema":{"type":"string","description":"How many pairs to return, clamped to 50. OMIT IT and you get the whole index — this is the sitemap's own source, so it is never truncated by default.","default":"","title":"Limit"},"description":"How many pairs to return, clamped to 50. OMIT IT and you get the whole index — this is the sitemap's own source, so it is never truncated by default."}],"responses":{"200":{"description":"One page of the published `/vs/` comparison index.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Public Vs Index Api Public Vs Get","$ref":"#/components/schemas/VsIndexResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}},"/api/public/vs/{slug}":{"get":{"summary":"One canonical product comparison","description":"Return a published comparison with columns, rows, summary and product sides. Unknown, retired or suppressed slugs return 404; missing cached products return 410. A non-canonical product order returns 200 with redirect_to naming the canonical slug. Cache-only.","operationId":"public_vs_api_public_vs__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"The comparison payload, OR — for a slug naming the same products in another order — an object carrying only `redirect_to`.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response 200 Public Vs Api Public Vs  Slug  Get","anyOf":[{"$ref":"#/components/schemas/VsPage"},{"$ref":"#/components/schemas/SlugRedirect"}]}}}},"404":{"description":"Unknown, retired or moderation-suppressed slug.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"410":{"description":"A comparison whose sides are no longer cached.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}},"/api/public/share/comparison/{snapshot_id}":{"get":{"summary":"A historical comparison-link redirect","description":"Resolve a historical shared-comparison token to its canonical comparison slug. A successful response contains redirect_to and result: \"redirect\"; it does not return the historical comparison body. Unknown or retired tokens return 404. Cache-only.","operationId":"public_share_comparison_api_public_share_comparison__snapshot_id__get","parameters":[{"name":"snapshot_id","in":"path","required":true,"schema":{"type":"string","title":"Snapshot Id"}}],"responses":{"200":{"description":"The canonical `/vs/` slug for that shared comparison.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Public Share Comparison Api Public Share Comparison  Snapshot Id  Get","$ref":"#/components/schemas/ShareRedirectResponse"}}}},"404":{"description":"Unknown or retired snapshot id.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"429":{"description":"Rate limit reached. Retry the same request after the `Retry-After` delay in seconds. `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` describe the current budget. These headers are also returned on successful requests while rate limiting is enabled. When disabled, rate-limit headers are absent.","headers":{"Retry-After":{"description":"Whole seconds to wait before retrying. Never less than one second.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"The per-caller budget in force for the current window.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"What is left of that budget — zero on this response, by definition.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Whole seconds until a slot frees.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"title":"RateLimited","type":"object","properties":{"detail":{"type":"string","description":"A short human-readable reason. Read the headers, not this string, to decide when to retry."}},"required":["detail"],"additionalProperties":true}}}}}}}},"components":{"schemas":{"AvailableRegion":{"properties":{"country":{"type":"string","title":"Country","description":"ISO 3166-1 alpha-2 country code of the region."},"name":{"type":"string","title":"Name","description":"The region's display name."},"currency":{"type":"string","title":"Currency","description":"ISO 4217 code the region's listings are priced in."}},"additionalProperties":true,"type":"object","required":["country","name","currency"],"title":"AvailableRegion","description":"A region served now, with its country code, display name and price currency."},"BrowseCard":{"properties":{"item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Item Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition"},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image","description":"Primary image URL."},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","description":"Affiliate-wrapped outbound link."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Why the ranker placed this card here."},"offers":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Offers","description":"Number of grouped offers represented by this card. Product detail instead uses offers for a list."},"from_price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"From Price","description":"Lowest price across the grouped offers."},"bucket":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bucket","description":"The condition bucket this card landed in."},"badges":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Badges","description":"Display badges the ranker assigned."},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"The marketplace routing token — build the `/p/` permalink from it. Added by the endpoint, not by the card projection."}},"additionalProperties":true,"type":"object","title":"BrowseCard","description":"A ranked category product card. Its fields differ from product detail; offers is a count of grouped offers."},"BrowseCategoryEntry":{"properties":{"slug":{"type":"string","title":"Slug","description":"The category's slug — the `{slug}` of `/api/public/browse/{slug}`."},"name":{"type":"string","title":"Name","description":"Display name."},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"ISO-8601 freshness of the newest cached listing in this category, or null when none is available."}},"additionalProperties":true,"type":"object","required":["slug","name","updated_at"],"title":"BrowseCategoryEntry"},"BrowseCategoryPage":{"properties":{"slug":{"type":"string","title":"Slug"},"category_id":{"type":"string","title":"Category Id"},"name":{"type":"string","title":"Name"},"h1":{"type":"string","title":"H1","description":"The page's H1, which may be a keyword-intent variant of `name`."},"qualifier":{"type":"string","title":"Qualifier","description":"The page's keyword qualifier within its category (e.g. `gaming`), or empty for a whole-category page. The in-app Browse hand-off sends the category id plus only this text.","default":""},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"siblings":{"items":{"$ref":"#/components/schemas/BrowseSibling"},"type":"array","title":"Siblings","description":"The other published categories, for nav."},"found":{"type":"boolean","title":"Found","description":"`false` means we hold NO cached listings — not that the category is unknown."},"noindex":{"type":"boolean","title":"Noindex","description":"`true` on the soft-empty page, so it is never indexed."},"products":{"items":{"$ref":"#/components/schemas/BrowseCard"},"type":"array","title":"Products","description":"The ranked cached cards, or `[]`."},"total":{"type":"integer","title":"Total","description":"Number of products in this response, not a catalogue-wide match total."},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"Freshest cached listing in the category, or `null`."}},"additionalProperties":true,"type":"object","required":["slug","category_id","name","h1","siblings","found","noindex","products","total","updated_at"],"title":"BrowseCategoryPage","description":"Cached products for a published category. found: false means no cached products are available; products is empty and noindex is true."},"BrowseIndexResponse":{"properties":{"categories":{"items":{"$ref":"#/components/schemas/BrowseCategoryEntry"},"type":"array","title":"Categories","description":"The published category set."}},"additionalProperties":true,"type":"object","required":["categories"],"title":"BrowseIndexResponse","description":"Every category that has a published Lianex page."},"BrowseSibling":{"properties":{"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"}},"additionalProperties":true,"type":"object","required":["slug","name"],"title":"BrowseSibling"},"CompareListing":{"properties":{"url":{"type":"string","title":"Url","description":"Affiliate-wrapped outbound link."},"marketplace":{"type":"string","title":"Marketplace","description":"The registry ROUTING TOKEN (`ebay`, `amazon`, …), not the stored locale label."},"item_id":{"type":"string","title":"Item Id","description":"The marketplace's full id, variation included."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Present only when we hold one."},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price","description":"Present only when we hold one."},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition","description":"Present only when we hold one."}},"additionalProperties":true,"type":"object","required":["url","marketplace","item_id"],"title":"CompareListing","description":"A resolved cached listing suitable for comparison."},"ErrorDetail":{"properties":{"detail":{"type":"string","title":"Detail","description":"Why the request could not be answered."}},"additionalProperties":true,"type":"object","required":["detail"],"title":"ErrorDetail","description":"An error response with a human-readable explanation."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ProductIndexEntry":{"properties":{"id":{"type":"string","title":"Id","description":"The permalink id — its page is `https://lianex.ai/p/<id>`."},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"ISO-8601 freshness, or `null`."}},"additionalProperties":true,"type":"object","required":["id","updated_at"],"title":"ProductIndexEntry"},"ProductIndexResponse":{"properties":{"products":{"items":{"$ref":"#/components/schemas/ProductIndexEntry"},"type":"array","title":"Products"},"offset":{"type":"integer","title":"Offset","description":"The offset actually applied (a negative request is clamped to 0)."},"page_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page Size","description":"The page size actually applied, or `null` when the whole index was returned."},"has_more":{"type":"boolean","title":"Has More","description":"Whether another page follows in the current result set."},"ignored":{"items":{"type":"string"},"type":"array","title":"Ignored","description":"Names of paging parameters we could not use. A bad value is ignored, never refused."}},"additionalProperties":true,"type":"object","required":["products","offset","page_size","has_more","ignored"],"title":"ProductIndexResponse","description":"Published product permalink IDs. Omit limit to return the full index; page_size is then null."},"ProductResponse":{"properties":{"item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Item Id","description":"The marketplace's own id for this listing."},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"The marketplace routing token: `ebay`, `amazon`, `aliexpress`, `jbhifi`, `shein`."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"The listing title as the marketplace states it."},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand","description":"The brand: the stored brand, else the listing's own Brand / Brand Name item specific — never a placeholder such as Unbranded."},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition","description":"The stored condition label, when we recorded one."},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price","description":"The price as a decimal STRING (`\"1649.00\"`), never a float — so it cannot lose cents to binary rounding on the way to you."},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency","description":"ISO currency code of `price`."},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image","description":"The primary image URL."},"images":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Images","description":"Additional gallery image URLs. May be empty."},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","description":"The affiliate-wrapped outbound link. `null` when the marketplace is switched off."},"marketplace":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marketplace","description":"The STORED locale label (`EBAY_AU`), which is not the same string as `provider`."},"category_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Id","description":"The marketplace category id we cached it under."},"category_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Name","description":"That category's display name."},"specifics":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Specifics","description":"The listing's own item specifics, minus empty/placeholder values."},"canonical_specs":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Canonical Specs","description":"The merged canonical spec sheet, when one could be derived."},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"ISO-8601 instant this listing was last re-checked."},"availability":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Availability","description":"`InStock` or `OutOfStock`, rolled up across every stored lane."},"gtin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gtin","description":"A GS1 barcode number (8, 12, 13 or 14 digits) from the listing's item specifics, included only when its check digit is valid."},"shipping":{"anyOf":[{"$ref":"#/components/schemas/ShippingTerms"},{"type":"null"}],"description":"eBay listings only: the listing's cheapest shipping option as last seen — cost, currency, cost type and the delivery-estimate window. Null for other marketplaces or when unknown."},"return_terms":{"anyOf":[{"$ref":"#/components/schemas/ReturnTerms"},{"type":"null"}],"description":"eBay listings only: whether returns are accepted, the return window in days, and who pays return postage. Null for other marketplaces or when unknown."},"id":{"type":"string","title":"Id","description":"The permalink id you asked for, echoed back."},"offers":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Offers","description":"Public-safe stored cross-marketplace offers, one entry per marketplace: marketplace, hits, and last_checked (ISO 8601, when that marketplace was last checked; absent when unknown). A hit includes in_stock: true only when its stock was confirmed. Never seller PII."},"seller_task_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seller Task Status","description":"Read-only status of any in-flight who-sells lane for this product. Reading it never schedules work."},"browse_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Browse Slug","description":"The published `/b/` category this product belongs to, or `null`."},"browse_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Browse Name","description":"That category's display name, or `null`."},"provider_disabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Provider Disabled","description":"Present and `true` only when this product's marketplace is switched off, in which case `url` is `null`. Absent otherwise."}},"additionalProperties":true,"type":"object","required":["id","offers"],"title":"ProductResponse","description":"A cached product detail record. Unavailable values may be explicit nulls."},"PublicProduct":{"properties":{"item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Item Id","description":"The marketplace's own id for this listing."},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"The marketplace routing token: `ebay`, `amazon`, `aliexpress`, `jbhifi`, `shein`."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"The listing title as the marketplace states it."},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand","description":"The brand: the stored brand, else the listing's own Brand / Brand Name item specific — never a placeholder such as Unbranded."},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition","description":"The stored condition label, when we recorded one."},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price","description":"The price as a decimal STRING (`\"1649.00\"`), never a float — so it cannot lose cents to binary rounding on the way to you."},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency","description":"ISO currency code of `price`."},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image","description":"The primary image URL."},"images":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Images","description":"Additional gallery image URLs. May be empty."},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","description":"The affiliate-wrapped outbound link. `null` when the marketplace is switched off."},"marketplace":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marketplace","description":"The STORED locale label (`EBAY_AU`), which is not the same string as `provider`."},"category_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Id","description":"The marketplace category id we cached it under."},"category_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Name","description":"That category's display name."},"specifics":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Specifics","description":"The listing's own item specifics, minus empty/placeholder values."},"canonical_specs":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Canonical Specs","description":"The merged canonical spec sheet, when one could be derived."},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"ISO-8601 instant this listing was last re-checked."},"availability":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Availability","description":"`InStock` or `OutOfStock`, rolled up across every stored lane."},"gtin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gtin","description":"A GS1 barcode number (8, 12, 13 or 14 digits) from the listing's item specifics, included only when its check digit is valid."},"shipping":{"anyOf":[{"$ref":"#/components/schemas/ShippingTerms"},{"type":"null"}],"description":"eBay listings only: the listing's cheapest shipping option as last seen — cost, currency, cost type and the delivery-estimate window. Null for other marketplaces or when unknown."},"return_terms":{"anyOf":[{"$ref":"#/components/schemas/ReturnTerms"},{"type":"null"}],"description":"eBay listings only: whether returns are accepted, the return window in days, and who pays return postage. Null for other marketplaces or when unknown."}},"additionalProperties":true,"type":"object","title":"PublicProduct","description":"A cached product. Pass its outbound url unchanged to preserve affiliate tracking. Fields may be missing or null when unavailable."},"ResolveCompareResponse":{"properties":{"listings":{"items":{"$ref":"#/components/schemas/CompareListing"},"type":"array","title":"Listings"}},"additionalProperties":true,"type":"object","required":["listings"],"title":"ResolveCompareResponse","description":"Resolved cached listings. Unresolvable IDs and IDs beyond the request limit are omitted; an empty set returns listings: []."},"ReturnTerms":{"properties":{"accepted":{"type":"boolean","title":"Accepted","description":"Whether the seller accepts returns."},"period_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Period Days","description":"The return window in calendar days, when stated."},"return_postage_payer":{"anyOf":[{"type":"string","enum":["BUYER","SELLER"]},{"type":"null"}],"title":"Return Postage Payer","description":"Who pays return postage, when stated: BUYER or SELLER."}},"additionalProperties":true,"type":"object","required":["accepted"],"title":"ReturnTerms","description":"An eBay listing's return terms as last seen."},"SearchFilters":{"properties":{"applied":{"additionalProperties":true,"type":"object","title":"Applied","description":"The normalised filters that were actually used."},"ignored":{"items":{"type":"string"},"type":"array","title":"Ignored","description":"NAMES of parameters we could not use — read this before trusting a result to be filtered or paged. `sort` and `offset` appear here too."}},"additionalProperties":true,"type":"object","required":["applied","ignored"],"title":"SearchFilters"},"SearchHit":{"properties":{"result":{"type":"string","const":"hit","title":"Result"},"query":{"type":"string","title":"Query"},"cache_only":{"type":"boolean","const":true,"title":"Cache Only"},"page_size":{"type":"integer","title":"Page Size"},"offset":{"type":"integer","title":"Offset"},"sort":{"type":"string","title":"Sort"},"filters":{"$ref":"#/components/schemas/SearchFilters"},"searched":{"type":"boolean","const":true,"title":"Searched"},"count":{"type":"integer","title":"Count","description":"Number of products on this page, not a catalogue-wide match total."},"has_more":{"type":"boolean","title":"Has More","description":"Whether another page follows. Read this instead of a total."},"products":{"items":{"$ref":"#/components/schemas/SearchProduct"},"type":"array","title":"Products"},"fields":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Fields","description":"Included when field selection is applied. Lists the selected product fields; unavailable fields may still be omitted from individual products. Absent for the full projection."},"deduped":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Deduped","description":"Number of duplicate rows removed from the ranked result pool before paging. Present only when dedupe is enabled; this is not the duplicate count on the current page. Deduplication keeps the first row for each provider and normalized title."}},"additionalProperties":true,"type":"object","required":["result","query","cache_only","page_size","offset","sort","filters","searched","count","has_more","products"],"title":"SearchHit","description":"A page of ranked cached products, containing up to page_size results."},"SearchMiss":{"properties":{"result":{"type":"string","const":"miss","title":"Result"},"query":{"type":"string","title":"Query"},"cache_only":{"type":"boolean","const":true,"title":"Cache Only"},"page_size":{"type":"integer","title":"Page Size"},"offset":{"type":"integer","title":"Offset"},"sort":{"type":"string","title":"Sort"},"filters":{"$ref":"#/components/schemas/SearchFilters"},"searched":{"type":"boolean","const":true,"title":"Searched"},"count":{"type":"integer","title":"Count","description":"Always 0 on this variant."},"has_more":{"type":"boolean","title":"Has More"},"products":{"items":{"$ref":"#/components/schemas/PublicProduct"},"type":"array","title":"Products","description":"Always empty on this variant."},"message":{"type":"string","title":"Message","description":"Explains that an empty result is a cache miss, not a non-existence claim."},"emptied_by":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Emptied By","description":"Present only when a filter alone guarantees an empty result — today only a currency that is not served: [\"currency\"]. Absent on every other miss."},"available_regions":{"anyOf":[{"items":{"$ref":"#/components/schemas/AvailableRegion"},"type":"array"},{"type":"null"}],"title":"Available Regions","description":"Present with emptied_by: the regions served now (Australia (prices in AUD)), each with its country code, name and currency."},"retry_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Retry Url","description":"Present with emptied_by: this request's path and query without the emptying filter, relative to the API origin."}},"additionalProperties":true,"type":"object","required":["result","query","cache_only","page_size","offset","sort","filters","searched","count","has_more","products","message"],"title":"SearchMiss","description":"No cached products matched this query or page position. products is empty and message explains the result. This does not mean the product does not exist."},"SearchNotSearched":{"properties":{"result":{"type":"string","const":"not_searched","title":"Result","description":"Read this BEFORE you read anything else."},"query":{"type":"string","title":"Query"},"cache_only":{"type":"boolean","const":true,"title":"Cache Only","description":"Always `true`: no endpoint here can trigger a fetch."},"page_size":{"type":"integer","title":"Page Size"},"offset":{"type":"integer","title":"Offset"},"sort":{"type":"string","title":"Sort"},"filters":{"$ref":"#/components/schemas/SearchFilters"},"searched":{"type":"boolean","const":false,"title":"Searched"},"message":{"type":"string","title":"Message","description":"Says in as many words that no search term was supplied."}},"additionalProperties":true,"type":"object","required":["result","query","cache_only","page_size","offset","sort","filters","searched","message"],"title":"SearchNotSearched","description":"No searchable term was supplied. products and has_more are absent. Do not display this as a search with no matches. offset echoes the requested position."},"SearchProduct":{"properties":{"item_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Item Id","description":"The marketplace's own id for this listing."},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"The marketplace routing token: `ebay`, `amazon`, `aliexpress`, `jbhifi`, `shein`."},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"The listing title as the marketplace states it."},"brand":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand","description":"The brand: the stored brand, else the listing's own Brand / Brand Name item specific — never a placeholder such as Unbranded."},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition","description":"The stored condition label, when we recorded one."},"price":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Price","description":"The price as a decimal STRING (`\"1649.00\"`), never a float — so it cannot lose cents to binary rounding on the way to you."},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency","description":"ISO currency code of `price`."},"image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Image","description":"The primary image URL."},"images":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Images","description":"Additional gallery image URLs. May be empty."},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","description":"The affiliate-wrapped outbound link. `null` when the marketplace is switched off."},"marketplace":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Marketplace","description":"The STORED locale label (`EBAY_AU`), which is not the same string as `provider`."},"category_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Id","description":"The marketplace category id we cached it under."},"category_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Name","description":"That category's display name."},"specifics":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Specifics","description":"The listing's own item specifics, minus empty/placeholder values."},"canonical_specs":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Canonical Specs","description":"The merged canonical spec sheet, when one could be derived."},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"ISO-8601 instant this listing was last re-checked."},"availability":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Availability","description":"`InStock` or `OutOfStock`, rolled up across every stored lane."},"gtin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Gtin","description":"A GS1 barcode number (8, 12, 13 or 14 digits) from the listing's item specifics, included only when its check digit is valid."},"shipping":{"anyOf":[{"$ref":"#/components/schemas/ShippingTerms"},{"type":"null"}],"description":"eBay listings only: the listing's cheapest shipping option as last seen — cost, currency, cost type and the delivery-estimate window. Null for other marketplaces or when unknown."},"return_terms":{"anyOf":[{"$ref":"#/components/schemas/ReturnTerms"},{"type":"null"}],"description":"eBay listings only: whether returns are accepted, the return window in days, and who pays return postage. Null for other marketplaces or when unknown."},"id":{"type":"string","title":"Id","description":"The URL-safe permalink id."},"permalink":{"type":"string","title":"Permalink","description":"`/p/<id>` — the human page for this product."}},"additionalProperties":true,"type":"object","required":["id","permalink"],"title":"SearchProduct","description":"A cached search result. id and permalink are always present. Other fields may be omitted when unavailable or excluded by field selection. Use product detail for stored offers and browse-category links."},"ShareRedirectResponse":{"properties":{"redirect_to":{"type":"string","title":"Redirect To","description":"The comparison set's one canonical descriptive `/vs/` slug."},"result":{"type":"string","const":"redirect","title":"Result"}},"additionalProperties":true,"type":"object","required":["redirect_to","result"],"title":"ShareRedirectResponse","description":"The canonical comparison slug for a historical shared link. The historical comparison body is not returned."},"ShippingTerms":{"properties":{"cost":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost","description":"Shipping cost as a decimal STRING; \"0.00\" means free."},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency","description":"ISO currency code of `cost`."},"cost_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cost Type","description":"eBay's shipping cost type, e.g. FIXED or CALCULATED."},"min_delivery":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Min Delivery","description":"ISO-8601 instant: the earliest estimated delivery date eBay quoted when we last saw the listing. An estimate, not a promise; it can be in the past."},"max_delivery":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Max Delivery","description":"ISO-8601 instant: the latest estimated delivery date eBay quoted when we last saw the listing. An estimate, not a promise; it can be in the past."},"captured_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Captured At","description":"ISO-8601 instant we read this delivery estimate; the estimate window is relative to it."}},"additionalProperties":true,"type":"object","title":"ShippingTerms","description":"An eBay listing's cheapest shipping option as last seen. Any field may be null when eBay did not state it."},"SlugRedirect":{"properties":{"redirect_to":{"type":"string","title":"Redirect To","description":"The slug to follow. Not a URL — a slug."}},"additionalProperties":true,"type":"object","required":["redirect_to"],"title":"SlugRedirect","description":"The requested address has a current canonical slug. This JSON response uses status 200. Request the returned slug on the same endpoint."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VsComparison":{"properties":{"columns":{"items":{},"type":"array","title":"Columns","description":"One column per compared product, in the frozen order."},"rows":{"items":{},"type":"array","title":"Rows","description":"The aligned attribute rows."},"summary":{"title":"Summary","description":"The frozen prose summary."}},"additionalProperties":true,"type":"object","required":["columns","rows"],"title":"VsComparison","description":"The stored comparison content: product columns, comparison rows and summary."},"VsIndexEntry":{"properties":{"slug":{"type":"string","title":"Slug","description":"The `{slug}` of `/api/public/vs/{slug}`."},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At","description":"ISO-8601 freshness of the fresher side, or `null`."}},"additionalProperties":true,"type":"object","required":["slug","updated_at"],"title":"VsIndexEntry"},"VsIndexResponse":{"properties":{"pairs":{"items":{"$ref":"#/components/schemas/VsIndexEntry"},"type":"array","title":"Pairs"},"offset":{"type":"integer","title":"Offset"},"page_size":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page Size"},"has_more":{"type":"boolean","title":"Has More","description":"Read this instead of a total; no total is reported."},"ignored":{"items":{"type":"string"},"type":"array","title":"Ignored"}},"additionalProperties":true,"type":"object","required":["pairs","offset","page_size","has_more","ignored"],"title":"VsIndexResponse","description":"Published comparisons ordered by slug. Omit limit to return the full index; page_size is then null. Results may change between requests."},"VsPage":{"properties":{"result":{"type":"string","const":"ok","title":"Result"},"slug":{"type":"string","title":"Slug"},"category_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Id"},"category_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category Name"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"sides":{"items":{"$ref":"#/components/schemas/PublicProduct"},"type":"array","title":"Sides","description":"The compared products, two or three of them."},"comparison":{"$ref":"#/components/schemas/VsComparison"},"siblings":{"items":{"$ref":"#/components/schemas/VsSibling"},"type":"array","title":"Siblings"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"},"a":{"anyOf":[{"$ref":"#/components/schemas/PublicProduct"},{"type":"null"}],"description":"Alias for `sides[0]`, present only on a two-sided comparison."},"b":{"anyOf":[{"$ref":"#/components/schemas/PublicProduct"},{"type":"null"}],"description":"Alias for `sides[1]`, present only on a two-sided comparison."}},"additionalProperties":true,"type":"object","required":["result","slug","sides","comparison"],"title":"VsPage","description":"A published head-to-head comparison of two or three cached products."},"VsSibling":{"properties":{"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"}},"additionalProperties":true,"type":"object","required":["slug","title"],"title":"VsSibling"}}},"servers":[{"url":"https://api.lianex.ai"}],"externalDocs":{"description":"Developer documentation","url":"https://lianex.ai/developers"}}