Skip to content

API Reference

Wiki Sync Bot edited this page Jul 20, 2025 · 1 revision

API Reference πŸ“‘

Complete documentation for Running Page 2.0 REST API endpoints.

🌐 Base URL

Local Development: http://localhost:3000/api
Production: https://your-domain.com/api

πŸ” Authentication

Most endpoints are public for read access. Write operations require proper authentication.

# No authentication required for read operations
GET /api/activities
GET /api/stats

# GitHub Actions use repository secrets for sync operations
POST /api/sync/strava

πŸ“Š Activities API

Get Activities

Retrieve paginated list of activities with filtering options.

GET /api/activities

Query Parameters:

Parameter Type Description Default
page number Page number (1-based) 1
limit number Items per page (max 50) 20
type string Activity types (comma-separated) all
source string Data sources (comma-separated) all
startDate string Start date (ISO 8601) -
endDate string End date (ISO 8601) -
minDistance number Minimum distance (km) -
maxDistance number Maximum distance (km) -
search string Search in activity names -

Example Request:

curl "https://your-domain.com/api/activities?page=1&limit=10&type=running,cycling&search=morning"

Response:

{
  "activities": [
    {
      "id": 12345,
      "name": "Morning Run",
      "type": "Run",
      "distance": 8500,
      "moving_time": 2304,
      "total_elevation_gain": 145,
      "start_date": "2025-07-20T06:30:00Z",
      "average_speed": 3.69,
      "average_heartrate": 165,
      "calories": 420,
      "location_city": "San Francisco",
      "location_country": "United States"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 150,
    "hasNext": true,
    "hasPrev": false
  },
  "summary": {
    "totalActivities": 150,
    "totalDistance": 1250.5,
    "totalTime": 345600,
    "typeDistribution": [
      { "type": "Run", "count": 89, "percentage": 59.3 },
      { "type": "Ride", "count": 45, "percentage": 30.0 },
      { "type": "Swim", "count": 16, "percentage": 10.7 }
    ]
  }
}

Get Single Activity

GET /api/activities/{id}

Response:

{
  "id": 12345,
  "name": "Morning Run",
  "type": "Run",
  "distance": 8500,
  "moving_time": 2304,
  "elapsed_time": 2400,
  "total_elevation_gain": 145,
  "start_date": "2025-07-20T06:30:00Z",
  "start_latlng": [37.7749, -122.4194],
  "end_latlng": [37.7849, -122.4094],
  "average_speed": 3.69,
  "max_speed": 5.2,
  "average_heartrate": 165,
  "max_heartrate": 185,
  "calories": 420,
  "location_city": "San Francisco",
  "location_state": "California",
  "location_country": "United States",
  "polyline": "encoded_polyline_string",
  "summary_polyline": "encoded_summary_polyline"
}

πŸ“ˆ Statistics API

Get Activity Statistics

GET /api/stats

Query Parameters:

Parameter Type Description Default
year number Filter by year current year
month number Filter by month (1-12) -
type string Activity types all

Response:

{
  "overview": {
    "totalActivities": 150,
    "totalDistance": 1250.5,
    "totalTime": 345600,
    "totalElevation": 12500,
    "averageDistance": 8.34,
    "averageTime": 2304
  },
  "monthly": [
    {
      "month": "2025-01",
      "activities": 12,
      "distance": 98.5,
      "time": 28800,
      "elevation": 1200
    }
  ],
  "typeDistribution": [
    { "type": "Run", "count": 89, "distance": 750.2, "time": 201600 },
    { "type": "Ride", "count": 45, "distance": 450.8, "time": 108000 },
    { "type": "Swim", "count": 16, "distance": 49.5, "time": 36000 }
  ],
  "heatmapData": [
    { "date": "2025-01-01", "count": 1, "distance": 8.5 },
    { "date": "2025-01-02", "count": 0, "distance": 0 }
  ],
  "personalRecords": {
    "longestDistance": { "value": 42.2, "date": "2025-06-15", "activityId": 98765 },
    "longestTime": { "value": 10800, "date": "2025-06-15", "activityId": 98765 },
    "fastestPace": { "value": 3.2, "date": "2025-05-20", "activityId": 87654 }
  }
}

πŸ—ΊοΈ Maps API

Check Static Map Availability

GET /api/maps/{activityId}

Response:

{
  "exists": true,
  "source": "cdn",
  "url": "https://cdn.jsdelivr.net/gh/user/repo@master/apps/web/public/maps/12345.png",
  "fallbackUrl": "https://api.mapbox.com/styles/v1/mapbox/dark-v10/static/...",
  "cached": true,
  "size": 245760
}

Get Cache Statistics

GET /api/cache/stats

Response:

{
  "totalMaps": 424,
  "cacheHitRate": "94.2%",
  "avgLoadTime": "245ms",
  "cdnHits": 387,
  "localHits": 36,
  "apiFallbacks": 1,
  "totalSize": "43.96 MB",
  "lastUpdated": "2025-07-20T10:30:00Z"
}

πŸ”„ Sync API

Trigger Strava Sync

POST /api/sync/strava

Headers:

Authorization: Bearer github_token
Content-Type: application/json

Request Body:

{
  "force": false,
  "generateMaps": true,
  "dateRange": {
    "start": "2025-01-01",
    "end": "2025-07-20"
  }
}

Response:

{
  "success": true,
  "message": "Sync completed successfully",
  "stats": {
    "newActivities": 5,
    "updatedActivities": 2,
    "mapsGenerated": 3,
    "processingTime": 45.2
  },
  "errors": []
}

Get Sync Status

GET /api/sync/status

Response:

{
  "isRunning": false,
  "lastSync": "2025-07-20T06:00:00Z",
  "nextSync": "2025-07-20T12:00:00Z",
  "status": "completed",
  "progress": {
    "current": 150,
    "total": 150,
    "percentage": 100
  },
  "logs": [
    { "timestamp": "2025-07-20T06:00:15Z", "level": "info", "message": "Starting Strava sync" },
    { "timestamp": "2025-07-20T06:01:30Z", "level": "success", "message": "Sync completed" }
  ]
}

πŸ” Debug API

System Information

GET /api/debug

Response:

{
  "version": "2.0.0",
  "environment": "production",
  "database": {
    "path": "./data/running_page_2.db",
    "size": "2.5 MB",
    "tables": ["activities", "users", "sync_logs"],
    "lastBackup": "2025-07-20T00:00:00Z"
  },
  "cache": {
    "redis": false,
    "memory": true,
    "hitRate": "89.5%"
  },
  "maps": {
    "total": 424,
    "size": "43.96 MB",
    "cdnEnabled": true
  },
  "performance": {
    "uptime": 86400,
    "memoryUsage": "125 MB",
    "cpuUsage": "2.5%"
  }
}

πŸ“Š Data Sources API

Get Available Data Sources

GET /api/data-sources

Response:

{
  "sources": [
    {
      "id": "strava",
      "name": "Strava",
      "enabled": true,
      "connected": true,
      "lastSync": "2025-07-20T06:00:00Z",
      "activities": 145,
      "status": "active"
    },
    {
      "id": "garmin",
      "name": "Garmin Connect",
      "enabled": false,
      "connected": false,
      "lastSync": null,
      "activities": 0,
      "status": "not_configured"
    }
  ],
  "total": 145,
  "lastUpdate": "2025-07-20T06:00:00Z"
}

❌ Error Responses

Standard Error Format

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid query parameters",
    "details": {
      "field": "limit",
      "value": 100,
      "constraint": "Maximum limit is 50"
    },
    "timestamp": "2025-07-20T10:30:00Z"
  }
}

Common Error Codes

Code Status Description
VALIDATION_ERROR 400 Invalid request parameters
NOT_FOUND 404 Resource not found
RATE_LIMITED 429 Too many requests
SERVER_ERROR 500 Internal server error
DATABASE_ERROR 500 Database connection issue
SYNC_ERROR 503 Data sync in progress

πŸ”§ Rate Limiting

# Rate limit headers in response
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1642694400

Limits:

  • Public API: 1000 requests/hour per IP
  • Sync API: 10 requests/hour per repository
  • Maps API: 500 requests/hour per IP

πŸ“ Request/Response Examples

cURL Examples

# Get recent activities
curl -X GET "https://your-domain.com/api/activities?limit=5" \
  -H "Accept: application/json"

# Get statistics for current year
curl -X GET "https://your-domain.com/api/stats?year=2025" \
  -H "Accept: application/json"

# Check map availability
curl -X GET "https://your-domain.com/api/maps/12345" \
  -H "Accept: application/json"

JavaScript Examples

// Fetch activities with filtering
const response = await fetch('/api/activities?type=running&limit=10');
const data = await response.json();

// Get activity statistics
const stats = await fetch('/api/stats?year=2025');
const statsData = await stats.json();

// Check cache status
const cache = await fetch('/api/cache/stats');
const cacheData = await cache.json();

πŸš€ SDK and Libraries

Official JavaScript SDK (Coming Soon)

import { RunningPageAPI } from '@running-page/sdk';

const api = new RunningPageAPI('https://your-domain.com');

// Get activities
const activities = await api.activities.list({ type: 'running', limit: 10 });

// Get statistics
const stats = await api.stats.get({ year: 2025 });

Need help with the API? Check out our Troubleshooting guide or open an issue! πŸ“‘

Clone this wiki locally