API REST
Toute la plateforme est pilotable par API
Chaque écran de fastergateway s’appuie sur cette API : connecteurs, routes, filtres, campagnes, contacts, soldes, accusés de réception. La référence ci-dessous est extraite du code du backend, pas rédigée à côté — elle ne peut donc pas dériver.
https://demo.fastergateway.net:3002/api/v1v1.0 · 172 opérationsAvant le premier appel
Quatre repères qui valent pour toutes les routes
Le reste se lit dans la référence.
Authentification
POST /api/v1/auth/login rend un jeton JWT et un jeton de rafraîchissement. Les routes marquées d’un cadenas attendent l’en-tête Authorization: Bearer.
Débit
10 requêtes par seconde et par adresse IP. Au-delà, la réponse est un 429 : le client doit réessayer plus tard, pas insister.
Enveloppe de réponse
Toujours la même forme, { success, data, error }, avec le code HTTP correspondant. Une erreur ne rend jamais 200.
Accusés de réception
La passerelle rappelle /api/v1/sms/dlr/gateway. Le DLR est ensuite embarqué dans le message et se relit par l’API des messages.
Secrets en transit
Chiffrer les mots de passe, si vous le voulez
Facultatif et par appelant : le backend regarde le champ et décide seul. Préfixe reconnu, il déchiffre ; autre chose, il prend la valeur telle quelle. Aucune requête existante ne change.
La clé
Remise en main propre par l’exploitant. Elle ne circule pas par l’API, ne se met pas dans un navigateur — un bundle JavaScript se lit —, et ne sert qu’au transport.
Format attendu
enc:v1:<iv>:<tag>:<chiffré> AES-256-GCM · iv 12 octets · tag 16 octets · les trois en base64
Node 20+
import { createCipheriv, randomBytes } from 'node:crypto';
const CLE = Buffer.from(process.env.SECRETS_KEY, 'base64');
export function chiffrer(clair) {
const iv = randomBytes(12);
const c = createCipheriv('aes-256-gcm', CLE, iv);
const corps = Buffer.concat([c.update(clair, 'utf8'), c.final()]);
return [
'enc:v1:' + iv.toString('base64'),
c.getAuthTag().toString('base64'),
corps.toString('base64'),
].join(':');
}
// await fetch(url, { method: 'POST', headers, body: JSON.stringify({
// uid: 'FAST_1234', gid: 'grp_8', username: 'client',
// password: chiffrer('MonSecret9'),
// })});Python 3 · cryptography
import base64, os
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
CLE = base64.b64decode(os.environ["SECRETS_KEY"])
def chiffrer(clair: str) -> str:
iv = os.urandom(12)
# AESGCM.encrypt colle le tag (16 octets) A LA FIN du chiffre :
# il faut l'en detacher, le format attendant les deux separement.
sortie = AESGCM(CLE).encrypt(iv, clair.encode(), None)
corps, tag = sortie[:-16], sortie[-16:]
b = lambda x: base64.b64encode(x).decode()
return f"enc:v1:{b(iv)}:{b(tag)}:{b(corps)}"Champs acceptant un secret chiffré
/auth/login · /auth/signup · /auth/reset-passwordpassword/users · /users/{id}password/jasmin-users · /jasmin-users/{uid}password/gateways · /gateways/{id}password/smpp-connectors · /smpp-connectors/{cid}password/bridges · /bridges/{id}bindPassword, authValue
Ce que cela ferme n’est pas l’interception — TLS s’en charge déjà — mais la trace qu’un mot de passe en clair laisse derrière lui : le journal d’un proxy, une capture interne, un rapport d’erreur. La protection vaut ce que vaut le secret de la clé.
Référence
Toutes les routes du backend
Groupées par domaine, telles que le serveur les expose.
172 opérations