π REST API Guide
This guide will help you integrate with the Neurolabs ZIA API to perform image recognition on your product catalogue.
Authenticationβ
All API requests require authentication using an API key. Include your API key in the request headers:
X-API-Key: your-api-key-here
Base URLβ
https://api.neurolabs.ai/v2
For interactive API documentation, visit: https://api.neurolabs.ai/v2/docs
1. Create a Catalogue Itemβ
Before you can perform image recognition, you need to create items in your catalogue. Each catalogue item represents a product that the system will learn to recognise.
Endpointβ
POST /v2/catalog-items
Content Typeβ
multipart/form-data
Parametersβ
| Parameter | Type | Required | Description |
|---|---|---|---|
thumbnail | file | Yes | Product image file (JPEG, PNG) |
name | string | Yes | Product name (max 255 characters) |
barcode | string | No | Product barcode |
custom_id | string | No | Your internal product ID (max 255 characters) |
height | float | No | Product height in metres |
width | float | No | Product width in metres |
depth | float | No | Product depth in metres |
brand | string | No | Brand name (max 255 characters) |
size | string | No | Size description (max 255 characters) |
container_type | string | No | Type of container (max 255 characters) |
flavour | string | No | Flavour description (max 255 characters) |
packaging_size | string | No | Packaging size (max 255 characters) |
tags | string | No | Comma-separated list of tags |
Example Request (cURL)β
curl -X POST https://api.neurolabs.ai/v2/catalog-items \
-H "X-API-Key: your-api-key-here" \
-F "thumbnail=@/path/to/product-image.jpg" \
-F "name=Coca-Cola 330ml Can" \
-F "barcode=5449000000996" \
-F "brand=Coca-Cola" \
-F "size=330ml" \
-F "container_type=Can" \
-F "height=0.115" \
-F "width=0.066" \
-F "depth=0.066"
Example Request (Python)β
import requests
url = "https://api.neurolabs.ai/v2/catalog-items"
headers = {
"X-API-Key": "your-api-key-here"
}
files = {
"thumbnail": open("/path/to/product-image.jpg", "rb")
}
data = {
"name": "Coca-Cola 330ml Can",
"barcode": "5449000000996",
"brand": "Coca-Cola",
"size": "330ml",
"container_type": "Can",
"height": 0.115,
"width": 0.066,
"depth": 0.066
}
response = requests.post(url, headers=headers, files=files, data=data)
print(response.json())
Example Responseβ
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"status": "ACTIVE",
"thumbnail_url": "https://example.com/",
"name": "Coca-Cola 330ml Can",
"barcode": "5449000000996",
"custom_id": null,
"height": 0.115,
"width": 0.066,
"depth": 0.066,
"brand": "Coca-Cola",
"size": "330ml",
"container_type": "Can",
"flavour": null,
"packaging_size": null,
"custom_props": [],
"created_at": "2025-10-27T10:30:00Z",
"updated_at": "2025-10-27T10:30:00Z"
}
2. Get Catalogue Itemsβ
Retrieve your catalogue items with optional filtering and pagination.
Endpointβ
GET /v2/catalog-items
Query Parametersβ
| Parameter | Type | Description |
|---|---|---|
name | string | Filter by exact product name |
custom_id | string | Filter by your internal product ID |
barcode | string | Filter by barcode |
limit | integer | Number of items per page (default: 50, max: 100) |
offset | integer | Number of items to skip for pagination (default: 0) |
Example Request - List All Itemsβ
curl -X GET "https://api.neurolabs.ai/v2/catalog-items?limit=10&offset=0" \
-H "X-API-Key: your-api-key-here"
Example Request - Filter by Barcodeβ
curl -X GET "https://api.neurolabs.ai/v2/catalog-items?barcode=5449000000996" \
-H "X-API-Key: your-api-key-here"
Example Responseβ
{
"items": [
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"status": "ACTIVE",
"thumbnail_url": "https://example.com/",
"name": "Coca-Cola 330ml Can",
"barcode": "5449000000996",
"brand": "Coca-Cola",
"size": "330ml",
"created_at": "2025-10-27T10:30:00Z",
"updated_at": "2025-10-27T10:30:00Z"
}
],
"total": 1,
"limit": 10,
"offset": 0
}
Get a Single Catalogue Itemβ
GET /v2/catalog-items/{item_uuid}
curl -X GET "https://api.neurolabs.ai/v2/catalog-items/123e4567-e89b-12d3-a456-426614174000" \
-H "X-API-Key: your-api-key-here"
3. Create an Image Recognition Taskβ
Before sending images for recognition, you need to create an Image Recognition Task. A task defines which catalogue items to look for in your images.
Endpointβ
POST /v2/image-recognition/tasks
Request Body (JSON)β
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Task name for identification |
catalog_items | array of UUIDs | Yes | List of catalogue item UUIDs to recognise |
description | string | No | Task description (default: "") |
task_type | string | No | Type of recognition task (e.g., "DETECTION") |
compute_realogram | boolean | No | Enable realogram computation (default: false) |
compute_shares | boolean | No | Enable share computation (default: false) |
Example Requestβ
curl -X POST https://api.neurolabs.ai/v2/image-recognition/tasks \
-H "X-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"name": "Shelf Recognition - Store 01",
"description": "Recognition task for beverage aisle",
"catalog_items": ["123e4567-e89b-12d3-a456-426614174000"],
"compute_realogram": false,
"compute_shares": false
}'
Example Request (Python)β
import requests
url = "https://api.neurolabs.ai/v2/image-recognition/tasks"
headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json"
}
payload = {
"name": "Shelf Recognition - Store 01",
"description": "Recognition task for beverage aisle",
"catalog_items": ["123e4567-e89b-12d3-a456-426614174000"],
"compute_realogram": False,
"compute_shares": False
}
response = requests.post(url, headers=headers, json=payload)
task = response.json()
print(f"Task created with UUID: {task['uuid']}")
Example Responseβ
{
"uuid": "987e6543-e21b-12d3-a456-426614174000",
"name": "Shelf Recognition - Store 01",
"task_type": null,
"description": "Recognition task for beverage aisle",
"created_at": "2025-10-27T10:35:00Z",
"updated_at": "2025-10-27T10:35:00Z",
"compute_realogram": false,
"compute_shares": false
}
Save the task UUID - you'll need it for sending images!
4. Send Images for Recognitionβ
Once you have a task created, you can send images to be processed. Choose the method that best fits your use case:
Option A: Single Image (Synchronous) β‘β
Best for: Real-time applications, testing, immediate results
This endpoint processes the image and waits up to 27 seconds to return the complete result.
POST /v2/image-recognition/tasks/{task_uuid}/sync-image
Request:
curl -X POST https://api.neurolabs.ai/v2/image-recognition/tasks/987e6543-e21b-12d3-a456-426614174000/sync-image \
-H "X-API-Key: your-api-key-here" \
-F "image=@/path/to/shelf-photo.jpg"
Python Example:
import requests
url = f"https://api.neurolabs.ai/v2/image-recognition/tasks/{task_uuid}/sync-image"
headers = {"X-API-Key": "your-api-key-here"}
files = {"image": open("/path/to/shelf-photo.jpg", "rb")}
response = requests.post(url, headers=headers, files=files)
result = response.json()
if response.status_code == 200:
print(f"Recognition complete! Found {len(result['postprocessing_results']['detections'])} products")
elif response.status_code == 408:
print(f"Processing timeout. Check result later: {result['uuid']}")
Response: Returns the complete result immediately (see "Result Structure" below).
If processing takes longer than 27 seconds, you'll receive a 408 Request Timeout with the result UUID. Processing continues in the background - poll the results endpoint to get the final result.
Option B: Multiple Images from Files (Asynchronous) π¦β
Best for: Batch processing, multiple images at once
Upload multiple image files simultaneously for batch processing.
POST /v2/image-recognition/tasks/{task_uuid}/images
Parameters:
images: Array of image files (multipart/form-data)callback: (Optional) Webhook URL to receive results when ready
Request:
curl -X POST https://api.neurolabs.ai/v2/image-recognition/tasks/987e6543-e21b-12d3-a456-426614174000/images \
-H "X-API-Key: your-api-key-here" \
-F "images=@/path/to/photo1.jpg" \
-F "images=@/path/to/photo2.jpg" \
-F "images=@/path/to/photo3.jpg" \
-F "callback=https://your-webhook-endpoint.com/results"
Python Example:
import requests
url = f"https://api.neurolabs.ai/v2/image-recognition/tasks/{task_uuid}/images"
headers = {"X-API-Key": "your-api-key-here"}
files = [
("images", open("/path/to/photo1.jpg", "rb")),
("images", open("/path/to/photo2.jpg", "rb")),
("images", open("/path/to/photo3.jpg", "rb"))
]
data = {"callback": "https://your-webhook-endpoint.com/results"}
response = requests.post(url, headers=headers, files=files, data=data)
result_uuids = response.json()
print(f"Processing {len(result_uuids)} images: {result_uuids}")
Response:
[
"result-uuid-1",
"result-uuid-2",
"result-uuid-3"
]
The endpoint returns immediately with result UUIDs. Processing happens asynchronously in the background.
Option C: Multiple Images from URLs (Asynchronous) πβ
Best for: Images already hosted online, integrations with existing systems
Process images that are publicly accessible via HTTP(S) URLs.
POST /v2/image-recognition/tasks/{task_uuid}/urls
Request Body:
{
"urls": [
"https://example.com/image1.jpg",
"https://example.com/image2.jpg"
],
"callback": "https://your-webhook-endpoint.com/results"
}
Request:
curl -X POST https://api.neurolabs.ai/v2/image-recognition/tasks/987e6543-e21b-12d3-a456-426614174000/urls \
-H "X-API-Key: your-api-key-here" \
-H "Content-Type: application/json" \
-d '{
"urls": [
"https://example.com/image1.jpg",
"https://example.com/image2.jpg"
],
"callback": "https://your-webhook-endpoint.com/results"
}'
Python Example:
import requests
url = f"https://api.neurolabs.ai/v2/image-recognition/tasks/{task_uuid}/urls"
headers = {
"X-API-Key": "your-api-key-here",
"Content-Type": "application/json"
}
payload = {
"urls": [
"https://example.com/image1.jpg",
"https://example.com/image2.jpg"
],
"callback": "https://your-webhook-endpoint.com/results"
}
response = requests.post(url, headers=headers, json=payload)
result_uuids = response.json()
print(f"Processing {len(result_uuids)} images")
Response:
[
"result-uuid-1",
"result-uuid-2"
]
Webhook Callbacks (Asynchronous Methods)β
When you provide a callback URL, Neurolabs will POST the complete result to your endpoint as soon as processing is complete. Each result is sent independently.
Callback Behaviour:
- One POST request per image result
- Sent as soon as each individual result is ready
- Automatic retry: up to 3 attempts with exponential backoff (max 300 seconds wait time)
- Payload: Complete result object (same structure as GET result endpoint)
5. Get Image Recognition Resultsβ
After submitting images for recognition, retrieve the results using these endpoints.
Get a Specific Resultβ
GET /v2/image-recognition/tasks/{task_uuid}/results/{result_uuid}
Request:
curl -X GET "https://api.neurolabs.ai/v2/image-recognition/tasks/987e6543-e21b-12d3-a456-426614174000/results/result-uuid-1" \
-H "X-API-Key: your-api-key-here"
Python Example:
import requests
import time
url = f"https://api.neurolabs.ai/v2/image-recognition/tasks/{task_uuid}/results/{result_uuid}"
headers = {"X-API-Key": "your-api-key-here"}
# Poll until complete
while True:
response = requests.get(url, headers=headers)
result = response.json()
if result["status"] == "COMPLETED":
print(f"Processing complete in {result['duration']} seconds")
print(f"Found {len(result['postprocessing_results']['detections'])} products")
break
elif result["status"] == "FAILED":
print(f"Processing failed: {result['failure_reason']}")
break
else:
print("Still processing...")
time.sleep(2)
Result Structureβ
{
"uuid": "result-uuid-1",
"task_uuid": "987e6543-e21b-12d3-a456-426614174000",
"image_url": "https://example.com/",
"status": "COMPLETED",
"failure_reason": "",
"duration": 3.45,
"created_at": "2025-10-27T10:40:00Z",
"updated_at": "2025-10-27T10:40:03Z",
"confidence_score": 0.95,
"postprocessing_results": {
"detections": [
{
"catalog_item_uuid": "123e4567-e89b-12d3-a456-426614174000",
"confidence": 0.95,
"bbox": [100, 150, 200, 300]
}
]
},
"coco": {
"annotations": [],
"images": [],
"categories": []
}
}
Result Status Valuesβ
| Status | Description |
|---|---|
IN_PROGRESS | Image is currently being processed |
COMPLETED | Processing finished successfully |
FAILED | Processing encountered an error (check failure_reason field) |
Get All Results for a Taskβ
List all results for an image recognition task with pagination and optional date filtering.
GET /v2/image-recognition/tasks/{task_uuid}/results
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
limit | integer | Number of results per page (default: 50) |
offset | integer | Pagination offset (default: 0) |
start_datetime | string | Filter results created after this time (ISO 8601 format) |
end_datetime | string | Filter results created before this time (ISO 8601 format) |
Example Request:
curl -X GET "https://api.neurolabs.ai/v2/image-recognition/tasks/987e6543-e21b-12d3-a456-426614174000/results?limit=20&offset=0" \
-H "X-API-Key: your-api-key-here"
With Date Filtering:
curl -X GET "https://api.neurolabs.ai/v2/image-recognition/tasks/987e6543-e21b-12d3-a456-426614174000/results?start_datetime=2025-10-27T00:00:00Z&end_datetime=2025-10-27T23:59:59Z&limit=50" \
-H "X-API-Key: your-api-key-here"
Response:
{
"items": [
{
"uuid": "result-uuid-1",
"task_uuid": "987e6543-e21b-12d3-a456-426614174000",
"image_url": "https://example.com/",
"status": "COMPLETED",
"confidence_score": 0.95,
"duration": 3.2,
"created_at": "2025-10-27T10:40:00Z",
"updated_at": "2025-10-27T10:40:03Z"
},
{
"uuid": "result-uuid-2",
"task_uuid": "987e6543-e21b-12d3-a456-426614174000",
"image_url": "https://example.com/",
"status": "IN_PROGRESS",
"confidence_score": null,
"duration": null,
"created_at": "2025-10-27T10:41:00Z",
"updated_at": "2025-10-27T10:41:00Z"
}
],
"total": 2,
"limit": 20,
"offset": 0
}
Complete Workflow Exampleβ
Here's a complete end-to-end example using Python:
import requests
import time
API_KEY = "your-api-key-here"
BASE_URL = "https://api.neurolabs.ai/v2"
headers = {"X-API-Key": API_KEY}
# Step 1: Create a catalogue item
print("Creating catalogue item...")
files = {"thumbnail": open("product.jpg", "rb")}
data = {"name": "Coca-Cola 330ml", "barcode": "5449000000996"}
response = requests.post(f"{BASE_URL}/catalog-items", headers=headers, files=files, data=data)
catalog_item = response.json()
print(f"β Created catalogue item: {catalog_item['uuid']}")
# Step 2: Create image recognition task
print("\nCreating image recognition task...")
payload = {
"name": "Store Recognition",
"catalog_items": [catalog_item["uuid"]]
}
headers_json = {**headers, "Content-Type": "application/json"}
response = requests.post(f"{BASE_URL}/image-recognition/tasks", headers=headers_json, json=payload)
task = response.json()
print(f"β Created task: {task['uuid']}")
# Step 3: Send image for recognition (synchronous)
print("\nProcessing image...")
files = {"image": open("shelf.jpg", "rb")}
response = requests.post(
f"{BASE_URL}/image-recognition/tasks/{task['uuid']}/sync-image",
headers=headers,
files=files
)
if response.status_code == 200:
result = response.json()
print(f"β Processing complete!")
print(f" Duration: {result['duration']}s")
print(f" Confidence: {result['confidence_score']}")
print(f" Detections: {len(result['postprocessing_results']['detections'])}")
elif response.status_code == 408:
result = response.json()
result_uuid = result['uuid']
print(f"β± Processing timeout, polling for result...")
# Poll for result
while True:
response = requests.get(
f"{BASE_URL}/image-recognition/tasks/{task['uuid']}/results/{result_uuid}",
headers=headers
)
result = response.json()
if result["status"] == "COMPLETED":
print(f"β Processing complete!")
print(f" Detections: {len(result['postprocessing_results']['detections'])}")
break
elif result["status"] == "FAILED":
print(f"β Processing failed: {result['failure_reason']}")
break
time.sleep(2)
Best Practicesβ
1. Image Recognitionβ
- Choose the right method:
- Use sync for real-time, single-image applications
- Use async batch for processing multiple images efficiently
- Use URLs when images are already hosted
- Implement webhooks: For async processing, webhooks are more efficient than polling
- Handle timeouts gracefully: Always check for 408 status and poll if needed
2. Error Handlingβ
- Retry logic: Implement exponential backoff for failed requests
- Monitor status: Check result status before processing data
- Log failures: Track
failure_reasonfor debugging
3. Performanceβ
- Batch when possible: Group multiple images in a single async request
- Use appropriate limits: Don't request more data than you need with pagination
- Cache catalogue items: Reduce API calls by caching catalogue data locally
Error Handlingβ
All endpoints return standard HTTP status codes:
| Status Code | Meaning | Action |
|---|---|---|
| 200 | OK | Request succeeded |
| 400 | Bad Request | Check parameters or request format |
| 401 | Unauthorized | Verify API key is valid |
| 403 | Forbidden | Check API key permissions |
| 404 | Not Found | Resource doesn't exist (check UUID) |
| 408 | Request Timeout | Sync processing took too long - poll for result |
| 422 | Validation Error | Invalid data format or missing required fields |
| 429 | Too Many Requests | Rate limit exceeded - wait and retry |
| 500 | Internal Server Error | Contact support if persistent |
Error Response Format:
{
"detail": "Invalid API key"
}
Rate Limitingβ
The API enforces rate limits to ensure fair usage and system stability. If you exceed the rate limit, you'll receive a 429 Too Many Requests response.
Best practices:
- Batch images together when possible
- Implement exponential backoff on retry attempts
- Monitor your usage patterns
- Contact support if you need higher limits
Resourcesβ
- Interactive API Documentation: https://api.neurolabs.ai/v2/docs
- Try endpoints live: Test all endpoints with the interactive Swagger UI
- Need Help?:
- Verify image formats are supported (JPEG, PNG)
- Check that API key has necessary permissions
- Ensure catalogue items exist before creating tasks
- Review the interactive docs for detailed schemas