POST https://api.iconscout.com/v3/reverse-image-search
Find visually similar assets from a reference image. Provide the image in one of three ways:
url — a publicly reachable raster image URLfile — a multipart/form-data raster upload (jpg, jpeg, png, webp; max 10 MB)image_hash — a hash returned by a previous call, to paginate or re-filter the same image without re-uploadingWhen url or file is supplied the image is embedded on the fly and the response echoes back an image_hash you can reuse for subsequent pages/filters.
Results can be narrowed with a subset of the /v3/search filters: asset, price, formats[], styles[] (icons and illustrations), categories[], include_categories[], exclude_categories[] and contributors[].
Not supported here. orientation[], icon_grid, include_tags[], exclude_tags[], start_date, end_date and sort are rejected with a 400 rather than silently ignored — the vector index does not carry those fields, and ordering is always by visual similarity. Use /v3/search when you need them.
Requires both Client-ID and Client-Secret headers.
Find icons similar to an image URL:
POST /v3/reverse-image-search
{ "url": "https://example.com/logo.png", "asset": "icon" }
Paginate a previous search by hash:
POST /v3/reverse-image-search
{ "image_hash": "a1b2c3d4-...", "asset": "icon", "page": 2 }
| Status | Meaning |
|---|---|
200 | Paginated list of visually similar assets. Includes the reusable image_hash. |
400 | Validation error — no image source supplied, an invalid parameter value, or a filter this endpoint does not support (orientation, icon_grid, include_tags, exclude_tags, start_date, end_date, sort). data.reason is invalid_request. |
401 | Unauthorized — missing or invalid Client-ID / Client-Secret. data.reason is invalid_credentials. |
422 | This client holds no active API subscription. data.reason is subscription_required. |
429 | Rate limit exceeded for this client. data.reason is rate_limit_exceeded.
Limits are per client, per product family and per method, and are set by your plan — support can raise them for an individual client. Read the X-RateLimit-* headers, which are returned on every response the limiter admits and not only this one, rather than hard-coding a number; back off on Retry-After. They are absent only where the call is refused before the limiter runs — a 401 on invalid credentials.
Distinct from the credit allowance, which refuses with quota_exhausted and is not cleared by waiting. |
curl -X POST 'https://api.iconscout.com/v3/reverse-image-search' \
-H 'Client-ID: your-client-id' \
-H 'Client-Secret: your-client-secret' \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com/logo.png", "asset": "icon"}'curl -X POST 'https://api.iconscout.com/v3/reverse-image-search' \
-H 'Client-ID: your-client-id' \
-H 'Client-Secret: your-client-secret' \
-F 'file=@/path/to/image.png' \
-F 'asset=icon'import requests
resp = requests.post(
'https://api.iconscout.com/v3/reverse-image-search',
headers={
'Client-ID': 'your-client-id',
'Client-Secret': 'your-client-secret',
},
json={'url': 'https://example.com/logo.png', 'asset': 'icon'},
)
data = resp.json()['response']
print(data['image_hash'])
for item in data['items']['data']:
print(item['name'], item['urls'])
Try it in the interactive reference →