Skip to main content
GET
/
api
/
stats
/
expiry-trends
Get Expiry Trends
curl --request GET \
  --url https://api.example.com/api/stats/expiry-trends \
  --header 'Authorization: <authorization>'
{
  "date": "<string>",
  "expiring": 123,
  "consumed": 123,
  "wasted_cost": 123
}

Overview

This endpoint provides comprehensive statistics about product expiry trends over time, including the number of expiring items, simulated consumption before expiry, and estimated cost of wasted items. This is useful for creating detailed trend visualizations and understanding consumption patterns.

Authentication

Authorization
string
required
Bearer token for authentication. Format: Bearer YOUR_ACCESS_TOKEN

Response

The endpoint returns an array of trend items, each representing a specific date with detailed statistics.
date
string
The expiry date in YYYY-MM-DD format
expiring
integer
Total number of items expiring on this date
consumed
integer
Estimated number of items consumed before expiry (simulated: 40-80% of active items)
wasted_cost
float
Estimated cost of wasted items (calculated as expired items × $50 per item)

Response Examples

Success

[
  {
    "date": "2026-03-01",
    "expiring": 10,
    "consumed": 6,
    "wasted_cost": 200.0
  },
  {
    "date": "2026-03-02",
    "expiring": 8,
    "consumed": 5,
    "wasted_cost": 150.0
  },
  {
    "date": "2026-03-03",
    "expiring": 15,
    "consumed": 9,
    "wasted_cost": 300.0
  }
]

Empty Result

[]

Error Responses

401 Unauthorized

Authentication failed or missing authorization header.
{
  "detail": "Authorization header missing or invalid."
}

Example Requests

cURL

curl -X GET "https://api.expireeye.com/api/stats/expiry-trends" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

JavaScript (Fetch)

const accessToken = "your-jwt-token";

fetch("https://api.expireeye.com/api/stats/expiry-trends", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${accessToken}`,
  },
})
  .then(response => response.json())
  .then(data => {
    const totalExpiring = data.reduce((sum, item) => sum + item.expiring, 0);
    const totalConsumed = data.reduce((sum, item) => sum + item.consumed, 0);
    const totalWasteCost = data.reduce((sum, item) => sum + item.wasted_cost, 0);
    
    console.log(`Total expiring: ${totalExpiring}`);
    console.log(`Total consumed: ${totalConsumed}`);
    console.log(`Total waste cost: $${totalWasteCost}`);
    console.log(`Consumption rate: ${((totalConsumed / totalExpiring) * 100).toFixed(1)}%`);
  })
  .catch(error => console.error("Error:", error));

Python (Requests)

import requests
from datetime import datetime

access_token = "your-jwt-token"
url = "https://api.expireeye.com/api/stats/expiry-trends"

headers = {
    "Authorization": f"Bearer {access_token}"
}

response = requests.get(url, headers=headers)

if response.status_code == 200:
    data = response.json()
    
    if data:
        total_expiring = sum(item["expiring"] for item in data)
        total_consumed = sum(item["consumed"] for item in data)
        total_waste_cost = sum(item["wasted_cost"] for item in data)
        
        consumption_rate = (total_consumed / total_expiring * 100) if total_expiring > 0 else 0
        
        print(f"Total expiring items: {total_expiring}")
        print(f"Total consumed: {total_consumed}")
        print(f"Consumption rate: {consumption_rate:.1f}%")
        print(f"Total waste cost: ${total_waste_cost:.2f}")
        
        # Find worst day
        worst_day = max(data, key=lambda x: x["wasted_cost"])
        print(f"\nWorst waste day: {worst_day['date']}")
        print(f"Waste cost on that day: ${worst_day['wasted_cost']:.2f}")
    else:
        print("No expiry trend data available")
else:
    print(f"Error: {response.status_code}")

Chart Visualization Example (React + Recharts)

import { useEffect, useState } from 'react';
import {
  LineChart,
  Line,
  BarChart,
  Bar,
  AreaChart,
  Area,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
  ComposedChart,
} from 'recharts';
import axios from 'axios';

interface ExpiryTrendItem {
  date: string;
  expiring: number;
  consumed: number;
  wasted_cost: number;
}

function ExpiryTrendsChart({ accessToken }: { accessToken: string }) {
  const [data, setData] = useState<ExpiryTrendItem[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    axios
      .get<ExpiryTrendItem[]>('https://api.expireeye.com/api/stats/expiry-trends', {
        headers: { Authorization: `Bearer ${accessToken}` },
      })
      .then(response => {
        setData(response.data);
      })
      .finally(() => setLoading(false));
  }, [accessToken]);

  if (loading) return <div>Loading trends...</div>;
  if (data.length === 0) return <div>No trend data available</div>;

  return (
    <div className="space-y-8">
      {/* Combined Chart: Bars (expiring) + Line (consumed) + Area (waste cost) */}
      <div>
        <h3 className="text-lg font-semibold mb-4">Expiry Trends Overview</h3>
        <ResponsiveContainer width="100%" height={400}>
          <ComposedChart data={data}>
            <CartesianGrid strokeDasharray="3 3" />
            <XAxis dataKey="date" />
            <YAxis yAxisId="left" />
            <YAxis yAxisId="right" orientation="right" />
            <Tooltip />
            <Legend />
            <Bar yAxisId="left" dataKey="expiring" fill="#8884d8" name="Expiring Items" />
            <Line
              yAxisId="left"
              type="monotone"
              dataKey="consumed"
              stroke="#82ca9d"
              name="Consumed Before Expiry"
            />
            <Area
              yAxisId="right"
              type="monotone"
              dataKey="wasted_cost"
              fill="#ff6b6b"
              stroke="#ff6b6b"
              fillOpacity={0.3}
              name="Waste Cost ($)"
            />
          </ComposedChart>
        </ResponsiveContainer>
      </div>

      {/* Summary Statistics */}
      <div className="grid grid-cols-4 gap-4">
        <div className="bg-white p-4 rounded-lg shadow">
          <p className="text-sm text-gray-600">Total Expiring</p>
          <p className="text-2xl font-bold">
            {data.reduce((sum, item) => sum + item.expiring, 0)}
          </p>
        </div>
        <div className="bg-white p-4 rounded-lg shadow">
          <p className="text-sm text-gray-600">Total Consumed</p>
          <p className="text-2xl font-bold text-green-600">
            {data.reduce((sum, item) => sum + item.consumed, 0)}
          </p>
        </div>
        <div className="bg-white p-4 rounded-lg shadow">
          <p className="text-sm text-gray-600">Consumption Rate</p>
          <p className="text-2xl font-bold text-blue-600">
            {(
              (data.reduce((sum, item) => sum + item.consumed, 0) /
                data.reduce((sum, item) => sum + item.expiring, 0)) *
              100
            ).toFixed(1)}
            %
          </p>
        </div>
        <div className="bg-white p-4 rounded-lg shadow">
          <p className="text-sm text-gray-600">Total Waste Cost</p>
          <p className="text-2xl font-bold text-red-600">
            ${data.reduce((sum, item) => sum + item.wasted_cost, 0).toFixed(2)}
          </p>
        </div>
      </div>
    </div>
  );
}

Data Calculation Details

The endpoint calculates statistics based on user product data:
  • Expiring: Total count of items with expiry dates on each date
  • Consumed: Simulated estimate using a random factor (40-80% of active items)
  • Wasted Cost: Calculated as expired items × $50 (fixed mock cost per item)
The consumed field is a simulated estimate based on a random uniform distribution (0.4 to 0.8). In a production environment, this should be replaced with actual consumption tracking data.
The wasted_cost uses a fixed mock value of $50 per item. Implement actual cost tracking by storing purchase prices or average market values for more accurate waste cost calculations.

Use Cases

  1. Trend Dashboard: Display multi-dimensional trends with bars, lines, and area charts
  2. Waste Reduction Planning: Identify patterns and high-waste periods to improve inventory management
  3. Cost Analysis: Calculate financial impact of food waste over time
  4. Consumption Insights: Understand consumption patterns and optimize purchasing
  5. Reporting: Generate monthly or quarterly waste reports with trend analysis

Build docs developers (and LLMs) love