Notify
Notify
Envoyez une notification à l'un de vos utilisateurs et laissez HonkIO choisir le canal : il essaie le push, le SMS et le courriel dans l'ordre et s'arrête au premier qui livre.
Démarrage rapide
Notify envoie une notification à l'un de vos utilisateurs et choisit le canal. Vous gardez un profil de destinataire pour chaque utilisateur, puis vous appelez l'API avec son identifiant et le texte. HonkIO essaie les canaux dans l'ordre et s'arrête au premier qui livre. Commencez avec une clé de test : chaque canal fonctionne dans son propre mode test.
- Enregistrez les coordonnées de la personne avec
PUT /v1/recipients/:user_id: un numéro de téléphone, une adresse courriel et une langue, selon ce que vous avez. - Envoyez avec
POST /v1/notify: leuser_idet untext(et unsubjectquand un courriel peut être essayé), ou untemplate. - Indiquez vos expéditeurs avec
from.smsetfrom.email. Un canal qui pourrait joindre la personne mais n'a pas d'expéditeur est refusé avec 422NOTIFY_SENDER_REQUIRED. - Lisez le résultat dans la réponse 202, avec
GET /v1/notifications/:idou par les webhooksnotification.deliveredetnotification.failed.
Les coordonnées se trouvent dans les profils de destinataires. Un utilisateur sans profil peut tout de même être joint par push s'il a un appareil actif.
const { data: notification, error } = await honkio.notify.send({
userId: 'user_1042',
text: 'Your Acme code is 123456',
subject: 'Your Acme code',
from: { sms: '+1416XXXXXXX', email: 'hello@yourapp.ca' },
}, { idempotencyKey: 'login-code-1042-2026-11-03' })
if (error) throw new Error(error.message)
console.log(notification.id, notification.status, notification.channel)from honkio import Honkio
client = Honkio() # reads HONKIO_API_KEY
notification = client.notify.send(
user_id="user_1042",
text="Your Acme code is 123456",
subject="Your Acme code",
from_={"sms": "+1416XXXXXXX", "email": "hello@yourapp.ca"},
idempotency_key="login-code-1042-2026-11-03",
)
print(notification["id"], notification["status"], notification["channel"])<?php
use Honkio\Honkio;
$honkio = new Honkio(); // reads HONKIO_API_KEY
$notification = $honkio->notify->send([
'user_id' => 'user_1042',
'text' => 'Your Acme code is 123456',
'subject' => 'Your Acme code',
'from' => ['sms' => '+1416XXXXXXX', 'email' => 'hello@yourapp.ca'],
], 'login-code-1042-2026-11-03');
echo $notification['id'], ' ', $notification['status'], ' ', $notification['channel'], PHP_EOL;<?php
use Honkio\Laravel\Facades\Honkio;
// In a controller, a job or a listener:
$notification = Honkio::notify()->send([
'user_id' => (string) $user->id,
'text' => 'Your Acme code is 123456',
'subject' => 'Your Acme code',
'from' => ['sms' => '+1416XXXXXXX', 'email' => 'hello@yourapp.ca'],
], 'login-code-' . $user->id . '-2026-11-03');curl -X POST https://api.honkio.ca/v1/notify \
-H "Authorization: Bearer mk_test_YOUR_KEY" \
-H "Idempotency-Key: login-code-1042-2026-11-03" \
-H "Content-Type: application/json" \
-d '{
"user_id": "user_1042",
"text": "Your Acme code is 123456",
"subject": "Your Acme code",
"from": { "sms": "+1416XXXXXXX", "email": "hello@yourapp.ca" }
}'
# Response 202: { "id": "ntf_...", "status": "delivered", "channel": "sms", "attempts": [...], ... }Canaux et ordre
Par défaut, Notify essaie le push, puis le SMS, puis le courriel, chacun au plus une fois. Définissez channels pour changer l'ordre ou écarter un canal.
Un canal est ignoré, avec une raison sur la tentative, quand la personne ne peut pas y être jointe (pas de numéro, pas de courriel, pas d'appareil actif), quand il est désactivé pour le compte ou, dans l'ordre par défaut, quand la clé n'a pas le droit d'y envoyer. Un canal que vous nommez et où la clé ne peut pas envoyer donne 403 FORBIDDEN. Les coordonnées sont lues à l'envoi : un canal où la personne ne pouvait pas être jointe à ce moment est ignoré, même si un numéro, une adresse ou un appareil est ajouté avant son tour.
Un SMS ou un courriel que son canal refuse passe au canal suivant, exactement là où /v1/messages ou /v1/emails l'auraient refusé : pas de consentement, un désabonnement, une suppression, une limite d'envoi, une pause ou un solde trop bas. Un profil de destinataire n'est jamais un consentement.
text est le SMS, le corps du push et le texte brut du courriel. subject et html précisent le courriel. Ou envoyez un template avec variables et chaque canal envoie sa propre partie, dans la langue du profil sauf si vous passez language. Voir Modèles.
const { data: notification, error } = await honkio.notify.send({
userId: 'user_1042',
template: 'order-shipped',
variables: { orderId: '5521' },
channels: ['sms', 'email'], // the order to try
from: { sms: '+1416XXXXXXX', email: 'hello@yourapp.ca' },
}, { idempotencyKey: 'order-5521-shipped' })
if (error) throw new Error(error.message)
for (const attempt of notification.attempts) console.log(attempt.channel, attempt.outcome, attempt.reason)from honkio import Honkio
client = Honkio() # reads HONKIO_API_KEY
notification = client.notify.send(
user_id="user_1042",
template="order-shipped",
variables={"orderId": "5521"},
channels=["sms", "email"], # the order to try
from_={"sms": "+1416XXXXXXX", "email": "hello@yourapp.ca"},
idempotency_key="order-5521-shipped",
)
for attempt in notification["attempts"]:
print(attempt["channel"], attempt["outcome"], attempt["reason"])<?php
use Honkio\Honkio;
$honkio = new Honkio(); // reads HONKIO_API_KEY
$notification = $honkio->notify->send([
'user_id' => 'user_1042',
'template' => 'order-shipped',
'variables' => ['orderId' => '5521'],
'channels' => ['sms', 'email'], // the order to try
'from' => ['sms' => '+1416XXXXXXX', 'email' => 'hello@yourapp.ca'],
], 'order-5521-shipped');
foreach ($notification['attempts'] as $attempt) {
echo $attempt['channel'], ' ', $attempt['outcome'], ' ', $attempt['reason'] ?? '', PHP_EOL;
}Les notifications servent aux codes, rappels, reçus et alertes. is_commercial vaut false par défaut. Ne le mettez à true que pour un courriel qui fait la promotion de quelque chose : il exige un consentement LCAP au dossier et ajoute le pied de page de désabonnement. Un SMS garde ses propres règles de consentement.
Ce que veut dire livrée
Une notification est livrée quand un canal l'accepte : un push qu'au moins un appareil (un téléphone ou un navigateur) a accepté, un SMS que l'opérateur a accepté ou un courriel que le service de courriel a accepté. Elle s'arrête là.
Un échec signalé après coup ne passe pas à un autre canal : un accusé de réception indiquant que le SMS n'est pas arrivé, un rebond ou une plainte. Accepté ne veut pas dire vu, et Notify n'envoie jamais deux fois la même notification pour compenser.
Un push qu'aucun appareil n'accepte passe au canal suivant après une attente d'au plus une minute, comme un push avec un SMS de repli. La notification est en attente pendant l'envoi d'un push ou d'un courriel. Un SMS que l'opérateur refuse, ou un courriel que le service de courriel refuse tout de suite, passe au canal suivant, et ce qui avait été facturé est remboursé.
Un canal sans verdict pendant une heure fait échouer la notification, avec la raison NOTIFY_STUCK sur ce canal et notify_stuck sur les canaux ignorés après lui. Un courriel encore en file (une pause, le plafond quotidien) est laissé à terminer, et s'il échoue ensuite aucun autre canal n'est essayé.
Un SMS dont l'appel à l'opérateur a expiré compte comme livré : l'opérateur l'a peut-être pris, donc aucun autre canal n'est essayé.
Envoyez un en-tête Idempotency-Key. La même clé renvoie la première notification, en attente ou non, sans jamais envoyer ni facturer deux fois. La même clé avec un corps différent donne 409 IDEMPOTENCY_KEY_REUSED.
Chaque notification liste ses tentatives dans l'ordre. Chacune a un canal, un résultat (delivered, pending, skipped, refused ou failed) et une raison s'il y en a une : l'une des raisons en minuscules ci-dessous, ou le code d'erreur du canal, comme NO_CONSENT, OPT_OUT_BLOCKED ou EMAIL_SUPPRESSED.
| no_active_device | La personne n'a aucun appareil push actif. |
| no_push_app | Le compte n'a aucune application push pour envoyer. |
| no_phone_number | Le profil n'a pas de numéro de téléphone. |
| no_email | Le profil n'a pas d'adresse courriel. |
| no_sender | Le canal n'avait pas d'expéditeur. |
| push_unavailable | Le canal est désactivé pour le compte. |
| push_disabled | Le canal est désactivé pour le compte. |
| email_unavailable | Le canal est désactivé pour le compte. |
| not_permitted | La clé n'a pas le droit d'envoyer sur ce canal. |
| template_channel_missing | Le modèle n'a pas de partie pour ce canal. |
| content_purged | Le texte de la notification a été effacé avant que ce canal soit essayé. |
| NOTIFY_STUCK | Un canal n'a pas eu de verdict en une heure. |
| notify_stuck | Ignoré parce qu'un canal précédent était bloqué. |
Tarification
Notify est inclus sans frais supplémentaires. Une notification est facturée au prix normal du canal qui la livre, et les tentatives qui passent au canal suivant ne sont pas facturées.
Un SMS ou un courriel refusé peut tout de même laisser un message ou un courriel en échec dans vos journaux, et déclencher son propre événement, comme le ferait le même envoi par /v1/messages ou /v1/emails.
Erreurs
Les refus reviennent dans le corps d'erreur habituel. Ces codes appartiennent à Notify; les autres sont dans la référence des erreurs.
| HTTP | Code | Signification |
|---|---|---|
| 501 | NOTIFY_COMING_SOON | Notify n'est pas encore activé pour la plateforme. |
| 404 | RECIPIENT_NOT_FOUND | Aucun profil avec ce user_id dans le mode de la clé, et aucun appareil push actif pour lui. |
| 422 | NOTIFY_SENDER_REQUIRED | Un canal qui peut joindre la personne n'a pas d'expéditeur. details.channel le nomme. |
| 422 | NOTIFY_CONTENT_REQUIRED | Rien à envoyer : indiquez text (et un subject pour le courriel), ou un template. details.field indique ce qui manque. |
| 422 | TEMPLATE_CHANNEL_MISSING | Le modèle n'a pas de partie pour un canal que vous avez nommé, ni pour aucun canal pouvant être essayé. |
| 422 | NOTIFY_CONTENT_TOO_LARGE | Ce que la notification enverrait sur les canaux qui peuvent joindre la personne, une fois rendu, dépasse 2 Mo. details.bytes et details.limit indiquent les tailles. |
| 409 | RECIPIENT_LIMIT_REACHED | Le compte a déjà son maximum de profils dans ce mode : 1 000 000 en direct, 1 000 en test. details.limit l'indique. |
| 409 | IDEMPOTENCY_KEY_REUSED | L'Idempotency-Key a servi pour une autre notification. |
| 403 | FORBIDDEN | La clé n'a pas notifications en écriture ou recipients en lecture, ou ne peut envoyer sur aucun canal, ou sur un canal nommé. |
Webhooks
notification.delivered survient quand un canal a livré la notification et notification.failed quand aucun ne l'a fait. Les deux portent la notification dans data, sans le texte du message.
Les données sont id, user_id, status, channel (celui qui a livré), message_id, email_id, push_id (tant que le push est actif), attempts (chacune avec canal, résultat et raison) et l'indicateur livemode, comme dans l'enveloppe.
Le SMS, le courriel ou le push derrière une notification déclenche aussi ses propres événements. Abonnez-vous aux événements de notification quand vous voulez une seule réponse par notification.
HonkIO