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