> ## Documentation Index
> Fetch the complete documentation index at: https://vij.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# GET /api/stats

> Retrieve error statistics and analytics

The GET `/api/stats` endpoint provides aggregated statistics and metrics about your error logs for dashboard analytics and reporting.

## Query Parameters

<ParamField query="startDate" type="string">
  Filter stats from this date (ISO 8601).

  **Example**: `/api/stats?startDate=2024-01-01T00:00:00Z`
</ParamField>

<ParamField query="endDate" type="string">
  Filter stats until this date (ISO 8601).

  **Example**: `/api/stats?endDate=2024-01-31T23:59:59Z`
</ParamField>

<ParamField query="environment" type="string">
  Filter stats by environment.

  **Example**: `/api/stats?environment=production`
</ParamField>

<ParamField query="appId" type="string">
  Filter stats by application ID.

  **Example**: `/api/stats?appId=my-frontend-app`
</ParamField>

<ParamField query="interval" type="string" default="1h">
  Time interval for time-series data.

  **Values**: `1h` (hourly), `1d` (daily), `1w` (weekly)

  **Example**: `/api/stats?interval=1d`
</ParamField>

## Response Fields

<ResponseField name="overview" type="object">
  High-level statistics.

  <Expandable title="Overview properties">
    <ResponseField name="totalErrors" type="number">
      Total number of errors in the time range.
    </ResponseField>

    <ResponseField name="errorRate" type="number">
      Average errors per hour.
    </ResponseField>

    <ResponseField name="uniqueGroups" type="number">
      Number of unique error groups.
    </ResponseField>

    <ResponseField name="newGroups" type="number">
      New error groups in the time range.
    </ResponseField>

    <ResponseField name="affectedUsers" type="number">
      Number of unique users affected (if userId in metadata).
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="bySeverity" type="object">
  Breakdown by severity level.

  ```json theme={null}
  {
    "error": 12000,
    "warning": 3500,
    "info": 500
  }
  ```
</ResponseField>

<ResponseField name="byEnvironment" type="array">
  Breakdown by environment.

  ```json theme={null}
  [
    { "environment": "production", "count": 10000 },
    { "environment": "staging", "count": 5000 },
    { "environment": "development", "count": 1000 }
  ]
  ```
</ResponseField>

<ResponseField name="byApplication" type="array">
  Breakdown by application.

  ```json theme={null}
  [
    { "appId": "frontend", "count": 8000 },
    { "appId": "backend-api", "count": 6000 },
    { "appId": "mobile-app", "count": 2000 }
  ]
  ```
</ResponseField>

<ResponseField name="timeseries" type="array">
  Error counts over time.

  ```json theme={null}
  [
    { "timestamp": "2024-01-01T00:00:00Z", "count": 45, "error": 35, "warning": 8, "info": 2 },
    { "timestamp": "2024-01-01T01:00:00Z", "count": 67, "error": 52, "warning": 12, "info": 3 }
  ]
  ```
</ResponseField>

<ResponseField name="topErrors" type="array">
  Most frequent error groups.

  <Expandable title="Error group properties">
    <ResponseField name="group" type="string">
      Error group fingerprint.
    </ResponseField>

    <ResponseField name="message" type="string">
      Representative error message.
    </ResponseField>

    <ResponseField name="count" type="number">
      Number of occurrences.
    </ResponseField>

    <ResponseField name="severity" type="string">
      Highest severity in the group.
    </ResponseField>

    <ResponseField name="firstSeen" type="string">
      When this error first appeared.
    </ResponseField>

    <ResponseField name="lastSeen" type="string">
      Most recent occurrence.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="trends" type="object">
  Trend analysis compared to previous period.

  ```json theme={null}
  {
    "totalChange": 12.5,        // Percentage change
    "errorRateChange": -5.2,    // Improvement
    "newGroupsChange": 8.3
  }
  ```
</ResponseField>

## Example Requests

<CodeGroup>
  ```bash Basic Stats theme={null}
  curl "https://vij.example.com/api/stats"
  ```

  ```bash Stats for Date Range theme={null}
  curl "https://vij.example.com/api/stats?startDate=2024-01-01T00:00:00Z&endDate=2024-01-31T23:59:59Z"
  ```

  ```bash Production Stats theme={null}
  curl "https://vij.example.com/api/stats?environment=production"
  ```

  ```bash App-Specific Stats theme={null}
  curl "https://vij.example.com/api/stats?appId=my-frontend-app"
  ```

  ```bash Daily Stats theme={null}
  curl "https://vij.example.com/api/stats?interval=1d&startDate=2024-01-01T00:00:00Z&endDate=2024-01-31T23:59:59Z"
  ```
</CodeGroup>

## Example Response

<ResponseExample>
  ```json Success (200) theme={null}
  {
    "overview": {
      "totalErrors": 15247,
      "errorRate": 42.3,
      "uniqueGroups": 347,
      "newGroups": 23,
      "affectedUsers": 2145
    },
    "bySeverity": {
      "error": 12000,
      "warning": 2800,
      "info": 447
    },
    "byEnvironment": [
      { "environment": "production", "count": 12000 },
      { "environment": "staging", "count": 2500 },
      { "environment": "development", "count": 747 }
    ],
    "byApplication": [
      { "appId": "frontend", "count": 8234 },
      { "appId": "backend-api", "count": 5123 },
      { "appId": "mobile-app", "count": 1890 }
    ],
    "timeseries": [
      {
        "timestamp": "2024-01-01T00:00:00Z",
        "count": 45,
        "error": 35,
        "warning": 8,
        "info": 2
      },
      {
        "timestamp": "2024-01-01T01:00:00Z",
        "count": 67,
        "error": 52,
        "warning": 12,
        "info": 3
      }
    ],
    "topErrors": [
      {
        "group": "abc123def456",
        "message": "TypeError: Cannot read property 'map' of undefined",
        "count": 2547,
        "severity": "error",
        "firstSeen": "2024-01-01T10:00:00Z",
        "lastSeen": "2024-01-03T14:30:00Z"
      },
      {
        "group": "def456ghi789",
        "message": "Payment processing failed",
        "count": 1234,
        "severity": "error",
        "firstSeen": "2024-01-02T08:00:00Z",
        "lastSeen": "2024-01-03T15:00:00Z"
      }
    ],
    "trends": {
      "totalChange": 12.5,
      "errorRateChange": -5.2,
      "newGroupsChange": 8.3
    }
  }
  ```
</ResponseExample>

## Use Cases

### Dashboard Overview

Display key metrics on your dashboard:

```javascript theme={null}
const stats = await fetch('https://vij.example.com/api/stats').then(r => r.json());

// Display metrics
document.getElementById('total-errors').textContent = stats.overview.totalErrors;
document.getElementById('error-rate').textContent = stats.overview.errorRate;
document.getElementById('unique-groups').textContent = stats.overview.uniqueGroups;
```

### Time-Series Chart

Generate error trends chart:

```javascript theme={null}
const stats = await fetch(
  'https://vij.example.com/api/stats?interval=1d&startDate=2024-01-01T00:00:00Z&endDate=2024-01-31T23:59:59Z'
).then(r => r.json());

// Use with Chart.js
new Chart(ctx, {
  type: 'line',
  data: {
    labels: stats.timeseries.map(t => t.timestamp),
    datasets: [
      {
        label: 'Errors',
        data: stats.timeseries.map(t => t.error),
        borderColor: 'red'
      },
      {
        label: 'Warnings',
        data: stats.timeseries.map(t => t.warning),
        borderColor: 'orange'
      }
    ]
  }
});
```

### Application Comparison

Compare error rates across apps:

```javascript theme={null}
const stats = await fetch('https://vij.example.com/api/stats').then(r => r.json());

stats.byApplication.forEach(app => {
  console.log(`${app.appId}: ${app.count} errors`);
});

// Output:
// frontend: 8234 errors
// backend-api: 5123 errors
// mobile-app: 1890 errors
```

### Alerting

Set up automated alerts:

```javascript theme={null}
const stats = await fetch('https://vij.example.com/api/stats').then(r => r.json());

// Alert if error rate too high
if (stats.overview.errorRate > 100) {
  sendAlert({
    severity: 'critical',
    message: `High error rate: ${stats.overview.errorRate}/hour`,
    details: stats
  });
}

// Alert on new error groups
if (stats.overview.newGroups > 10) {
  sendAlert({
    severity: 'warning',
    message: `${stats.overview.newGroups} new error groups detected`,
    details: stats.topErrors
  });
}
```

### Weekly Report

Generate weekly summary:

```javascript theme={null}
const oneWeekAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
const stats = await fetch(
  `https://vij.example.com/api/stats?startDate=${oneWeekAgo}`
).then(r => r.json());

const report = `
Weekly Error Report

Total Errors: ${stats.overview.totalErrors}
Average Rate: ${stats.overview.errorRate}/hour
New Error Groups: ${stats.overview.newGroups}

Top Errors:
${stats.topErrors.map((e, i) => `${i + 1}. ${e.message} (${e.count} occurrences)`).join('\n')}

Trend: ${stats.trends.totalChange > 0 ? '↑' : '↓'} ${Math.abs(stats.trends.totalChange)}%
`;

sendEmail(report);
```

## Filtering by Time Range

### Last 24 Hours

```bash theme={null}
startDate=$(date -u -d '1 day ago' +%Y-%m-%dT%H:%M:%SZ)
curl "https://vij.example.com/api/stats?startDate=$startDate"
```

### Last 7 Days

```bash theme={null}
startDate=$(date -u -d '7 days ago' +%Y-%m-%dT%H:%M:%SZ)
curl "https://vij.example.com/api/stats?startDate=$startDate"
```

### Specific Month

```bash theme={null}
curl "https://vij.example.com/api/stats?startDate=2024-01-01T00:00:00Z&endDate=2024-01-31T23:59:59Z"
```

### Year to Date

```bash theme={null}
startDate=$(date -u +%Y-01-01T00:00:00Z)
curl "https://vij.example.com/api/stats?startDate=$startDate"
```

## Time-Series Intervals

### Hourly (1h)

Best for: Last 24-48 hours

```bash theme={null}
curl "https://vij.example.com/api/stats?interval=1h&startDate=2024-01-01T00:00:00Z&endDate=2024-01-02T00:00:00Z"
```

**Result**: One data point per hour

### Daily (1d)

Best for: Last 30-90 days

```bash theme={null}
curl "https://vij.example.com/api/stats?interval=1d&startDate=2024-01-01T00:00:00Z&endDate=2024-01-31T23:59:59Z"
```

**Result**: One data point per day

### Weekly (1w)

Best for: Last 3-12 months

```bash theme={null}
curl "https://vij.example.com/api/stats?interval=1w&startDate=2024-01-01T00:00:00Z&endDate=2024-12-31T23:59:59Z"
```

**Result**: One data point per week

## Performance Optimization

<AccordionGroup>
  <Accordion title="Use appropriate time ranges">
    ```bash theme={null}
    # Good - last 30 days
    startDate=$(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ)

    # Slow - all time
    # No time filter
    ```
  </Accordion>

  <Accordion title="Choose right interval">
    ```bash theme={null}
    # Good - hourly for 24h
    interval=1h&startDate=$(date -u -d '1 day ago' +%Y-%m-%dT%H:%M:%SZ)

    # Good - daily for 30d
    interval=1d&startDate=$(date -u -d '30 days ago' +%Y-%m-%dT%H:%M:%SZ)

    # Bad - hourly for 1 year (too many data points)
    interval=1h&startDate=$(date -u -d '1 year ago' +%Y-%m-%dT%H:%M:%SZ)
    ```
  </Accordion>

  <Accordion title="Filter by app or environment">
    ```bash theme={null}
    # Faster - single app
    curl "https://vij.example.com/api/stats?appId=my-app"

    # Slower - all apps
    curl "https://vij.example.com/api/stats"
    ```
  </Accordion>

  <Accordion title="Cache results">
    Stats change infrequently - cache for 1-5 minutes:

    ```javascript theme={null}
    const CACHE_TTL = 60 * 1000; // 1 minute
    let statsCache = null;
    let cacheTime = 0;

    async function getStats() {
      if (Date.now() - cacheTime < CACHE_TTL) {
        return statsCache;
      }

      statsCache = await fetch('/api/stats').then(r => r.json());
      cacheTime = Date.now();
      return statsCache;
    }
    ```
  </Accordion>
</AccordionGroup>

## Client Implementation

### TypeScript

```typescript theme={null}
interface StatsQuery {
  startDate?: string;
  endDate?: string;
  environment?: string;
  appId?: string;
  interval?: '1h' | '1d' | '1w';
}

interface Stats {
  overview: {
    totalErrors: number;
    errorRate: number;
    uniqueGroups: number;
    newGroups: number;
    affectedUsers: number;
  };
  bySeverity: {
    error: number;
    warning: number;
    info: number;
  };
  byEnvironment: Array<{ environment: string; count: number }>;
  byApplication: Array<{ appId: string; count: number }>;
  timeseries: Array<{
    timestamp: string;
    count: number;
    error: number;
    warning: number;
    info: number;
  }>;
  topErrors: Array<{
    group: string;
    message: string;
    count: number;
    severity: string;
    firstSeen: string;
    lastSeen: string;
  }>;
  trends: {
    totalChange: number;
    errorRateChange: number;
    newGroupsChange: number;
  };
}

async function fetchStats(query: StatsQuery = {}): Promise<Stats> {
  const params = new URLSearchParams(
    Object.entries(query)
      .filter(([_, v]) => v !== undefined)
      .map(([k, v]) => [k, String(v)])
  );

  const response = await fetch(
    `https://vij.example.com/api/stats?${params}`
  );

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }

  return response.json();
}
```

## Caching Headers

Stats responses include cache headers:

```
Cache-Control: public, max-age=60
ETag: "abc123def456"
```

**Use ETags for conditional requests**:

```bash theme={null}
curl -H 'If-None-Match: "abc123def456"' \
  https://vij.example.com/api/stats
```

If data hasn't changed: `304 Not Modified`

## Related Endpoints

<CardGroup cols={2}>
  <Card title="GET /api/logs" icon="list" href="/api-reference/logs/get">
    Retrieve individual error logs
  </Card>

  <Card title="GET /api/groups" icon="layer-group" href="/api-reference/groups">
    Retrieve error groups
  </Card>

  <Card title="Analytics Guide" icon="chart-line" href="/advanced/analytics">
    Learn about VIJ analytics
  </Card>

  <Card title="Dashboard Features" icon="gauge" href="/dashboard/features">
    Explore dashboard visualizations
  </Card>
</CardGroup>
