Aller au contenu
Échap
  • Tapez ce que vous cherchez avec vos mots : « Slack », « 503 », « prix ».

Battement de cœur

Surveiller ce qui tourne sans page — un cron, un worker, une sauvegarde — par l'absence d'appel.

Mis à jour le 11 septembre 2026

Sur cette page

Tout ce qui tourne sans page : un cron de sauvegarde, un worker qui vide une file, un script de facturation nocturne. Aucune URL à vérifier — et quand ça s'arrête, rien ne le dit. Le site répond 200, la sauvegarde n'a pas tourné depuis trois semaines. Le battement de cœur inverse la logique : c'est votre script qui appelle PostShip à la fin de chaque passage, et c'est l'absence d'appel qui déclenche l'alerte.

Ce que PostShip fait

Un battement est une cible sans URL à demander. PostShip fabrique une adresse secrète de la forme https://postship.fr/api/heartbeat/<jeton>, et attend qu'elle soit appelée :

  • en GET ou en POST, indifféremment — un curl en fin de script est un GET, un webhook d'outil est un POST ;
  • le corps est ignoré ; tout ce qui compte est « on nous a appelés, et quand » ;
  • la réponse est OK, en texte, statut 200. Un jeton inconnu ou désactivé répond 404 « Jeton inconnu. » — les deux se répondent pareil, pour qu'un jeton désactivé ne révèle pas qu'il a existé.

À chaque cycle du projet (toutes les 30 minutes sur Free, 5 minutes sur Pro et Team), PostShip relit la date du dernier appel et la compare à l'intervalle promis, avec une marge d'un quart d'intervalle, plafonnée à une heure : un cron horaire qui appelle à 10:00:00 puis 11:00:04 ne doit pas alerter à 11:00:01. Assez pour absorber un démarrage lent, pas assez pour laisser passer une exécution manquée.

Le premier passage. Un battement qui n'a encore jamais été appelé n'est pas en panne — le script n'est peut-être pas encore déployé. Il passe pendant un intervalle plein (plus sa marge) à compter de sa création, puis échoue : au bout de ce délai, « jamais appelé » est un vrai silence.

Le jeton est le seul secret, et il vaut ce qu'il vaut : quelqu'un qui l'a peut faire croire qu'un cron tourne. C'est le modèle de Healthchecks.io et Cronitor, et c'est acceptable parce que le pire effet est un silence — pas un accès à quoi que ce soit.

Régler

Projet → URLs → « Ajouter un battement » :

  1. Nom : « sauvegarde nocturne », 80 caractères au plus.
  2. Attendu : toutes les 5 minutes, 15 minutes, toutes les heures, toutes les 6 heures, tous les jours (par défaut), toutes les semaines. Une liste et non un champ libre : ces six valeurs couvrent les crons réels, et un intervalle de 37 minutes est presque toujours une faute de frappe.
  3. « Créer le battement ». L'adresse à appeler est sur la page de la cible, panneau « Battement de cœur », avec le délai attendu, le dernier appel, et deux boutons « Copier » — l'adresse seule, ou la ligne curl prête à coller.

Puis, à la fin de votre script :

À la fin du script
curl -fsS https://postship.fr/api/heartbeat/VOTRE_JETON > /dev/null

-fsS : un échec de l'appel lui-même se voit dans les journaux du cron, sans bruit quand tout va bien. Appelez après le travail, pas avant : un appel en début de script dirait « ça tourne » d'une sauvegarde qui échoue à la deuxième ligne.

Désactiver un battement (menu de la cible) fait ignorer les appels et n'envoie aucune alerte — pour une maintenance, ou un cron retiré.

Ce qui déclenche une alerte

CodePhrase de l'écranPhrase de l'alerte
heartbeat_lateLe script n'a pas appelé PostShip dans le délai prévu.Le battement de cœur n'est plus reçu — sauvegarde nocturne
heartbeat_neverLe script n'a jamais appelé PostShip depuis la création de ce battement.Le battement de cœur n'a jamais été reçu — sauvegarde nocturne

Le détail du passage donne le retard en minutes. L'alerte part au franchissement du délai — après la confirmation du projet, qui compte ici en cycles — et une seule fois par silence ; « Rétabli » suit le prochain appel reçu. Un battement en retard ouvre un incident comme n'importe quelle cible.

Limites et plans

Disponible sur tous les plans. Un battement compte pour une URL du quota (Free 3, Pro 15, Team 50) : c'est une cible que vous demandez. Le verdict est relu à chaque cycle du projet : un silence est donc constaté avec au plus 30 minutes de retard sur Free, 5 minutes sur Pro et Team.

IntervalleMargeAlerte au plus tôt après le dernier appel
5 min1 min 156 min 15
1 h15 min1 h 15
6 h1 h7 h
1 jour1 h25 h
1 semaine1 h7 jours et 1 h

Dépannage

Pourquoi l'alerte n'est pas partie alors que le cron a sauté une exécution ?

Regardez la marge : un cron toutes les 5 minutes a 1 min 15 de marge, et le verdict n'est relu qu'au cycle du projet — 5 minutes sur Pro et Team, 30 sur Free. Un retard de trois minutes peut donc passer entre deux cycles, et sur Free un battement de 5 minutes n'a pas de sens : choisissez un intervalle d'au moins une heure.

Mon script appelle l'adresse mais le panneau dit « jamais »

L'appel n'a pas atteint PostShip : curl sans -f masque un 404, une variable d'environnement vide donne une adresse tronquée, un pare-feu sortant bloque postship.fr. Lancez la ligne à la main et lisez la réponse : elle doit être OK.

Puis-je changer l'intervalle ?

Supprimez le battement et recréez-le avec le bon intervalle : le jeton change, mettez à jour votre script. L'ancien jeton répond 404 immédiatement.