SDKSDK Node.js

SDK

SDK Node.js

Installez @sofia-post/node et appelez l’API Sofia depuis Node.js : publier, programmer, envoyer des médias, lire les statistiques, avec des erreurs typées.

Le SDK Node.js officiel enveloppe l’API Sofia v1 dans une seule classe, Sofia : une méthode par route, des requêtes et des réponses typées, et un seul type d’erreur pour tout échec. Il n’a aucune dépendance et tourne sur Node.js 20 ou plus.

Installation

Le SDK est publié sur npm sous le nom @sofia-post/node. Il s’utilise aussi bien avec import qu’avec require.

npm install @sofia-post/node

Démarrage rapide

Créez un client avec votre clé, trouvez l’établissement pour lequel publier, puis programmez un post sur Instagram :

import { Sofia } from '@sofia-post/node';

const sofia = new Sofia(process.env.SOFIA_API_KEY);

const [establishment] = await sofia.establishments();

const post = await sofia.post({
  establishmentId: establishment.id,
  targets: [{ platform: 'instagram', text: 'Tarte tatin du jour 🍎' }],
  scheduledAt: new Date('2026-12-01T09:00:00Z'),
});

console.log(post.id, post.status);

Authentification

Le constructeur prend une clé personnelle, créée dans Réglages › API, onglet Accès personnel, ou un jeton d’accès OAuth si votre application agit pour d’autres utilisateurs de Sofia (OAuth2). Le SDK l’envoie en Authorization: Bearer … à chaque requête.

Le client parle à https://api.sofia-post.com par défaut. Le second argument change l’URL de base, ou le fetch avec lequel il envoie ses requêtes :

const sofia = new Sofia(apiKey, { baseUrl: 'http://localhost:3008' });

Méthodes

MéthodeCe qu’elle fait
me()Pour qui la clé agit, ses scopes, et s’il s’agit d’une clé de test
platforms()Les règles de chaque réseau : longueur du texte, médias, formats
establishments()Les établissements que la clé atteint
accounts(establishmentId)Les comptes sociaux connectés à un établissement
connectionLink(establishmentId, input)Une page hébergée par Sofia où la personne connecte un réseau
insights(establishmentId, period?)Portée, engagement et abonnés, réseau par réseau
post(input, options?)Publier maintenant, programmer avec scheduledAt ou enregistrer un brouillon
postList(filters?)Une page de posts, filtrés par établissement, état ou dates
getPost(id) · updatePost(id, input) · deletePost(id)Lire, modifier ou retirer un post
upload(input) · uploadFromUrl(input)Ajouter un fichier ou une URL à la médiathèque de l’établissement
mediaList(filters) · getMedia(id) · deleteMedia(id)Lire et nettoyer la médiathèque
createWebhook(input) · webhooks() · deleteWebhook(id) · testWebhook(id)Être prévenu quand un post part ou échoue

Posts

Un post a une cible par réseau, chacune avec son texte, ses médias et son format. Vérifiez-le d’abord avec dryRun : rien n’est écrit, et un refus liste chaque règle enfreinte. Passez une idempotencyKey pour qu’une requête rejouée ne publie jamais deux fois. scheduledAt prend une Date ou une chaîne ISO 8601.

import type { PublishPostInput } from '@sofia-post/node';

const input: PublishPostInput = {
  establishmentId,
  targets: [
    { platform: 'instagram', text: 'Menu du jour', media: [{ id: media.id }] },
    { platform: 'facebook', text: 'Menu du jour : tarte tatin et café' },
  ],
};

await sofia.post(input, { dryRun: true });
await sofia.post(input, { idempotencyKey: crypto.randomUUID() });

Médias

Envoyez le fichier une fois, puis mettez son id dans les media d’un post. upload prend un Buffer, un Uint8Array ou un Blob, et lit le type de contenu dans le nom du fichier sauf si vous donnez contentType. uploadFromUrl laisse Sofia télécharger le fichier elle-même.

import { readFile } from 'node:fs/promises';

const media = await sofia.upload({
  establishmentId,
  file: await readFile('tarte-tatin.jpg'),
  fileName: 'tarte-tatin.jpg',
});

const imported = await sofia.uploadFromUrl({ establishmentId, url: 'https://example.com/menu.png' });

Pagination

postList et mediaList répondent une page à la fois. Passez le nextCursor d’une page comme cursor de l’appel suivant ; la dernière page n’en a pas.

let cursor: string | undefined;
do {
  const page = await sofia.postList({ establishmentId, status: 'published', limit: 100, cursor });
  page.data.forEach((post) => console.log(post.id));
  cursor = page.nextCursor;
} while (cursor);

Erreurs

Chaque méthode lève une SofiaApiError quand l’API refuse l’appel. Elle porte le status HTTP, le code stable de l’enveloppe d’erreur, ses details (pour un post refusé, chaque règle de réseau enfreinte), le requestId à donner au support et, sur un 429, retryAfterSeconds.

import { SofiaApiError } from '@sofia-post/node';

try {
  await sofia.post(input);
} catch (error) {
  if (!(error instanceof SofiaApiError)) throw error;
  if (error.code === 'post_refused') console.log(error.details);
  if (error.status === 429) await wait(error.retryAfterSeconds);
}

Quand l’API est injoignable, l’erreur a le code network_error et le statut 0. Le SDK ne réessaie jamais de lui-même : attendez retryAfterSeconds sur un 429 et espacez vos essais sur un 5xx.

TypeScript

Le paquet livre ses types : PublishPostInput, Post, Media, SocialAccount, EstablishmentInsights et les autres sont exportés à côté de Sofia, pour que votre éditeur complète chaque champ et chaque valeur d’énumération.

Ensuite : la référence de l’API décrit chaque route que le SDK appelle, et la CLI pilote la même API depuis un terminal.

Cette page vous a-t-elle aidé ?