API Reference
Analytics API
Retrieve analytics events including searches, clicks, page views, and conversions for your application.
Overview
The Analytics API allows you to retrieve paginated analytics events tracked through your SearchX integration. Events include user searches, product clicks, page views, and conversions, with detailed context, location, and device information.
Endpoint: GET /api/v2/applications/{app_id}/analytics
Try It Live
Open in Swagger UI → to test analytics queries interactively.
All requests require Bearer token authentication. See API Authentication for details.
Get Analytics Events
Retrieve paginated analytics events for your application.
Request
GET /api/v2/applications/YOUR_APP_ID/analytics?per_page=20&page=1 HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
cURL Example:
curl -X GET "https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID/analytics?per_page=20&page=1" \
-H "Authorization: Bearer YOUR_API_KEY"
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
per_page | integer | No | 20 | Number of events per page (1-100) |
page | integer | No | 1 | Page number (starting from 1) |
Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"current_page": 1,
"per_page": 20,
"total": 1250,
"last_page": 63,
"from": 1,
"to": 20,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"event_type": "search",
"context": {
"search_query": "red shoes",
"result_count": 45,
"filters": {
"price_min": 50,
"price_max": 200
}
},
"user_agent_info": {
"platform": "MacIntel",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)...",
"language": "en-US"
},
"location_info": {
"country": "US",
"countryCode": "US",
"region": "CA",
"city": "San Francisco",
"lat": 37.7749,
"lon": -122.4194,
"timezone": "America/Los_Angeles"
},
"timestamp": "2024-03-27T14:30:00Z",
"created_at": "2024-03-27T14:30:05Z"
},
{
"id": "660f9511-f30c-52e5-b827-557766551111",
"event_type": "product_click",
"context": {
"product_id": "prod_123",
"product_name": "Nike Air Max",
"search_query": "running shoes",
"position": 3
},
"user_agent_info": {
"platform": "Win32",
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)..."
},
"location_info": {
"country": "United Kingdom",
"countryCode": "GB",
"city": "London"
},
"timestamp": "2024-03-27T14:25:30Z",
"created_at": "2024-03-27T14:25:32Z"
},
{
"id": "770fa622-g41d-63f6-c938-668877662222",
"event_type": "add_to_cart",
"context": {
"product_id": "prod_456",
"product_name": "Wireless Headphones XYZ",
"search_query": "wireless headphones"
},
"user_agent_info": {
"platform": "iPhone",
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)..."
},
"location_info": {
"country": "Canada",
"countryCode": "CA",
"city": "Toronto"
},
"timestamp": "2024-03-27T14:20:15Z",
"created_at": "2024-03-27T14:20:18Z"
}
]
}
Get Analytics Summary
Retrieve pre-aggregated daily analytics metrics for your application. This endpoint is optimized for dashboards and reporting, providing much faster responses than the raw events endpoint for large date ranges.
Endpoint: GET /api/v2/applications/{app_id}/analytics/summary
Performance
This endpoint uses pre-computed daily aggregates for 40-100x faster queries compared to raw events. Ideal for dashboards, charts, and monthly/quarterly reports.
Request
GET /api/v2/applications/YOUR_APP_ID/analytics/summary?start_date=2024-02-26&end_date=2024-03-27 HTTP/1.1
Host: admin.searchxengine.ai
Authorization: Bearer YOUR_API_KEY
cURL Example:
curl -X GET "https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID/analytics/summary?start_date=2024-02-26&end_date=2024-03-27" \
-H "Authorization: Bearer YOUR_API_KEY"
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
start_date | string | No | 30 days ago | Start date for summary (YYYY-MM-DD format) |
end_date | string | No | Yesterday | End date for summary (YYYY-MM-DD format, max: yesterday) |
Date Range Limitation
The end_date is limited to yesterday because today's data hasn't been aggregated yet. For real-time data, use the raw events endpoint.
Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"daily": [
{
"date": "2024-03-27",
"total_searches": 1250,
"total_product_clicks": 380,
"total_add_to_carts": 95,
"total_page_views": 2150,
"total_sort_changes": 45
},
{
"date": "2024-03-26",
"total_searches": 1180,
"total_product_clicks": 356,
"total_add_to_carts": 89,
"total_page_views": 2050,
"total_sort_changes": 42
}
// ... more days
],
"totals": {
"total_searches": 35420,
"total_product_clicks": 10650,
"total_add_to_carts": 2840,
"total_page_views": 68500,
"total_sort_changes": 1245
},
"metrics": {
"click_through_rate": 30.05,
"add_to_cart_rate": 8.02,
"average_daily_searches": 1180.67
},
"start_date": "2024-02-26",
"end_date": "2024-03-27",
"days": 30
}
Response Fields
| Field | Type | Description |
|---|---|---|
daily | array | Array of daily aggregated metrics |
totals | object | Summed totals across the entire date range |
metrics | object | Computed performance metrics (CTR, conversion rates) |
start_date | string | First date in the range (YYYY-MM-DD) |
end_date | string | Last date in the range (YYYY-MM-DD) |
days | integer | Number of days in the range |
Daily Metrics
Each item in the daily array contains:
| Field | Type | Description |
|---|---|---|
date | string | Date (YYYY-MM-DD) |
total_searches | integer | Number of search events |
total_product_clicks | integer | Number of product click events |
total_add_to_carts | integer | Number of add-to-cart events |
total_page_views | integer | Number of page view events |
total_sort_changes | integer | Number of sort change events |
Computed Metrics
| Field | Type | Description |
|---|---|---|
click_through_rate | number | Percentage of searches that led to product clicks |
add_to_cart_rate | number | Percentage of searches that led to add-to-cart |
average_daily_searches | number | Average number of searches per day in the date range |
Use Cases
Dashboard Widgets
Perfect for displaying KPIs on dashboards:
const summary = await fetch(
'https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID/analytics/summary?start_date=2024-02-26&end_date=2024-03-27',
{
headers: { Authorization: `Bearer ${API_KEY}` },
},
).then((r) => r.json());
// Display KPIs
console.log(`Total Searches: ${summary.totals.total_searches}`);
console.log(`Click-Through Rate: ${summary.metrics.click_through_rate}%`);
console.log(`Conversion Rate: ${summary.metrics.add_to_cart_rate}%`);
Charts and Visualizations
Use daily data for time-series charts:
import { LineChart } from 'chart-library';
const summary = await fetchAnalyticsSummary(appId);
const chartData = {
labels: summary.daily.map((d) => d.date),
datasets: [
{
label: 'Daily Searches',
data: summary.daily.map((d) => d.total_searches),
},
{
label: 'Product Clicks',
data: summary.daily.map((d) => d.total_product_clicks),
},
],
};
<LineChart data={chartData} />;
Month-over-Month Comparison
async function compareMonths(appId, apiKey) {
const thisMonth = await fetch(
`https://admin.searchxengine.ai/api/v2/applications/${appId}/analytics/summary?start_date=2024-03-01&end_date=2024-03-31`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
).then((r) => r.json());
const lastMonth = await fetch(
`https://admin.searchxengine.ai/api/v2/applications/${appId}/analytics/summary?start_date=2024-02-01&end_date=2024-02-29`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
).then((r) => r.json());
const growth =
((thisMonth.totals.total_searches - lastMonth.totals.total_searches) /
lastMonth.totals.total_searches) *
100;
console.log(`Search Growth: ${growth.toFixed(1)}%`);
}
When to Use Each Endpoint
| Endpoint | Use Case | Performance |
|---|---|---|
/analytics | Detailed event analysis, debugging, exports | Standard |
/analytics/summary | Dashboards, charts, monthly reports, KPIs | 40-100x faster |
Best Practice
Use /analytics/summary for dashboards and reporting (30-90 day ranges). Use /analytics for detailed event analysis and exports.
Event Types
Analytics events are categorized into five types:
Search Events (search)
Tracks when users perform searches on your site.
Context Fields:
search_query— The search term enteredresult_count— Number of results returnedfilters— Any filters applied (category, price range, etc.)page— Page URL where search occurred
Product Click Events (product_click)
Tracks when users click on search results.
Context Fields:
product_id— ID of the clicked productproduct_name— Name of the productsearch_query— Original search queryposition— Position in search results (1-based)page— Page URL where click occurred
Add to Cart Events (add_to_cart)
Tracks when users add products to their cart.
Context Fields:
product_id— Product added to cartproduct_name— Name of the productsearch_query— Original search query that led to add-to-cartpage— Page URL where add-to-cart occurred
Sort Change Events (sort_change)
Tracks when users change the sort order of search results.
Context Fields:
sort_by— New sort criteria (e.g., "price_asc", "price_desc", "relevance")search_query— Active search querypage— Page URL where sort changed
Page View Events (page_view)
Tracks page visits on your site.
Context Fields:
page— Page URL visitedreferrer— Previous page URLtitle— Page title
Response Fields
Pagination Fields
| Field | Type | Description |
|---|---|---|
current_page | integer | Current page number |
per_page | integer | Number of events per page |
total | integer | Total number of events across all pages |
last_page | integer | Last page number |
from | integer | First event index on current page |
to | integer | Last event index on current page |
Event Fields
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique event identifier |
event_type | string | Event type: search, product_click, add_to_cart, sort_change, page_view |
context | object | Event-specific data (varies by event type) |
user_agent_info | object | Browser and device information |
location_info | object | Geographic location data (from IP) |
timestamp | string (ISO 8601) | When the event occurred |
created_at | string (ISO 8601) | When the event was recorded |
Location Info Fields
| Field | Type | Description |
|---|---|---|
country | string | Country name |
countryCode | string | ISO 3166-1 alpha-2 country code |
region | string | Region/state code |
city | string | City name |
lat | number | Latitude |
lon | number | Longitude |
timezone | string | IANA timezone identifier |
Note: Location data is derived from IP address using a geolocation service. Fields may be null if location cannot be determined.
Pagination Example
// Fetch first page (events 1-20)
const page1 = await fetch(
'https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID/analytics?per_page=20&page=1',
{
headers: {
Authorization: `Bearer ${API_KEY}`,
},
},
).then((r) => r.json());
console.log(`Showing ${page1.from}-${page1.to} of ${page1.total} events`);
// Output: Showing 1-20 of 1250 events
// Fetch second page (events 21-40)
const page2 = await fetch(
'https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID/analytics?per_page=20&page=2',
{
headers: {
Authorization: `Bearer ${API_KEY}`,
},
},
).then((r) => r.json());
console.log(`Page ${page2.current_page} of ${page2.last_page}`);
// Output: Page 2 of 63
Filtering and Exporting
Filter by Date Range
Note: Date filtering is not currently available via query parameters. To filter events by date, fetch paginated results and filter client-side:
const response = await fetch(
'https://admin.searchxengine.ai/api/v2/applications/YOUR_APP_ID/analytics?per_page=100',
{
headers: { Authorization: `Bearer ${API_KEY}` },
},
).then((r) => r.json());
// Filter events from last 7 days
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
const recentEvents = response.data.filter((event) => new Date(event.timestamp) >= sevenDaysAgo);
Export All Events
To export all analytics events:
async function exportAllAnalytics(appId, apiKey) {
let allEvents = [];
let currentPage = 1;
let lastPage = 1;
do {
const response = await fetch(
`https://admin.searchxengine.ai/api/v2/applications/${appId}/analytics?per_page=100&page=${currentPage}`,
{
headers: { Authorization: `Bearer ${apiKey}` },
},
).then((r) => r.json());
allEvents = allEvents.concat(response.data);
lastPage = response.last_page;
currentPage++;
// Respect rate limits
await new Promise((resolve) => setTimeout(resolve, 500));
} while (currentPage <= lastPage);
return allEvents;
}
// Export to CSV
const events = await exportAllAnalytics('YOUR_APP_ID', 'YOUR_API_KEY');
const csv = convertToCSV(events);
Rate Limiting
When fetching multiple pages, be mindful of the 120 requests/minute rate limit. Add delays between requests or use the rate limiting strategies from API Errors.
Best Practices
1. Use Appropriate Page Size
// ❌ Fetching too many events at once
{
per_page: 100;
} // Only use for exports
// ✅ Standard pagination for UI
{
per_page: 20;
} // Faster response, better UX
2. Cache Analytics Data
Analytics data changes infrequently. Cache results to reduce API calls:
const cache = new Map();
async function getAnalytics(appId, page = 1, ttl = 300000) {
// 5 min TTL
const key = `analytics:${appId}:${page}`;
const cached = cache.get(key);
if (cached && Date.now() - cached.timestamp < ttl) {
return cached.data;
}
const data = await fetchAnalytics(appId, page);
cache.set(key, { data, timestamp: Date.now() });
return data;
}
3. Handle Pagination Efficiently
// ❌ Loading all pages upfront
const allEvents = await loadAllPages(); // Slow, heavy
// ✅ Load pages on demand
function AnalyticsTable() {
const [page, setPage] = useState(1);
const { data } = useAnalytics(appId, page);
return (
<>
<EventList events={data.data} />
<Pagination current={data.current_page} total={data.last_page} onChange={setPage} />
</>
);
}
4. Monitor Event Types
Track the distribution of event types to understand user behavior:
const response = await fetchAnalytics(appId);
const eventCounts = response.data.reduce((acc, event) => {
acc[event.event_type] = (acc[event.event_type] || 0) + 1;
return acc;
}, {});
console.log(eventCounts);
// { search: 450, product_click: 280, add_to_cart: 95, sort_change: 45, page_view: 380 }
Analytics Dashboard Example
import { useState, useEffect } from 'react';
function AnalyticsDashboard({ appId, apiKey }) {
const [analytics, setAnalytics] = useState(null);
const [page, setPage] = useState(1);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadAnalytics() {
setLoading(true);
const response = await fetch(
`https://admin.searchxengine.ai/api/v2/applications/${appId}/analytics?per_page=20&page=${page}`,
{
headers: {
Authorization: `Bearer ${apiKey}`,
},
},
);
if (response.ok) {
const data = await response.json();
setAnalytics(data);
}
setLoading(false);
}
loadAnalytics();
}, [appId, apiKey, page]);
if (loading) return <div>Loading...</div>;
return (
<div>
<h1>Analytics Events</h1>
<p>
Showing {analytics.from}-{analytics.to} of {analytics.total} events
</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>Context</th>
<th>Location</th>
<th>Timestamp</th>
</tr>
</thead>
<tbody>
{analytics.data.map((event) => (
<tr key={event.id}>
<td>{event.event_type}</td>
<td>
{event.event_type === 'search' && event.context.search_query}
{event.event_type === 'product_click' && event.context.product_name}
{event.event_type === 'add_to_cart' && event.context.product_name}
{event.event_type === 'sort_change' && event.context.sort_by}
</td>
<td>
{event.location_info?.city}, {event.location_info?.countryCode}
</td>
<td>{new Date(event.timestamp).toLocaleString()}</td>
</tr>
))}
</tbody>
</table>
<div>
<button onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={page === 1}>
Previous
</button>
<span>
Page {analytics.current_page} of {analytics.last_page}
</span>
<button
onClick={() => setPage((p) => Math.min(analytics.last_page, p + 1))}
disabled={page === analytics.last_page}
>
Next
</button>
</div>
</div>
);
}
Next Steps
- Applications API — Manage your applications
- Search API — Execute product searches
- API Errors — Complete error reference