RESTful API for accessing Vestigio route rankings and athlete data
https://vestigio.app
The Vestigio API provides programmatic access to route rankings, trial data, and athlete information. All endpoints return JSON responses and follow RESTful conventions.
Currently, the API endpoints are publicly accessible. Future versions may require API keys or OAuth authentication.
/api/ranking
Returns the complete ranking for a specific route, including all trial details and athlete information.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | The route GUID (not the numeric ID) |
GET /api/ranking?id=abc123-def456-ghi789
Returns a JSON object with route information and an array of ranking entries.
{
"route": {
"id": 1,
"name": "Cerro San Cristóbal",
"description": "Ruta desde Plaza Italia hasta la cumbre",
"meters": 3500,
"minutes": 45,
"city": "Santiago",
"country": "Chile",
"guid": "abc123-def456-ghi789"
},
"ranking": [
{
"trialId": 123,
"seconds": 1845,
"timeFormatted": "00:30:45",
"startMillis": 1704067200000,
"endMillis": 1704069045000,
"daysOld": 5,
"valid": true,
"suspicious": false,
"discipline": "Running",
"user": {
"id": 45,
"guid": "user-guid-123",
"email": "athlete@example.com",
"publicName": "John Doe",
"alias": "SpeedRunner",
"gender": 1,
"age": 28,
"city": "Santiago",
"country": "Chile",
"instagram": "@speedrunner"
},
"startLocation": {
"id": 10,
"name": "Plaza Italia",
"latLong": "-33.4378,-70.6504",
"city": "Santiago",
"country": "Chile"
},
"endLocation": {
"id": 11,
"name": "Cerro San Cristóbal",
"latLong": "-33.4245,-70.6389",
"city": "Santiago",
"country": "Chile"
}
}
]
}
Missing required parameter
{
"error": "Missing routeId parameter"
}
Route not found
{
"error": "Route not found for id=abc123-def456-ghi789"
}
route (object) - Route informationranking (array) - Array of trial/ranking entries, sorted by time (fastest first)id (number) - Route numeric IDname (string) - Route namedescription (string) - Route descriptionmeters (number) - Route distance in metersminutes (number) - Estimated time in minutescity (string) - City where route is locatedcountry (string) - Country where route is locatedguid (string) - Route unique identifier (use this for API calls)trialId (number) - Trial IDseconds (number) - Elapsed time in secondstimeFormatted (string) - Formatted time (HH:MM:SS)startMillis (number) - Start timestamp in millisecondsendMillis (number) - End timestamp in millisecondsdaysOld (number) - Days since the trial was completedvalid (boolean) - Whether the trial is validsuspicious (boolean) - Whether the trial is flagged as suspiciousdiscipline (string|null) - Discipline name (e.g., "Running", "Cycling")user (object|null) - Athlete/user informationstartLocation (object|null) - Start location detailsendLocation (object|null) - End location detailsid (number) - User numeric IDguid (string) - User unique identifieremail (string) - User email addresspublicName (string) - Public display name (alias or email prefix)alias (string|null) - User alias/usernamegender (number) - Gender (0 = female, 1 = male)age (number) - User agecity (string|null) - User citycountry (string|null) - User countryinstagram (string|null) - Instagram handleid (number) - Location numeric IDname (string) - Location namelatLong (string) - Coordinates in "lat,lng" formatcity (string|null) - Citycountry (string|null) - Countryguid (not the numeric id) in API calls/api/trials
Returns the last 1000 trials for a specific user/athlete, including trial details and route information.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | The user/athlete GUID |
GET /api/trials?id=user-guid-123-456-789
Returns a JSON object with user information and an array of their trials.
{
"user": {
"id": 45,
"guid": "user-guid-123-456-789",
"email": "athlete@example.com",
"publicName": "John Doe",
"alias": "SpeedRunner",
"gender": 1,
"age": 28,
"city": "Santiago",
"country": "Chile",
"instagram": "@speedrunner"
},
"trials": [
{
"trialId": 123,
"seconds": 1845,
"timeFormatted": "00:30:45",
"startMillis": 1704067200000,
"endMillis": 1704069045000,
"daysOld": 5,
"valid": true,
"suspicious": false,
"discipline": "Running",
"comments": "Great run today!",
"route": {
"id": 1,
"guid": "route-guid-abc-123",
"name": "Cerro San Cristóbal",
"description": "Ruta desde Plaza Italia hasta la cumbre",
"meters": 3500,
"minutes": 45,
"city": "Santiago",
"country": "Chile"
},
"startLocation": {
"id": 10,
"name": "Plaza Italia",
"latLong": "-33.4378,-70.6504",
"city": "Santiago",
"country": "Chile"
},
"endLocation": {
"id": 11,
"name": "Cerro San Cristóbal",
"latLong": "-33.4245,-70.6389",
"city": "Santiago",
"country": "Chile"
}
}
]
}
Missing required parameter
{
"error": "Missing user id parameter"
}
User not found
{
"error": "User not found for id=user-guid-123-456-789"
}
user (object) - User/athlete informationtrials (array) - Array of trial entries, sorted by most recent firstid (number) - User numeric IDguid (string) - User unique identifieremail (string) - User email addresspublicName (string) - Public display name (alias or email prefix)alias (string|null) - User alias/usernamegender (number) - Gender (0 = female, 1 = male)age (number) - User agecity (string|null) - User citycountry (string|null) - User countryinstagram (string|null) - Instagram handletrialId (number) - Trial IDseconds (number) - Elapsed time in secondstimeFormatted (string) - Formatted time (HH:MM:SS)startMillis (number) - Start timestamp in millisecondsendMillis (number) - End timestamp in millisecondsdaysOld (number) - Days since the trial was completedvalid (boolean) - Whether the trial is validsuspicious (boolean) - Whether the trial is flagged as suspiciousdiscipline (string|null) - Discipline name (e.g., "Running", "Cycling")comments (string|null) - User comments on the trialroute (object|null) - Route informationstartLocation (object|null) - Start location detailsendLocation (object|null) - End location detailsid (number) - Route numeric IDguid (string) - Route unique identifiername (string) - Route namedescription (string) - Route descriptionmeters (number) - Route distance in metersminutes (number) - Estimated time in minutescity (string|null) - City where route is locatedcountry (string|null) - Country where route is locatedid (number) - Location numeric IDname (string) - Location namelatLong (string) - Coordinates in "lat,lng" formatcity (string|null) - Citycountry (string|null) - Countryguid (not the numeric id) in API calls/api/routeStats
Returns comprehensive statistics for a specific route, including time analysis, percentiles, gender breakdown, and more.
| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string | Yes | The route GUID (not the numeric ID) |
GET /api/routeStats?id=abc123-def456-ghi789
Returns a JSON object with route information and comprehensive statistics.
{
"route": {
"id": 1,
"guid": "abc123-def456-ghi789",
"name": "Cerro San Cristóbal",
"description": "Ruta desde Plaza Italia hasta la cumbre",
"meters": 3500,
"city": "Santiago",
"country": "Chile"
},
"statistics": {
"totalTrials": 150,
"uniqueAthletes": 85,
"times": {
"best": {
"seconds": 1245,
"formatted": "00:20:45"
},
"worst": {
"seconds": 5400,
"formatted": "01:30:00"
},
"mean": {
"seconds": 2100,
"formatted": "00:35:00"
},
"median": {
"seconds": 1980,
"formatted": "00:33:00"
},
"standardDeviation": 650.5
},
"percentiles": {
"p10": {
"seconds": 1350,
"formatted": "00:22:30"
},
"p25": {
"seconds": 1620,
"formatted": "00:27:00"
},
"p50": {
"seconds": 1980,
"formatted": "00:33:00"
},
"p75": {
"seconds": 2520,
"formatted": "00:42:00"
},
"p90": {
"seconds": 3240,
"formatted": "00:54:00"
}
},
"gender": {
"male": {
"count": 100,
"uniqueAthletes": 60,
"best": 1245,
"mean": 2000,
"median": 1900
},
"female": {
"count": 50,
"uniqueAthletes": 25,
"best": 1380,
"mean": 2300,
"median": 2200
}
},
"dateRange": {
"firstTrial": "2023-01-15T10:30:00Z",
"lastTrial": "2024-01-10T14:45:00Z"
}
}
}
When the route exists but has no finished trials
{
"route": {
"id": 1,
"guid": "abc123-def456-ghi789",
"name": "Cerro San Cristóbal"
},
"message": "No finished trials for this route",
"stats": null
}
Missing required parameter
{
"error": "Missing route id parameter"
}
Route not found
{
"error": "Route not found for id=abc123-def456-ghi789"
}
route (object) - Route informationstatistics (object) - Comprehensive statistics for the routeid (number) - Route numeric IDguid (string) - Route unique identifiername (string) - Route namedescription (string) - Route descriptionmeters (number) - Route distance in meterscity (string|null) - City where route is locatedcountry (string|null) - Country where route is locatedtotalTrials (number) - Total number of completed trialsuniqueAthletes (number) - Number of unique athletestimes (object) - Time statistics (best, worst, mean, median, stdDev)percentiles (object) - Percentile breakdown (p10, p25, p50, p75, p90)gender (object) - Statistics grouped by genderdateRange (object) - First and last trial datesbest (object) - Best (fastest) time with seconds and formatted stringworst (object) - Worst (slowest) timemean (object) - Average timemedian (object) - Median time (50th percentile)standardDeviation (number) - Standard deviation in secondsp10 (object) - 10th percentile (top 10% cutoff)p25 (object) - 25th percentile (top 25% cutoff)p50 (object) - 50th percentile (median)p75 (object) - 75th percentilep90 (object) - 90th percentileContains keys: male, female, other (if data exists)
count (number) - Number of trials by this genderuniqueAthletes (number) - Unique athletes of this genderbest (number) - Best time in secondsmean (number) - Average time in secondsmedian (number) - Median time in secondsfirstTrial (string|null) - ISO 8601 date of the first triallastTrial (string|null) - ISO 8601 date of the most recent trialguid (not the numeric id) in API callsFor questions, issues, or feature requests related to the API, please contact us.