API Reference
Search API
Execute advanced product searches with filtering, faceting, and hybrid semantic search.
Overview
The Search API allows you to perform full-text product searches with advanced filtering, faceting, sorting, and highlighting. Supports hybrid search combining semantic (AI) and keyword matching.
Endpoint: POST /api/v2/applications/{app_id}/search
Try It Live
Open in Swagger UI → to test search queries interactively.
All requests require Bearer token authentication. See API Authentication for details.
Basic Search
Execute a product search with a text query.
POST /api/v2/applications/{app_id}/search
Request
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "red shoes"
}
cURL Example:
curl -X POST "https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID/search" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"q": "red shoes"}'
Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"hits": [
{
"id": "prod_123",
"name": "Red Running Shoes",
"price": 79.99,
"category": "shoes",
"brand": "Nike",
"image": "https://cdn.example.com/red-shoes.jpg"
}
],
"query": "red shoes",
"processingTimeMs": 12,
"limit": 20,
"offset": 0,
"estimatedTotalHits": 156
}
Search Parameters
All search parameters are optional. You can combine them to build powerful queries.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
q | string | No | "" | Search query (max 500 characters) |
limit | integer | No | 20 | Results per page (1-100) |
offset | integer | No | 0 | Number of results to skip |
filter | string | No | - | Filter expression (max 2000 characters) |
facets | array | No | [] | Attributes to compute facets on (max 50) |
attributesToRetrieve | array | No | ["*"] | Attributes to include (max 100, * = all) |
attributesToHighlight | array | No | [] | Attributes to highlight search terms in |
highlightPreTag | string | No | "<em>" | Opening tag for highlights |
highlightPostTag | string | No | "</em>" | Closing tag for highlights |
attributesToCrop | array | No | [] | Attributes to crop/truncate |
cropLength | integer | No | 10 | Number of words to show when cropping |
cropMarker | string | No | "..." | String to mark cropped text |
sort | array | No | [] | Sort criteria (max 20) |
matchingStrategy | string | No | "all" | How to match terms: all or last |
showMatchesPosition | boolean | No | false | Include match positions in response |
hybrid | object | No | - | Hybrid (semantic + keyword) search config |
hybrid.semanticRatio | number | No | - | Balance: 0.0 (keyword) to 1.0 (semantic) |
hybrid.embedder | string | No | - | Embedder name configured in application |
Query String (Optional)
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "smartphone android"
}
Empty query returns all products (useful with filters).
Example: Get all products in a category
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "",
"filter": "category = 'shoes' AND price < 100",
"limit": 20
}
Pagination (Optional)
Control result pagination:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit | integer | No | 20 | Results per page (1-100) |
offset | integer | No | 0 | Number of results to skip |
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "phone",
"limit": 20,
"offset": 40
}
Pagination Example:
// Page 1 (results 1-20)
{ "q": "phone", "limit": 20, "offset": 0 }
// Page 2 (results 21-40)
{ "q": "phone", "limit": 20, "offset": 20 }
// Page 3 (results 41-60)
{ "q": "phone", "limit": 20, "offset": 40 }
Filtering (Optional)
Filter results using filter expressions:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "shoes",
"filter": "price > 50 AND category = 'running'"
}
Filter Syntax:
# Equality
"brand = 'Nike'"
# Inequality
"price < 100"
"price >= 50"
# Logical operators
"brand = 'Nike' AND price < 100"
"category = 'shoes' OR category = 'boots'"
# IN operator
"brand IN ['Nike', 'Adidas', 'Puma']"
# Range
"price 50 TO 150"
# Negation
"brand != 'Generic'"
"NOT (category = 'clearance')"
String Limits:
- Filter expression: max 2000 characters
Faceting (Optional)
Get facet counts for filtering UI:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "shoes",
"facets": ["brand", "category", "color", "size"]
}
Response includes facet counts:
HTTP/1.1 200 OK
Content-Type: application/json
{
"hits": [...],
"facetDistribution": {
"brand": {
"Nike": 45,
"Adidas": 32,
"Puma": 18
},
"category": {
"running": 67,
"casual": 28
},
"color": {
"black": 40,
"white": 30,
"red": 25
}
}
}
Limits:
- Max 50 facets per request
- Facet name: max 100 characters each
Sorting (Optional)
Sort results by one or more attributes:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "phone",
"sort": ["price:asc", "name:desc"]
}
Sort Direction:
:asc— Ascending (low to high):desc— Descending (high to low)
Examples:
// Price low to high
{ "sort": ["price:asc"] }
// Newest first
{ "sort": ["created_at:desc"] }
// Multi-level sorting
{ "sort": ["category:asc", "price:asc"] }
Limits:
- Max 20 sort criteria per request
Attributes to Retrieve (Optional)
Specify which product attributes to include in results:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "shoes",
"attributesToRetrieve": ["id", "name", "price", "image"]
}
Benefits:
- Reduce response size
- Faster response times
- Only fetch needed data
Limits:
- Max 100 attributes per request
Highlighting (Optional)
Highlight search terms in results:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "red shoes",
"attributesToHighlight": ["name", "description"]
}
Response with highlighting:
HTTP/1.1 200 OK
Content-Type: application/json
{
"hits": [
{
"id": "prod_123",
"name": "Red Running Shoes",
"_formatted": {
"name": "<em>Red</em> Running <em>Shoes</em>",
"description": "Comfortable <em>red</em> athletic <em>shoes</em>..."
}
}
]
}
Customize highlight tags:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "shoes",
"attributesToHighlight": ["name"],
"highlightPreTag": "<mark>",
"highlightPostTag": "</mark>"
}
Text Cropping (Optional)
Truncate long text fields to show only relevant excerpts around search matches:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "comfortable shoes",
"attributesToCrop": ["description"],
"cropLength": 20,
"cropMarker": "..."
}
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
attributesToCrop | array | No | [] | Attributes to truncate |
cropLength | integer | No | 10 | Number of words to show around each match |
cropMarker | string | No | "..." | String to indicate cropped text |
Response with cropping:
HTTP/1.1 200 OK
Content-Type: application/json
{
"hits": [
{
"id": "prod_123",
"name": "Running Shoes Pro",
"description": "Premium athletic footwear designed for...",
"_formatted": {
"description": "...athletic footwear designed for <em>comfortable</em> running with advanced <em>shoes</em> technology..."
}
}
]
}
Use cases:
- Display search snippets in results
- Reduce response size for large text fields
- Show context around matches
Match Position Tracking (Optional)
Get the exact character positions where search terms match:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "red shoes",
"showMatchesPosition": true
}
Response with match positions:
HTTP/1.1 200 OK
Content-Type: application/json
{
"hits": [
{
"id": "prod_123",
"name": "Red Running Shoes",
"_matchesPosition": {
"name": [
{
"start": 0,
"length": 3
},
{
"start": 12,
"length": 5
}
]
}
}
]
}
Use cases:
- Build custom highlighting logic
- Advanced search analytics
- Custom snippet generation
Matching Strategy (Optional)
Control how search terms are matched:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "red running shoes",
"matchingStrategy": "last"
}
Strategies:
all(default) — All terms must matchlast— Remove terms from right until match found
Use last for:
- Better recall (more results)
- Handling long queries
- Typo-tolerant searches
Hybrid Search (Optional, Beta)
Combine semantic (AI) and keyword search:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "comfortable running footwear",
"hybrid": {
"semanticRatio": 0.5,
"embedder": "default"
}
}
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
semanticRatio | number | No | - | Balance: 0.0 = keyword only, 1.0 = semantic only, 0.5 = balanced |
embedder | string | No | - | Embedder name configured in your application |
Semantic Ratio Guide:
// Pure keyword search
{ "hybrid": { "semanticRatio": 0.0 } }
// Balanced (recommended)
{ "hybrid": { "semanticRatio": 0.5 } }
// Pure semantic search
{ "hybrid": { "semanticRatio": 1.0 } }
// Keyword-focused with semantic boost
{ "hybrid": { "semanticRatio": 0.3 } }
Embedder Configuration
Hybrid search requires an embedder to be configured in your application settings. See Search Settings for setup instructions.
Error if embedder not configured:
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"message": "Invalid payload.",
"errors": {
"hybrid.embedder": ["The embedder 'default' is not configured for this application."]
}
}
Complete Example
Full-featured search request:
POST /api/v2/applications/YOUR_APP_ID/search HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"q": "red running shoes",
"limit": 20,
"offset": 0,
"filter": "price > 50 AND price < 200 AND brand IN ['Nike', 'Adidas']",
"facets": ["brand", "size", "color"],
"attributesToRetrieve": ["id", "name", "price", "image", "brand"],
"attributesToHighlight": ["name", "description"],
"sort": ["price:asc"],
"matchingStrategy": "last",
"hybrid": {
"semanticRatio": 0.5,
"embedder": "default"
}
}
Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"hits": [
{
"id": "prod_456",
"name": "Nike Air Zoom Pegasus",
"price": 129.99,
"image": "https://cdn.example.com/nike-pegasus.jpg",
"brand": "Nike",
"_formatted": {
"name": "Nike Air Zoom Pegasus <em>Running</em> <em>Shoes</em>",
"description": "Lightweight <em>red</em> <em>running</em> <em>shoes</em>..."
}
}
],
"query": "red running shoes",
"processingTimeMs": 15,
"limit": 20,
"offset": 0,
"estimatedTotalHits": 42,
"facetDistribution": {
"brand": {
"Nike": 25,
"Adidas": 17
},
"size": {
"9": 8,
"10": 12,
"11": 7
},
"color": {
"red": 42
}
}
}
Best Practices
1. Use Filters Instead of Query
// ❌ Slow: searching in query
{ "q": "Nike shoes" }
// ✅ Fast: filter by brand
{ "q": "shoes", "filter": "brand = 'Nike'" }
2. Limit Returned Attributes
// ❌ Returns all attributes
{ "q": "shoes" }
// ✅ Returns only needed attributes
{
"q": "shoes",
"attributesToRetrieve": ["id", "name", "price", "image"]
}
3. Use Pagination
// ❌ Loads too many results
{ "q": "shoes", "limit": 100 }
// ✅ Load in pages
{ "q": "shoes", "limit": 20, "offset": 0 }
4. Cache Popular Searches
const cache = new Map();
async function cachedSearch(query) {
const key = `search:${query}`;
const cached = cache.get(key);
if (cached && Date.now() - cached.timestamp < 300000) {
// 5 min
return cached.data;
}
const data = await searchAPI(query);
cache.set(key, { data, timestamp: Date.now() });
return data;
}
Next Steps
- Applications API — Manage your applications
- API Errors — Complete error reference
- SDK Reference — Client-side integration