Skip to content

Get Notification Statistics ​

Retrieve notification statistics with optional filtering.

Endpoint ​

http
GET /notifications/notifications/stats

Authentication: Required (JWT)

Query Parameters ​

ParameterTypeRequiredDefaultDescription
userIdstringNo-Filter by user ID
startDatestringNo-Start date for date range (ISO 8601)
endDatestringNo-End date for date range (ISO 8601)

Request Examples ​

All Statistics ​

bash
curl "http://localhost:3000/notifications/notifications/stats" \
  -H "Authorization: Bearer <access_token>"

User-Specific Statistics ​

bash
curl "http://localhost:3000/notifications/notifications/stats?userId=507f1f77bcf86cd799439010" \
  -H "Authorization: Bearer <access_token>"

Date Range Statistics ​

bash
curl "http://localhost:3000/notifications/notifications/stats?startDate=2024-02-01T00:00:00Z&endDate=2024-02-28T23:59:59Z" \
  -H "Authorization: Bearer <access_token>"

Combined Filters ​

bash
curl "http://localhost:3000/notifications/notifications/stats?userId=507f1f77bcf86cd799439010&startDate=2024-02-01T00:00:00Z&endDate=2024-02-28T23:59:59Z" \
  -H "Authorization: Bearer <access_token>"

Response ​

Status Code: 200 OK

json
{
  "total": 150,
  "sent": 140,
  "failed": 5,
  "pending": 3,
  "retrying": 2,
  "read": 85,
  "unread": 65,
  "byChannel": {
    "email": 100,
    "whatsapp": 30,
    "push": 20
  },
  "byType": {
    "CONTEST_REMINDER": 120,
    "CONTEST_STARTING": 20,
    "CONTEST_ENDING": 8,
    "SYSTEM_ALERT": 2
  },
  "byStatus": {
    "SENT": 140,
    "FAILED": 5,
    "PENDING": 3,
    "RETRYING": 2
  },
  "successRate": 93.33,
  "failureRate": 3.33,
  "averageDeliveryTime": 2.5,
  "dateRange": {
    "start": "2024-02-01T00:00:00.000Z",
    "end": "2024-02-28T23:59:59.999Z"
  }
}

Response Fields ​

Overall Statistics ​

FieldTypeDescription
totalnumberTotal number of notifications
sentnumberSuccessfully sent notifications
failednumberFailed notifications
pendingnumberPending notifications
retryingnumberNotifications being retried
readnumberRead notifications
unreadnumberUnread notifications

By Channel ​

ChannelDescription
emailEmail notifications count
whatsappWhatsApp notifications count
pushPush notifications count

By Type ​

TypeDescription
CONTEST_REMINDERContest reminder notifications
CONTEST_STARTINGContest starting notifications
CONTEST_ENDINGContest ending notifications
SYSTEM_ALERTSystem alert notifications

By Status ​

StatusDescription
SENTSuccessfully delivered
FAILEDDelivery failed
PENDINGQueued for delivery
RETRYINGRetry in progress

Metrics ​

FieldTypeDescription
successRatenumberPercentage of successful deliveries
failureRatenumberPercentage of failed deliveries
averageDeliveryTimenumberAverage delivery time in seconds
dateRangeobjectDate range for statistics (if filtered)

Use Cases ​

  1. Dashboard Analytics: Display notification metrics
  2. Performance Monitoring: Track delivery success rates
  3. User Engagement: Measure notification read rates
  4. Debugging: Identify delivery issues
  5. Reporting: Generate notification reports
  6. Optimization: Analyze channel performance

Example: User-Specific Stats ​

json
{
  "total": 25,
  "sent": 24,
  "failed": 1,
  "pending": 0,
  "read": 15,
  "unread": 10,
  "byChannel": {
    "email": 25
  },
  "byType": {
    "CONTEST_REMINDER": 20,
    "CONTEST_STARTING": 5
  },
  "successRate": 96.0,
  "failureRate": 4.0
}

Example: Date Range Stats ​

json
{
  "total": 50,
  "sent": 48,
  "failed": 2,
  "byChannel": {
    "email": 35,
    "push": 15
  },
  "successRate": 96.0,
  "dateRange": {
    "start": "2024-02-01T00:00:00.000Z",
    "end": "2024-02-07T23:59:59.999Z"
  }
}

Error Responses ​

401 Unauthorized ​

json
{
  "statusCode": 401,
  "message": "Unauthorized",
  "error": "Unauthorized"
}

400 Bad Request ​

json
{
  "statusCode": 400,
  "message": "Invalid date format",
  "error": "Bad Request"
}

Integration Example ​

React Dashboard Component ​

typescript
const NotificationStats = () => {
  const [stats, setStats] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetchStats();
  }, []);
  
  const fetchStats = async () => {
    try {
      const response = await fetch(
        'http://localhost:3000/notifications/notifications/stats',
        {
          headers: {
            'Authorization': `Bearer ${accessToken}`
          }
        }
      );
      
      const data = await response.json();
      setStats(data);
    } catch (error) {
      console.error('Failed to fetch stats:', error);
    } finally {
      setLoading(false);
    }
  };
  
  if (loading) return <div>Loading...</div>;
  
  return (
    <div className="stats-dashboard">
      <div className="stat-card">
        <h3>Total Notifications</h3>
        <p>{stats.total}</p>
      </div>
      <div className="stat-card">
        <h3>Success Rate</h3>
        <p>{stats.successRate.toFixed(2)}%</p>
      </div>
      <div className="stat-card">
        <h3>Unread</h3>
        <p>{stats.unread}</p>
      </div>
    </div>
  );
};

Vue Dashboard Component ​

typescript
<script setup lang="ts">
import { ref, onMounted } from 'vue';

const stats = ref(null);
const loading = ref(true);

const fetchStats = async () => {
  try {
    const { data } = await useFetch('/notifications/notifications/stats', {
      headers: {
        Authorization: `Bearer ${accessToken.value}`
      }
    });
    stats.value = data.value;
  } catch (error) {
    console.error('Failed to fetch stats:', error);
  } finally {
    loading.value = false;
  }
};

onMounted(() => {
  fetchStats();
});
</script>

<template>
  <div v-if="!loading" class="stats-dashboard">
    <div class="stat-card">
      <h3>Total</h3>
      <p>{{ stats.total }}</p>
    </div>
    <div class="stat-card">
      <h3>Success Rate</h3>
      <p>{{ stats.successRate.toFixed(2) }}%</p>
    </div>
  </div>
</template>

Best Practices ​

✅ Do ​

  • Cache statistics for dashboard displays
  • Use date ranges for historical analysis
  • Monitor success rates regularly
  • Track trends over time
  • Use statistics for optimization decisions

❌ Don't ​

  • Poll this endpoint too frequently
  • Ignore failure rates
  • Request statistics without date ranges for large datasets
  • Use statistics as real-time monitoring (use health check instead)

Built with ❤️ for competitive programmers worldwide.