API Bluesky et programmation : publier par le code
Bluesky n'a pas de programmation. L'API écrit un post dès que tu appelles com.atproto.repo.createRecord, et le schéma de l'enregistrement ne définit aucun champ pour le retenir. Pour programmer, tu fais tourner ta propre file d'attente ou tu passes par un outil qui garde le post pour toi. Chaque endpoint, limite et prix ci-dessous a été vérifié sur les sources officielles le 17 septembre 2026.
Peut-on programmer des posts sur Bluesky ?
Pas via le protocole. Le schéma d'enregistrement d'un post exige exactement deux champs, text et createdAt, et les champs optionnels actuels sont langs, facets, embed, reply, labels et tags. Il n'y a pas de publishAt ni de scheduledFor. L'API séparée app.bsky.draft ne fait que stocker des brouillons en privé, sans heure de publication. createdAt est un horodatage que tu écris toi-même, et en mettre un dans le futur ne met rien en file d'attente : l'enregistrement est dans ton dépôt et sur le réseau dès que l'écriture réussit.
Le guide sur les horodatages de Bluesky indique que son propre App View trie un post dont le createdAt est dans le futur selon l'heure à laquelle le serveur l'a indexé, dans les fils d'auteur, les fils de réponses et les autres fils chronologiques. Programmer sur Bluesky, c'est donc toujours quelqu'un qui retient le post jusqu'à ce qu'une horloge donne le top. Soit ton cron, soit celui d'un prestataire.
L'API Bluesky en cinq minutes
Deux appels. Crée un mot de passe d'application dans les paramètres, n'utilise jamais le mot de passe de ton compte, puis échange-le contre une session.
curl -X POST https://bsky.social/xrpc/com.atproto.server.createSession \
-H "Content-Type: application/json" \
-d '{"identifier": "you.bsky.social", "password": "xxxx-xxxx-xxxx-xxxx"}'
La réponse contient accessJwt (courte durée de vie) et refreshJwt. Ensuite, écris l'enregistrement :
curl -X POST https://bsky.social/xrpc/com.atproto.repo.createRecord \
-H "Authorization: Bearer $ACCESS_JWT" \
-H "Content-Type: application/json" \
-d '{
"repo": "you.bsky.social",
"collection": "app.bsky.feed.post",
"record": {
"$type": "app.bsky.feed.post",
"text": "Posted from a cron job.",
"createdAt": "2026-09-17T08:00:00.000Z",
"langs": ["en"]
}
}'
Tu récupères l'emplacement de l'enregistrement et son hash :
{
"uri": "at://did:plc:u5cwb2mwiv2bfq53cjufe6yn/app.bsky.feed.post/3k4duaz5vfs2b",
"cid": "bafyreibjifzpqj6o6wcq3hejh7y4z4z2vmiklkvykc57tw3pcbx3kxifpm"
}
C'est toute la surface de publication. Pas de revue d'app, pas de compte professionnel, pas de programme partenaire. Comparé à ce que demandent Instagram et TikTok, détaillé dans le guide des API de réseaux sociaux, Bluesky est de loin l'API la plus simple du secteur.
Ce qu'accepte un enregistrement de post Bluesky
D'après le lexicon, vérifié le 17 septembre 2026.
| Champ | Limite |
|---|---|
text |
300 graphèmes, 3 000 octets |
langs |
3 entrées |
tags |
8 entrées, 64 graphèmes chacune |
| Images par post | 4 avec app.bsky.embed.images ; le nouvel embed app.bsky.embed.gallery en autorise 20 dans le schéma, mais demande aux applis de s'en tenir à 10 pour l'instant |
| Taille des images | 2 000 000 octets chacune (contre 1 000 000 auparavant) |
| Upload de blob (limite serveur, sur la page des limites de débit) | 52 428 800 octets (50 Mo) |
Deux pièges. Les liens et les mentions ne sont pas extraits de ton texte : c'est à toi d'attacher les plages d'octets dans facets, sinon ton URL s'affiche en texte brut. Et 300, ce sont des graphèmes, pas des points de code : le len() de Python surcompte les drapeaux, les tons de peau et les emoji combinés (un emoji famille compte pour 7) et peut rejeter un post que Bluesky accepterait. Compte les graphèmes, et vérifie le plafond de 3 000 octets à part.
Limites de débit de l'API Bluesky
La page des limites de débit applique un budget de points aux écritures, en plus des plafonds de requêtes par IP.
| Limite | Valeur |
|---|---|
| Budget d'écriture | 5 000 points par heure, 35 000 points par jour |
| Coût d'une création | 3 points, soit 1 666 créations par heure |
| Coût d'une mise à jour / suppression | 2 points / 1 point |
| Requêtes API globales | 3 000 par tranche de 5 minutes, par IP |
createSession |
30 par tranche de 5 minutes, 300 par jour, par compte |
Pour un planificateur, c'est généreux au point de ne pas compter : une file de publication qui poste dix fois par jour consomme 30 points sur 35 000. Celui à surveiller, c'est createSession. Ne t'authentifie pas à chaque job. Mets la session en cache et rafraîchis-la, sinon une boucle de worker chargée atteindra les 30 en cinq minutes sans rien publier.
Le planifier toi-même
Le planificateur le moins cher, c'est une table et un cron. Stocke le texte, les médias et un publish_at, puis lance toutes les minutes :
import os, requests, datetime as dt
BASE = "https://bsky.social/xrpc"
def session():
r = requests.post(f"{BASE}/com.atproto.server.createSession", json={
"identifier": os.environ["BSKY_HANDLE"],
"password": os.environ["BSKY_APP_PASSWORD"],
})
r.raise_for_status()
return r.json()
def publish(s, text):
now = dt.datetime.now(dt.timezone.utc).isoformat().replace("+00:00", "Z")
r = requests.post(f"{BASE}/com.atproto.repo.createRecord",
headers={"Authorization": f"Bearer {s['accessJwt']}"},
json={"repo": s["did"], "collection": "app.bsky.feed.post",
"record": {"$type": "app.bsky.feed.post", "text": text, "createdAt": now}})
r.raise_for_status()
return r.json()["uri"]
Trois règles que j'ai apprises à mes dépens. Renseigne createdAt au moment de la publication, pas au moment de la mise en file : le guide des timestamps de Bluesky indique que son App View trie un post selon createdAt quand cette date est passée, donc un post horodaté une heure avant sa mise en ligne se retrouve classé une heure plus bas. Rends le job idempotent, une ligne, un verrou, sinon une nouvelle tentative publie le post en double. Et garde une trace de l'uri renvoyée, parce que c'est ta preuve que le post existe.
Les outils qui planifient Bluesky pour toi
Prix relevés sur la page tarifs de chaque éditeur le 17 septembre 2026.
| Outil | Prix | Bluesky | Hébergé | Idéal pour |
|---|---|---|---|---|
| Buffer | Offre gratuite : 3 canaux, 10 posts planifiés par canal. Essentials 5 $ par canal par mois, facturé à l'année, soit 60 $ par an | Oui | Oui | Une personne, quelques canaux |
| Postiz | 29 $ par mois pour 5 canaux, 49 $ pour 30, ou héberge toi-même la version open source | Oui | Les deux | Les équipes qui veulent pouvoir auto-héberger |
| Mixpost | Licence unique : Lite gratuite, Pro 299 $, Enterprise 1 199 $. Bluesky est inclus dans Pro | Oui | Auto-hébergé, plus Mixpost Cloud (pas de prix public) | Achète une fois, fais-le tourner sur ton propre serveur |
| Ayrshare | 149 $ par mois pour 1 profil, 299 $ pour 10, à partir de 599 $ pour 30 | Oui, valeur de plateforme bluesky |
Oui | Produits API-first qui revendent la publication |
| Blotato | 29 $ par mois pour 20 comptes, 97 $ pour 40 | Oui, indiqué sur sa page d'accueil | Oui | Workflows de contenu IA sur neuf réseaux |
| PlugKit | 29 $ par mois pour 5 comptes connectés, 97 $ pour 30 | Non | Oui | Agents sur Instagram, TikTok, LinkedIn, X, YouTube, Facebook, WhatsApp, Telegram |
| Ton propre cron | Coût du serveur uniquement | Oui | Auto-hébergé | Un compte, contrôle total, zéro abstraction |
Si Bluesky est le seul réseau sur lequel tu publies, aucun de ces outils ne vaut son prix. L'API, c'est un POST avec un bearer token, et la limite est de 1 666 créations par heure. Écris le cron.
Où PlugKit a sa place, et où il ne l'a pas
PlugKit ne prend pas en charge Bluesky, aujourd'hui. Les huit plateformes sont Instagram, Facebook, LinkedIn, TikTok, YouTube, X, WhatsApp et Telegram, listées sur plugkit.co ce matin. Si ta liste de comptes se résume à Bluesky et Mastodon, prends Buffer ou un script et arrête de lire ici.
Là où il mérite sa place, c'est dans le cas inverse : les API pénibles. La revue d'app de Meta, le scope Direct Post de TikTok, X facturé à l'appel. Une clé, un serveur MCP hébergé à https://api.plugkit.co/mcp, ajouté avec claude mcp add -t http plugkit https://api.plugkit.co/mcp, et ton agent publie sur Instagram, Facebook, LinkedIn, TikTok, YouTube, X et Telegram, lit les messages et y répond sur Instagram, Facebook, WhatsApp et Telegram, et répond aux commentaires et fait tourner des automatisations commentaire-vers-DM sur Instagram et Facebook. Ça fait 29 $ par mois pour 5 comptes connectés, résiliable à tout moment. Les limites par plateforme sont dans la référence des limites de débit, la configuration de l'agent dans le guide Hermes Agent, et le compromis entre hébergé et auto-hébergé dans alternatives à Postiz.
Pour une autre API récente, cette fois chez Meta, consulte l'API Threads.
FAQ
Peut-on programmer des posts sur Bluesky ?
Pas nativement. L'enregistrement de post de l'AT Protocol n'a aucun champ de planification, et un createdAt daté dans le futur ne retarde pas la publication. La planification vient de quelque chose qui garde le post en dehors de Bluesky : ton propre cron, ou un outil comme Buffer, Postiz ou Mixpost.
L'API Bluesky est-elle gratuite ?
Oui, pour un usage normal. La doc développeur de Bluesky liste des limites de débit mais aucun forfait, aucun prix ni aucuns frais par appel, et tu t'authentifies avec un mot de passe d'application gratuit en restant sous 5 000 points d'écriture par heure, soit environ 1 666 posts. C'est l'inverse de X, qui facture chaque lecture et chaque publication.
Comment je m'authentifie auprès de l'API Bluesky ?
Crée un mot de passe d'application dans tes réglages Bluesky, puis envoie en POST ton handle et ce mot de passe à com.atproto.server.createSession. Tu obtiens un accessJwt à envoyer comme bearer token et un refreshJwt pour le renouveler. N'utilise jamais ton vrai mot de passe, et mets la session en cache : createSession est limité à 30 appels par tranche de 5 minutes.
Quelle est la limite de caractères d'un post Bluesky ?
300 graphèmes, avec un plafond strict de 3 000 octets. Un emoji compte pour un seul graphème mais occupe de 4 à 25 octets, donc le plafond en octets ne se fait sentir que sur un texte bourré d'emoji combinés, comme les familles ou les couples. Avec l'embed images, tu peux joindre jusqu'à quatre images de 2 000 000 octets chacune.
PlugKit prend-il en charge Bluesky ?
Non. PlugKit couvre Instagram, Facebook, LinkedIn, TikTok, YouTube, X, WhatsApp et Telegram. Si tu as besoin de Bluesky dès aujourd'hui, scripte-le directement sur l'AT Protocol ou utilise un outil qui le prend en charge, et garde PlugKit pour les plateformes où OAuth, la revue d'app et la facturation à l'appel justifient de payer une API hébergée.
Un plug pour chaque plateforme que ton agent touche
29 $ par mois pour 5 comptes connectés, résiliable à tout moment. Toutes les fonctionnalités dans tous les forfaits.
Récupère ta clé API →