REST API

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.

Headerhttp
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

Productiontext
https://api-runify.domainedunet.fr

Create a track

POST/tracks

Creates a new GPS track. Call this endpoint when tracking starts.

Request body

ParamTypeRequiredDescription
device_track_idstringrequiredUnique device identifier (1–100 chars)
titlestringoptionalTrack title (max 500 chars). If omitted, auto-generated: "Sortie du 12 mars à 09h20"
activity_typestringoptionalrun | walk | bike | hike (default: run)
start_tsISO 8601optionalStart date/time
user_idstringoptionalUser identifier (max 255 chars)
image_urlURLoptionalAssociated image URL
Examplebash
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"
  }'
Response 201json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "device_track_id": "track_2024_001"
}

Send GPS points

POST/tracks/:id/points

Send a batch of GPS points. Up to 10,000 points per request. Fire-and-forget (204 response).

Point fields

ParamTypeRequiredDescription
latitudenumberrequired-90 → 90
longitudenumberrequired-180 → 180
timestampISO 8601requiredPoint timestamp
altitudenumberoptionalAltitude in meters
accuracynumberoptionalGPS accuracy in meters
speed_mpsnumberoptionalSpeed in m/s
headingnumberoptionalHeading (0–360°)
batterynumberoptionalBattery level (0–1)
originstringoptionalforeground | background | native
Examplebash
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"
      }
    ]
  }'
💡 Response 204 No Content — points are processed asynchronously.

Update a track

PATCH/tracks/:id

Update the title, state, or end time of a track.

ParamTypeRequiredDescription
titlestringoptionalNew title
statestringoptionalrunning | paused | stopped
end_tsISO 8601optionalEnd date/time
Examplebash
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

POST/tracks/:id/finish

Finalize a track. Automatically computes statistics (distance, pace, elevation…).

Examplebash
curl -X POST https://api-runify.domainedunet.fr/tracks/TRACK_ID/finish \
  -H "X-API-Key: YOUR_APP_TOKEN"

Full sync

POST/sync

All-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

ParamTypeRequiredDescription
trackobjectrequiredTrack object (see POST /tracks)
pointsarrayrequiredArray of GPS points
statsobjectoptionalPre-computed statistics

Stats fields (optional)

ParamTypeRequiredDescription
distance_metersnumberoptionalTotal distance in meters
duration_secintegeroptionalTotal duration in seconds
elevation_gain_mnumberoptionalElevation gain (m)
elevation_loss_mnumberoptionalElevation loss (m)
mean_speed_mpsnumberoptionalAverage speed (m/s)
pace_sec_per_kmnumberoptionalPace (s/km)
max_speed_mpsnumberoptionalMax speed (m/s)
max_altitude_mnumberoptionalMax altitude (m)
min_altitude_mnumberoptionalMin altitude (m)
points_countintegeroptionalNumber of points
Examplebash
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
    }
  }'
Response 201json
{
  "track_id": "550e8400-e29b-41d4-a716-446655440000"
}

Get a track

GET/tracks/:id

Returns a track's details with its computed statistics.

Examplebash
curl https://api-runify.domainedunet.fr/tracks/TRACK_ID \
  -H "X-API-Key: YOUR_APP_TOKEN"
Response 200json
{
  "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

GET/tracks/:id/points

Returns all GPS points for a track, sorted by timestamp ascending.

Query parameters

ParamTypeRequiredDescription
limitintegeroptionalMax number of points (default: all, max: 50,000)
offsetintegeroptionalNumber of points to skip (default: 0)
Examplebash
curl "https://api-runify.domainedunet.fr/tracks/TRACK_ID/points?limit=1000" \
  -H "X-API-Key: YOUR_APP_TOKEN"
Response 200json
{
  "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

StatusCodeDescription
401UNAUTHORIZEDMissing or invalid token
400BAD_REQUESTInvalid data (Zod validation)
404NOT_FOUNDTrack not found
409CONFLICTdevice_track_id already in use
429RATE_LIMITToo many requests

Quick start

Typical flow to track an activity in real-time:

1

Create the track at start

POST /tracksget the id
2

Send points in batches

POST /tracks/:id/pointsevery 5–30 seconds
3

Finalize at the end

POST /tracks/:id/finishautomatically computes stats
💡 Alternative: use POST /sync to send everything in a single request at the end of the session.