API Reference

API Error Codes

Complete reference for all SearchX API error codes and how to handle them.


Interactive API Documentation

View error responses in context with our Swagger UI: Open Interactive API Docs →


Overview

The SearchX API uses conventional HTTP status codes and structured error responses with numeric error codes. All error responses include an errorCode (numeric) and message (human-readable description).

HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
  "errorCode": 4012,
  "message": "Invalid API Key."
}

HTTP Status Codes

2xx Success

CodeNameDescription
200OKRequest succeeded
201CreatedResource created successfully
202AcceptedRequest accepted for async processing

4xx Client Errors

401 Unauthorized — Authentication failed

  • 4011 — Missing API Key or Bearer Token
  • 4012 — Invalid API Key
  • 4013 — API Key does not match any organization
  • 4014 — Missing application ID
  • 4015 — API key has been revoked

403 Forbidden — Authenticated but not authorized

  • 4031 — API key does not belong to this application
  • 4032 — Origin mismatch (browser requests only)
  • 4033 — Application missing website_origin configuration (browser requests only)

404 Not Found — Resource does not exist

  • 4041 — Resource not found

422 Unprocessable Entity — Validation error

Check request payload for validation errors. No specific subcodes — errors include field-level details.

429 Too Many Requests — Rate limit exceeded

120 requests per minute limit. No specific subcodes.

5xx Server Errors

500 Internal Server Error — Unexpected server error

  • 5001 — Application context not found

502 Bad Gateway — Upstream search service error

  • 5021 — Search service error

Authentication Errors (401)

Authentication errors occur when credentials are missing, invalid, or expired.

4011: Missing API Key or Bearer Token

Status: 401 Unauthorized

Cause: No Authorization header provided or api_key query parameter is missing.

Solution:

Include the Bearer token in request headers:

curl -X GET "https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"

Alternatively, pass as query parameter:

curl -X GET "https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID?api_key=YOUR_API_KEY"

4012: Invalid API Key

Status: 401 Unauthorized

Cause: The provided API key does not exist in our system.

Possible Reasons:

  • Typo in the API key
  • API key was regenerated and old key is being used
  • API key was deleted

Solution:

  1. Verify your API key in the SearchX Dashboard
  2. Navigate to Applications → Select your app → API Keys
  3. Copy the correct API key
  4. If key was regenerated, update your integration with the new key
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
  "errorCode": 4012,
  "message": "Invalid API Key."
}

Security

Invalid API key attempts are logged for security monitoring. Repeated failed attempts from the same IP may trigger additional rate limiting.


4013: API Key Does Not Match Any Organization

Status: 401 Unauthorized

Cause: The API key exists but its associated organization was deleted or is in an invalid state.

Solution:

Contact support at [email protected] — this indicates a data integrity issue.


4014: Missing Application ID

Status: 401 Unauthorized

Cause: The {app_id} path parameter is missing or malformed.

Solution:

Ensure your request URL includes a valid 10-character alphanumeric application ID:

✅ Correct:   /api/v2/applications/a1b2c3d4e5/search
❌ Incorrect: /api/v2/applications//search
❌ Incorrect: /api/v2/applications/invalid_id/search

4015: API Key Has Been Revoked

Status: 401 Unauthorized

Cause: The API key has been revoked and is no longer valid.

Response:

HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
  "errorCode": 4015,
  "message": "This API key has been revoked. Please regenerate or create a new key."
}

Solution:

  1. Go to SearchX Dashboard
  2. Navigate to Applications → Select your app → API Keys
  3. Find the revoked key and click Regenerate to create a new token
  4. Update your integration with the new API key

Security

Revoked keys cannot be re-enabled. This is a security feature to prevent unauthorized access after a key has been compromised.


Authorization Errors (403)

Authorization errors occur when you're authenticated but don't have permission for the requested resource.

4031: API Key Does Not Belong to Application

Status: 403 Forbidden

Cause: You're using an API key that belongs to a different application.

Example:

Request:  /api/v2/applications/a1b2c3d4e5/search
API Key:  Belongs to x9y8z7w6v5
Result:   403 Forbidden

Solution:

Ensure you're using the correct API key for the application:

# Get your app_id from the dashboard
APP_ID="YOUR_APP_ID"

# Get the API key for THAT specific application
API_KEY="YOUR_API_KEY"

curl -X POST "https://admin.searchxengine.ai/api/v2/applications/${APP_ID}/search" \
  -H "Authorization: Bearer ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"q": "shoes"}'

App-Scoped Security

The API enforces app-scoped authentication for enhanced security. Each API key is bound to a specific application and cannot access other applications, even within the same organization.


4032: Origin Mismatch

Status: 403 Forbidden API Version: Both v1 SDK and v2 Public API

Cause: For browser requests to active applications, the Origin header doesn't match the configured website_origin.

Response:

HTTP/1.1 403 Forbidden
Content-Type: application/json
{
  "errorCode": 4032,
  "message": "Origin mismatch. Expected: https://example.com, Got: https://wrong-domain.com"
}

Solution:

  1. Go to Applications → Select your app → Settings
  2. Update the Website Origin to match your domain
  3. Ensure no trailing slashes (use https://example.com not https://example.com/)

Server-to-Server

Origin validation only applies to browser requests (those with an Origin header). Server-to-server API calls are not affected.


4033: Website Origin Not Configured

Status: 403 Forbidden API Version: Both v1 SDK and v2 Public API

Cause: Application is in active status and received a browser request, but website_origin is not configured.

Response:

HTTP/1.1 403 Forbidden
Content-Type: application/json
{
  "errorCode": 4033,
  "message": "Application configuration error: website_origin not set. Configure origin in application settings."
}

Solution:

  1. Go to Applications → Select your app → Settings
  2. Set the Website Origin field to your website's origin
  3. Save changes

Resource Errors (404)

4041: Resource Not Found

Status: 404 Not Found

Cause: No application exists with the provided app_id.

Possible Reasons:

  • Typo in the application ID
  • Application was deleted
  • Using wrong environment (staging vs production)

Solution:

  1. Verify the application ID in the dashboard
  2. Check if the application still exists
  3. Ensure you're using the correct environment
HTTP/1.1 404 Not Found
Content-Type: application/json
{
  "errorCode": 4041,
  "message": "Resource not found."
}

Validation Errors (422)

Status: 422 Unprocessable Entity

Validation errors occur when the request payload doesn't meet the API's requirements.

Response Format:

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
  "message": "The feed_url field must be a valid URL.",
  "errors": {
    "feed_url": ["The feed_url field must be a valid URL."],
    "name": ["The name field must not be greater than 255 characters."]
  }
}

Common Validation Rules:

String Length Limits

FieldMaximum Length
Application name255 characters
Description1000 characters
Feed URL2048 characters
Website URL2048 characters
Search query (q)500 characters
Filter expression2000 characters
Attribute name100 characters

Array Size Limits

FieldMaximum Items
facets50
attributesToRetrieve100
sort20
context (analytics)50 keys

Enum Validations

FieldAllowed Values
feed_typegoogle, facebook, skroutz
matchingStrategyall, last
Event type (analytics)search, product_click, add_to_cart, sort_change, page_view

Example Validation Errors:

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
// Invalid feed type
{
  "message": "The selected feed type is invalid.",
  "errors": {
    "feed_type": ["The selected feed type is invalid."]
  }
}

// Search query too long
{
  "message": "The q field must not be greater than 500 characters.",
  "errors": {
    "q": ["The q field must not be greater than 500 characters."]
  }
}

// Invalid embedder
{
  "message": "Invalid payload.",
  "errors": {
    "hybrid.embedder": [
      "The embedder 'invalid' is not configured for this application."
    ]
  }
}

Rate Limiting (429)

Status: 429 Too Many Requests

Cause: You've exceeded the rate limit of 120 requests per minute per IP address.

Response:

HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
Retry-After: 60
Content-Type: application/json
{
  "message": "Rate limit exceeded. You can make 120 requests per minute. Please retry after 60 seconds."
}

Solution:

1. Implement Exponential Backoff

async function apiRequest(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);

      if (response.status === 429) {
        const retryAfter = parseInt(response.headers.get('Retry-After') || '60');
        const delay = Math.min(retryAfter * 1000 * Math.pow(2, i), 60000);
        await new Promise((resolve) => setTimeout(resolve, delay));
        continue;
      }

      return response;
    } catch (error) {
      if (i === maxRetries - 1) throw error;
    }
  }
}

2. Implement Request Queuing

class RateLimitedClient {
  constructor() {
    this.queue = [];
    this.processing = false;
    this.requestsPerMinute = 120;
    this.interval = 60000; // 1 minute
  }

  async request(url, options) {
    return new Promise((resolve, reject) => {
      this.queue.push({ url, options, resolve, reject });
      this.processQueue();
    });
  }

  async processQueue() {
    if (this.processing || this.queue.length === 0) return;

    this.processing = true;
    const item = this.queue.shift();

    try {
      const response = await fetch(item.url, item.options);
      item.resolve(response);
    } catch (error) {
      item.reject(error);
    }

    // Delay to stay under rate limit
    setTimeout(() => {
      this.processing = false;
      this.processQueue();
    }, this.interval / this.requestsPerMinute);
  }
}

3. Cache Results

Cache search results and analytics data to reduce API calls:

const cache = new Map();

async function cachedSearch(query, ttl = 300000) {
  // 5 min TTL
  const key = `search:${query}`;
  const cached = cache.get(key);

  if (cached && Date.now() - cached.timestamp < ttl) {
    return cached.data;
  }

  const data = await fetch('/api/v2/applications/APP_ID/search', {
    method: 'POST',
    body: JSON.stringify({ q: query }),
  }).then((r) => r.json());

  cache.set(key, { data, timestamp: Date.now() });
  return data;
}

Rate Limit Scope

Rate limits apply per IP address, with a limit of 120 requests per minute.


Server Errors (5xx)

5001: Application Context Not Found

Status: 500 Internal Server Error

Cause: Internal error — application context missing from middleware (should never happen).

Solution:

This indicates a server-side bug. Contact support immediately at [email protected] with:

  • Request ID (from response headers)
  • Timestamp
  • Request details (endpoint, method, app_id)

5021: Search Service Error

Status: 502 Bad Gateway

Cause: Search service is unavailable or returned an error.

Response:

HTTP/1.1 502 Bad Gateway
Content-Type: application/json
{
  "errorCode": 5021,
  "message": "Search service error."
}

Possible Reasons:

  • Search service is temporarily unavailable
  • Index doesn't exist (no products imported yet)
  • Invalid search configuration

Solution:

  1. Verify your application has products imported
  2. Check application status in dashboard
  3. Retry the request after a short delay
  4. If problem persists, contact support

Error Handling Best Practices

1. Always Check Status Codes

const response = await fetch('/api/v2/applications/APP_ID', {
  headers: { Authorization: `Bearer ${API_KEY}` },
});

if (!response.ok) {
  const error = await response.json();
  console.error(`API Error ${response.status}:`, error);

  switch (response.status) {
    case 401:
      // Re-authenticate or update API key
      break;
    case 403:
      // Check app_id matches API key
      break;
    case 429:
      // Implement retry with backoff
      break;
    case 422:
      // Fix validation errors
      console.error('Validation errors:', error.errors);
      break;
    default:
    // Generic error handling
  }
}

2. Log Error Details

function logError(response, errorData) {
  console.error('SearchX API Error', {
    status: response.status,
    errorCode: errorData.errorCode,
    message: errorData.message,
    errors: errorData.errors,
    timestamp: new Date().toISOString(),
    url: response.url,
  });
}

3. Implement Graceful Fallbacks

async function searchWithFallback(query) {
  try {
    const response = await searchAPI(query);
    return response.hits;
  } catch (error) {
    if (error.status === 502) {
      // Search service down - return cached results
      return getCachedResults(query);
    }
    if (error.status === 429) {
      // Rate limited - show message to user
      throw new Error('Too many searches. Please wait a moment.');
    }
    throw error;
  }
}

4. User-Friendly Error Messages

function getUserMessage(errorCode) {
  const messages = {
    4011: 'Authentication required. Please sign in.',
    4012: 'Invalid credentials. Please check your API key.',
    4031: 'Access denied. Please verify your application settings.',
    4041: 'Resource not found.',
    429: 'Too many requests. Please try again in a moment.',
    502: 'Search is temporarily unavailable. Please try again.',
  };

  return messages[errorCode] || 'An error occurred. Please try again.';
}

Need Help?

If you encounter persistent errors:

  1. Check the Applications API and Search API for correct usage
  2. Verify your Authentication setup
  3. Review our Status Page for service health
  4. Contact support: [email protected]

Include these details when reporting errors:

  • Error code and message
  • Request endpoint and method
  • Application ID (not the full API key)
  • Timestamp
  • Expected vs actual behavior
Previous
Analytics API