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.


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.

ParameterTypeRequiredDefaultDescription
qstringNo""Search query (max 500 characters)
limitintegerNo20Results per page (1-100)
offsetintegerNo0Number of results to skip
filterstringNo-Filter expression (max 2000 characters)
facetsarrayNo[]Attributes to compute facets on (max 50)
attributesToRetrievearrayNo["*"]Attributes to include (max 100, * = all)
attributesToHighlightarrayNo[]Attributes to highlight search terms in
highlightPreTagstringNo"<em>"Opening tag for highlights
highlightPostTagstringNo"</em>"Closing tag for highlights
attributesToCroparrayNo[]Attributes to crop/truncate
cropLengthintegerNo10Number of words to show when cropping
cropMarkerstringNo"..."String to mark cropped text
sortarrayNo[]Sort criteria (max 20)
matchingStrategystringNo"all"How to match terms: all or last
showMatchesPositionbooleanNofalseInclude match positions in response
hybridobjectNo-Hybrid (semantic + keyword) search config
hybrid.semanticRationumberNo-Balance: 0.0 (keyword) to 1.0 (semantic)
hybrid.embedderstringNo-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:

ParameterTypeRequiredDefaultDescription
limitintegerNo20Results per page (1-100)
offsetintegerNo0Number 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:

ParameterTypeRequiredDefaultDescription
attributesToCroparrayNo[]Attributes to truncate
cropLengthintegerNo10Number of words to show around each match
cropMarkerstringNo"..."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 match
  • last — 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:

ParameterTypeRequiredDefaultDescription
semanticRationumberNo-Balance: 0.0 = keyword only, 1.0 = semantic only, 0.5 = balanced
embedderstringNo-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 }
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

Previous
Applications API