Sections
Documentation API
Plateforme
Authentification, clés API, webhooks, limites de débit, erreurs et les outils qui servent dans toute l’API.
Authentification
Toutes les requêtes API nécessitent un jeton Bearer dans l'en-tête Authorization. Utilisez test keys (mk_test_...) pour le développement : aucun vrai SMS n'est envoyé, aucuns frais. Utilisez live keys (mk_live_...) pour la production.
Mode test
Une clé de test (mk_test_...) fonctionne dès la création de votre compte, avant toute recharge. Un nouveau compte démarre en PENDING_PAYMENT : une clé de production reçoit 402 PAYMENT_REQUIRED pour tout, sauf quelques lectures de démarrage (GET /v1/accounts/me, GET /v1/accounts/:id, GET /v1/accounts/:id/topup-allowance et GET /v1/pricing) ; les clés de test passent quand même.
Un envoi de test applique les mêmes vérifications qu’un envoi réel : consentement et désabonnement LCAP, les listes d’autorisation et de blocage de la clé API, les vérifications de central réservé et de numéro injoignable, et la vérification de destination canadienne. Il ne vérifie pas la propriété du numéro from, la vérification du propriétaire, votre solde, les limites d’envoi, ni la vérification LNNTE (non appliquée à aucun envoi pour l’instant). Aucun message n’atteint un opérateur : il est tarifé exactement comme un envoi réel, pour que vous voyiez le coût réel, puis la ligne est marquée comme livrée.
Une clé de test est un bac à sable sans portée réelle : elle ne peut pas acheter ni libérer de numéros de téléphone, créer, renouveler ou révoquer des clés de production, envoyer le code de vérification du propriétaire, lancer un effacement, modifier les webhooks, déposer une demande de volume ou d’allocation de numéros, ni modifier les listes ou le refus par défaut d’une clé de production, et elle ne peut pas lire la file des lettres mortes. L’historique des messages et des vérifications via une clé de test ne montre que des lignes de test. Les contacts, groupes, listes, consentements et désabonnements restent modifiables, sauf ceux que la liste d’autorisation ou de refus d’une clé de production référence : les modifier exige aussi une clé de production.
Clés API et permissions
Chaque clé API porte un objet de permissions, une chaîne de lettres par ressource : r (lecture, GET), w (écriture, POST), m (modification, PATCH ou PUT), d (suppression, DELETE). Une ressource absente ou une chaîne vide signifie aucun accès à celle-ci. Vous pouvez aussi transmettre la clé dans un en-tête X-API-Key plutôt qu’un jeton Bearer dans Authorization. Quelques routes exigent une lettre moins évidente : POST /v1/compliance/erasure exige compliance:d ; POST /v1/accounts/:id/phone-verification et son /confirm exigent account:m ; POST /v1/compliance/dncl/check exige compliance:r ; DELETE /v1/contact-groups/:id/members/:contactId exige contact_groups:m ; et DELETE /v1/accounts/:id/api-keys/:keyId/lists/:mode exige api_keys:m.
Les ressources qu’un objet de permissions peut nommer :
| Ressource | Signification |
|---|---|
| messages | Envoyer et lire les messages SMS |
| phone_numbers | Provisionner, rechercher et libérer des numéros de téléphone |
| contacts | Gérer les contacts |
| contact_groups | Gérer les groupes de contacts et les diffusions |
| lists | Gérer les listes de contacts d’autorisation et de blocage |
| compliance | Consentements LCAP, désinscriptions et vérifications LNNTE |
| webhooks | Gérer les points de terminaison webhook |
| verify | Envoyer des NPU et vérifier les codes |
| account | Consulter ou modifier le profil du compte et son utilisation |
| api_keys | Gérer les clés API |
| emails | Envoyer et lire des courriels |
| email_domains | Gérer les domaines courriel |
| email_suppressions | Gérer les listes de suppression courriel |
| email_templates | Gérer les modèles de courriel enregistrés |
Une nouvelle clé hérite par défaut des permissions de la clé qui l’a créée : omettez permissions et elle obtient exactement ce que l’appelant possède. En demander davantage nécessite une confirmation par mot de passe (un en-tête X-Step-Up-Token avec la portée api_keys:elevate), sinon la requête est refusée avec 403 PERMISSION_ESCALATION. Une clé de test ne peut créer que des clés de test.
Limites de débit
Chaque compte peut faire 100 requêtes API par seconde, toutes clés confondues, de test comme réelles. Chaque réponse authentifiée porte X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset (secondes Unix). Une requête au-delà de la limite est refusée avec 429 RATE_LIMITED et Retry-After: 1, et rien n’est facturé.
L’envoi a ses propres limites en plus de celle-ci, comme un plafond quotidien et un débit par destinataire : consultez les limites d’envoi SMS et les limites du courriel.
Webhooks
Enregistrez un point de terminaison webhook avec les événements que vous souhaitez recevoir. Le signing_secret de la réponse n’est affiché qu’une seule fois, à la création.
curl -X POST https://api.honkio.ca/v1/webhooks \
-H "Authorization: Bearer mk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/honkio",
"events": ["message.delivered", "message.failed", "message.received"]
}'
# Response 201: { "id": "...", "url": "...", "events": [...],
# "signing_secret": "64 hex characters, shown once", "active": true, "created_at": "..." }Les événements SMS, de désabonnement et de numéro de téléphone et leur contenu sont décrits sur la page de l’API SMS.
Les événements de courriel (email.* et email_domain.*) et leur contenu sont décrits sur la page de l’API de courriel.
L’enveloppe
Chaque évènement arrive sous forme d’un seul objet JSON avec les mêmes six champs de premier niveau. Seul data change d’un évènement à l’autre.
| Champ | Signification |
|---|---|
| id | L’identifiant de l’évènement, un UUID. Il est le même à chaque tentative et à chaque rejeu de cet évènement : conservez-le et ignorez tout id déjà traité. |
| type | Le nom de l’évènement, par exemple message.received. La même valeur est envoyée dans l’en-tête X-HonkIO-Event. |
| created | Le moment de l’évènement, en ISO 8601 UTC avec millisecondes. Une nouvelle tentative ou un rejeu garde la valeur d’origine. |
| account_id | Le compte HonkIO auquel appartient l’évènement. |
| livemode | true quand l’action d’une clé réelle a causé l’évènement, false pour une simulation avec une clé de test. Les évènements de compte et de numéro de téléphone valent toujours true. |
| data | Les champs propres à l’évènement, décrits sous chaque évènement ci-dessous. |
Chaque événement porte aussi un champ livemode au premier niveau : true quand l’action d’une clé réelle l’a causé, false pour une simulation avec une clé de test. Les événements de compte et de numéro de téléphone sont toujours réels.
Nouvelles tentatives, lettres mortes et désactivation
Répondez directement par un code 2xx en moins de 10 secondes : les livraisons ne suivent jamais une redirection, donc un code 3xx compte comme une tentative échouée, tout comme un autre statut, un délai dépassé ou une erreur de connexion. Un évènement échoué est retenté une fois environ une seconde plus tard (sauf si le point de terminaison échouait déjà), puis à environ 1 minute, 5 minutes, 30 minutes, 2 heures, 6 heures et 16 heures d’intervalle : environ 24 heures en tout, jusqu’à huit tentatives. La livraison se fait au moins une fois dès la première tentative : dès qu’une tentative a échoué, l’évènement est conservé et ses nouvelles tentatives survivent à nos redémarrages et déploiements (un plantage pendant la toute première tentative peut faire perdre cet évènement). Chaque tentative est signée à nouveau et porte le même id d’évènement : dédupliquez sur celui-ci. Un évènement dont toutes les tentatives échouent va dans votre file des lettres mortes. Votre point de terminaison reste actif pendant tout ce temps : il n’est désactivé que lorsque toutes les tentatives vers lui ont échoué pendant au moins 24 heures, sans aucune livraison réussie entre-temps, et qu’au moins 5 évènements différents ont échoué ; toute livraison réussie remet ce compte à zéro, tout comme un échec survenu plus de 17 heures après le précédent (le plus long intervalle entre deux tentatives, plus une heure). Nous vous écrivons une heure après le début d’une série d’échecs, puis de nouveau si le point de terminaison est désactivé, et tant qu’il échoue, GET /v1/webhooks/:id indique failing_since, failed_events et last_failure_reason. Les évènements échoués avant la désactivation d’un point de terminaison sont conservés comme lettres mortes que vous pouvez rejouer ; ceux survenus pendant qu’il est désactivé ne lui sont pas livrés et ne sont pas conservés. Listez les lettres mortes avec GET /v1/webhooks/:id/dead-letters, renvoyez-en une avec POST /v1/webhooks/dead-letters/:id/replay (409 DEAD_LETTER_ALREADY_REPLAYED si elle est déjà partie ou qu’un rejeu est en cours) ou supprimez-la avec DELETE /v1/webhooks/dead-letters/:id, et réactivez le point de terminaison avec POST /v1/webhooks/:id/reactivate. Les lettres mortes rejouées sont conservées 90 jours ; toutes disparaissent à la limite de rétention des messages.
Vérifier les signatures
Chaque livraison porte les entêtes X-HonkIO-Signature, X-HonkIO-Timestamp et X-HonkIO-Event. Vérifiez la signature avant de faire confiance au contenu, et rejetez tout ce qui ne correspond pas. Le secret de signature est retourné une seule fois, à la création du webhook.
signed_string = timestamp + "." + body
signature = HMAC_SHA256(key = signing_secret, message = signed_string)
# timestamp: the X-HonkIO-Timestamp value as sent, decimal Unix epoch seconds
# body: the raw request bytes, read before any JSON parsing
# key: the UTF-8 bytes of the secret as issued, not hex decoded- Séparateur : un point littéral se trouve entre l’horodatage et le premier octet du corps.
- Horodatage : la valeur
X-HonkIO-Timestampexactement telle qu’envoyée, en secondes Unix décimales. - Corps : les octets bruts de la requête, lus avant toute analyse JSON. Tout ce qui analyse puis resérialise le JSON modifie les octets, et l’empreinte ne correspondra jamais.
- Signature : hexadécimal minuscule, 64 caractères. Rejetez tout ce qui ne fait pas 64 caractères hexadécimaux avant de décoder, puis comparez en temps constant.
- Secret : les octets UTF-8 du secret de signature exactement tel qu’émis. Ne le décodez pas au préalable.
Un vérificateur complet, qui refuse par défaut, en Node :
import { createHmac, timingSafeEqual } from 'node:crypto'
// rawBody must be the unparsed body. Most frameworks hand you a parsed object
// by default; reach for the raw buffer (express.raw, request.text(), and so on).
export function verifyHonkioWebhook(rawBody, headers, secret, toleranceSeconds = 300) {
const timestamp = headers['x-honkio-timestamp']
const signature = headers['x-honkio-signature']
if (!timestamp || !signature) return false
const ts = Number.parseInt(timestamp, 10)
if (!Number.isFinite(ts)) return false
if (Math.abs(Date.now() / 1000 - ts) > toleranceSeconds) return false
// Buffer.from(x, 'hex') drops invalid bytes without complaining, which can
// truncate two different values into a match. Check the shape first.
if (!/^[0-9a-f]{64}$/i.test(signature)) return false
const expected = createHmac('sha256', secret)
.update(`${timestamp}.${rawBody}`)
.digest('hex')
return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'))
}Validez votre implémentation avec ce vecteur. Si vous reproduisez la signature, c’est terminé :
secret deadbeef00112233445566778899aabbccddeeffdeadbeef0123456789abcdef
timestamp 1788920816
body {"id":"00000000-0000-4000-8000-000000000000","type":"message.delivered","created":"2026-09-09T02:26:57Z","account_id":"acc_test","data":{"message_id":"msg_test","to":"+16135550123","status":"delivered"}}
signature 058aca981d55947bb71d2ba4ff98487d5f5c6caf01189af72266cb3f1e22ccbfLe secret ci-dessus est jetable et n’appartient à aucun compte, vous pouvez donc le placer dans un test. Votre propre secret n’a jamais besoin de quitter votre serveur, et nous ne l’enverrons jamais par courriel, pas plus qu’une signature.
Rejetez tout ce qui sort d’une fenêtre de 300 secondes par rapport à X-HonkIO-Timestamp, et dédupliquez sur l’id de l’évènement. La livraison se fait au moins une fois, donc le même id peut légitimement arriver plusieurs fois.
Les nouvelles tentatives et les rejeux sont signés au moment de leur envoi, un même id d’évènement peut donc arriver avec un horodatage et une signature différents à chaque fois. Les livraisons rejouées portent aussi X-HonkIO-Replay: true. Vérifiez toujours avec l’entête d’horodatage arrivé avec cette requête, jamais avec un horodatage conservé auparavant.
Il n’existe pas de point de terminaison pour la rotation des secrets. Pour changer un secret, enregistrez un second point de terminaison, confirmez qu’il vérifie correctement, puis supprimez le premier. Les deux reçoivent les évènements tant qu’ils sont actifs, ce que votre déduplication par id absorbe.
Événements de compte
Trois événements de compte ne portent aucun message : account.delivery_warning lorsque plus de 10 % de vos 50 derniers messages réels ont échoué chez l’opérateur ; account.sending_paused lorsqu’une pause automatique se déclenche (channel vaut sms ou email ; une pause courriel ajoute bounce_rate_pct ou complaint_rate_pct) ; account.spend_warning lorsque les dépenses réelles d’une heure dépassent le plus élevé de 5 $ et de la moitié d’une journée typique. Chacun est aussi envoyé par courriel. Leur contenu figure dans la référence ci-dessous.
account.delivery_warning
Plus de 10 % de vos 50 derniers messages réels ont échoué chez l’opérateur. Envoyé avant toute pause automatique, au plus une fois par période de pause. Aussi envoyé par courriel.
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "account.delivery_warning",
"created": "2026-09-24T12:00:00.000Z",
"account_id": "clxxxaccountxxxxxxxxxxxxx",
"livemode": true,
"data": {
"failure_rate_pct": 14,
"failed": 7,
"sample": 50
}
}| Champ de data | Signification |
|---|---|
| failure_rate_pct | La part de l’échantillon qui a échoué, en pourcentage arrondi. |
| failed | Le nombre de messages de l’échantillon qui ont échoué chez l’opérateur. |
| sample | Le nombre de vos messages réels les plus récents examinés. |
account.sending_paused
Une pause automatique a arrêté l’envoi réel jusqu’à paused_until. Le mode test n’est pas touché. Aussi envoyé par courriel.
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "account.sending_paused",
"created": "2026-09-24T12:00:00.000Z",
"account_id": "clxxxaccountxxxxxxxxxxxxx",
"livemode": true,
"data": {
"channel": "sms",
"paused_until": "2026-09-25T14:00:00.000Z",
"reason": "FAILURE_RATE"
}
}| Champ de data | Signification |
|---|---|
| channel | L’envoi arrêté : sms ou email. L’autre canal n’est pas en pause. |
| paused_until | Le moment où l’envoi réel reprend de lui-même, en ISO 8601 UTC. |
| reason | Pourquoi : OPT_OUT_RATE ou FAILURE_RATE pour les SMS ; BOUNCE_RATE ou COMPLAINT_RATE pour les courriels. |
| bounce_rate_pct | Pauses de courriel pour BOUNCE_RATE seulement : votre taux récent de rebonds réels, en pourcentage. |
| complaint_rate_pct | Pauses de courriel pour COMPLAINT_RATE seulement : votre taux récent de plaintes réelles, en pourcentage. |
account.spend_warning
Vos dépenses réelles de la dernière heure ont dépassé le plus élevé de 5 $ et de la moitié d’une journée habituelle. Aussi envoyé par courriel.
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"type": "account.spend_warning",
"created": "2026-09-24T12:00:00.000Z",
"account_id": "clxxxaccountxxxxxxxxxxxxx",
"livemode": true,
"data": {
"spent_last_hour_cents": 1250,
"typical_daily_cents": 400,
"threshold_cents": 500
}
}| Champ de data | Signification |
|---|---|
| spent_last_hour_cents | Vos dépenses réelles de la dernière heure, en cents canadiens. |
| typical_daily_cents | Ce que votre compte dépense habituellement en une journée, en cents canadiens ; 0 sans historique. |
| threshold_cents | La dépense en une heure qui déclenche cet avertissement pour votre compte, en cents canadiens. |
SDK Node.js
@honkio/node est le SDK Node.js officiel : Node 18 ou plus récent, ESM et CommonJS, aucune dépendance à l’exécution. Chaque appel se résout en { data, error } et les erreurs de l’API ne lèvent jamais d’exception : error.name est le code de l’API (NON_CANADIAN_NUMBER, par exemple) et error.statusCode son statut HTTP.
npm install @honkio/nodeimport { Honkio } from '@honkio/node'
const honkio = new Honkio(process.env.HONKIO_API_KEY)
const { data, error } = await honkio.messages.send({
from: '+1416XXXXXXX', // one of your HonkIO numbers
to: '+1613XXXXXXX', // a Canadian number you hold consent for
body: 'Hello from HonkIO!',
})
if (error) console.error(error.name, error.message)
else console.log(data.id, data.status)Il couvre les messages, les consentements et les webhooks, y compris webhooks.verify, qui vérifie pour vous la signature d’une livraison, et toutes les ressources de courriel : courriels, envois groupés, domaines, suppressions et modèles.
Référence complète du SDK sur npm →Agents IA (MCP)
HonkIO fournit un serveur Model Context Protocol : un agent de codage IA peut ainsi envoyer des SMS, lancer une vérification téléphonique, acheter des numéros canadiens et vérifier le consentement LCAP en votre nom, en langage courant et sans SDK à brancher. Il communique avec cette même API REST au moyen de votre clé API, depuis notre point d'accès hébergé ou depuis une copie sur votre poste.
Le point d'accès hébergé ne demande aucune installation. Pointez votre client vers lui et transmettez votre clé dans un en-tête. Dans Claude Code :
claude mcp add --transport http honkio https://mcp.honkio.ca/mcp \
--header "Authorization: Bearer mk_test_YOUR_KEY"Ou dans un fichier .mcp.json partagé, en lisant la clé depuis votre shell pour qu'elle ne se retrouve jamais dans git. Cursor, VS Code, les connecteurs claude.ai et l'API Messages de Claude se connectent de la même façon, par URL.
{
"mcpServers": {
"honkio": {
"type": "http",
"url": "https://mcp.honkio.ca/mcp",
"headers": { "Authorization": "Bearer ${HONKIO_API_KEY}" }
}
}
}VS Code demande votre clé au premier démarrage du serveur et la conserve. Cursor s'installe avec une valeur fictive : remplacez mk_test_YOUR_KEY dans ~/.cursor/mcp.json avant utilisation.
Vous pouvez aussi vous connecter au lieu de coller une clé. Dans Claude Code, ajoutez le point d'accès sans en-tête et lancez /mcp : une page sur honkio.ca vous demande d'approuver la connexion et de choisir le mode production ou test. Une connexion en production demande aussi le mot de passe de votre compte. Les clients compatibles OAuth, comme les connecteurs claude.ai, le font d'eux-mêmes. Chaque connexion apparaît sur la page de vos clés API et peut y être révoquée.
Vous préférez l'exécuter localement ? Le même serveur est sur npm. Rien à installer : npx le télécharge à la première utilisation.
{
"mcpServers": {
"honkio": {
"command": "npx",
"args": ["-y", "@honkio/mcp"],
"env": { "HONKIO_API_KEY": "mk_test_YOUR_KEY" }
}
}
}Utilisez une clé de test pendant vos essais : elle fonctionne avant votre premier rechargement, et les envois et vérifications sont simulés gratuitement, sans envoi réel ni facturation. Les outils qui achètent ou libèrent des numéros de téléphone, modifient les webhooks ou lancent un effacement exigent une clé de production.
62 outils sont offerts, couvrant la liste ci-dessous ainsi que le courriel. Les 15 outils courriel n’apparaissent que si le courriel est activé sur votre compte.
- L'envoi de SMS, la liste des messages et l'état de livraison
- Le lancement d'un code de vérification, sa validation et la liste des tentatives
- La recherche, l'achat et la libération de numéros canadiens
- L'enregistrement et la vérification du consentement LCAP, ainsi que les retraits
- La gestion des webhooks et la relance des livraisons échouées
- Les détails du compte, l'utilisation et la gestion des clés API
- La consultation de l’utilisation par rapport au plafond quotidien, la demande d’un volume plus élevé et l’allocation de rechargement
- Le courriel : envois, envois programmés, domaines, suppressions et modèles (comptes avec courriel seulement)
Ensuite, demandez simplement
« Trouve un numéro 416 disponible, dis-moi son coût, et n'achète rien pour l'instant. »
Codes d'erreur
Chaque erreur est un objet JSON plat : code, message (suit Accept-Language), messageEn, messageFr, statusCode, et un champ details facultatif précisant la cause. Une requête mal formée, comme un champ manquant ou une valeur hors des limites documentées, retourne 422 VALIDATION_ERROR avec details qui nomme le champ. Une requête que le framework rejette lui-même avant que votre code ne s’exécute, comme un JSON invalide (400), un corps dépassant la limite de taille (413) ou un type de contenu non pris en charge (415), retourne un code Fastify FST_ERR_* avec un message uniquement en anglais.
| HTTP | Code | Signification |
|---|---|---|
| 401 | UNAUTHORIZED | Clé API manquante ou invalide |
| 401 | API_KEY_REVOKED | Cette clé API a été révoquée. Utilisez une autre clé. |
| 402 | INSUFFICIENT_BALANCE | Solde du compte insuffisant |
| 402 | PAYMENT_REQUIRED | Le compte n’a pas encore effectué sa première recharge. Les clés de production sont bloquées jusque-là, sauf quelques lectures de compte et de tarifs ; les clés de test ne sont pas concernées. |
| 403 | FORBIDDEN | La clé API n’a pas la permission requise, skip_consent_check a été envoyé avec une clé de production, le compte est suspendu ou fermé (voir details.reason), ou l’identifiant dans le chemin appartient à un autre compte |
| 403 | LIVE_KEY_REQUIRED | Une clé de test a été utilisée pour une action réservée aux clés de production. |
| 403 | PERMISSION_ESCALATION | Une clé nouvelle ou renouvelée a demandé des permissions plus étendues que celles de l’appelant, sans confirmation par mot de passe. |
| 403 | KEY_FENCED | Cette clé est restreinte par ses propres listes d’autorisation ou de blocage ou par le refus par défaut ; elle ne peut donc pas modifier ces listes ni les groupes et contacts qu’elles incluent, changer les réglages de listes d’une clé, créer de clés, ni renouveler une autre clé qu’elle-même. |
| 403 | ACCOUNT_NOT_VERIFIED | Le compte n’a pas encore vérifié de numéro de téléphone propriétaire, requis avant un envoi réel. |
| 403 | SENDING_PAUSED | L’envoi réel est suspendu sur ce compte (les détails indiquent la reprise et la raison) |
| 404 | NOT_FOUND | Aucune ressource ne correspond à l’identifiant donné. |
| 409 | DEAD_LETTER_ALREADY_REPLAYED | Cet événement a déjà été rejoué, ou un rejeu est en cours. Rien n’a été envoyé, et réessayer n’y changera rien. |
| 409 | CONFLICT | Une ressource avec cet identifiant existe déjà, ou le renouvellement d’une clé a échoué parce qu’elle était déjà révoquée, est une clé de session, ou qu’une autre requête l’a renouvelée en premier |
| 422 | VALIDATION_ERROR | Échec de la validation du corps ou de la requête (voir details) |
| 422 | WEBHOOK_LIMIT_REACHED | Limite de 10 points de terminaison webhook par compte atteinte. Supprimez-en un avant d’en enregistrer un autre |
| 429 | RATE_LIMITED | Trop de requêtes. Veuillez ralentir |
| 500 | INTERNAL_ERROR | Une erreur serveur inattendue s’est produite. Réessayez |
| 502 | WEBHOOK_REPLAY_FAILED | Le point de terminaison n’a pas accepté le rejeu. L’évènement reste dans la file des lettres mortes |
| 503 | SERVICE_UNAVAILABLE | Les nouvelles inscriptions sont temporairement désactivées (POST /v1/accounts), ou la vérification téléphonique est temporairement indisponible (POST /v1/accounts/:id/phone-verification). Réessayez plus tard |
Les codes propres à un produit sont sur sa propre page : codes d’erreur SMS et codes d’erreur du courriel.
HonkIO