Référence API

Programmez des publications sur vos comptes connectés depuis vos propres outils. Chaque endpoint s'authentifie avec une clé API générée dans Réglages → Clés API. L'API est incluse dans les formules Pro et Enterprise, essai gratuit compris.

URL de base — https://hello-socials.com/api/v1

Vous préférez publier en le demandant à Claude ou ChatGPT ? Connectez le serveur MCP

Authentification

Transmettez votre clé en Bearer token. Les clés sont stockées hachées — la valeur en clair n'est affichée qu'une fois, à la création. Une clé porte des scopes : read pour les endpoints GET, write pour les POST.

Authorization: Bearer hs_live_xxxxxxxxxxxxxxxxxxxx
GET/api/v1/accounts

Liste vos comptes connectés. Appelez-le une fois et stockez les identifiants dans la configuration de votre outil : un nom d'affichage change quand vous renommez une page, un identifiant jamais.

curl https://hello-socials.com/api/v1/accounts \
  -H "Authorization: Bearer hs_live_xxx"
{
  "data": [
    {
      "id": "cmnj4p2z0000abcd",
      "network": "TWITTER",
      "username": "hellowesign",
      "displayName": "HelloWeSign",
      "status": "connected"
    },
    {
      "id": "cmnj53dc0000efgh",
      "network": "LINKEDIN_PAGE",
      "username": "hellowesign",
      "displayName": "HelloWeSign",
      "status": "connected"
    }
  ]
}

status indique si un compte doit être reconnecté avant de lui envoyer quoi que ce soit : connected, expiring_soon ou expired.

POST/api/v1/posts

Crée une publication programmée : texte seul, avec des images ou avec une vidéo. X, LinkedIn, Facebook et Threads acceptent le texte seul ; Instagram, Pinterest et TikTok exigent une image ou une vidéo. YouTube n'est pas encore disponible par l'API.

curl -X POST https://hello-socials.com/api/v1/posts \
  -H "Authorization: Bearer hs_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Audit trail de signature électronique : retrouver chaque étape d'\''un document.",
    "socialAccountIds": ["cmnj53dc0000efgh"],
    "scheduledAt": "2026-09-04T09:30:00Z",
    "media": [
      { "url": "https://example.com/images/audit-trail.png" }
    ]
  }'

Vidéo vers TikTok et en reel Instagram en un seul appel :

curl -X POST https://hello-socials.com/api/v1/posts \
  -H "Authorization: Bearer hs_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Nouvelle fonctionnalité #meetarabic",
    "socialAccountIds": ["<tiktok-account-id>", "<instagram-account-id>"],
    "scheduledAt": "2026-10-20T18:00:00+02:00",
    "media": [
      { "url": "https://example.com/videos/demo.mp4", "type": "video", "coverTimestampMs": 2500 }
    ],
    "postType": "reel",
    "tiktok": { "privacyLevel": "PUBLIC_TO_EVERYONE", "disableComment": false }
  }'

Champs du corps

contentObligatoire. Le texte de la publication.
socialAccountIdsObligatoire. Tableau d'identifiants issus de GET /accounts. Un seul identifiant est le cas courant ; plusieurs envoient le même texte sur plusieurs comptes en une fois.
scheduledAtFacultatif. ISO 8601 avec fuseau, dans le futur.
mediaFacultatif. Tableau d'objets { "url": "https://…" }, dans l'ordre d'affichage. Ou une seule vidéo : [{ "url": "https://…", "type": "video", "coverTimestampMs": 2500 }] : la couverture est l'image à cet instant (1 s par défaut), envoyée en image à Instagram et Facebook et en instant à TikTok ; "thumbnailUrl" permet de fournir une image de couverture à la place. Obligatoire pour Instagram, Pinterest et TikTok.
captionsFacultatif. { "<socialAccountId>": "légende" } : une légende propre à un compte, à la place de content (par exemple une légende TikTok différente). Les comptes absents utilisent content.
postTypesFacultatif. { "<socialAccountId>": "post" | "reel" | "story" } : un format propre à un compte Instagram ou Facebook, prioritaire sur postType (par exemple deux pages Facebook en post, Instagram en story).
postTypeFacultatif, Instagram et Facebook. "post" (par défaut), "reel" (vidéo obligatoire) ou "story". Une vidéo seule sur Instagram part en reel dans tous les cas.
draftFacultatif. true enregistre le post en brouillon (statut DRAFT) : rien n'est publié tant que vous ne l'avez pas relu et programmé dans HelloSocials, onglet Posts › Brouillons.
tiktokFacultatif, comptes TikTok uniquement. privacyLevel (PUBLIC_TO_EVERYONE par défaut, ou MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY), title (90 caractères max), disableComment, disableDuet, disableStitch (true par défaut), autoAddMusic (true par défaut), isCommercial avec isOwnBrand ou isPaidPartnership.

À propos de scheduledAt

Un horodatage ISO 8601 avec fuseau explicite. Un horodatage sans fuseau est refusé : il serait lu dans le fuseau du serveur, et une publication prévue à 9h30 partirait à une autre heure. Omettez le champ pour publier au plus tôt — le worker passe toutes les 5 minutes.

"2026-09-04T09:30:00Z"        ✓
"2026-09-04T11:30:00+02:00"   ✓
"2026-09-04T09:30:00"         ✗ pas de fuseau
"2026-09-04"                  ✗

À propos des médias

Transmettez des URL https publiques. Chaque image est téléchargée à la création, convertie en JPEG (1080 px sur le plus grand côté) et stockée chez nous : la publication ne dépend plus de votre URL, même si elle part plusieurs jours plus tard. Sources acceptées : JPEG, PNG, GIF (première image) et WebP, 20 Mo maximum chacune. Si une image échoue, rien n'est créé et la réponse indique laquelle. Vidéo : un seul élément { "url", "type": "video", "thumbnailUrl"? }, MP4 ou MOV, 50 Mo maximum, stockée telle quelle (sans réencodage) ; Facebook, Instagram, TikTok, X, LinkedIn et Threads l'acceptent, pas Pinterest.

Images par réseau

TWITTER4
LINKEDIN9
LINKEDIN_PAGE9
FACEBOOK10
THREADS10
INSTAGRAM10
PINTEREST1
TIKTOK35

La validation est tout ou rien

Si un seul compte ciblé échoue à la validation, rien n'est créé et la réponse détaille le problème. Cela évite qu'une publication parte sur un réseau et échoue silencieusement sur l'autre.

{
  "error": "Caption exceeds the character limit for at least one target network",
  "details": {
    "accounts": [{ "id": "cmnj4p2z0000abcd", "network": "TWITTER", "limit": 280, "length": 412 }]
  }
}
GET/api/v1/posts/{id}

Renvoie l'état d'une publication, réseau par réseau. La publication est asynchrone : la création répond PENDING, et le résultat réel n'existe qu'après le passage du worker.

{
  "data": {
    "id": "cmtlg7ca2000004jp",
    "status": "PUBLISHED",
    "scheduledAt": "2026-09-04T09:30:00.000Z",
    "publishedAt": "2026-09-04T09:30:12.000Z",
    "media": [{ "url": "https://…/posts/…/k3J9x.jpg" }],
    "results": [
      {
        "socialAccountId": "cmnj53dc0000efgh",
        "network": "LINKEDIN_PAGE",
        "status": "PUBLISHED",
        "externalId": "urn:li:share:7123456789",
        "error": null
      }
    ]
  }
}

Limites de caractères

X est compté comme X le fait : chaque URL vaut 23 caractères quelle que soit sa longueur, les emojis et caractères CJK valent 2. Les autres réseaux comptent les caractères bruts.

TWITTER280
LINKEDIN3000
LINKEDIN_PAGE3000
FACEBOOK63206
THREADS500
INSTAGRAM2200
PINTEREST500
TIKTOK2200

Erreurs

Les erreurs renvoient un corps JSON avec un champ error, et details quand un compte ou un champ précis est en cause.

400Corps invalide, compte inconnu, réseau non supporté, contenu trop long, trop d'images, image inaccessible ou invalide, date incorrecte
401Clé API absente, invalide, révoquée ou expirée
403La clé n'a pas le scope requis, ou le compte n'a pas d'abonnement Pro ou Enterprise actif
404Publication introuvable pour le détenteur de cette clé