Welcome to nyris' API Documentation. nyris is a high performance visual product search, object detection and visual recommendations engine for retail and industry. This documentation covers our visual product search engine and the visual recommendations engine.
The implementation in your website or app comprises of three steps.
1. Submit your product & image data
In order to recognize your products, we need to know your products. The product feed section covers all details how to submit your product data to us and the specifications for your product or object images.
2. Implement nyris API in your app, website or messenger bot
The nyris engine can be integrated in your app, website, messenger bots, BI solutions - wherever you want to make your customers happy or optimize your data management process. We provide you with code examples on how to query our Find API and Regions API and have ready to go SDKs for iOS and Android.
3. Implement automated feedback in your app, website or messenger bot
By tying user interactions to automated feedback in our Feedback API, you allow for automatic statistic generation and continous improvement of the
search results.
To get started, email us at mailto:support@nyris.io. Our team will provision API keys to access our API. Always feel free to contact us should you have questions or suggestions for our service or this documentation. In addition, you can always find our open source code github.com/nyris.
Try it with Postman — You can explore and test the nyris API directly using our public Postman workspace. It includes ready-to-use collections for Find, Recommend, Regions, and Images APIs.
Thank You & happy coding!
Markus (CTO / Founder)
All nyris API requests require an API key passed in the X-Api-Key header.
How do I get an API key?
To get started, email us at support@nyris.io. Our team will provision an API key for you.
What if I don't want to share the API key with front-end users?
If you want to control each request, you can create your own proxy that forwards the requests to the nyris API. That way you can have your own authentication method and control over each request.
Send an image to the Find API and receive a JSON object with metadata for the identified items. You can optionally pass a session ID to correlate multiple requests.
POST https://api.nyris.io/find/v1.1
To search with filters, send the image and filter fields as multipart/form-data. Filtered responses include only items matching the given filter types and values. You can also append a session ID as a query parameter: POST https://api.nyris.io/find/v1.1?session=xxxxxx.
Request Headers
Key | Value
---|---
X-Api-Key | The API key provided by us.
Content-Type | image/jpeg, image/png, multipart/form-data (filters), or application/json (base64).
Content-Length | The size of image in bytes.
Accept | (Optional) application/items.complete+json for the full response format. Default is minimal.
X-Session | (Optional) A valid session identifier to correlate multiple requests.
X-Options | (Optional) Search parameters, e.g. limit=10 threshold=0.5. See below.
If no value is provided for X-Session (or the session query argument), a new session is started and its ID is returned with the response. Front-ends are encouraged to pass the session ID returned by the previous request to the next request, thereby linking requests together.
Request Body
Content-Type: image/jpeg or image/png.multipart/form-data and include the image plus the filter fields described below.Content-Type: application/json with a JSON object containing the image as a base64-encoded string. This is convenient for clients that work with JSON APIs end-to-end and avoids managing binary or multipart boundaries.JSON Body Schema
Field | Type | Required | Description
---|---|---|---
image | String | Yes | Base64-encoded image (plain or data URI, e.g. data:image/jpeg;base64,...).
text | String | No | Optional text query (max 512 characters).
filters | Array | No | Same filter format as multipart: [{"key": "MachineSerial", "values": ["SN-40821"]}].
Note: base64 encoding increases payload size by ~33%. Stay within the usual image size limits.
Filter Schema (multipart)
When sending filters via multipart/form-data, include one or more filter type/value pairs. The AND operator is used between filter types; OR is used between values of the same type.
Name | Type | Explanation
---|---|---
filterType | String | The filter type, example: color
filterValues | String [] | The filter values, example: [red, blue]
Search Parameters (X-Options)
Control result count and score thresholds via the X-Options header. Parameters are key=value pairs separated by a space, e.g. X-Options: limit=10 threshold=0.5.
Parameter | Example Value | Explanation
---|---|---
limit | limit=20 (default), integers between 1 and 100 | The upper limit for the number of results to be returned.
threshold | threshold=0.8 | The final threshold to apply to the scores. Only results above or equal to that score will be returned.
Response Headers
Requests are automatically tagged with a Request ID and a Session ID:
Key | Value
---|---
X-Matching-Request | The identifier of the request; used for tracing and with the Feedback API.
X-Session | A session identifier covering multiple requests; used for tracing and with the Feedback API.
Response Format
By default, a minimal response is returned. Use the Accept header to request the full format:
Accept value | Description
---|---
application/minimal+json | Return minimal response (the default).
application/items.complete+json | Return all available fields.
We guarantee that existing fields will not be removed or have their type changed. Additional fields can be added at any point; application code should gracefully ignore unknown fields.
Image Requirements
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.nyris.io/find/v1.1")
.post(null)
.addHeader("x-api-key", "KEY")
.addHeader("x-session", "...")
.addHeader("content-type", "image/jpeg")
.addHeader("content-length", "image-file-size-in-bytes")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
OkHttpClient client = new OkHttpClient();
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("filters[0].filterType","color")
.addFormDataPart("filters[0].filterValues[0]","Red")
.addFormDataPart("image","image.jpg",
RequestBody.create(MediaType.parse("application/octet-stream"),
new File("image.jpg")))
.build();
Request request = new Request.Builder()
.url("https://api.nyris.io/find/v1.1")
.method("POST", body)
.addHeader("x-api-key", "<SET_YOUR_KEY_HERE>")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
{
"image": "/9j/4AAQSkZJRg...",
"text": "hydraulics",
"filters": [
{
"key": "MachineSerial",
"values": ["SN-40821"]
},
{
"key": "Assembly",
"values": ["Hydraulics", "Pneumatics"]
}
]
}
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
OkHttpClient client = new OkHttpClient();
byte[] imageBytes = Files.readAllBytes(Path.of("image.jpg"));
String imageB64 = Base64.getEncoder().encodeToString(imageBytes);
String json = "{"
+ "\"image\":\"" + imageB64 + "\","
+ "\"text\":\"hydraulics\","
+ "\"filters\":["
+ "{\"key\":\"MachineSerial\",\"values\":[\"SN-40821\"]},"
+ "{\"key\":\"Assembly\",\"values\":[\"Hydraulics\",\"Pneumatics\"]}"
+ "]}";
RequestBody body = RequestBody.create(
MediaType.parse("application/json"), json);
Request request = new Request.Builder()
.url("https://api.nyris.io/find/v1.1")
.post(body)
.addHeader("x-api-key", "KEY")
.build();
Response response = client.newCall(request).execute();
{
"id": "c7ac45c0165a54feb005aa2049f19235",
"session": "c7ac45c0165a54feb005aa2049f19235",
"results": [
{
"sku": "123454643",
"score": 0.96
},
{
"sku": "123454644",
"score": 0.92
},
{
"sku": "123454645",
"score": 0.88
},
{
"sku": "123454646",
"score": 0.83
}
]
}
{
"id": "c7ac45c0165a54feb005aa2049f19235",
"session": "c7ac45c0165a54feb005aa2049f19235",
"results": [{
"title": "test product",
"descriptionShort": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr.",
"descriptionLong": "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat.",
"language": "de-DE",
"brand": "test brand",
"catalogNumbers": ["test_catalog_number_0", "test_catalog_number_1"],
"customIds": {
"DEMO_CUSTOM_ID": "DEMO_ID_123"
},
"keywords": ["demo", "demonstration", "test"],
"categories": ["Demo", "Test"],
"availability": "in stock",
"feedId": "1",
"groupId": "1",
"price": "10.00 EUR",
"salePrice": "1.00 EUR",
"links": {
"main": "https://example.com/product/123",
"mobile": "https://example.com/product/123/thumbnail.jpg"
},
"images": ["https://img.nyris.io/example1.jpg", "https://img.nyris.io/example2.jpg"],
"metadata": "This product is for demonstrations only",
"sku": "123456",
"score": 1,
"filters": {
"color": ["Red"],
"product": ["Shoes"]
}
}]
}
If products have geolocation data, you can narrow results by distance. Coordinates must be in WGS84 format.
When using multipart/form-data (for filters), pass geolocation as form fields. Otherwise, use query parameters: POST https://api.nyris.io/find/v1.1?lat=LAT&lon=LON&dist=DIST.
Name | Example | Explanation
--|--|--
lat | 52.5200 | The latitude of the user.
lon | 13.4050 | The longitude of the user.
dist | 10000 | The maximum distance from the center in meters.
The Find API matches on the entire image. For images containing multiple objects, you may want to detect and crop to specific areas first. The Regions API identifies parts of the image likely to contain relevant objects, allowing your UI to propose sections of the image for the user to search with.
POST https://api.nyris.io/find/v2/regions
Request Headers
Key | Value
---|---
X-Api-Key | The API key provided by us.
Content-Type | image/jpeg, image/png, multipart/form-data, or application/json (base64).
Content-Length | The size of image in bytes (for binary uploads).
Request Body
Content-Type: image/jpeg or image/png.multipart/form-data and include the image as a file field named image.Content-Type: application/json with a JSON object containing the image as a base64-encoded string.JSON Body Schema
Field | Type | Required | Description
---|---|---|---
image | String | Yes | Base64-encoded image (plain or data URI).
Response Format
The response contains a regions array. Each region has a confidence score (0–1) and a bounding box with pixel coordinates relative to the submitted image.
Property | Description
---|---
confidence | Confidence value (0..1) that an object was detected at this location.
region.top | Top-most coordinate in pixels (floating point).
region.left | Left-most coordinate in pixels (floating point).
region.bottom | Bottom-most coordinate in pixels (floating point).
region.right | Right-most coordinate in pixels (floating point).
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.nyris.io/find/v2/regions")
.post(null)
.addHeader("x-api-key", "KEY")
.addHeader("content-type", "image/jpeg")
.addHeader("content-length", "image-file-size-in-bytes")
.addHeader("cache-control", "no-cache")
.build();
Response response = client.newCall(request).execute();
{
"image": "/9j/4AAQSkZJRg..."
}
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Base64;
OkHttpClient client = new OkHttpClient();
byte[] imageBytes = Files.readAllBytes(Path.of("image.jpg"));
String imageB64 = Base64.getEncoder().encodeToString(imageBytes);
String json = "{\"image\":\"" + imageB64 + "\"}";
RequestBody body = RequestBody.create(
MediaType.parse("application/json"), json);
Request request = new Request.Builder()
.url("https://api.nyris.io/find/v2/regions")
.post(body)
.addHeader("x-api-key", "KEY")
.build();
Response response = client.newCall(request).execute();
{
"regions": [
{
"confidence": 0.8876233,
"region": {
"top": 43.0,
"left": 153.0,
"bottom": 577.0,
"right": 427.0
}
}
]
}
Get visually similar items for a product in your catalogue by submitting its SKU. Since we already have your product data (from the feed import), we perform a visual similarity search based on the main image of the given product. The submitted SKU itself is excluded from results.
GET https://api.nyris.io/recommend/v1/{sku}
Request Headers
Key | Value
---|---
X-Api-Key | The API key provided by us.
Accept | (Optional) application/items.complete+json for full response.
Accept-Language | (Optional) Filter results by language, e.g. de,*;q=0.5.
Path Parameters
Name | Example | Explanation
---|---|---
sku | 03764560 | The SKU of the product to find recommendations for.
{
"id": "575e838883cf5e60859889c112b1463e",
"session": "575e838883cf5e60859889c112b1463e",
"results": [
{
"sku": "123454643",
"image": "https://img.nyris.io/example.jpg",
"score": 0.96
},
{
"sku": "123454644",
"image": "https://img.nyris.io/example2.jpg",
"score": 0.92
}
]
}
Retrieve the public images associated with a product by its SKU.
GET https://api.nyris.io/find/v1.1/images/{sku}
Request Headers
Key | Value
---|---
X-Api-Key | The API key provided by us.
Accept | application/items.complete+json
Path Parameters
Name | Example | Explanation
---|---|---
sku | D005 | The SKU of the product to retrieve images for.
{
"images": [
"https://img.nyris.io/7bb/7bb5d2940a23084f307ed9a4bf8d74c6e03cf38cd10ca1e909eb6205774629ff.jpg"
]
}
Retrieve the available filter attributes that can be used with the Find API.
GET https://api.nyris.io/find/v1.1/filters
Request Headers
Key | Value
---|---
X-Api-Key | The API key provided by us.
Accept | application/items.complete+json
{
"filters": [
{
"filterType": "color",
"filterValues": ["Red", "Blue", "Green", "Black", "White"]
},
{
"filterType": "category",
"filterValues": ["Shoes", "Bags", "Accessories"]
}
]
}
The fastest and easiest way to integrate visual search to your website is using our Javascript Widget. All you have to do is to add some lines of code to a runtime file of your website and you are ready to start using visual search.
What I need to start using this code?
You need to follow these steps:
Done. You are ready to use visual search on your website!
Sample
See the nyris demo widget in action: https://widget.nyris.app/
Where is the source code? Can I change it
The code is on github. Follow the readme file to build the project. You can change or adjust the JS / CSS files according to your needs and host them on your server as well.
You can find the latest Android SDK including the implementation documentation on github:
You can find the latest iOS SDK including the implementation documentation on github:
https://github.com/nyris/Nyris.IMX.iOS
Should you have any questions, please send and e-mail to support@nyris.io
There are several ways to submit your product and image data to us. You can provide any kind of structured file that we can pull (xml, csv, txt, json, etc.), or use the Data Management API to programmatically manage your items and images. If you are already providing your data to an affiliate network like Affilinet, Awin or Google Shopping, you are probably all set for the start. In this case we just need access to your feed URL. Please be aware that those feeds usually only include the link to the main product image. As image recognition works best the more images of a specific product we have, you might need to adjust those feeds to include all your product images. Please find more details below.
If you don't have a product feed, we can also directly access your product data trough an API for the following systems:
Shop Systems.
PIM
You can also create a data feed using Google Sheets. Details on how to use Goole Sheets and an example file can be found in a section below.
The Data Management API lets you programmatically manage items and images in your nyris index. Use it to create, update, list, and delete product data and associated images.
The Data Management API requires a separate API key. For security, the keys used for the Find API and Recommend API do not work with the Data Management API, and vice versa. Contact mailto:support@nyris.io to obtain your Data API key.
The full OpenAPI reference is available at api.nyris.io/manage/swagger.
All Data Management API requests require an API key passed via the X-Api-Key header. This key is different from the one used for the Find and Recommend APIs.
Key | Value
---|---
X-Api-Key | Your Data Management API key (not the same as the Find API key).
Creates a new item in your index. The key field is required and must be unique within your index.
{
"key": "product-001",
"text": {
"name": "Red Running Shoe",
"description": "Lightweight running shoe in red",
"brand": "ExampleBrand",
"language": "en-US"
},
"category": ["Shoes", "Running"],
"links": {
"main": "https://example.com/products/product-001"
},
"price": {
"value": 89.99,
"currency": "EUR"
}
}
{
"id": "18b7f87a-1577-4486-a680-a460d970b584",
"indexId": "adc23661-bc7f-4514-875e-c60d1ac61b93",
"key": "product-001",
"text": {
"name": "Red Running Shoe",
"description": "Lightweight running shoe in red",
"brand": "ExampleBrand",
"language": "en-US"
},
"category": ["Shoes", "Running"],
"links": {
"main": "https://example.com/products/product-001"
},
"price": {
"value": 89.99,
"currency": "EUR"
},
"images": [],
"created": "2026-03-19T12:00:00Z",
"modified": "2026-03-19T12:00:00Z"
}
Creates an item if the key does not exist yet, or updates the existing item. This is the recommended way to keep your index in sync with your product catalog.
The request body is the same as for creating an item. Returns 201 if a new item was created, 200 if an existing item was updated.
Returns a paginated list of items in your index.
Name | Type | Description
---|---|---
size | integer | Number of items per page (optional).
pageToken | uuid | Token for the next page (from a previous response).
sort | string | Sort by UpdateDate, CreationDate, or UniqueKey.
order | string | Ascending or Descending.
{
"items": [
{
"id": "18b7f87a-1577-4486-a680-a460d970b584",
"key": "product-001",
"text": { "name": "Red Running Shoe" },
"images": [],
"created": "2026-03-19T12:00:00Z",
"modified": "2026-03-19T12:00:00Z"
}
],
"pageToken": "18b7f87a-1577-4486-a680-a460d970b584",
"nextPageToken": "29c5bf8b-2688-5597-b791-991443195695"
}
Retrieves a single item using your unique key.
Deletes an item by its unique key. All associated images are also removed.
Adds an image to an existing item, identified by its key. You can provide the image as a URL (JSON body) or upload it directly (multipart/form-data or raw image bytes).
{
"url": "https://example.com/images/product-001.jpg",
"visible": true,
"main": true
}
{
"id": "63a4ac04-d267-442c-9be4-880332084127",
"indexId": "adc23661-bc7f-4514-875e-c60d1ac61b93",
"itemId": "18b7f87a-1577-4486-a680-a460d970b584",
"url": "https://example.com/images/product-001.jpg",
"visible": true,
"main": true,
"created": "2026-03-19T12:01:00Z"
}
Returns all images belonging to an item.
Removes a specific image by its ID.
The complete OpenAPI specification, including all endpoints, schemas, and error codes, is available in the interactive Swagger documentation:
You can also import the OpenAPI spec directly into Postman or other API tools using the JSON URL:
https://api.nyris.io/manage/swagger/v1/swagger.json
The bare minimum is a unique ID (sku) and the main_image_link. To get a full list of possible attributes please download the following sheet or use a copy of it as base for your item or product feed. When gathering your data, please keep always in mind that all submitted information will be used for improving your search results. Completeness and quality of data often makes the difference:
Download Feed Example and full attribute description (google sheets)
| Attribute | Example | Comment |
|---|---|---|
| sku | sku1 | unique item or product identifier (e.g. EAN code) |
| main_image_link | https://storage.googleapis.com/nyris/share/image_a1.png | main image link. should be publicly available. ideally, product in question should be at the center of the image |
Image Links
To improve the search, additional images can be provided. All referenced images (main, additional and recognition types)
are used for search. main and additional images are treated identically, with the main image being the designated
reference to be shown e.g. in the Portal. If requested, these image links can be returned as part of the response.
recognition image links, on the other hand, are purely used for recognition and are never returned as part of any response.
Attribute | Example | Comment
---|---|---
additional_image_link_0 | https://storage.googleapis.com/nyris/share/image_a1.png | additional images
additional_image_link_1 | | additional images
additional_image_link_N | | Nth additional image
recognition_image_link_0 | | additional recognition images (images that will never show up on frontend) ideally taken from different angles and w/o packaging
recognition_image_link_1 | https://storage.googleapis.com/nyris/share/image_r1.png | additional recognition images (images that will never show up on frontend** ideally taken from different angles and w/o packaging
recognition_image_link_N | | Nth additional recognition image
Textual description
Providing these values will enable both OCR (text matching) functionality, finer grained recognition of results and item class distribution results. While optional, providing these values is thus strongly recommended.
Attribute | Example | Comment
---|---|---
title | title 1 | Product or item title (supports OCR recognition step)
brand | brand 1 | Brand (supports brand recogntion step)
description_short | description short 1 | Short description (supports OCR recognition step)
description_long | description long 1 | Long description (supports OCR recognition step)
custom_category | cat1 > cat2 | your product or item category. Please separate with > (e.g. building materials, wood, windows & doors > windows > window ledges). Providing this field will be used to improve recommendations.
language | de-DE | Language Culture Name (https://learn.microsoft.com/en-us/openspecs/office_standards/ms-oe376/db9b9b72-b10b-4e7e-844c-09f88c972219)
Key-value pairs
By providing custom key-value pairs, we are able to improve detection in combination with text matching functionality, and/or will be able to return named IDs as part of the response. If your system requires multiple IDs or custom data pairs, use these fields.
Attribute | Example | Comment
---|---|---
custom_id_key_0 | pzn | custom ID key (e.g. for Barcode recognition) and
custom_id_value_0 | 123456 | custom ID value (e.g. for Barcode recognition),
custom_id_key_N | pzn | Nth custom ID key and
custom_id_value_N | 123456 | Nth custom ID value
Catalog numbers
These values are mainly used for identifying products within catalogs, and catalogs by IDs.
Attribute | Example | Comment
---|---|---
catalog_number_0 | 3306 | catalog numbers from your printed advertisment. Used by PDF importer
catalog_number_1 | cat1 | catalog numbers from your printed advertisment. Used by PDF importer
catalog_number_N | ... | Nth catalog number
Keywords
These values are used for exactly matching keywords, such as item materials, colors, etc., with text found during OCR; thus, providing these values improves text matching. Keywords are treated as a set, so values specified multiple times would be considered identical.
To simplify specification of keywords, you can specify keywords in a delimiter-separated list
via the configurable keywords column. By default, keywords are split at the , (comma) delimiter:
Attribute | Example | Comment
---|---|---
keywords | keyword, keyword, keyword 2 | Registers the two keywords keyword and keyword 2
keyword(",") | keyword 1, keyword 2 | Registers the two keywords keyword 1 and keyword 2
keyword("AND") | keyword 1 AND keyword 2 | Registers the two keywords keyword 1 and keyword 2
To provide single keywords or individual keywords per column, use the keyword / keyword_N variant instead.
Here, values are not split:
Attribute | Example | Comment
---|---|---
keyword | a nice, individual keyword | Registers the keyword a nice, individual keyword
keyword_0 | keyword 0 | The first keyword in a set
keyword_1 | keyword 1 | The second keyword in a set
keyword_N | ... | The Nth keyword in a set
Geolocation Fields
If provided, the coordinates can be used to narrow down the search by the location of the product. The provided coordinates have to be in the WGS84 format with signed decimal numbers as the notation.
Attribute | Example | Comment
---|---|---
latitude | 52.5200 | Latitude of the product. Use together with longitude to associate the product with a location.
longitude | 13.4050 | Longitude of the product. Use together with latitude to associate the product with a location.
Item relations
Some items are related to other entries, and some IDs may have different meaning across logical separations of feeds (e.g. when there is a feed per country).
Attribute | Example | Comment
---|---|---
feed_id | 1 | Feed ID, required only if you have multiple feeds as one merchant. The value has to be an integer.
group_id | 23 | for variation products (size, colour etc. variations)
Item URLs
Attribute | Example | Comment
---|---|---
main_offer_link | https://www.nyris.io/products/visual-search-api | product or landing page link
mobile_offer_link | https://vimeo.com/788577734 | secondary product or landing page link (mobile, video etc.)
PreFilter Attributes
Attribute | Example | Comment
---|---|---
filter_key_0 | color | filter key used by faceted search and
filter_value_0 | Red,Blue | comma separated filter values for the key for the item,
filter_key_N | shape | Nth filter key (Max N = 10)and
filter_value_N | candle,capsule | Nth filter values for the item
Other Optional Fields
Attribute | Example | Comment
---|---|---
meta_data | some additional text data | any data you would like to store additionally (text field); the content is not interpreted
availability | in stock | valid values: in stock, out of stock, preorder, back in stock soon, removed
price | 17.30 EUR | . as decimal, 3-digit ISO Code for currency
sale_price | 15.00 EUR | . as decimal, 3-digit ISO Code for currency
image_version | 1234 | image version; if changed, images will be re-imported
Visual search analytics show how customers interact with search results and help improve search performance over time.
Nyris provides two levels of analytics:
| Type | Merchant implementation | What you get |
|---|---|---|
| General usage & index analytics | None required | Search volume, product count, image count in your index |
| Click & conversion analytics | Required (see below) | Which results were clicked, which led to conversions, tied to each search request_id |
This document covers click & conversion analytics — how to send customer events to the Nyris Feedback API.
For most commerce stores, use the Nyris events tracking script — a single drop-in snippet that captures searches, clicks, and conversions automatically.
Once embedded, the script:
request_id of each search,dataLayer,It requires no changes to your store's source code in the typical case and is built so it cannot break the host page (all logic is error-isolated).
Place the tag in the <head>. async is recommended.
Minimal — only the API key is required:
Typical commerce setup — configure result cards, product ids, and add-to-cart labels:
With this markup, a click on the card (or its link) is reported as a click, and a click on the add-to-cart button is reported as a conversion — both carrying the product id:
<script
async
src="https://assets.nyris.io/nyris-tracking/v1/nyris-tracker.min.js"
data-api-key="YOUR_NYRIS_API_KEY">
</script>
<script
async
src="https://assets.nyris.io/nyris-tracking/v1/nyris-tracker.min.js"
data-api-key="YOUR_NYRIS_API_KEY"
data-results-selector=".product-card"
data-product-id-attr="data-product-id"
data-cart-button-labels="Add to cart,In den Warenkorb">
</script>
<div class="product-card" data-product-id="SKU-9987">
<a href="/products/sku-9987">Trail Runner Jacket</a>
<button type="button">Add to cart</button>
</div>
The script works when the browser calls the Nyris Find API directly (https://api.nyris.io/find/...). It intercepts those responses to obtain the request_id.
If your store proxies search through your own backend and never calls the Find API from the browser, inject the request id into the results container instead:
Without a request_id (from interception or data-nyris-request-id), click and conversion events are not sent.
<div id="search-results" data-nyris-request-id="REQUEST_ID_FROM_SERVER">
<!-- result cards -->
</div>
The tracker resolves the product id for each result card in this order:
data-product-id-attr on (or inside) the card (default: data-product-id).data-product-text-selector, if configured.For most stores the position fallback works out of the box when result order matches the API response.
Add-to-cart is detected automatically from button labels. Purchases happen on the order-confirmation page and must be declared once the order is known.
HTML attributes:
JavaScript API:
Custom DOM event (useful with tag managers):
If you already send GA4 e-commerce events to window.dataLayer, enable the GA4 bridge (default) to mirror add_to_cart and purchase events automatically.
<button
data-nyris-conversion="purchase"
data-nyris-product-ids="SKU-9987,SKU-1234"
data-nyris-order-id="ORD-123"
data-nyris-revenue-amount="49.99"
data-nyris-revenue-currency="EUR">
Complete purchase
</button>
Set options as data-* attributes on the script tag, or as window.nyrisTrackerConfig before the script loads.
| data-* attribute | nyrisTrackerConfig key | Default | Description |
|---|---|---|---|
| data-api-key | apiKey | — (required) | Nyris API key. Sent as X-Api-Key. |
| data-results-selector | resultsSelector | .product-card | CSS selector for a single search-result card. |
| data-results-container | resultsContainer | document.body | Scope where results live. |
| data-product-id-attr | productIdAttr | data-product-id | Attribute holding the product id/SKU. |
| data-product-text-selector | productTextSelector | none | CSS selector whose text is the product id. |
| data-cart-button-labels | cartButtonLabels | Add to cart,Add to basket,In den Warenkorb | Comma-separated, case-insensitive add-to-cart labels. Replaces defaults when set. |
| data-mode | mode | cookiefree | cookiefree or full. See GDPR modes. |
| data-attribution-window-minutes | attributionWindowMinutes | 30 | How long a search stays eligible for attributed conversions. |
| data-ga4-bridge | ga4Bridge | true | Bidirectional GA4 dataLayer integration. |
| data-feedback-url | feedbackUrl | https://api.nyris.io/feedback/v1 | Override endpoint (restricted to api.nyris.io/feedback/). |
| data-debug | debug | false | Log [NyrisTracker] messages to the console. |
window.nyrisTrackerConfig example:
<script>
window.nyrisTrackerConfig = {
apiKey: 'YOUR_NYRIS_API_KEY',
resultsSelector: '.search-result',
cartButtonLabels: ['Add to cart', 'Buy now'],
};
</script>
<script async src="https://assets.nyris.io/nyris-tracking/v1/nyris-tracker.min.js"></script>
| Method | Description |
|---|---|
| NyrisTracker.conversion(subtype, options) | Report a conversion. options: product_ids, positions, quantity, revenue. |
| NyrisTracker.grantConsent() | Switch to full mode after cookie consent. |
| NyrisTracker.getRequestId() | Current Nyris request_id, or null. |
| Mode | Storage | Consent | Notes |
|---|---|---|---|
| cookiefree (default) | sessionStorage, else in-memory | Not required | No cookies, no persistent visitor id. |
| full | localStorage | Required | Call NyrisTracker.grantConsent() after opt-in. |
The default cookiefree mode uses no cookies and no cross-session identifier. Confirm with your DPO whether a consent banner is required for your jurisdiction.
Enable debug output while integrating:
Then open the browser console and look for [NyrisTracker] initialized, search captured, click, and add_to_cart / conversion messages.
data-debug="true"
Use the raw Feedback API implementation below if you:
Implement click and conversion analytics yourself by POSTing JSON events to the Feedback API. Use this path when you cannot embed the tracking script or need a custom integration.
Every Find API response includes a unique request id and optionally a session id:
| Source | Header | JSON body fallback |
|---|---|---|
| Request id | X-Matching-Request | id |
| Session id | X-Session | session |
Store the request id when you receive search results. Attach it to every subsequent click or conversion event for that search.
Perform a Find API search first (see Find API documentation), then POST events to the Feedback API using the same API key.
POST https://api.nyris.io/feedback/v1
| Header | Value |
|---|---|
| X-Api-Key | Your Nyris API key |
| Content-Type | application/json, application/event+json, or text/json |
Every event is a JSON object with these fields:
| Property | Required | Description |
|---|---|---|
| request_id | Yes | Request id from the Find API response |
| session_id | No | Session id from the Find API response. Groups multiple searches from the same user. |
| timestamp | Yes | Event time in ISO 8601 UTC, e.g. 2020-11-06T17:53:25.511Z |
| event | Yes | Event type: click, conversion, feedback, or region |
| data | Depends on event | Event-specific payload (see below) |
A successful POST returns HTTP 2xx. Invalid JSON or missing required fields may return an error.
| event value | Purpose |
|---|---|
| click | User clicked or selected a result (position and/or product id) |
| conversion | A result led to business value (e.g. add to cart, purchase) |
| feedback | End-user feedback on the result set ("Did we find what you were looking for?") |
Tracks which result the user interacted with.
data properties:
| Property | Type | Description |
|---|---|---|
| product_ids | string[] | Product ids as in your product data / Find API SKUs |
| positions | number[] | Zero-based index in the Find API result list |
Provide product ids where possible — they remain accurate even if the frontend reorders or filters results.
Example:
{
"request_id": "e8848827-27af-41d7-a98f-1a2f94b0f19a",
"session_id": "e8848827-27af-41d7-a98f-1a2f94b0f19a",
"timestamp": "2020-11-06T17:53:25.511Z",
"event": "click",
"data": {
"positions": [0],
"product_ids": ["1234"]
}
}
Tracks that a search result led to a conversion (add to cart, purchase, product view, etc.).
data properties:
| Property | Type | Description |
|---|---|---|
| product_ids | string[] | Product ids involved in the conversion |
| positions | number[] | Zero-based positions in the original result list |
| quantity | number | Optional item quantity |
The data field is optional. A conversion with no data still marks the request as successful if a prior click event was sent for the same request_id.
Example (with product data):
Example (minimal — relies on prior click):
The tracking script may send a subtype field inside data (e.g. add_to_cart, purchase) to distinguish conversion types. The Feedback API currently ignores subtype — it does not return an error, but the value is not stored or surfaced in analytics yet. Support for subtypes is planned.
Until then, treat all conversion events equally and include product_ids and positions in data where available. Do not rely on subtype for reporting.
{
"request_id": "e8848827-27af-41d7-a98f-1a2f94b0f19a",
"session_id": "e8848827-27af-41d7-a98f-1a2f94b0f19a",
"timestamp": "2020-11-06T17:53:25.511Z",
"event": "conversion",
"data": {
"positions": [0],
"product_ids": ["1234"],
"quantity": 1
}
}
{
"request_id": "e8848827-27af-41d7-a98f-1a2f94b0f19a",
"session_id": "e8848827-27af-41d7-a98f-1a2f94b0f19a",
"timestamp": "2020-11-06T17:53:25.511Z",
"event": "conversion"
}
End-user feedback on the overall result set, e.g. from a "Did we find what you were looking for?" prompt.
data properties:
| Property | Type | Description |
|---|---|---|
| success | boolean | Whether the search was successful from the user's perspective |
| comment | string | Optional free-text comment |
Where possible, also send click and conversion events — they provide automatic, behaviour-based feedback.
Example:
{
"request_id": "e8848827-27af-41d7-a98f-1a2f94b0f19a",
"session_id": "e8848827-27af-41d7-a98f-1a2f94b0f19a",
"timestamp": "2020-11-06T17:53:25.511Z",
"event": "feedback",
"data": {
"success": true,
"comment": "Thank you!"
}
}
X-Matching-Request / X-Session (or id / session from the JSON body if headers are not exposed).click event with product_ids and positions.conversion event with the same request_id and relevant product_ids.feedback event as applicable.Product ids must match the SKUs in your product data and Find API results, or Nyris cannot correlate events with your catalogue.
All event types should return HTTP 2xx when the payload is valid.