Tag product photos twice as accurately as Amazon Rekognition, for 98% less
SIE reads each product photo and fills in its type, colour and material, choosing from your own lists. There’s no model to train, and you pay only for the photos you tag.
SIE SigLIP so400m
All three right
Picked from your own lists
- Type51 choices
- ottoman then stool, sofa
- Colour14 choices
- blue then brown, purple
- Material11 choices
- velvet then suede, fabric
Rekognition and GPT-6 Luna mislabel what you sell
Amazon Rekognition
Filed as a table- Coffee Table100.0
- Furniture100.0
- Table100.0
- Dining Table57.2
- Roof Rack55.0
- Aluminium53.0
- Bench51.3
No “Bed” among its 7 labels. Even a label mapping fitted to the test photos themselves gets only 35% of them fully right.
SIE SigLIP so400m
Right type: bed- Type51 choices
- bed then headboard, bench
GPT-6 Luna, reasoning high
Tagged the bedding- Type
- bed
- Colour
- white
- Material
- fabric
Same answer in 3 of 3 runs
SIE SigLIP so400m
All three right- Type
- bed
- Colour
- black
- Material
- metal
Twice Amazon Rekognition’s accuracy, for 98% less
| Model | All three fields right | Cost per million photos |
|---|---|---|
| SIE SigLIP so400m | 72.3% | $24 |
| GPT-6 Luna | 84.4% | $183 |
| Claude Haiku 5.5 | 90.6% | $271 |
| Amazon Rekognition | 26.8% | $1,750 |
| GPT-6.1 Sol | 86.9% | $3,311 |
| Claude Sonnet 5.5 | 92.3% | $4,883 |
938 product photos from Amazon’s public furniture and home catalogue, each tagged from the same 51 types, 14 colours and 11 materials
- Right
- Type, colour and material all match the product’s own listing
- Tuning
- Prompts and Rekognition’s label map were chosen on 311 separate photos
- LLMs
- Each at its best-scoring setting
- Prices
- Real-time list prices on each model’s recorded usage
Rank your own labels from a photo
from pathlib import Pathfrom urllib.request import urlopenimport numpy as npfrom sie_sdk import SIEClientclient = SIEClient(api_key="API keysk-sie-…")banks = { "type": ["type labelottoman", "type labelstool", "type labelsofa"], "colour": ["colour labelblue", "colour labelbrown", "colour labelpurple"], "material": ["material labelvelvet", "material labelsuede", "material labelfabric"]}templates = { "type": ["a photo of {article} {label}.", "{label}", "a product photo of {article} {label}."], "colour": ["a {label} object."], "material": ["a photo of a product made of {label}."]}image_url = imageblue-velvet-ottoman.jpgbrowsewith urlopen(image_url) as source: image_bytes = source.read()image = {"data": image_bytes, "format": "jpeg"}prompts = [ (bank, label, template.format(label=label, article="an" if label[0].lower() in "aeiou" else "a")) for bank, labels in banks.items() for label in labels for template in templates[bank]]···# Native output is dense vectors; these rankings are computed by the caller.vecs = client.encode("modelgoogle/siglip-so400m-patch14-384", [ {"images": [image]}, *[{"text": text} for _, _, text in prompts],])print(rank_banks([vector["dense"] for vector in vecs]))import { readFile } from 'node:fs/promises';
import { SIEClient } from '@superlinked/sie-sdk';
const client = new SIEClient(undefined, { apiKey: 'sk-sie-…' });
const banks = {
"type": ["ottoman", "stool", "sofa"],
"colour": ["blue", "brown", "purple"],
"material": ["velvet", "suede", "fabric"]
};
const templates = {
"type": ["a photo of {article} {label}.", "{label}", "a product photo of {article} {label}."],
"colour": ["a {label} object."],
"material": ["a photo of a product made of {label}."]
};
const imageUrl = "https://superlinked.com/reference/image-classify/blue-velvet-ottoman.jpg";
const source = await fetch(imageUrl);
if (!source.ok) throw new Error('Could not download the original image.');
const image = new Uint8Array(await source.arrayBuffer());
const names = ['type', 'colour', 'material'] as const;
const prompts = names.flatMap((bank) => banks[bank].flatMap((label) =>
templates[bank].map((template) => ({ bank, label, text: template
.replaceAll('{article}', /^[aeiou]/i.test(label) ? 'an' : 'a')
.replaceAll('{label}', label) })),
));
const vecs = await client.encode('google/siglip-so400m-patch14-384', [
{ images: [image] },
...prompts.map(({ text }) => ({ text })),
]);
···
console.log(result);image_bytes=$(curl --fail --silent --show-error --location 'https://superlinked.com/reference/image-classify/blue-velvet-ottoman.jpg' | base64 | tr -d '\n')
curl https://api.superlinked.com/v1/encode/google%2Fsiglip-so400m-patch14-384 \
-H "Authorization: Bearer sk-sie-…" \
-H "Content-Type: application/json" \
-d "{\"items\":[{\"images\":[{\"data\":\"$image_bytes\",\"format\":\"jpeg\"}]},{\"text\":\"a photo of an ottoman.\"},{\"text\":\"ottoman\"},{\"text\":\"a product photo of an ottoman.\"},{\"text\":\"a photo of a stool.\"},{\"text\":\"stool\"},{\"text\":\"a product photo of a stool.\"},{\"text\":\"a photo of a sofa.\"},{\"text\":\"sofa\"},{\"text\":\"a product photo of a sofa.\"},{\"text\":\"a blue object.\"},{\"text\":\"a brown object.\"},{\"text\":\"a purple object.\"},{\"text\":\"a photo of a product made of velvet.\"},{\"text\":\"a photo of a product made of suede.\"},{\"text\":\"a photo of a product made of fabric.\"}],\"params\":{\"output_types\":[\"dense\"]}}" > image-vectors.json
···Build the "Image classify" capability into my app using the Superlinked Inference Engine (SIE).
Context
- SIE is an OpenAI-style inference API. Python SDK: `from sie_sdk import SIEClient`; TypeScript: `@superlinked/sie-sdk`.
- Base URL: https://api.superlinked.com (or my regional endpoint). Auth: Bearer key from env `SIE_API_KEY` (never hard-code it).
- Model: google/siglip-so400m-patch14-384 (SIE primitive: /encode). Keep the model id configurable.
Task
- Input: an uploaded image plus candidate labels.
- Behaviour: return the candidate image labels ranked by similarity
- Encode the original image and all type, colour and material prompts in one batched /encode call. Use the visible recipe's three type templates and its colour/material templates. Normalize each vector, compute cosine per prompt, average the three type prompt scores per label, and select each bank's independent argmax in caller code. Native output is dense vectors, not classification probabilities.
Deliverables
- A typed client wrapper, an application-level function for this task, error handling for timeouts/empty input, and unit tests with a stubbed client.
- Wire it into my existing stack (ask me which framework if unclear) and add a short usage example.Best match from each of your lists
Type
3 choices- ottoman 0.136
- stool 0.106
- sofa 0.084
Colour
3 choices- blue 0.065
- brown 0.026
- purple 0.026
Material
3 choices- velvet 0.109
- suede 0.073
- fabric 0.067
SIE returns one vector for the photo and one per label prompt. Your code compares them by cosine and keeps the best value in each list.
Tag a million photos a month for $24 instead of $1,750 on Amazon Rekognition
Serverless API
We host the models; you call one API.
- No idle GPUs, pay for what you use
- SOC 2 Type 2, US or EU data residency
- $50 of credit to start, no card required
Self-hosted (Kubernetes)
SIE in your clusters, backed by our engineers.
- Data stays in your own cloud account
- Same models and API as Serverless
- Terraform to your cloud in minutes
Run locally
The open-source server on your own machine.
pip install "sie-server[local]" && sie-server serve