API Documentation
Integrate Runify GPS tracking into your mobile app. Send positions in real-time or sync at the end of a session.
Authentication
All requests require an application token sent via the X-API-Key header.
X-API-Key: YOUR_APP_TOKEN
The token is automatically generated when you create an event in the dashboard. The Authorization: Bearer header is also accepted.
Base URL
https://api-runify.domainedunet.fr
Create a track
/tracksCreates a new GPS track. Call this endpoint when tracking starts.
Request body
| Param | Type | Required | Description |
|---|---|---|---|
| device_track_id | string | required | Unique device identifier (1–100 chars) |
| title | string | optional | Track title (max 500 chars). If omitted, auto-generated: "Sortie du 12 mars à 09h20" |
| activity_type | string | optional | run | walk | bike | hike (default: run) |
| start_ts | ISO 8601 | optional | Start date/time |
| user_id | string | optional | User identifier (max 255 chars) |
| image_url | URL | optional | Associated image URL |
curl -X POST https://api-runify.domainedunet.fr/tracks \
-H "X-API-Key: YOUR_APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"device_track_id": "track_2024_001",
"title": "Morning run",
"activity_type": "run",
"start_ts": "2024-03-15T07:30:00Z"
}'{
"id": "550e8400-e29b-41d4-a716-446655440000",
"device_track_id": "track_2024_001"
}Send GPS points
/tracks/:id/pointsSend a batch of GPS points. Up to 10,000 points per request. Fire-and-forget (204 response).
Point fields
| Param | Type | Required | Description |
|---|---|---|---|
| latitude | number | required | -90 → 90 |
| longitude | number | required | -180 → 180 |
| timestamp | ISO 8601 | required | Point timestamp |
| altitude | number | optional | Altitude in meters |
| accuracy | number | optional | GPS accuracy in meters |
| speed_mps | number | optional | Speed in m/s |
| heading | number | optional | Heading (0–360°) |
| battery | number | optional | Battery level (0–1) |
| origin | string | optional | foreground | background | native |
curl -X POST https://api-runify.domainedunet.fr/tracks/TRACK_ID/points \
-H "X-API-Key: YOUR_APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"points": [
{
"latitude": 48.8566,
"longitude": 2.3522,
"altitude": 35.2,
"accuracy": 5.0,
"speed_mps": 3.2,
"timestamp": "2024-03-15T07:30:05Z",
"origin": "foreground"
},
{
"latitude": 48.8567,
"longitude": 2.3524,
"altitude": 35.5,
"timestamp": "2024-03-15T07:30:10Z"
}
]
}'Update a track
/tracks/:idUpdate the title, state, or end time of a track.
| Param | Type | Required | Description |
|---|---|---|---|
| title | string | optional | New title |
| state | string | optional | running | paused | stopped |
| end_ts | ISO 8601 | optional | End date/time |
curl -X PATCH https://api-runify.domainedunet.fr/tracks/TRACK_ID \
-H "X-API-Key: YOUR_APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{"state": "paused"}'Finish a track
/tracks/:id/finishFinalize a track. Automatically computes statistics (distance, pace, elevation…).
curl -X POST https://api-runify.domainedunet.fr/tracks/TRACK_ID/finish \ -H "X-API-Key: YOUR_APP_TOKEN"
Full sync
/syncAll-in-one endpoint: creates the track, sends points and statistics in a single request. Ideal for end-of-session sync. Up to 50,000 points.
Request body
| Param | Type | Required | Description |
|---|---|---|---|
| track | object | required | Track object (see POST /tracks) |
| points | array | required | Array of GPS points |
| stats | object | optional | Pre-computed statistics |
Stats fields (optional)
| Param | Type | Required | Description |
|---|---|---|---|
| distance_meters | number | optional | Total distance in meters |
| duration_sec | integer | optional | Total duration in seconds |
| elevation_gain_m | number | optional | Elevation gain (m) |
| elevation_loss_m | number | optional | Elevation loss (m) |
| mean_speed_mps | number | optional | Average speed (m/s) |
| pace_sec_per_km | number | optional | Pace (s/km) |
| max_speed_mps | number | optional | Max speed (m/s) |
| max_altitude_m | number | optional | Max altitude (m) |
| min_altitude_m | number | optional | Min altitude (m) |
| points_count | integer | optional | Number of points |
curl -X POST https://api-runify.domainedunet.fr/sync \
-H "X-API-Key: YOUR_APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"track": {
"device_track_id": "track_2024_001",
"title": "Trail du Glazig - 25km",
"activity_type": "run",
"start_ts": "2024-03-15T07:30:00Z",
"end_ts": "2024-03-15T09:45:00Z"
},
"points": [
{
"latitude": 48.2345,
"longitude": -3.5678,
"altitude": 45.2,
"speed_mps": 2.8,
"timestamp": "2024-03-15T07:30:05Z"
}
],
"stats": {
"distance_meters": 25340,
"duration_sec": 8100,
"elevation_gain_m": 850,
"mean_speed_mps": 3.13,
"pace_sec_per_km": 319
}
}'{
"track_id": "550e8400-e29b-41d4-a716-446655440000"
}Get a track
/tracks/:idReturns a track's details with its computed statistics.
curl https://api-runify.domainedunet.fr/tracks/TRACK_ID \ -H "X-API-Key: YOUR_APP_TOKEN"
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"device_track_id": "track_2024_001",
"title": "Sortie du 12 mars à 09h20",
"activity_type": "run",
"state": "running",
"start_ts": "2026-03-12T09:20:00.000Z",
"end_ts": null,
"image_url": null,
"points_count": 121,
"stats": {
"distance_meters": 1200,
"duration_sec": 600,
"elevation_gain_m": 15,
"mean_speed_mps": 2.0,
"pace_sec_per_km": 500
},
"created_at": "2026-03-12T09:20:00.000Z",
"updated_at": "2026-03-12T09:30:00.000Z"
}List GPS points
/tracks/:id/pointsReturns all GPS points for a track, sorted by timestamp ascending.
Query parameters
| Param | Type | Required | Description |
|---|---|---|---|
| limit | integer | optional | Max number of points (default: all, max: 50,000) |
| offset | integer | optional | Number of points to skip (default: 0) |
curl "https://api-runify.domainedunet.fr/tracks/TRACK_ID/points?limit=1000" \ -H "X-API-Key: YOUR_APP_TOKEN"
{
"track_id": "550e8400-e29b-41d4-a716-446655440000",
"count": 121,
"points": [
{
"latitude": 48.8566,
"longitude": 2.3522,
"timestamp": "2026-03-12T09:20:00.000Z",
"altitude": 35.7,
"accuracy": 5,
"speed_mps": 2.1,
"heading": 180,
"battery": 0.85
}
]
}Error codes
| Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Missing or invalid token |
| 400 | BAD_REQUEST | Invalid data (Zod validation) |
| 404 | NOT_FOUND | Track not found |
| 409 | CONFLICT | device_track_id already in use |
| 429 | RATE_LIMIT | Too many requests |
Quick start
Typical flow to track an activity in real-time:
Create the track at start
POST /tracks→ get the idSend points in batches
POST /tracks/:id/points→ every 5–30 secondsFinalize at the end
POST /tracks/:id/finish→ automatically computes stats