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
| Code | Name | Description |
|---|---|---|
200 | OK | Request succeeded |
201 | Created | Resource created successfully |
202 | Accepted | Request accepted for async processing |
4xx Client Errors
401 Unauthorized — Authentication failed
4011— Missing API Key or Bearer Token4012— Invalid API Key4013— API Key does not match any organization4014— Missing application ID4015— API key has been revoked
403 Forbidden — Authenticated but not authorized
4031— API key does not belong to this application4032— 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:
- Verify your API key in the SearchX Dashboard
- Navigate to Applications → Select your app → API Keys
- Copy the correct API key
- 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:
- Go to SearchX Dashboard
- Navigate to Applications → Select your app → API Keys
- Find the revoked key and click Regenerate to create a new token
- 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:
- Go to Applications → Select your app → Settings
- Update the Website Origin to match your domain
- Ensure no trailing slashes (use
https://example.comnothttps://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:
- Go to Applications → Select your app → Settings
- Set the Website Origin field to your website's origin
- 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:
- Verify the application ID in the dashboard
- Check if the application still exists
- 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
| Field | Maximum Length |
|---|---|
| Application name | 255 characters |
| Description | 1000 characters |
| Feed URL | 2048 characters |
| Website URL | 2048 characters |
Search query (q) | 500 characters |
| Filter expression | 2000 characters |
| Attribute name | 100 characters |
Array Size Limits
| Field | Maximum Items |
|---|---|
facets | 50 |
attributesToRetrieve | 100 |
sort | 20 |
context (analytics) | 50 keys |
Enum Validations
| Field | Allowed Values |
|---|---|
feed_type | google, facebook, skroutz |
matchingStrategy | all, 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:
- Verify your application has products imported
- Check application status in dashboard
- Retry the request after a short delay
- 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:
- Check the Applications API and Search API for correct usage
- Verify your Authentication setup
- Review our Status Page for service health
- 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