Aller au contenu principal

Référence API SMS-C

← Retour à l'Index de Documentation

Référence pour l'API REST SMS-C, générée à partir de la table de routage en direct (config/config.exs) et des implémentations de contrôleur. Chaque point de terminaison ci-dessous est réellement routé par le service en cours d'exécution.

L'application elle-même sert une spécification OpenAPI lisible par machine et une interface Swagger UI interactive. Ceux-ci sont toujours synchronisés avec la version déployée :

GET /api/schema      # Spécification OpenAPI JSON
GET /api/docs # Swagger UI

Table des Matières​

Aperçu​

URL de Base​

https://<host>:8443/api

Port par Défaut : 8443 (configurable via config :api_ex, api: %{port: ...}) Protocole : HTTPS lorsque enable_tls est activé (par défaut). Tous les itinéraires sont montés sous le préfixe /api.

Type de Contenu​

Les corps de requête et de réponse sont en JSON :

Content-Type: application/json

Il n'y a pas de versionnement d'API basé sur l'URL. La table de routage est le contrat ; consultez /api/schema pour la forme exacte déployée.

Authentification​

L'API n'a aucune authentification au niveau de l'application. Le pipeline de requête ne négocie que le type de contenu et attache la spécification OpenAPI ; il n'y a pas de clé API, de jeton d'authentification ou de vérification de session devant les itinéraires.

Le contrôle d'accès est donc censé être géré en dehors de l'application :

  • TLS : lorsque enable_tls est vrai, l'auditeur termine HTTPS en utilisant le tls_cert_path / tls_key_path configuré. Utilisez-le en production.
  • Contrôles réseau : restreindre le port API aux sources de confiance avec un pare-feu ou un proxy inverse en amont. Plusieurs points de terminaison enregistrent l'IP de l'appelant (à partir de X-Forwarded-For ou du socket) pour l'audit, mais ne bloquent pas sur cela.

Ne pas exposer le port API directement à des réseaux non fiables.

Conventions de Réponse​

Les contrôleurs renvoient la ressource directement, sans enveloppe data.

Ressource unique :

{ "id": 12345, "status": "queued" }

Les collections sont renvoyées sous forme de tableau JSON brut :

[ { "id": 12345 }, { "id": 12346 } ]

Les erreurs au niveau du contrôleur utilisent une chaîne error plate :

{ "error": "payload_hex is required. For plaintext, use POST /api/messages_plaintext" }

Les erreurs au niveau du framework (échecs de routage, corps non analysables) reviennent sous forme de :

{ "status": "error", "response": "Not Found" }

Statut​

Vérification de la santé pour la surveillance et les équilibreurs de charge.

Requête :

GET /api/status

Réponse (200 OK) :

{
"status": "ok",
"application": "OmniMessage",
"timestamp": "2025-11-01T23:00:00Z"
}

Exemple :

curl https://host:8443/api/status

Messages​

La file d'attente de messages est la ressource principale. Le contenu du message est transporté sous payload_hex (les octets TP-User-Data) plus un octet dcs (schéma de codage de données) et un udh_hex optionnel (en-tête de données utilisateur). Les appelants en texte clair devraient utiliser Soumettre du Texte Clair, qui effectue l'encodage, la sélection DCS et le fractionnement multipart pour vous.

Objet Message​

Champs renvoyés pour un message (voir ApiEx.Schemas.MessageSchema) :

ChampTypeRemarques
identierID du message
source_msisdnchaîneNuméro source
destination_msisdnchaîneNuméro de destination
payload_hexchaîneOctets TP-User-Data en hex (contenu canonique)
dcschaîneSchéma de codage de données sous forme d'octet hex (00=GSM7, 08=UCS2, 04=8bit, C8=MWI)
udh_hexchaîne / nullOctets d'en-tête de données utilisateur en hex
message_textchaîne / nullTexte UTF-8 dérivé pour affichage uniquement (non utilisé pour la livraison)
source_smscchaîneIdentifiant SMSC source
dest_smscchaîne / nullIdentifiant SMSC de destination
statuschaîneUn des queued, backoff, sent, delivered, expired, dropped, auto_replied, balance_rejected, deleted
send_timedatetime
deliver_timedatetime / null
expiresdatetime
delivery_attemptsentier
deadletterbooléen
message_partsentier / null
message_part_numberentier / null
smsc_node_namechaîneNoeud qui possède le message

Lister les Messages​

Requête :

GET /api/messages

En-têtes Optionnels :

  • smsc: <frontend_name> - mode de sondage : renvoie les messages destinés à ce SMSC.
  • include-unrouted: true|1 - en mode de sondage, renvoie également les messages sans enregistrement de localisation (par défaut : faux).
  • x-decode: true|1 - inclut une vue décodée de chaque charge utile de message.

Paramètres de Requête (mode liste, utilisés uniquement lorsqu'aucun en-tête smsc n'est présent) :

  • status - filtre par un seul atome de statut (voir la liste des statuts ci-dessus).
  • limit - max enregistrements (par défaut 100, max 1000).
  • offset - enregistrements à ignorer (par défaut 0).

Le point de terminaison est toujours paginé en mode liste : sans limit, il renvoie au maximum 100 enregistrements, jamais l'ensemble du magasin.

Réponse (200 OK) - un tableau JSON d'objets message.

Exemples :

# Sondage pour les messages d'un frontend
curl -H "smsc: uk_gateway" https://host:8443/api/messages

# Sondage incluant des messages non routés
curl -H "smsc: uk_gateway" -H "include-unrouted: true" https://host:8443/api/messages

# Lister les messages livrés
curl "https://host:8443/api/messages?status=delivered&limit=50"

Obtenir un Message​

Requête :

GET /api/messages/:id

L'en-tête optionnel x-decode: true ajoute une vue de charge utile décodée.

Réponse (200 OK) : un seul objet message. 404 avec {"error": "Message not found"} si l'id est inconnu.

curl https://host:8443/api/messages/12345

Soumettre un Message​

Soumettez un message pré-encodé. payload_hex est requis ; les requêtes sans cela sont rejetées avec 422.

Requête :

POST /api/messages
Content-Type: application/json

Corps :

{
"source_msisdn": "15555551234",
"destination_msisdn": "15555555678",
"payload_hex": "c8329bfd06dddf723619",
"dcs": "00",
"source_smsc": "api_client"
}

Champs :

  • source_msisdn, destination_msisdn - numéros.
  • payload_hex - requis. Octets TP-User-Data en hex.
  • dcs - octet hex du schéma de codage de données (défauts appliqués en aval).
  • udh_hex - en-tête de données utilisateur hex optionnel.
  • source_smsc - identifie le système soumetteur.
  • source_type - classification de source optionnelle.

Réponse (201 Created) : l'objet message créé. Les rejets retournent 422 avec une chaîne error (par exemple, payload_hex manquant).

curl -X POST https://host:8443/api/messages \
-H "Content-Type: application/json" \
-d '{
"source_msisdn": "15555551234",
"destination_msisdn": "15555555678",
"payload_hex": "c8329bfd06dddf723619",
"dcs": "00",
"source_smsc": "api_client"
}'

Soumettre du Texte Clair​

Soumettez une chaîne UTF-8 et laissez le SMS-C gérer l'encodage (GSM7 vs UCS2), la sélection DCS, et le fractionnement multipart.

Requête :

POST /api/messages_plaintext
Content-Type: application/json

Corps :

{
"source_msisdn": "15555551234",
"destination_msisdn": "15555555678",
"message": "Hello World",
"source_smsc": "api_client"
}

Le texte du message peut être donné comme message, text, ou body. source_msisdn et destination_msisdn sont requis.

Réponse (201 Created) :

  • Partie unique : l'objet message créé.
  • Multipart : { "parts": <n>, "messages": [ ... ] }.
curl -X POST https://host:8443/api/messages_plaintext \
-H "Content-Type: application/json" \
-d '{
"source_msisdn": "15555551234",
"destination_msisdn": "15555555678",
"message": "Hello World",
"source_smsc": "api_client"
}'

Soumettre un PDU Brut​

Soumettez un PDU SMS brut (hex) pour une compatibilité maximale avec les frontends hérités et SIP.

Requête :

POST /api/messages_raw
Content-Type: application/json

Corps :

{
"message_body": "0001000B916407007009F0000004D4F29C0E",
"source_smsc": "legacy_system"
}

Champs :

  • message_body - requis. PDU SMS encodé en hex (ou TPDU, voir ci-dessous).
  • source_msisdn - optionnel.
  • source_smsc / smsc_node_name - requis en mode uniquement TPDU.
  • rp_originator_address, rp_destination_address - fournissez-les pour soumettre un TPDU brut (la couche RP est synthétisée).

L'IP de l'appelant est prise à partir de X-Forwarded-For (ou du socket) pour résoudre le frontend d'origine.

Réponses :

  • 201 Created avec { "status": "success", "response": { "id": <id> } } (un champ hex rp_ack est inclus lorsqu'il est généré).
  • 200 OK avec { "status": "success", "response": { "status": "delivery_report_received" } } lorsque le PDU est un rapport de livraison plutôt qu'un nouveau message.
  • 422 avec une chaîne error pour hex manquant/invalid ou échecs de décodage.
curl -X POST https://host:8443/api/messages_raw \
-H "Content-Type: application/json" \
-d '{
"message_body": "0001000B916407007009F0000004D4F29C0E",
"source_smsc": "legacy_system"
}'

Le service décode le PDU (3GPP TS 23.040), extrait les numéros/texte/DCS, détecte les rapports de livraison et applique le routage. Les rapports de livraison sont enregistrés mais ne sont pas stockés comme de nouveaux messages.

Mettre à Jour un Message (PATCH)​

Mise à jour partielle d'un message stocké.

Requête :

PATCH /api/messages/:id
Content-Type: application/json

Envoyez tous les champs de message modifiables (par exemple dest_smsc, deliver_after, status). Les modifications de métadonnées sont enregistrées dans le journal des événements.

Réponse (200 OK) : l'objet message mis à jour. 404 si non trouvé, 422 en cas de mise à jour rejetée.

curl -X PATCH https://host:8443/api/messages/12345 \
-H "Content-Type: application/json" \
-d '{ "dest_smsc": "backup_gateway" }'

Incrémenter la Tentative de Livraison​

Enregistrer une livraison échouée : incrémente le compteur de tentatives, déplace le message vers backoff, et planifie la prochaine tentative avec un retour d'exponentiel.

Deux formes équivalentes existent :

PUT  /api/messages/:id                  # la ressource messages, PUT = incrémenter
POST /api/messages_increment_attempt (id dans le corps)
PUT /api/messages_increment_attempt/:id (id dans l'URL)

PUT /api/messages/:id est distinct de PATCH /api/messages/:id : PATCH effectue une mise à jour partielle, PUT incrémente la tentative de livraison. Passez keep_route=true pour conserver le dest_smsc actuel lors de la nouvelle tentative.

Réponse (200 OK) : le message mis à jour, par exemple :

{ "id": 12345, "status": "backoff", "delivery_attempts": 2 }
curl -X PUT https://host:8443/api/messages/12345

Marquer Comme Livré​

Marquer un message comme livré (stock local ou fédéré).

POST /api/messages_mark_delivered           (id dans le corps)
PUT /api/messages_mark_delivered/:id (id dans l'URL)

L'en-tête optionnel smsc sélectionne le SMSC fédéré lorsque le message n'est pas conservé localement.

Réponse (200 OK) : l'objet message livré. 404 si non trouvé.

curl -X POST https://host:8443/api/messages_mark_delivered \
-H "Content-Type: application/json" \
-d '{ "id": 12345 }'

Réacheminer un Message​

Réévaluer les règles de routage pour un message stocké et mettre à jour son dest_smsc.

Requête :

POST /api/messages/reroute
Content-Type: application/json

Corps : { "id": 12345 }

Réponse (200 OK) :

{ "message_id": 12345, "new_dest_smsc": "uk_gateway", "status": "rerouted" }

404 si le message n'est pas trouvé, 422 si aucune route ne correspond.

Effacer un Champ​

Réinitialiser un champ de message spécifique à null.

Requête :

POST /api/messages/clear_field
Content-Type: application/json

Corps : { "id": 12345, "field": "dest_smsc" }

field doit être l'un de delivery_time, dest_smsc, ou deliver_after; toute autre valeur renvoie 400. Le changement est enregistré dans le journal des événements.

Réponse (200 OK) : l'objet message mis à jour.

Supprimer un Message​

Requête :

DELETE /api/messages/:id

Réponse (204 No Content). 404 si non trouvé. La suppression est permanente.

curl -X DELETE https://host:8443/api/messages/12345

Indication de Message en Attente​

Soumettez une notification MWI (Indication de Message en Attente). Le contrôleur construit le PDU MWI selon 3GPP TS 23.038 et stocke un message prêt à être livré avec un payload_hex et un dcs pré-calculés.

Requête :

POST /api/mwi
Content-Type: application/json

Corps :

{
"source_msisdn": "12345",
"destination_msisdn": "15555555678",
"indication_type": "voicemail",
"indication_active": true,
"message_body": "Vous avez 1 nouveau message vocal",
"source_smsc": "IMS_SMSC"
}

Champs :

  • indication_type - voicemail (par défaut), fax, email, ou autre.
  • indication_active - true pour définir l'indicateur, false pour le supprimer (par défaut true).
  • message_body - texte d'accompagnement optionnel (encodé en GSM7).
  • source_msisdn, destination_msisdn, source_smsc, dest_smsc.

Réponse (201 Created) : l'objet message créé. 422 en cas d'échec.

Emplacements​

Enregistrements de localisation des abonnés pour la livraison mobile-terminée. Ressource REST standard ; le segment de chemin :id est l'IMSI.

GET    /api/locations           # lister (paginé : ?limit=&offset=, en-tête x-total-count)
GET /api/locations/:id # obtenir par IMSI
POST /api/locations # créer ou mettre à jour (identifié par IMSI)
PATCH /api/locations/:id # mise à jour partielle
PUT /api/locations/:id # mise à jour
DELETE /api/locations/:id # supprimer

Corps de Création/Mise à Jour :

{
"msisdn": "15555551234",
"imsi": "001001000000001",
"location": "msc1.region1.example.com",
"ran_location": "cell_tower_12345",
"imei": "123456789012345",
"ims_capable": true,
"csfb": false,
"registered": true,
"expires": "2025-11-01T23:30:00Z",
"user_agent": "Samsung Galaxy"
}

imsi et msisdn sont requis ; les champs restants sont optionnels. Les réponses sont l'objet de localisation (200/201) ; les échecs de validation retournent 422. Appelés par les systèmes de gestion de mobilité lorsqu'un abonné s'enregistre ou se désenregistre.

Frontends​

Suivez les connexions SMSC des frontends. Cette ressource expose index, show, et create uniquement (il n'y a pas de sous-routes active, stats, history, ou register).

GET  /api/frontends           # lister toutes les inscriptions
GET /api/frontends/:id # obtenir une inscription
POST /api/frontends # enregistrer ou actualiser un frontend

Corps d'Inscription (POST /api/frontends) :

{
"frontend_name": "smpp-gateway-1",
"frontend_type": "SMPP",
"ip_address": "10.0.1.5",
"hostname": "smpp-gw-01",
"uptime_seconds": 3600,
"configuration": "{\"port\": 2775, \"system_id\": \"smpp_user\"}"
}

frontend_name est requis. Si ip_address est omis, il est rempli à partir de l'IP source de la requête (X-Forwarded-For ou socket). Si une inscription active existe déjà pour le frontend_name, elle est mise à jour ; sinon, une nouvelle est créée. Les inscriptions expirent après environ 90 secondes, donc les frontends doivent se réinscrire périodiquement.

Réponse (201 Created) : l'objet d'inscription.

Événements​

Événements de cycle de vie par message. Les événements sont conservés dans ETS avec un TTL roulant.

Obtenir les Événements de Message​

Requête :

GET /api/events/:id

:id est l'ID numérique du message.

Réponse (200 OK) :

{
"message_id": 12345,
"events": [
{ "event_epoch": 1698672000, "name": "message_inserted", "description": "..." },
{ "event_epoch": 1698672005, "name": "message_delivered", "description": "..." }
]
}

400 si l'id n'est pas un entier.

Enregistrer un Événement​

Requête :

POST /api/events
Content-Type: application/json

Corps :

{
"message_id": 12345,
"name": "external_delivery_confirmed",
"description": "Confirmé par le système en aval"
}

message_id, name, et description sont tous requis. La source de l'événement est détectée automatiquement à partir de l'IP de l'appelant (correspondant aux inscriptions de frontend actives), revenant au nom de nœud configuré.

Réponse (201 Created) :

{
"status": "success",
"message": "Événement enregistré avec succès",
"event": {
"message_id": 12345,
"name": "external_delivery_confirmed",
"description": "Confirmé par le système en aval",
"event_source": "smpp-gateway-1",
"event_epoch": 1698672010
}
}

Campagnes​

Messagerie en masse : téléchargez une liste de destinataires nommée, puis exécutez une campagne à débit limité contre celle-ci. Consultez le guide de Messagerie en Masse / Campagnes pour les concepts (filtre d'audience, taux de goutte, cycle de vie, statistiques).

Listes de Destinataires​

GET    /api/campaign_lists           # toutes les listes
GET /api/campaign_lists/:id # une liste, inclut "recipients"
POST /api/campaign_lists # créer une liste
PATCH /api/campaign_lists/:id # ajouter des destinataires
DELETE /api/campaign_lists/:id # supprimer la liste et ses destinataires

Chaque destinataire peut porter jusqu'à quatre variables de modèle (var1..var4). Fournissez les destinataires sous forme de tableau JSON, de chaîne CSV brute, ou les deux. Les destinataires JSON peuvent être des chaînes MSISDN simples ou des objets avec var1..var4 :

{
"name": "Clients VIP",
"description": "Abonnés de grande valeur",
"recipients": [
{ "msisdn": "12025550101", "var1": "Alice", "var2": "Gold" },
"12025550102"
]
}

Pour CSV, une ligne d'en-tête nommant une colonne msisdn / destination_msisdn / number / phone sélectionne la colonne MSISDN (sinon, la première colonne est utilisée) ; les colonnes restantes deviennent var1..var4 dans l'ordre des colonnes :

{ "name": "Importé", "csv": "msisdn,first,plan\n12025550101,Alice,Gold\n" }

PATCH ajoute des destinataires (il ne les remplace pas).

Réponse (201 Created) : { "id": 1, "name": "Clients VIP", "recipient_count": 2 }

Campagnes​

GET    /api/campaigns        # toutes les campagnes (paginé, les plus récentes en premier)
GET /api/campaigns/:id # une campagne, y compris les statistiques en direct
POST /api/campaigns # créer une campagne (commence en brouillon)
DELETE /api/campaigns/:id # arrêter une campagne mais conserver son enregistrement

Corps de Création :

{
"name": "Avis de maintenance",
"message": "Maintenance prévue ce soir de 02:00 à 03:00.",
"source_msisdn": "12345",
"source_smsc": "IMS_SMSC",
"list_id": 1,
"audience": "active_only",
"drip_tps": 50
}

Champs :

  • name, message, source_msisdn, source_smsc - requis. message prend en charge des variables de modèle par destinataire ({{ var1 }}..{{ var4 }}, {{ msisdn }}).
  • list_id - liste de destinataires. Omettez pour cibler tous les abonnés actuellement actifs (enregistrés).
  • audience - active_only (par défaut) ou all. Ignoré lorsque list_id est omis.
  • drip_tps - messages soumis dans la file d'attente par seconde (par défaut à partir de la configuration).
  • validity_hours - validité du message en heures ; définit l'expires de chaque message.
  • deliver_after - heure ISO 8601 optionnelle pour maintenir les messages jusqu'à (envoi programmé).

DELETE arrête la livraison mais conserve l'enregistrement afin que l'historique et les statistiques restent visibles ; il retourne la campagne annulée (200) et est purgé automatiquement une fois passé le TTL de conservation.

Réponse (GET /api/campaigns/:id) :

{
"id": 7,
"name": "Avis de maintenance",
"list_id": 1,
"audience": "active_only",
"status": "running",
"drip_tps": 50,
"total_targets": 1000,
"stats": {
"total": 1000, "pending": 600, "queued": 300,
"delivered": 90, "failed": 10, "skipped_inactive": 0,
"dispatched": 400, "progress_percent": 40, "delivery_percent": 22
}
}

Contrôler une Campagne​

Requête :

POST /api/campaigns/control
Content-Type: application/json

Corps : { "campaign_id": 7, "action": "start" }

action est l'un de start, pause, resume, cancel. Retourne la campagne mise à jour (200), 404 si non trouvée, ou 422 si l'action est invalide pour l'état actuel.

Résultats par Destinataire​

GET /api/campaign_targets/:id              # :id est l'ID de la campagne
GET /api/campaign_targets/:id?state=failed # filtre par état de cible

Prend en charge la pagination limit/offset ; le nombre total (après tout filtre state) est dans l'en-tête de réponse x-total-count. Chaque entrée porte l'state du destinataire (pending / queued / delivered / failed / skipped_inactive).

Autres Familles de Points de Terminaison​

Les familles de routes suivantes font partie de la même API mais sont documentées en profondeur dans leurs guides dédiés. Les chemins sont listés ici pour complétude.

Routage​

GET    /api/routes            # lister les routes
GET /api/routes/:id # obtenir une route
POST /api/routes # créer une route
PATCH /api/routes/:id # mettre à jour
PUT /api/routes/:id # mettre à jour
DELETE /api/routes/:id # supprimer
GET /api/routes/export # exporter toutes les routes
POST /api/routes/import # importation en masse
POST /api/routes/simulate # simulation d'une décision de route

Voir le guide de Routage SMS.

Traductions de Numéros​

GET    /api/translations           # lister
GET /api/translations/:id # obtenir
POST /api/translations # créer
PATCH /api/translations/:id # mettre à jour
DELETE /api/translations/:id # supprimer
GET /api/translations/export # exporter
POST /api/translations/import # importation en masse
POST /api/translations/simulate # simulation d'une traduction

Voir le guide de Traduction de Numéros.

Opérations​

GET  /api/operations                    # index des opérations
POST /api/operations/clear_messages # purger le magasin de messages
POST /api/operations/clear_routes # purger les routes
POST /api/operations/clear_translations # purger les traductions
POST /api/operations/clear_frontends # purger les inscriptions de frontend

Ce sont des actions de maintenance destructrices ; protégez le port API en conséquence.

Fédération​

GET  /api/federation/status          # statut de la fédération
GET /api/federation/identity # identité de fédération de ce nœud
POST /api/federation/health # rapport de santé des pairs
POST /api/federation/registry # échange de registre
POST /api/federation/notify # notification de message entrant
POST /api/federation/delivery_status # rappel de statut de livraison
GET /api/federation_messages # vue de message fédéré

Voir le guide de Fédération.

Diameter, Journaux, et DNS​

GET  /api/diameter   # statut de pair/dip Diameter Sh
GET /api/logs # journaux structurés récents
POST /api/naptr # test de résolution NAPTR

La recherche d'abonnés Diameter Sh est décrite dans le guide de recherche d'abonnés HSS.

Codes de Statut HTTP​

CodeSignificationUtilisation Typique
200OKLecture ou mise à jour réussie
201CrééRessource créée
202AcceptéAccepté pour traitement asynchrone
204Pas de ContenuSuppression réussie
400Mauvaise RequêteEntrée mal formée (par exemple, id non entier, champ invalide)
404Non TrouvéRessource inconnue
422Entité Non TraitableÉchec de validation
500Erreur Interne du ServeurErreur serveur inattendue

Format d'Erreur​

Les erreurs au niveau du contrôleur retournent une chaîne error plate :

{ "error": "Message not found" }

Les erreurs au niveau du framework (itinéraires non correspondants, corps non analysables) retournent l'enveloppe normalisée :

{ "status": "error", "response": "Not Found" }

Meilleures Pratiques​

Soumission de Message​

  1. Pré-encodé vs texte clair : envoyez payload_hex à /api/messages lorsque vous avez déjà encodé le TPDU ; sinon, utilisez /api/messages_plaintext et laissez le SMS-C encoder et fractionner.
  2. Toujours définir source_smsc afin que les événements et le routage puissent attribuer le message.
  3. Utilisez des numéros au format E.164 de manière cohérente.
  4. Gérez 422 en inspectant la chaîne error plutôt qu'en réessayant à l'aveugle.

Intégration de Frontend​

  1. Se réinscrire sur POST /api/frontends bien avant la fenêtre d'expiration d'environ 90 secondes.
  2. Sonder avec l'en-tête smsc pour vos messages ; utilisez include-unrouted uniquement si vous souhaitez délibérément du trafic non routé.
  3. Marquer comme livré via /api/messages_mark_delivered après succès.
  4. Incrémenter en cas d'échec via PUT /api/messages/:id (ou /api/messages_increment_attempt) pour planifier une nouvelle tentative avec retour.
  5. Enregistrer des événements pour les confirmations en aval.

Opérationnel​

  1. Terminez TLS et restreignez le port API au niveau réseau ; il n'y a pas d'authentification intégrée.
  2. Réutilisez les connexions HTTP et définissez des délais d'attente client raisonnables.
  3. Surveillez les métriques Prometheus (voir METRICS.md) pour la santé de la file d'attente et de la livraison.