api.rail-horizon.com — Documentation des endpoints
● Online Node.js / Express Socket.IO

📡 Vue d'ensemble

L'API Node.js gère la réception GPS temps-réel, les notifications push VAPID, et la distribution des données publiques. Le site PHP (rail-horizon.com) orchestre l'authentification et la gestion métier.

ℹ️ Base URL : https://api.rail-horizon.com — Toutes les routes sont en HTTPS. Le serveur est optionnel : si il devient inaccessible, le site PHP bascule automatiquement sur un fallback base de données.
GroupePréfixeDescription
/trackingGPS TrackingRéception des positions, historique, dernière position
/pushPushClés VAPID, abonnements, envoi de notifications
/publicPublicFlotte publique, info réseau (auth : clé API association)
/widgetWidgetScript JS de suivi intégrable sur n'importe quel site
/overlaysOverlaysDonnées Open Data ferroviaires (proxy interne)
/healthSantéÉtat du serveur et de la base de données

🔐 Authentification

Trois mécanismes selon l'appelant.

TypeHeader / ParamUtilisé par
api_key appareil Header X-API-Key ou body api_key Applications GPS (Traccar, BGeo) pour envoyer des positions
Bearer (association) Header Authorization: Bearer CLE ou ?key=CLE API publique — récupérer la flotte/réseau d'une association
X-Internal-Secret Header X-Internal-Secret: SECRET Serveur PHP uniquement (push/notify, relais internes)
Public (aucune auth) Lecture des positions live/historique via le slug public

📍 GPS Tracking

Endpoints pour envoyer des positions depuis une application mobile et lire les données en temps réel.

POST /tracking/update api_key Envoi d'une position GPS

Accepte trois formats de body JSON :

Format Background Geolocation (BGeo)

{
  "device_id": "RH-XXXXXXXX",
  "api_key":   "votre_cle_api_appareil",
  "location": {
    "coords": {
      "latitude":  48.8566,
      "longitude": 2.3522,
      "speed":     13.8,    // m/s — -1 si indisponible
      "heading":   90.0,
      "altitude":  35.0,
      "accuracy":  4.2
    },
    "battery": { "level": 0.87, "is_charging": false },
    "is_moving": true,
    "odometer": 12345.6
  }
}

Format plat

{
  "device_id": "RH-XXXXXXXX",
  "api_key":   "votre_cle_api_appareil",
  "lat":       48.8566,
  "lon":       2.3522,
  "speed":     45.5,     // km/h
  "altitude":  35.0,
  "accuracy":  4.2
}

Réponse : {"ok": true} — La position est diffusée en temps réel via Socket.IO (room track:ACCESS_SLUG).

GET /tracking/live/:slug public Dernière position connue

:slug est l'access_slug du véhicule ou le delegate_slug d'une délégation.

{
  "slug":       "abc123",
  "lat":        48.8566,
  "lon":        2.3522,
  "speed":      45.5,
  "heading":    90,
  "altitude":   35,
  "battery":    87,
  "accuracy":   4.2,
  "is_moving":  true,
  "is_charging": false,
  "ts":         "2026-04-29T10:30:00.000Z"
}
GET /tracking/history/:slug public Historique des positions
ParamètreDescription
limitNombre de points (défaut: 200, max: 1000)optionnel
dateFiltrer sur un jour précis — format YYYY-MM-DD. Renvoie tous les points dans l'ordre chronologique (pas de LIMIT).optionnel

Retourne un tableau JSON de positions. Sans date : ordre DESC + LIMIT. Avec date : ordre ASC, toute la journée.

WS Socket.IO (namespace /) public Suivi temps réel

Connexion et abonnement

// Script Socket.IO disponible sur l'API elle-même
const socket = io('https://api.rail-horizon.com');

// S'abonner au slug d'un véhicule
socket.emit('subscribe', 'abc123');

// Recevoir les positions en temps réel
socket.on('position', (data) => {
  console.log(data.lat, data.lon, data.speed);
  // data.slug, data.lat, data.lon, data.speed, data.heading,
  // data.altitude, data.battery, data.accuracy,
  // data.is_moving, data.is_charging, data.ts
});

// Se désabonner
socket.emit('unsubscribe', 'abc123');

Chaque véhicule émet dans la room track:ACCESS_SLUG à chaque nouvelle position reçue.

📱 Configuration Traccar Client

Le protocole OsmAnd permet d'envoyer des positions via une simple requête GET. Idéal pour Traccar Client (Android/iOS).

GET /tracking unique_id + api_key Protocole OsmAnd / Traccar

Format de l'URL à configurer dans Traccar Client :

https://api.rail-horizon.com/tracking?id={deviceId}&lat={lat}&lon={lon}&speed={speed}&bearing={heading}&altitude={altitude}&batt={battery}
ParamètreDescription
idIdentifiant unique de l'appareil (unique_id ex: RH-35DB4223) ou delegate_unique_id d'une délégationrequis
latLatitude décimalerequis
lonLongitude décimalerequis
speedVitesse en nœuds (×1.852 = km/h)optionnel
bearingCap en degrés (0–360)optionnel
altitudeAltitude en mètresoptionnel
battNiveau batterie (0–100)optionnel
⚠️ L'authentification via Traccar Client se fait par l'unique_id de l'appareil. Cet identifiant est généré automatiquement et visible dans le Dashboard → Véhicules. Il n'est pas à confondre avec la clé API de l'association.

Paramètres recommandés dans Traccar Client

Frequency10–30 secondes selon la vitesse du véhicule
Distance50–100 mètres
AccuracyHigh (GPS)

🔔 Notifications Push

Web Push VAPID — les abonnements sont liés à des "sites push" créés dans le Dashboard. Chaque site a sa propre paire de clés VAPID.

GET /push/vapid-public/:siteApiKey public Clé VAPID publique d'un site

Retourne la clé publique VAPID nécessaire pour créer un abonnement push côté navigateur.

{ "publicKey": "BGxxxxxx..." }
POST /push/subscribe/:siteApiKey public Abonner un navigateur
{
  "subscription": {
    "endpoint": "https://fcm.googleapis.com/...",
    "keys": { "p256dh": "...", "auth": "..." }
  }
}

Utiliser l'objet retourné par serviceWorkerRegistration.pushManager.subscribe().

POST /push/unsubscribe/:siteApiKey public Désabonner un navigateur
{ "endpoint": "https://fcm.googleapis.com/..." }
POST /push/notify X-Internal-Secret Envoyer une notification (PHP uniquement)
⚠️ Cet endpoint est réservé au serveur PHP. Il nécessite le header X-Internal-Secret partagé entre les deux serveurs.
{
  "site_id": 42,
  "title":   "Nouvelle position",
  "body":    "Le train est en gare de Lyon.",
  "url":     "https://www.rail-horizon.com/track/abc123",
  "icon":    "https://..."   // optionnel
}

🌐 API Publique

Accès aux données d'une association depuis un service externe. Nécessite la clé API de l'association (visible dans Dashboard → Intégration).

GET /public/fleet Bearer Flotte complète de l'association

Deux formes d'authentification acceptées :

// Via header
Authorization: Bearer VotreCleApiAssociation

// Via query param
GET /public/fleet?key=VotreCleApiAssociation

Réponse

[
  {
    "id":           1,
    "name":         "BB 26000",
    "vehicle_type": "locomotive",
    "access_slug":  "abc123",
    "is_online":    true,
    "last_lat":     48.8566,
    "last_lon":     2.3522,
    "last_speed":   145.0,
    "last_seen":    "2026-04-29T10:30:00.000Z"
  }
]
GET /public/network/:slug public Informations publiques d'un réseau

Retourne les infos de l'association et ses véhicules actifs. Le :slug est visible dans l'URL rail-horizon.com/reseau/:slug.

{
  "id":          1,
  "name":        "Association AAPSL",
  "description": "...",
  "logo_url":    "https://...",
  "vehicles": [
    { "name": "BB 26000", "access_slug": "abc123", "is_online": true, ... }
  ]
}

💚 Santé du serveur

Endpoint de monitoring pour vérifier que l'API et la base de données sont opérationnelles.

GET /health public État du serveur
// Réponse OK (200)
{ "status": "ok", "ts": "2026-04-29T10:30:00.000Z" }

// Réponse erreur BDD (503)
{ "status": "db_error", "error": "..." }

🚂 Référence — Types de véhicules

Valeurs acceptées pour le champ vehicle_type.

ValeurDescription
locomotiveLocomotive (BB, CC, BB…)
automotriceAutomotrice (TGV, Intercités, Transilien…)
autorailAutorail (X 73500, AGC…)
tramTramway
busBus / Car
voitureVoiture remorquée
bateauBateau / ferry
autreAutre (défaut)