> ## Documentation Index
> Fetch the complete documentation index at: https://compass.docs.sunnyscoach.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Hourly Email Traffic Trends

> Returns hourly email volume (received and sent) between the given start and end dates.   Each day is broken down into 24 hourly buckets, showing how many emails were received and sent during each hour.
- **If no date range is provided**, the system automatically adjusts it to a week from today.   - **Each entry** in the result corresponds to an hour of the day (`00:00:00` → `23:00:00`).   - Useful for visualizing hourly trends in dashboards.


Returns hourly email volume (received and sent) between the given start and end dates. Each day is broken down into 24 hourly buckets, showing how many emails were received and sent during each hour.

## Request

### Headers

| Name          | Type   | Required | Description  |
| ------------- | ------ | -------- | ------------ |
| Authorization | string | Yes      | Bearer token |

### Path Parameters

| Parameter | Type   | Required | Description                           |
| --------- | ------ | -------- | ------------------------------------- |
| startDate | string | Yes      | Start date for the range (YYYY-MM-DD) |
| endDate   | string | Yes      | End date for the range (YYYY-MM-DD)   |

#### Parameter Format

* **Format**: `YYYY-MM-DD` (ISO 8601 date)
* **Timezone**: UTC
* **Default**: Last 7 days if not provided

## Response

### 200 OK - Hourly email trends between given dates

```json theme={null}
{
  "message": "",
  "data": {
    "labels": [
      "00:00:00",
      "01:00:00",
      "02:00:00",
      "03:00:00",
      "04:00:00",
      "05:00:00",
      "06:00:00",
      "07:00:00",
      "08:00:00",
      "09:00:00",
      "10:00:00",
      "11:00:00",
      "12:00:00",
      "13:00:00",
      "14:00:00",
      "15:00:00",
      "16:00:00",
      "17:00:00",
      "18:00:00",
      "19:00:00",
      "20:00:00",
      "21:00:00",
      "22:00:00",
      "23:00:00"
    ],
    "series": {
      "received": [
        {
          "name": "2025-10-01",
          "data": [0, 1, 3, 2, 5, 10, 6, 8, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        },
        {
          "name": "2025-10-02",
          "data": [0, 2, 5, 3, 8, 15, 12, 18, 25, 22, 19, 15, 12, 18, 20, 16, 14, 8, 5, 2, 1, 0, 0, 0]
        }
      ],
      "sent": [
        {
          "name": "2025-10-01",
          "data": [0, 0, 2, 1, 3, 8, 5, 8, 12, 15, 18, 14, 10, 8, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0]
        },
        {
          "name": "2025-10-02",
          "data": [0, 1, 3, 2, 6, 8, 8, 10, 15, 20, 25, 22, 18, 15, 12, 10, 8, 5, 2, 1, 0, 0, 0, 0]
        }
      ]
    }
  }
}
```

### 401 Unauthorized

```json theme={null}
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Missing or invalid token"
  }
}
```

### 500 Internal Server Error

```json theme={null}
{
  "error": {
    "code": "SERVER_ERROR",
    "message": "Internal server error"
  }
}
```

## Example

```bash theme={null}
curl -X GET 'http://localhost:2000/email-meter/stats/hourly-trends/2025-10-01/2025-10-20' \
  -H 'Authorization: oBearer your-jwt-token'
```

## Data Structure

### Labels Array

| Field  | Type  | Description                           |
| ------ | ----- | ------------------------------------- |
| labels | array | Hour labels from 00:00:00 to 23:00:00 |

### Series Object

| Field    | Type  | Description                                     |
| -------- | ----- | ----------------------------------------------- |
| received | array | Series showing received emails per hour per day |
| sent     | array | Series showing sent emails per hour per day     |

#### Data Series Structure

Each object in received/sent arrays contains:

| Field | Type   | Description                         |
| ----- | ------ | ----------------------------------- |
| name  | string | Date of the data point (YYYY-MM-DD) |
| data  | array  | 24-hour email counts                |

## Data Alignment

* `series.received[i].data[j]` corresponds to `labels[j]` for received emails on date `series.received[i].name`
* `series.sent[i].data[j]` corresponds to `labels[j]` for sent emails on date `series.sent[i].name`
* All data arrays have exactly 24 elements (one for each hour)

## Use Cases

* **Peak Hours Analysis**: Identify busiest email hours
* **Staff Scheduling**: Optimize agent scheduling based on volume
* **Resource Planning**: Allocate resources during peak times
* **Performance Monitoring**: Track hourly performance patterns
* **Heat Map Visualization**: Create hourly heat maps

## Analysis Examples

### Peak Hour Identification

```javascript theme={null}
const findPeakHours = (data) => {
  const hourlyTotals = data.labels.map((_, hourIndex) => {
    return data.series.received.reduce((sum, day) => sum + day.data[hourIndex], 0);
  });
  
  const maxVolume = Math.max(...hourlyTotals);
  const peakHour = hourlyTotals.indexOf(maxVolume);
  
  return {
    peakHour: data.labels[peakHour],
    peakVolume: maxVolume,
    peakHourIndex: peakHour
  };
};
```

### Daily Pattern Analysis

```javascript theme={null}
const analyzeDailyPatterns = (data) => {
  return data.series.received.map(day => ({
    date: day.name,
    totalEmails: day.data.reduce((a, b) => a + b, 0),
    peakHour: data.labels[day.data.indexOf(Math.max(...day.data))],
    peakVolume: Math.max(...day.data)
  }));
};
```

### Business Hours vs Non-Business Hours

```javascript theme={null}
const businessHoursAnalysis = (data) => {
  const businessHourIndices = [9, 10, 11, 12, 13, 14, 15, 16]; // 9 AM - 5 PM
  const nonBusinessHourIndices = [0, 1, 2, 3, 4, 5, 6, 7, 8, 17, 18, 19, 20, 21, 22, 23];
  
  const businessVolume = data.series.received.reduce((sum, day) => {
    return sum + businessHourIndices.reduce((daySum, hour) => daySum + day.data[hour], 0);
  }, 0);
  
  const nonBusinessVolume = data.series.received.reduce((sum, day) => {
    return sum + nonBusinessHourIndices.reduce((daySum, hour) => daySum + day.data[hour], 0);
  }, 0);
  
  return {
    businessHours: businessVolume,
    nonBusinessHours: nonBusinessVolume,
    businessPercentage: (businessVolume / (businessVolume + nonBusinessVolume)) * 100
  };
};
```

## Visualization Examples

### Heat Map

```javascript theme={null}
// Create heat map data
const heatMapData = data.series.received.map(day => day.data);

// Example using Chart.js with heatmap plugin
new Chart(ctx, {
  type: 'matrix',
  data: {
    datasets: [{
      label: 'Email Volume',
      data: heatMapData.flat().map((value, index) => ({
        x: index % 24,
        y: Math.floor(index / 24),
        v: value
      })),
      backgroundColor(ctx) {
        const value = ctx.dataset.data[ctx.dataIndex].v;
        const alpha = value / maxVolume;
        return `rgba(54, 162, 235, ${alpha})`;
      }
    }]
  }
});
```

### Multi-Day Line Chart

```javascript theme={null}
const ctx = document.getElementById('hourlyTrends').getContext('2d');
new Chart(ctx, {
  type: 'line',
  data: {
    labels: data.labels,
    datasets: data.series.received.map(day => ({
      label: day.name,
      data: day.data,
      borderColor: `hsl(${Math.random() * 360}, 70%, 50%)`,
      tension: 0.4
    }))
  }
});
```

## Best Practices

1. **Date Range**: Use reasonable ranges (recommended: max 30 days for hourly detail)
2. **Time Zone**: Convert UTC times to local time zones for display
3. **Aggregation**: Consider aggregating multiple days for pattern analysis
4. **Visualization**: Use heat maps for better pattern visualization
5. **Business Hours**: Focus analysis on business hours for operational insights

## Performance Considerations

* **Data Volume**: Hourly data generates 24x more points than daily
* **Processing Time**: Larger date ranges take longer to process
* **Memory Usage**: Consider client-side memory for large datasets
* **Caching**: Cache results for dashboard performance

## Related Endpoints

* Use `/email-meter/stats/emails-trend` for daily trends
* Use `/email-meter/stats/email-counts` for aggregate statistics
* Use `/email-meter/stats/response-times` for hourly response analysis

## Notes

* All times are in UTC - convert to local time for operational analysis
* Zero-value hours are included for complete timeline
* Data includes all email types (incoming, outgoing, internal)
* Weekends and holidays are included in hourly breakdown
* Automated emails are included unless filtered specifically


## OpenAPI

````yaml GET /email-meter/stats/hourly-trends/{startDate}/{endDate}
openapi: 3.0.3
info:
  title: COMPASS API
  version: 1.0.0
  description: OpenAPI specification for the Compass backend routes.
servers:
  - url: http://localhost:2000
    description: Local development server
security: []
tags:
  - name: Auth
    description: >-
      Authentication and session management endpoints (OAuth and session
      validation)
  - name: Users
    description: Operations for managing user records
  - name: Departments
    description: Operations for managing departments
  - name: Email Meter
    description: APIs to get Email Meter Stats
  - name: HubSpot Tickets
    description: Feedback APIs
  - name: Permissions
    description: Permissions APIs
  - name: Transcription
    description: Transcription APIs
paths:
  /email-meter/stats/hourly-trends/{startDate}/{endDate}:
    get:
      tags:
        - Email Meter
      summary: Get hourly email traffic trends
      description: >
        Returns hourly email volume (received and sent) between the given start
        and end dates.   Each day is broken down into 24 hourly buckets, showing
        how many emails were received and sent during each hour.

        - **If no date range is provided**, the system automatically adjusts it
        to a week from today.   - **Each entry** in the result corresponds to an
        hour of the day (`00:00:00` → `23:00:00`).   - Useful for visualizing
        hourly trends in dashboards.
      parameters:
        - name: startDate
          in: path
          required: true
          schema:
            type: string
            format: date
          description: Start date for the range (YYYY-MM-DD)
          example: '2025-10-01'
        - name: endDate
          in: path
          required: true
          schema:
            type: string
            format: date
          description: End date for the range (YYYY-MM-DD)
          example: '2025-10-07'
      responses:
        '200':
          description: Hourly email trends between given dates
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: ''
                  data:
                    type: object
                    properties:
                      labels:
                        type: array
                        description: Hour labels from 00:00:00 to 23:00:00
                        items:
                          type: string
                          example: '08:00:00'
                        example:
                          - '00:00:00'
                          - '01:00:00'
                          - '02:00:00'
                      series:
                        type: object
                        description: Email trends for each day in the date range
                        properties:
                          received:
                            type: array
                            description: Series showing received emails per hour per day
                            items:
                              type: object
                              properties:
                                name:
                                  type: string
                                  description: Date of the data point (YYYY-MM-DD)
                                  example: '2025-10-01'
                                data:
                                  type: array
                                  description: 24-hour email counts
                                  items:
                                    type: integer
                                    example: 12
                                  example:
                                    - 0
                                    - 1
                                    - 3
                                    - 2
                                    - 5
                                    - 10
                                    - 6
                                    - 8
                                    - 3
                                    - 1
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                          sent:
                            type: array
                            description: Series showing sent emails per hour per day
                            items:
                              type: object
                              properties:
                                name:
                                  type: string
                                  example: '2025-10-01'
                                data:
                                  type: array
                                  items:
                                    type: integer
                                    example: 7
                                  example:
                                    - 0
                                    - 2
                                    - 5
                                    - 1
                                    - 3
                                    - 8
                                    - 6
                                    - 4
                                    - 2
                                    - 1
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
                                    - 0
        '400':
          description: Invalid date format or missing parameters
        '401':
          description: Unauthorized (missing or invalid token)
        '500':
          description: Internal server error
      security:
        - bearerAuth: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````