TL;DR, Réponse Rapide
8 min de lectureMastodon documente scheduled_at comme devant se situer au moins 5 minutes dans le futur, et la source l'appuie avec MINIMUM_OFFSET = 5.minutes dans ScheduledStatus. Tout ce qui est plus proche renvoie un HTTP 422 avec une erreur de validation. Un horodatage dans le passé se comporte autrement : PostStatusService l'écarte et publie le statut immédiatement. Deux autres limites, 300 statuts programmés au total et 25 par jour, n'apparaissent que dans la source.
Quel est le décalage minimum de scheduled_at sur l'API Mastodon ?
Toute valeur scheduled_at de l'API Mastodon doit tomber plus de 5 minutes après l'horloge du serveur, sinon POST /api/v1/statuses rejette la requête avec un HTTP 422. La documentation form-data de ce point de terminaison le dit en une ligne : « Datetime at which to schedule a status. Providing this parameter will cause ScheduledStatus to be returned instead of Status. Must be at least 5 minutes in the future. »
Le point de terminaison de mise à jour répète la règle avec des mots un peu différents. PUT /api/v1/scheduled_statuses/:id documente son propre scheduled_at comme « Datetime at which the status will be published. Must be at least 5 minutes into the future », déplacer une publication déjà programmée plus près que cinq minutes échoue donc de la même façon que d'en créer une.
Le nombre n'est pas une convention de documentation. C'est une constante du modèle, MINIMUM_OFFSET = 5.minutes.freeze dans app/models/scheduled_status.rb, et la validation qui l'utilise se lit ainsi :
def validate_future_date
errors.add(:scheduled_at, I18n.t('scheduled_statuses.too_soon')) if scheduled_at.present? && scheduled_at <= Time.now.utc + MINIMUM_OFFSET
endLa comparaison est <=, un horodatage exactement à 5 minutes échoue donc. « At least 5 minutes » dans la documentation veut dire strictement plus de 5 minutes dans le code.
Que renvoie l'API quand l'heure est trop proche ?
Un 422 avec un message de validation dans le champ error. La gestion des erreurs de l'API Mastodon transforme l'exception Rails directement en JSON :
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
render json: { error: e.to_s }, status: 422
endCe concern vit dans app/controllers/concerns/api/error_handling.rb et il est inclus par Api::BaseController, le corps est donc la chaîne de l'exception elle-même plutôt qu'un code lisible par une machine. Il n'y a ni code d'erreur, ni liste de champs, ni indication de retry-after ; l'analyser revient à faire correspondre du texte anglais.
Pourquoi la chaîne d'erreur documentée diffère-t-elle de celle qu'envoient les serveurs ?
Parce que la chaîne de traduction a changé et pas l'exemple de la documentation. La page scheduled_statuses montre ce corps 422 pour le point de terminaison de mise à jour :
{
"error": "Validation failed: Scheduled at The scheduled date must be in the future"
}Le config/locales/en.yml actuel sur la branche main de mastodon/mastodon porte une formule plus courte :
scheduled_statuses:
over_daily_limit: You have exceeded the limit of %{limit} scheduled posts for today
over_total_limit: You have exceeded the limit of %{limit} scheduled posts
too_soon: date must be in the futureRails préfixe le nom d'attribut humanisé, un serveur à jour produit donc « Validation failed: Scheduled at date must be in the future ». L'exemple documenté porte encore l'ancienne formulation « The scheduled date must be in the future ».
| Source | Chaîne |
|---|---|
| docs.joinmastodon.org, exemple 422 de scheduled_statuses | « Validation failed: Scheduled at The scheduled date must be in the future » |
config/locales/en.yml, branche main | « Validation failed: Scheduled at date must be in the future » |
Tout client qui fait correspondre la phrase documentée à l'identique ratera l'erreur sur un serveur à jour. Faites plutôt correspondre le statut 422 et la présence de scheduled_at dans votre propre requête plutôt que la phrase.

Que se passe-t-il si scheduled_at est dans le passé ?
La publication part immédiatement, et aucune erreur n'est levée. C'est le comportement que la documentation ne mentionne jamais, et il vit dans PostStatusService :
@scheduled_at = @options[:scheduled_at]&.to_datetime
@scheduled_at = nil if scheduled_in_the_past?avec
def scheduled_in_the_past?
@scheduled_at.present? && @scheduled_at <= Time.now.utc
endMettre @scheduled_at à nil rend scheduled? faux, ce qui route la requête par process_status! plutôt que par schedule_status!. La réponse est une entité Status, pas un ScheduledStatus, un client qui suppose que scheduled_at donne toujours un ScheduledStatus lira donc un id manquant pour une publication déjà publique.
Trois issues, un seul paramètre :
AdaptlyPost
Commencez votre essai gratuit de 7 jours
Analyses multiplateforme
Boîte sociale
Assistant IA
Valeur de scheduled_at | Résultat | Réponse |
|---|---|---|
| Dans le passé, ou exactement maintenant | Publié immédiatement | Status |
| À moins de 5 minutes de maintenant | Rejeté | 422, erreur de validation |
| À plus de 5 minutes d'avance | Mis en file | ScheduledStatus |
La bande du milieu est le piège. Une boucle de reprise qui repousse un envoi raté « de deux ou trois minutes » tombe sur le 422 ; celle qui se rabat sur « publie-le tout de suite » en envoyant un horodatage passé obtient une publication en ligne au lieu de l'erreur qu'elle attendait.
- Tombe dans la zone des 5 minutes
- Le serveur répond 422
- Envoie un horodatage dans le passé
- PostStatusService abandonne scheduled_at
- Le statut est publié immédiatement
Combien de statuts programmés un compte peut-il conserver ?
Deux autres limites siègent à côté du décalage dans le même modèle, et aucune des deux n'apparaît dans la documentation de l'API :
TOTAL_LIMIT = 300
DAILY_LIMIT = 25
MINIMUM_OFFSET = 5.minutes.freezeTOTAL_LIMIT plafonne le nombre de statuts programmés qu'un compte peut garder en file à un instant donné, et le message est « You have exceeded the limit of 300 scheduled posts ». DAILY_LIMIT plafonne combien peuvent partager une même date calendaire, validé avec scheduled_at::date = ?::date contre la base de données, et le message est « You have exceeded the limit of 25 scheduled posts for today ».
Les deux arrivent sous la même forme 422, avec le message porté par base plutôt que par scheduled_at. Une file qui charge un mois de publications en une seule passe heurtera le mur des 25 par jour bien avant les 300 au total, et rien sur docs.joinmastodon.org n'avertit de l'un ni de l'autre.
Quel format prend scheduled_at ?
Un datetime RFC 3339, que Mastodon documente séparément comme son format de date : [YYYY]-[MM]-[DD]T[hh]:[mm]:[ss].[s][TZD], où le désignateur de fuseau est soit Z pour UTC, soit un décalage comme +02:00. La documentation est explicite sur deux points : le séparateur est un T majuscule et le Z est toujours en majuscule.
La validation compare avec Time.now.utc sur le serveur, pas sur le client. La dérive d'horloge du client mange donc directement la marge de cinq minutes, ce qui est une bonne raison de programmer à six ou sept minutes plutôt qu'à cinq minutes et une seconde. Le même mode d'échec apparaît chaque fois qu'une file fait confiance à l'heure locale, comme c'est le cas entre Mastodon et Bluesky et sur toute autre API qui valide contre sa propre horloge.

Comment modifier ou annuler un statut programmé ?
Trois points de terminaison gèrent la file après la création. GET /api/v1/scheduled_statuses les liste, avec 20 résultats par défaut et un maximum de 40. PUT /api/v1/scheduled_statuses/:id prend un nouveau scheduled_at, soumis à la même règle des 5 minutes. DELETE /api/v1/scheduled_statuses/:id en annule un et renvoie un objet vide.
Changer le texte est une autre opération. Mastodon note que PUT /api/v1/statuses/:id modifie un statut publié, et que « To edit the scheduled_at attribute of a ScheduledStatus to change the publication date, use the scheduled status endpoint. » Le contenu d'une publication en file vit dans l'objet params de l'entité ScheduledStatus et le point de terminaison de mise à jour n'accepte que la date, changer la formulation revient donc à supprimer puis recréer.
Un statut en file qui n'existe plus renvoie un 404 avec {"error": "Record not found"}, ce que renvoie aussi un statut programmé appartenant à un autre compte.
Que signifie le plancher de 5 minutes pour une file de publication ?
Il fixe le plus court écart utile entre « décider de publier » et « publier ». Tout ce qui passe sous cinq minutes doit partir comme statut immédiat plutôt que comme statut programmé, un planificateur a donc besoin d'un embranchement et non d'un seul chemin de code : sous le seuil, on retire scheduled_at et on publie ; au-dessus, on met en file et on stocke l'id ScheduledStatus renvoyé.
Deux autres nombres appartiennent à la même passe de planification. La longueur de publication par défaut de Mastodon est de 500 caractères, traitée dans la limite de caractères de Mastodon, et la limitation de débit propre à chaque serveur se pose par-dessus tout cela, de la même façon que Bluesky publie ses propres limites de débit d'API séparément de ses règles de publication. Construire le calendrier autour du plancher de la plateforme plutôt qu'autour des préférences d'un outil est l'habitude générale derrière la programmation fiable de publications sur les réseaux sociaux.
Une réserve couvre tous les nombres ci-dessus. Les constantes viennent de la branche main de mastodon/mastodon, et un serveur qui fait tourner un fork ou une version plus ancienne peut porter d'autres valeurs, lisez donc le corps du 422 plutôt que de supposer que 5, 25 et 300 tiennent partout.
Questions fréquentes
scheduled_at accepte-t-il une heure exactement à 5 minutes d'ici ?
Non. La validation compare avec <=, donc scheduled_at <= Time.now.utc + 5.minutes échoue. La formule documentée « at least 5 minutes in the future » veut dire strictement plus de cinq minutes une fois la source lue.
Quel statut HTTP Mastodon renvoie-t-il pour un scheduled_at trop proche ?
- Mastodon rattrape
ActiveRecord::RecordInvalidet rend{ error: e.to_s }avec le statut 422, le corps est donc une phrase de validation en anglais courant plutôt qu'un objet d'erreur structuré.
Quelle version de Mastodon a ajouté scheduled_at ?
2.7.0. L'historique des versions sur la documentation de POST /api/v1/statuses liste « 2.7.0 - scheduled_at added », et les trois points de terminaison scheduled_statuses sont arrivés dans la même version.
AdaptlyPost
Commencez votre essai gratuit de 7 jours
Analyses multiplateforme
Boîte sociale
Assistant IA
Une publication programmée renvoie-t-elle un Status ou un ScheduledStatus ?
Un ScheduledStatus, dès que scheduled_at est accepté. Mastodon indique que le point de terminaison « Returns: Status. When scheduled_at is present, ScheduledStatus is returned instead. » L'horodatage passé fait exception, car le serveur écarte le paramètre et publie immédiatement, en renvoyant un Status.
Peut-on programmer plus de 25 publications Mastodon pour le même jour ?
Pas sur un serveur par défaut. DAILY_LIMIT = 25 dans app/models/scheduled_status.rb compte les statuts programmés existants qui partagent la même date et rejette le vingt-sixième avec « You have exceeded the limit of 25 scheduled posts for today ». Un TOTAL_LIMIT = 300 distinct plafonne toute la file. Aucun de ces deux nombres n'apparaît dans la documentation de l'API.
Où le minimum de 5 minutes est-il documenté ?
Sur la page des méthodes statuses à docs.joinmastodon.org/methods/statuses/, dans le paramètre form-data scheduled_at, et de nouveau sur docs.joinmastodon.org/methods/scheduled_statuses/ pour le point de terminaison de mise à jour. La constante derrière est MINIMUM_OFFSET = 5.minutes.freeze dans app/models/scheduled_status.rb du dépôt mastodon/mastodon.
Combien de résultats GET /api/v1/scheduled_statuses renvoie-t-il par défaut ?
Vingt. L'endpoint renvoie 20 statuts programmés par page par défaut, avec un maximum de 40, donc un compte proche de la limite totale de 300 a besoin de plusieurs requêtes pour parcourir toute sa file.
Que se passe-t-il si tu consultes un statut programmé déjà annulé ?
Le serveur répond 404 avec {"error": "Record not found"}. C'est la même réponse que pour un statut programmé appartenant à un autre compte, donc un 404 ici ne distingue pas entre "n'a jamais existé", "déjà annulé" et "n'est pas à toi".
Peut-on modifier le texte d'un statut Mastodon programmé ?
Modifier le texte revient à supprimer le statut programmé et à en créer un nouveau, pas à le modifier sur place. L'endpoint de mise à jour n'accepte qu'un nouveau scheduled_at, et le contenu d'un statut en attente vit dans l'objet params de l'entité ScheduledStatus.
Combien de temps à l'avance faut-il vraiment programmer un statut Mastodon ?
Plus de cinq minutes, et six ou sept minutes sont plus sûres que cinq minutes et une seconde. La validation se fait contre l'horloge du serveur, pas celle du client, donc toute dérive de l'heure locale ronge directement cette marge.
Mettez cela en pratique avec AdaptlyPost
Cet article vous a-t-il été utile ?
Dites-nous ce que vous en pensez !
Nous voir plus souvent sur Google
Un clic définit AdaptlyPost comme source préférée. Nos articles remontent alors dans vos À la une, en mode IA et dans les aperçus IA.
Avant de partir...
AdaptlyPost
Planifiez vos contenus sur toutes les plateformes
Gérez tous vos comptes de réseaux sociaux en un seul endroit avec AdaptlyPost.
Analyses multiplateforme
Boîte sociale
Assistant IA
Termes connexes du glossaire


Ce que renvoie l'endpoint content_publishing_limit d'Instagram
L'endpoint content_publishing_limit d'Instagram renvoie quota_usage plus un bloc config contenant quota_total à 50 et quota_duration à 86400 secondes.


Le long lived access token Facebook et son horloge de 60 jours
Un long lived access token Facebook dure environ 60 jours, et le jeton de Page que vous en dérivez n'a aucune date d'expiration. Avec l'appel d'échange.


Lire le status_code du conteneur Instagram avant de publier
Toutes les valeurs du status_code du conteneur Instagram que documente Meta, la cadence de sondage conseillée, la fenêtre de 24 heures et quoi faire sur ERROR.
Articles Connexes


Pourquoi un jeton d'accès LinkedIn expire au bout de 60 jours
Les 60 jours de tout jeton d'accès LinkedIn, le 5184000 que renvoie expires_in, les règles du refresh token et ce qui tue un jeton plus tôt.


Comment fonctionne la limite de 250 posts par jour de l'API Threads
Meta applique la limite de 250 posts par jour de l'API Threads en fenêtre mobile de 24 heures. Un carrousel compte une fois et un endpoint dit ce qui reste.


Pourquoi chunk_size de l'API TikTok et total_chunk_count doivent tomber juste
Quatre règles encadrent le chunk_size de l'API TikTok : plancher de 5 Mo, plafond de 64 Mo, dernier morceau à 128 Mo, total_chunk_count arrondi à l'inférieur.

