Si votre pipeline de contenu est en Python, que ce soit un scraper, une tâche de données ou un workflow LLM, publier ne devrait pas obliger à sortir vers autre chose.
Installer et s’authentifier
pip install bulkpublish
from bulkpublish import BulkPublish
bp = BulkPublish("bp_your_key_here")
Le client lit aussi BULKPUBLISH_API_KEY depuis l’environnement, ce qui est la meilleure habitude :
import os
from bulkpublish import BulkPublish
bp = BulkPublish(os.environ["BULKPUBLISH_API_KEY"])
Créer d’abord un brouillon
post = bp.posts.create(
content="Launching our new product today!",
channels=[
{"channelId": 1, "platform": "x"},
{"channelId": 2, "platform": "linkedin"},
],
status="draft",
)
Les brouillons sont visibles dans l’application, ce qui vous permet de voir ce que votre code a réellement produit avant qu’un public ne le voie. Passez à "scheduled" une fois satisfait.
Récupérez vos identifiants de canaux plutôt que de les coder en dur :
channels = bp.channels.list()
En planifier un
post = bp.posts.create(
content="Launching our new product today!",
channels=[{"channelId": 1, "platform": "x"}],
status="scheduled",
scheduled_at="2026-04-10T09:00:00Z",
timezone="America/New_York",
)
scheduled_at est au format ISO-8601 et timezone est un nom IANA. Passez le fuseau horaire explicitement pour tout ce qui est récurrent, sinon votre heure de publication dérive d’une heure deux fois par an au changement d’heure d’été.
Les exigences par plateforme
C’est la partie qui surprend le plus. Certaines plateformes demandent des champs que d’autres n’exigent pas, et platform_specific est l’endroit où ils vont. YouTube, par exemple, exige un titre de 1 à 100 caractères.
post = bp.posts.create(
content="Behind the scenes on this month's build.",
channels=[{"channelId": 5, "platform": "youtube"}],
media_files=[file_id],
platform_specific={"youtube": {"title": "How we ship every week"}},
status="scheduled",
scheduled_at="2026-04-10T09:00:00Z",
)
Si un champ obligatoire propre à une plateforme manque, le post est rejeté au moment de sa création plutôt que d’échouer silencieusement plus tard. Interceptez cette exception et journalisez-la, car dans un pipeline automatisé, personne ne surveille l’écran.
Un texte différent par plateforme
platform_content accepte des surcharges par plateforme, ce qui permet à un seul appel de publier sur plusieurs réseaux sans envoyer le même texte partout :
bp.posts.create(
content="Default text for anything not overridden.",
platform_content={
"x": "The short version.",
"linkedin": "The longer version, with the reasoning behind it.",
},
channels=[
{"channelId": 1, "platform": "x"},
{"channelId": 2, "platform": "linkedin"},
],
status="draft",
)
Cela vaut la peine d’être utilisé. Un pipeline qui diffuse un texte identique sur quinze réseaux, c’est précisément ce qui rend une publication automatisée évidente.
Limites de débit
| Free | Pro | Business | |
|---|---|---|---|
| Requêtes API/jour | 30 | 5 000 | 50 000 |
| Clés API | 1 | 5 | 10 |
| Les 30 requêtes par jour du plan Free servent à évaluer l’API. Un vrai pipeline a besoin d’un plan payant, et une boucle sans backoff épuisera l’allocation gratuite en quelques secondes. |
Si un LLM rédige le contenu
Deux règles qui comptent plus en Python qu’ailleurs, parce que c’est souvent là que vivent ces pipelines.
Créez des brouillons, pas des posts publiés, au moins le temps de l’observer un peu. Un texte généré est faux avec assurance, d’une manière qu’un brouillon humain n’est pas.
Ne laissez jamais le modèle affirmer un fait sur un produit. Les prix et les limites changent, et un modèle en produira volontiers un plausible. Tout élément factuel doit venir d’une source.
En résumé
pip install bulkpublish, construisez le client avec votre clé issue de l’environnement, appelez bp.posts.create. Utilisez platform_specific pour les champs obligatoires propres à une plateforme comme les titres YouTube, platform_content pour un texte différent par réseau, passez un fuseau horaire pour tout ce qui est planifié, et commencez par des brouillons.