Documentation J+SERVICES Guides Référence API

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:

Erreurs

{
  "success": false,
  "code": "ROUTER_OFFLINE",
  "message": "Routeur injoignable.",
  "reachable": false,
  "last_seen_at": "2026-09-30T08:00:00.000Z"
}

Codes:

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..."
  }
}