Search API
Search your images using natural language with AI-powered semantic search.
Endpoint
http
GET /get/searchAuthentication
Required.
Prerequisites
- AI analysis must be enabled in your account
- OpenAI API key must be configured
- Images must have been analyzed (happens automatically on upload)
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
q | String | Required | Natural language search query |
threshold | Float | 0.7 | Similarity threshold (0.0 to 1.0) |
limit | Integer | 10 | Maximum number of results |
Response
json
{
"query": "red sports car",
"count": 3,
"objects": [
"https://files.reimage.dev/abc123/xyz789/",
"https://files.reimage.dev/abc123/abc456/"
],
"urls": [
"https://files.reimage.dev/abc123/xyz789/original.webp",
"https://files.reimage.dev/abc123/abc456/original.webp"
],
"thumbnails": [
"https://files.reimage.dev/abc123/xyz789/h-200_w-200.webp",
"https://files.reimage.dev/abc123/abc456/h-200_w-200.webp"
],
"captions": [
"A red sports car parked on a street",
"Red Ferrari on a mountain road"
],
"similarities": [
0.923,
0.856
]
}Response Fields
| Field | Type | Description |
|---|---|---|
query | String | Your search query |
count | Integer | Number of results found |
objects | Array | Base URLs for matching images |
urls | Array | Optimized WebP URLs |
thumbnails | Array | Thumbnail URLs |
captions | Array | AI-generated captions for each image |
similarities | Array | Similarity scores (0.0 to 1.0) |
Code Examples
javascript
async function searchImages(query, options = {}) {
const params = new URLSearchParams({
q: query,
threshold: options.threshold || 0.7,
limit: options.limit || 10
});
const response = await fetch(
`https://api.reimage.dev/get/search?${params}`,
{
headers: {
'Authorization': `Bearer ${process.env.REIMAGE_API_KEY}`
}
}
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.error || 'Search failed');
}
return await response.json();
}
// Usage
const results = await searchImages('sunset over ocean');
console.log(`Found ${results.count} images`);
results.urls.forEach((url, i) => {
console.log(`${url} - ${results.captions[i]} (${results.similarities[i]})`);
});python
import requests
import os
def search_images(query, threshold=0.7, limit=10):
"""Search images using natural language"""
headers = {
'Authorization': f'Bearer {os.environ.get("REIMAGE_API_KEY")}'
}
params = {
'q': query,
'threshold': threshold,
'limit': limit
}
response = requests.get(
'https://api.reimage.dev/get/search',
headers=headers,
params=params
)
if response.status_code == 403:
error = response.json()
raise Exception(error.get('error', 'AI analysis not enabled'))
response.raise_for_status()
return response.json()
# Usage
results = search_images('sunset over ocean', limit=5)
print(f"Found {results['count']} images")
for i, url in enumerate(results['urls']):
print(f"{url}")
print(f" Caption: {results['captions'][i]}")
print(f" Similarity: {results['similarities'][i]:.3f}")php
<?php
function searchImages($query, $threshold = 0.7, $limit = 10) {
$apiKey = getenv('REIMAGE_API_KEY');
$params = http_build_query([
'q' => $query,
'threshold' => $threshold,
'limit' => $limit
]);
$url = "https://api.reimage.dev/get/search?$params";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 403) {
throw new Exception('AI analysis not enabled');
} elseif ($httpCode !== 200) {
throw new Exception("Search failed: $httpCode");
}
return json_decode($response, true);
}
// Usage
$results = searchImages('sunset over ocean', 0.7, 5);
echo "Found " . $results['count'] . " images\n";
foreach ($results['urls'] as $i => $url) {
echo "$url\n";
echo " Caption: " . $results['captions'][$i] . "\n";
echo " Similarity: " . $results['similarities'][$i] . "\n";
}
?>go
package main
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
)
type SearchResponse struct {
Query string `json:"query"`
Count int `json:"count"`
Objects []string `json:"objects"`
URLs []string `json:"urls"`
Thumbnails []string `json:"thumbnails"`
Captions []string `json:"captions"`
Similarities []float64 `json:"similarities"`
}
func searchImages(apiKey, query string, threshold float64, limit int) (*SearchResponse, error) {
baseURL := "https://api.reimage.dev/get/search"
params := url.Values{}
params.Add("q", query)
params.Add("threshold", fmt.Sprintf("%.2f", threshold))
params.Add("limit", fmt.Sprintf("%d", limit))
fullURL := fmt.Sprintf("%s?%s", baseURL, params.Encode())
req, err := http.NewRequest("GET", fullURL, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("search failed with status: %d", resp.StatusCode)
}
var result SearchResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}
return &result, nil
}
func main() {
apiKey := os.Getenv("REIMAGE_API_KEY")
results, err := searchImages(apiKey, "sunset over ocean", 0.7, 5)
if err != nil {
fmt.Printf("Error: %v\n", err)
return
}
fmt.Printf("Found %d images\n", results.Count)
for i, url := range results.URLs {
fmt.Printf("%s\n", url)
fmt.Printf(" Caption: %s\n", results.Captions[i])
fmt.Printf(" Similarity: %.3f\n", results.Similarities[i])
}
}rust
use reqwest::header::{HeaderMap, HeaderValue, AUTHORIZATION};
use serde::{Deserialize, Serialize};
#[derive(Debug, Deserialize)]
struct SearchResponse {
query: String,
count: usize,
objects: Vec<String>,
urls: Vec<String>,
thumbnails: Vec<String>,
captions: Vec<String>,
similarities: Vec<f64>,
}
async fn search_images(
api_key: &str,
query: &str,
threshold: f64,
limit: u32,
) -> Result<SearchResponse, Box<dyn std::error::Error>> {
let url = format!(
"https://api.reimage.dev/get/search?q={}&threshold={}&limit={}",
urlencoding::encode(query),
threshold,
limit
);
let mut headers = HeaderMap::new();
headers.insert(
AUTHORIZATION,
HeaderValue::from_str(&format!("Bearer {}", api_key))?,
);
let client = reqwest::Client::new();
let response = client
.get(&url)
.headers(headers)
.send()
.await?;
if !response.status().is_success() {
return Err(format!("Search failed: {}", response.status()).into());
}
let result = response.json::<SearchResponse>().await?;
Ok(result)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = std::env::var("REIMAGE_API_KEY")?;
let results = search_images(&api_key, "sunset over ocean", 0.7, 5).await?;
println!("Found {} images", results.count);
for (i, url) in results.urls.iter().enumerate() {
println!("{}", url);
println!(" Caption: {}", results.captions[i]);
println!(" Similarity: {:.3}", results.similarities[i]);
}
Ok(())
}React Search Component
jsx
import { useState } from 'react';
function ImageSearch() {
const [query, setQuery] = useState('');
const [results, setResults] = useState(null);
const [loading, setLoading] = useState(false);
const handleSearch = async (e) => {
e.preventDefault();
if (!query.trim()) return;
setLoading(true);
try {
const params = new URLSearchParams({
q: query,
threshold: '0.7',
limit: '20'
});
const response = await fetch(
`https://api.reimage.dev/get/search?${params}`,
{
headers: {
'Authorization': `Bearer ${process.env.REACT_APP_REIMAGE_API_KEY}`
}
}
);
if (!response.ok) {
throw new Error('Search failed');
}
const data = await response.json();
setResults(data);
} catch (error) {
alert(error.message);
} finally {
setLoading(false);
}
};
return (
<div>
<form onSubmit={handleSearch}>
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search images... (e.g., 'red car' or 'sunset')"
/>
<button type="submit" disabled={loading}>
{loading ? 'Searching...' : 'Search'}
</button>
</form>
{results && (
<div>
<p>Found {results.count} images</p>
<div className="image-grid">
{results.urls.map((url, i) => (
<div key={i} className="image-card">
<img src={results.thumbnails[i]} alt={results.captions[i]} />
<p>{results.captions[i]}</p>
<small>Similarity: {(results.similarities[i] * 100).toFixed(1)}%</small>
</div>
))}
</div>
</div>
)}
</div>
);
}Error Responses
AI Analysis Not Enabled
json
{
"error": "AI analysis not enabled for this user"
}Status Code: 403 Forbidden
Missing OpenAI API Key
json
{
"error": "OpenAI API key not configured"
}Status Code: 403 Forbidden
Missing Query Parameter
json
{
"error": "Query parameter \"q\" is required"
}Status Code: 400 Bad Request
How It Works
- When you upload an image, it's automatically analyzed by AI
- A caption is generated describing the image content
- The caption is converted to a vector embedding
- When you search, your query is also converted to an embedding
- Similar images are found using vector similarity
Adjusting Similarity Threshold
- 0.9 - 1.0: Very strict, only near-exact matches
- 0.7 - 0.9: Balanced (recommended)
- 0.5 - 0.7: More lenient, broader results
- 0.0 - 0.5: Very broad, may include unrelated images
javascript
// Strict search - only very similar images
const strict = await searchImages('red car', { threshold: 0.9 });
// Broad search - more results
const broad = await searchImages('red car', { threshold: 0.6 });Example Queries
- "red sports car on a mountain road"
- "person wearing sunglasses"
- "sunset over the ocean"
- "modern office interior"
- "food on a white plate"
- "happy dog playing in park"
Next Steps
- Upload API - Upload images for analysis
- Get Images API - Traditional filtering by tags
- AI Image Search Guide - Detailed guide