GET
/
qranalytics
/
timeline
Scans Timeline
curl --request GET \
  --url https://jmpy.me/api/v1/qranalytics/timeline \
  --header 'Authorization: Bearer <token>'
{
  "data": [
    {
      "date": "<string>",
      "scans": 123,
      "uniqueScanners": 123,
      "uniqueScans": 123
    }
  ]
}
Get scan data over time with configurable granularity. This endpoint returns time-series data showing scan counts, unique scanners, and unique scans for each time period.
This endpoint returns user-level aggregated timeline data across all your QR codes. For timeline data on a specific QR code, use the Complete Analytics endpoint.

Query Parameters

days
integer
default:30
Number of days to include in the timeline (1-365).
granularity
string
default:"day"
Time interval granularity for grouping data: hour, day, week.
  • hour - Best for short timeframes (1-7 days)
  • day - Best for medium timeframes (7-90 days)
  • week - Best for long timeframes (30-365 days)

Response

data
array
Array of timeline data points.

Request Examples

# Get daily timeline for last 30 days
curl -X GET "https://jmpy.me/api/v1/qranalytics/timeline?days=30&granularity=day" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Get hourly data for last 7 days
curl -X GET "https://jmpy.me/api/v1/qranalytics/timeline?days=7&granularity=hour" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Get weekly data for last 90 days
curl -X GET "https://jmpy.me/api/v1/qranalytics/timeline?days=90&granularity=week" \
  -H "Authorization: Bearer YOUR_API_KEY"

Response Examples

{
  "success": true,
  "data": [
    {
      "date": "2025-01-01",
      "scans": 78,
      "uniqueScanners": 65,
      "uniqueScans": 52
    },
    {
      "date": "2025-01-02",
      "scans": 92,
      "uniqueScanners": 78,
      "uniqueScans": 61
    },
    {
      "date": "2025-01-03",
      "scans": 156,
      "uniqueScanners": 120,
      "uniqueScans": 89
    }
  ]
}

Use Cases

Analyze scan patterns to identify peak usage times.
import requests
from collections import defaultdict

def analyze_scan_patterns():
    response = requests.get(
        'https://jmpy.me/api/v1/qranalytics/timeline',
        headers={'Authorization': 'Bearer YOUR_API_KEY'},
        params={'days': 30, 'granularity': 'day'}
    )
    timeline = response.json()['data']
    
    # Group by day of week
    from datetime import datetime
    day_totals = defaultdict(int)
    
    for point in timeline:
        date = datetime.strptime(point['date'], '%Y-%m-%d')
        day_name = date.strftime('%A')
        day_totals[day_name] += point['scans']
    
    # Find best day
    best_day = max(day_totals, key=day_totals.get)
    print(f"Best performing day: {best_day} ({day_totals[best_day]} total scans)")
    
    return dict(day_totals)
Compare current week performance to the previous week.
async function getWeeklyGrowth(): Promise<number> {
  const response = await fetch(
    'https://jmpy.me/api/v1/qranalytics/timeline?days=14&granularity=day',
    { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
  );
  const { data } = await response.json();
  
  // Split into two weeks
  const thisWeek = data.slice(-7);
  const lastWeek = data.slice(0, 7);
  
  const thisWeekTotal = thisWeek.reduce((sum, d) => sum + d.scans, 0);
  const lastWeekTotal = lastWeek.reduce((sum, d) => sum + d.scans, 0);
  
  const growth = lastWeekTotal > 0 
    ? ((thisWeekTotal - lastWeekTotal) / lastWeekTotal) * 100 
    : 0;
  
  console.log(`Week-over-week growth: ${growth.toFixed(1)}%`);
  return growth;
}

Analytics Overview

Get aggregated summary statistics

Top Performing QR Codes

See which QR codes drive the most scans

Recent Activity

View the latest scan events

Complete Analytics

Get all analytics for a specific QR code