Get scent suggestions
Get relevance-ranked scent suggestions.
Catalog
/api/v1/scent/suggestionsA discovery variant of GET /api/v1/scent/scents. It accepts the SAME query parameters and
returns the SAME PagedScentResponse shape, but results are ordered by relevance — the count
of requested notes + accords each scent matches (highest first), ties broken by the default
name order. Falls back to the default scent order when no note/accord is requested.
Query parameters
pageinteger1-based page number (default 1). A value below 1, or one that is not a whole number, returns 400 VALIDATION_INVALID_PAGE.
pageSizeintegerItems per page, 1 to 100 (default 20). Any other value returns 400 VALIDATION_INVALID_PAGE_SIZE; it is never silently clamped.
langstringLanguage code for localized fields (e.g. ar, en). Falls back to Arabic.
includestringComma-separated extra data. Allowed tokens: profile (fills the profile fields of info), pricing (fills pricing.from). Any other token returns 400 VALIDATION_UNKNOWN_INCLUDE.
idarray of string (uuid)Repeatable — filter to one or more ids (e.g. ?id=a&id=b). An id that does not exist simply matches nothing.
brandIdarray of string (uuid)Repeatable — filter to one or more brands (e.g. ?brandId=a&brandId=b).
concentrationarray of stringRepeatable concentration code (e.g. Edp, Edt, Parfum, EauFraiche), case-insensitive. An unknown code returns 400 VALIDATION_UNKNOWN_LOOKUP_CODE.
audiencearray of stringRepeatable audience code (e.g. Masculine, Feminine, Unisex, Kids), case-insensitive. An unknown code returns 400 VALIDATION_UNKNOWN_LOOKUP_CODE.
notearray of stringRepeatable — match rows whose scent carries at least one of these fragrance notes, any layer (e.g. ?note=Oud¬e=Amber), case-insensitive.
accordarray of stringRepeatable — match rows whose scent carries at least one of these accords (e.g. ?accord=Woody&accord=Floral), case-insensitive.
minPricenumber (decimal)Minimum end-user (consumer) price, inclusive — matched against marketing.currentPrice, not the price you pay.
maxPricenumber (decimal)Maximum end-user (consumer) price, inclusive — matched against marketing.currentPrice, not the price you pay.
changedSincestring (date-time)Only return rows changed strictly after this UTC instant. See the Catalog delta sync guide. Read as UTC when it carries no offset; a date-only value means 00:00Z. An unparseable value, or a from/to pair with from after to, returns 400 VALIDATION_INVALID_DATE.
activeOnlybooleanReturn inactive rows too when false. Must be true or false.
Response
itemsarray of objectpagination.pageintegerpagination.pageSizeintegerpagination.totalCountintegerpagination.totalPagesintegerpagination.hasPreviousbooleanWhether there is a previous page.
pagination.hasNextbooleanWhether there is a next page.
Other responses
400A query parameter was rejected. An unknown concentration/audience code returns VALIDATION_UNKNOWN_LOOKUP_CODE. Everything else uses the shared query codes: VALIDATION_UNKNOWN_QUERY_PARAMETER, VALIDATION_INVALID_QUERY_PARAMETER, VALIDATION_UNKNOWN_INCLUDE, VALIDATION_INVALID_PAGE_SIZE, VALIDATION_INVALID_PAGE, VALIDATION_INVALID_DATE (see the InvalidQuery examples and the Errors guide).401No bearer token (UNAUTHORIZED_MISSING_TOKEN), an invalid token (UNAUTHORIZED_INVALID_TOKEN) or an expired one (UNAUTHORIZED_TOKEN_EXPIRED — mint a new token). UPSTREAM_AUTH_FAILED is different: a dependent service refused the Gateway itself. That is a server-side fault — retry later and do NOT re-mint your token. See the Errors guide.403The route is not available to your credential (FORBIDDEN).404No API route matches this path (NOT_FOUND_ROUTE). A missing resource on a real route returns that service’s own NOT_FOUND_* code instead.429Too many requests — see the Rate limits guide. Retry after the Retry-After header (seconds).502A dependent service returned an invalid response (BAD_GATEWAY). Retry with backoff.503The service is temporarily unavailable (SERVICE_UNAVAILABLE). Retry with backoff.504A dependent service did not respond in time (GATEWAY_TIMEOUT). Retry with backoff.curl --request GET \ --url https://api-omni.linra.net/api/v1/scent/suggestions \ --header 'Authorization: Bearer $TOKEN'const res = await fetch('https://api-omni.linra.net/api/v1/scent/suggestions', { headers: { Authorization: `Bearer ${token}`, },});const { payload } = await res.json();var response = await httpClient.GetAsync("https://api-omni.linra.net/api/v1/scent/suggestions");
var envelope = await response.Content.ReadFromJsonAsync<ApiResponse<PagedScentResponse>>();Response
{ "state": "SUCCESS", "payload": { "items": [ { "id": "5b1e3a1c-9d2e-4f3a-8b1c-9f0a2e3d4c5b", "brandId": "5b1e3a1c-9d2e-4f3a-8b1c-9f0a2e3d4c5b", "name": "string", "description": "string", "images": [ "string" ], "pricing": { "currency": "SAR", "from": 0 }, "info": { "concentration": "string", "productType": "string", "audience": "string", "story": "string", "releaseYear": 0, "perfumer": "string", "countryOfOrigin": "string", "seasons": "string", "dayNight": "string", "longevity": "string", "sillage": "string", "fragranceFamily": "string", "notes": { "top": [], "heart": [], "base": [], "key": [] }, "accords": [ "string" ] } } ], "pagination": { "page": 0, "pageSize": 0, "totalCount": 0, "totalPages": 0, "hasPrevious": true, "hasNext": true } }, "details": null}
