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

ParameterTypeRequiredDefaultDescription
per_pageintegerNo20Number of events per page (1-100)
pageintegerNo1Page 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

ParameterTypeRequiredDefaultDescription
start_datestringNo30 days agoStart date for summary (YYYY-MM-DD format)
end_datestringNoYesterdayEnd 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

FieldTypeDescription
dailyarrayArray of daily aggregated metrics
totalsobjectSummed totals across the entire date range
metricsobjectComputed performance metrics (CTR, conversion rates)
start_datestringFirst date in the range (YYYY-MM-DD)
end_datestringLast date in the range (YYYY-MM-DD)
daysintegerNumber of days in the range

Daily Metrics

Each item in the daily array contains:

FieldTypeDescription
datestringDate (YYYY-MM-DD)
total_searchesintegerNumber of search events
total_product_clicksintegerNumber of product click events
total_add_to_cartsintegerNumber of add-to-cart events
total_page_viewsintegerNumber of page view events
total_sort_changesintegerNumber of sort change events

Computed Metrics

FieldTypeDescription
click_through_ratenumberPercentage of searches that led to product clicks
add_to_cart_ratenumberPercentage of searches that led to add-to-cart
average_daily_searchesnumberAverage 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

EndpointUse CasePerformance
/analyticsDetailed event analysis, debugging, exportsStandard
/analytics/summaryDashboards, charts, monthly reports, KPIs40-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 entered
  • result_count — Number of results returned
  • filters — 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 product
  • product_name — Name of the product
  • search_query — Original search query
  • position — 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 cart
  • product_name — Name of the product
  • search_query — Original search query that led to add-to-cart
  • page — 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 query
  • page — Page URL where sort changed

Page View Events (page_view)

Tracks page visits on your site.

Context Fields:

  • page — Page URL visited
  • referrer — Previous page URL
  • title — Page title

Response Fields

Pagination Fields

FieldTypeDescription
current_pageintegerCurrent page number
per_pageintegerNumber of events per page
totalintegerTotal number of events across all pages
last_pageintegerLast page number
fromintegerFirst event index on current page
tointegerLast event index on current page

Event Fields

FieldTypeDescription
idstring (UUID)Unique event identifier
event_typestringEvent type: search, product_click, add_to_cart, sort_change, page_view
contextobjectEvent-specific data (varies by event type)
user_agent_infoobjectBrowser and device information
location_infoobjectGeographic location data (from IP)
timestampstring (ISO 8601)When the event occurred
created_atstring (ISO 8601)When the event was recorded

Location Info Fields

FieldTypeDescription
countrystringCountry name
countryCodestringISO 3166-1 alpha-2 country code
regionstringRegion/state code
citystringCity name
latnumberLatitude
lonnumberLongitude
timezonestringIANA 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

Previous
Search API