Contrat API Passerelle Routeur
Base: /api/v1/clients/routers/:allocationId
Toutes les routes exigent requireAuth, requireClientRole, requireLinkedClient, un quota
routerGatewayLimiter, et l’appartenance de :allocationId au client authentifié.
Il n’existe pas de montage singulier /api/v1/client/routers/*. Les routes historiques
/api/v1/clients/router/* et leur alias legacy /api/v1/client/router/* restent séparés pour
l’application mobile.
Enveloppe de lecture
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "REST",
"data": {}
}
reachable indique si le routeur a répondu à cette requête. Une donnée servie depuis le cache a
donc reachable:false, source:"CACHE", et transport vaut le transport de la donnée d’origine.
Règles de cache:
- lecture normale: cache servi s’il a moins de 5 minutes;
?refresh=true: lecture directe obligatoire;- lecture directe impossible: cache de secours jusqu’à 7 jours;
- cache de plus de 24 h:
stale:true; - aucun cache ou cache de plus de 7 jours:
503 ROUTER_OFFLINE.
Erreurs
{
"success": false,
"code": "ROUTER_OFFLINE",
"message": "Routeur injoignable.",
"reachable": false,
"last_seen_at": "2026-09-30T08:00:00.000Z"
}
Codes:
ROUTER_OFFLINE503AUTH_FAILED502ADDRESS_UNRESOLVED503TRANSPORT_TIMEOUT504ROUTER_NOT_LINKED409FORBIDDEN_ROUTER403ROUTER_WRITE_FORBIDDEN409(WRITE_GUARD_BLOCKED)TERMINAL_READ_ONLY403
Routes
GET /identity
Transport: REST via vpn-management.
Règle d’injoignabilité: identité, routerboard et ressource tous vides ou absents.
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "REST",
"data": {
"serial": "HHD123ABC",
"identity": "Boutique Centre",
"model": "hAP ax3",
"board_name": "C53UiG+5HPaxD2HPaxD",
"routeros_version": "7.15.3",
"routeros_major": 7
}
}
GET /health
Transport: REST via vpn-management.
Règle d’injoignabilité: objet ressource vide.
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "REST",
"data": {
"uptime": "3d12h",
"cpu_load": 7,
"free_memory": 134217728,
"total_memory": 268435456,
"version": "7.15.3"
}
}
GET /hotspot/servers
Transport: REST via vpn-management.
Règle d’injoignabilité: liste vide.
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "REST",
"data": [
{
"name": "hotspot1",
"interface": "bridge-hotspot",
"profile": "hsprof1",
"address_pool": "hs-pool",
"disabled": "false"
}
]
}
GET /hotspot/user-profiles
Transport: REST via vpn-management.
Règle d’injoignabilité: liste vide. Un hotspot vivant expose au moins le profil default.
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "REST",
"data": [
{
"name": "default",
"rate_limit": "2M/5M",
"session_timeout": "1h",
"shared_users": "1"
}
]
}
GET /hotspot/users?limit=100&offset=0
Transport: REST via vpn-management, avec repli SSH v6 du service existant.
Règle d’injoignabilité: exception transport; une liste d’utilisateurs vide est possible.
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "REST",
"data": {
"items": [{ "name": "VC-001", "profile": "default", "comment": "batch-a" }],
"total": 1,
"limit": 100,
"offset": 0
}
}
GET /walled-garden
Transport: SSH.
Règle d’injoignabilité: échec de lecture SSH.
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "SSH",
"data": {
"entries": [
{
"dst_host": "pay.example.com",
"action": "allow",
"comment": null,
"ours": true
}
],
"missing": [],
"conform": true
}
}
POST /walled-garden/apply
Transport: SSH.
Ajoute uniquement les hôtes manquants calculés par la même source que le déploiement du portail.
Le second appel est idempotent (added:0). Si le routeur est hors ligne, la réponse contient un
script manuel.
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "SSH",
"data": {
"status": "repaired",
"missing": ["pay.example.com"],
"added": 1,
"conform": false
}
}
Erreur hors ligne:
{
"success": false,
"code": "ROUTER_OFFLINE",
"message": "Routeur injoignable : script manuel requis.",
"reachable": false,
"last_seen_at": "2026-09-30T08:00:00.000Z",
"script": "# TiketMOMO - walled-garden..."
}
POST /terminal
Transport: REST pour les commandes print simples, repli interne inchangé du service terminal.
Seules les commandes print simples sont acceptées. Les mutations, export, file=, les scripts
enchaînés avec ;, blocs {}, variables $ et commandes : sont refusés.
{
"command": "/system resource print"
}
{
"success": true,
"reachable": true,
"source": "LIVE",
"read_at": "2026-09-30T08:45:00.000Z",
"stale": false,
"transport": "REST",
"data": {
"success": true,
"data": [{ "uptime": "3d12h", "version": "7.15.3" }],
"formatted": "FLAGS # UPTIME VERSION..."
}
}