Skip to content

Usage Examples

This guide provides practical code examples for integrating the Koral API into your applications.

// Using fetch API (browser or Node.js with node-fetch)
async function searchSimilarImages(imageUrl) {
const response = await fetch('https://search.koral.com/api/v1/search/image', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
imageData: encoded_image,
limit: 10,
offset: 0,
searchId: 'your_customer_feed_id'
})
});
const data = await response.json();
return data.results;
}
// Example usage
searchSimilarImages('https://example.com/image.jpg')
.then(results => {
console.log('Similar images:', results);
})
.catch(error => {
console.error('Error searching for similar images:', error);
});
import requests
import base64
def search_by_local_image(image_path, search_id):
# Read and encode the image
with open(image_path, 'rb') as image_file:
encoded_image = base64.b64encode(image_file.read()).decode('utf-8')
# Make the API request
response = requests.post(
'https://search.koral.com/api/v1/search/image',
headers={
'Content-Type': 'application/json'
},
json={
'imageData': encoded_image,
'limit': 10,
'offset': 0,
'searchId': search_id
}
)
# Check for errors
response.raise_for_status()
# Return the results
return response.json()['results']
# Example usage
try:
search_id = 'your_customer_feed_id'
results = search_by_local_image('path/to/image.jpg', search_id)
print(f"Found {len(results)} similar images")
for result in results:
print(f"- {result['metadata']['title']} (Score: {result['similarity_score']})")
except Exception as e:
print(f"Error: {e}")
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Koral Visual Search Demo</title>
<style>
.search-container {
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
.results-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
gap: 20px;
margin-top: 20px;
}
.result-card {
border: 1px solid #eee;
border-radius: 8px;
overflow: hidden;
}
.result-card img {
width: 100%;
height: 200px;
object-fit: cover;
}
.result-info {
padding: 10px;
}
.dropzone {
border: 2px dashed #ccc;
border-radius: 8px;
padding: 40px;
text-align: center;
margin-bottom: 20px;
cursor: pointer;
}
.dropzone.highlight {
border-color: #2196F3;
background-color: #f8f9fa;
}
</style>
</head>
<body>
<div class="search-container">
<h1>Visual Search Demo</h1>
<div id="dropzone" class="dropzone">
<p>Drag & drop an image here or click to upload</p>
<input type="file" id="fileInput" accept="image/*" style="display: none;">
</div>
<div id="results" class="results-grid"></div>
</div>
<script>
// Note: In a production environment, you should never expose your API key in client-side code.
// Instead, create a backend proxy that makes the API calls with your key.
const API_ENDPOINT = 'https://search.koral.com/api/v1/search/image';
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('fileInput');
const resultsContainer = document.getElementById('results');
// Handle file selection
dropzone.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', handleFileSelect);
// Handle drag and drop
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.classList.add('highlight');
});
dropzone.addEventListener('dragleave', () => {
dropzone.classList.remove('highlight');
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.classList.remove('highlight');
if (e.dataTransfer.files.length) {
handleFiles(e.dataTransfer.files);
}
});
function handleFileSelect(e) {
if (e.target.files.length) {
handleFiles(e.target.files);
}
}
function handleFiles(files) {
const file = files[0];
if (file.type.startsWith('image/')) {
const reader = new FileReader();
reader.onload = (e) => {
const base64Image = e.target.result.split(',')[1];
searchByImage(base64Image);
};
reader.readAsDataURL(file);
}
}
async function searchByImage(base64Image) {
// Show loading state
resultsContainer.innerHTML = '<p>Searching for similar images...</p>';
try {
// In a real application, you would send this request to your backend
// which would then call the Koral API with your API key
const response = await fetch(API_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
imageData: base64Image,
offset: 0,
limit: 12,
searchId: 'your_customer_feed_id',
})
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error?.message || 'An error occurred');
}
displayResults(data.results);
} catch (error) {
resultsContainer.innerHTML = `<p>Error: ${error.message}</p>`;
}
}
function displayResults(results) {
if (!results.length) {
resultsContainer.innerHTML = '<p>No similar images found</p>';
return;
}
resultsContainer.innerHTML = results.map(result => `
<div class="result-card">
<img src="${result.url}" alt="${result.metadata?.title || 'Similar image'}">
<div class="result-info">
<h3>${result.metadata?.title || 'Product'}</h3>
${result.metadata?.price ? `<p>$${result.metadata.price.toFixed(2)}</p>` : ''}
<p>Similarity: ${(result.similarity_score * 100).toFixed(0)}%</p>
</div>
</div>
`).join('');
}
</script>
</body>
</html>
import { useState } from 'react';
function VisualSearch() {
const [isLoading, setIsLoading] = useState(false);
const [results, setResults] = useState([]);
const [error, setError] = useState(null);
const handleImageUpload = async (event) => {
const file = event.target.files[0];
if (!file) return;
setIsLoading(true);
setError(null);
try {
// Read the file as base64
const base64Image = await readFileAsBase64(file);
// Make API request (in a real app, this would go through your backend)
const response = await fetch('https://search.koral.com/api/v1/search/image', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
imageData: base64Image,
limit: 10,
offset: 0,
searchId: 'your_customer_feed_id'
}),
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.message || 'Failed to search for similar images');
}
setResults(data.results);
} catch (err) {
setError(err.message);
setResults([]);
} finally {
setIsLoading(false);
}
};
const readFileAsBase64 = (file) => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const base64String = reader.result.split(',')[1];
resolve(base64String);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
};
return (
<div className="visual-search">
<h2>Find Similar Products</h2>
<div className="upload-container">
<label htmlFor="image-upload" className="upload-button">
Upload an Image
</label>
<input
id="image-upload"
type="file"
accept="image/*"
onChange={handleImageUpload}
style={{ display: 'none' }}
/>
</div>
{isLoading && <p>Searching for similar products...</p>}
{error && <p className="error">Error: {error}</p>}
{results.length > 0 && (
<div className="results-grid">
{results.map((result) => (
<div key={result.id} className="product-card">
<img src={result.url} alt={result.metadata?.title || 'Product'} />
<div className="product-info">
<h3>{result.metadata?.title || 'Product'}</h3>
{result.metadata?.price && (
<p className="price">${result.metadata.price.toFixed(2)}</p>
)}
<p className="similarity">
{(result.similarity_score * 100).toFixed(0)}% match
</p>
</div>
</div>
))}
</div>
)}
</div>
);
}
export default VisualSearch;