Aller au contenu
Selamia

API & développeurs

Selamia pour les développeurs et les agents IA

Une API REST claire, des webhooks pour tous les événements et un serveur MCP : programme des posts depuis ton site, ton CRM ou ta caisse, envoie chaque nouvel avis Google dans Slack, ou laisse Claude préparer ta semaine. Inclus dans les offres Pro, Pilote et Agence.

Inclus dans les offres Pro, Pilote et Agence (et pendant l'essai gratuit).

Vue d'ensemble

API REST v1

JSON, dates ISO, pagination par curseur, création idempotente, messages d'erreur en français prêts à afficher.

Webhooks pour tout

14 événements signés HMAC-SHA256, relances automatiques, journal des envois et test en un clic.

Serveur MCP

8 outils pour Claude, Cursor et tout client MCP — avec les temps forts français et ton Brand Kit.

Ce que Selamia fait mieux

  • Des webhooks pour tous les événements, pas seulement la publication
  • Les mêmes règles que l'appli : limites des réseaux, quotas, validation client
  • Idempotency-Key : un nouvel essai ne crée jamais de doublon
  • Import de médias par URL sécurisé (aucun réseau privé, taille et type vérifiés)
  • Une clé par espace et par outil : pensé pour les agences
  • Messages d'erreur en français, prêts à montrer à tes clients

Authentification

Crée une clé dans Paramètres › Développeurs (propriétaire ou admin). Envoie-la dans l'en-tête Authorization de chaque requête. Une clé appartient à un espace et agit avec le rôle actuel de la personne qui l'a créée : si elle quitte l'équipe, la clé cesse de fonctionner. Seule une empreinte SHA-256 est conservée : la clé n'est montrée qu'une fois.

HTTP
GET /api/v1/me HTTP/1.1
Host: selamia.com
Authorization: Bearer pk_live_…
Droits (scopes)
Droits (scopes)Description
posts:readLire les posts
posts:writeCréer et programmer des posts
accounts:readVoir les réseaux connectés
media:writeEnvoyer des médias
stats:readLire les statistiques
ai:writeUtiliser l'IA

Démarrage rapide

Trois appels pour programmer ton premier post. scheduledAt accepte une date ISO 8601 avec fuseau, "next_slot" (prochain créneau libre de la file) ou "now". Sans scheduledAt, le post reste en brouillon.

curl
export SELAMIA_KEY="pk_live_…"

# 1. Ton espace, tes droits et ta consommation
curl https://selamia.com/api/v1/me -H "Authorization: Bearer $SELAMIA_KEY"

# 2. Tes réseaux connectés (identifiants)
curl https://selamia.com/api/v1/accounts -H "Authorization: Bearer $SELAMIA_KEY"

# 3. Programmer un post au prochain créneau libre
curl -X POST https://selamia.com/api/v1/posts \
  -H "Authorization: Bearer $SELAMIA_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: menu-de-saison-2026" \
  -d '{
    "caption": "Le menu de saison arrive mardi 🍂",
    "hashtags": ["lyon", "bistrot"],
    "accountIds": ["<instagram-id>", "<facebook-id>"],
    "mediaUrls": ["https://example.com/photos/menu.jpg"],
    "scheduledAt": "next_slot",
    "overrides": {
      "<facebook-id>": { "caption": "Version Facebook : réserve ta table !" }
    }
  }'
201 Created
{
  "object": "post",
  "id": "21eef5cd-043d-4c21-aa56-9d873a29c2c2",
  "status": "scheduled",
  "format": "image",
  "caption": "Le menu de saison arrive mardi 🍂",
  "scheduledAt": "2026-10-20T10:30:00.000Z",
  "targets": [
    { "network": "Instagram", "status": "scheduled", "permalink": null, "error": null },
    { "network": "Facebook", "status": "scheduled", "permalink": null, "error": null }
  ],
  "url": "https://selamia.com/app/posts/21eef5cd-…"
}

Endpoints

Adresse de base : https://selamia.com/api/v1

MéthodeCheminScopeDescription
GET/me—Espace, clé, rôle, offre et consommation du mois
GET/accountsaccounts:readRéseaux connectés (formats, limites)
GET/posts?from&to&status&accountId&cursorposts:readPosts triés par date, pagination par curseur
GET/posts/:idposts:readUn post et son statut par réseau
POST/postsposts:writeBrouillon, programmation, publication immédiate ou file
PATCH/posts/:idposts:writeModification partielle, (re)programmation
DELETE/posts/:idposts:writeSuppression (publications prévues annulées)
POST/posts/:id/retryposts:writeRelance des publications en échec
POST/mediamedia:writeFichier (multipart) ou import d'URL sécurisé
GET/slots/next?accountIds&countposts:readProchains créneaux libres de la file
GET/stats/summary?period=30dstats:readChiffres clés, meilleurs posts, recommandations
POST/ai/captionai:writeLégendes IA dans le ton de la marque (1 crédit)
GET/brand-kit—Identité de la marque (couleurs, ton, contact)
GET/moments?days=45—Temps forts français à venir + idées de posts

Schémas complets : openapi.json (à importer dans Postman, Insomnia ou ton générateur de code).

Webhooks

Ajoute une adresse HTTPS dans Paramètres › Développeurs, choisis les événements : Selamia envoie un POST signé pour chacun. Réponds par un code 2xx en moins de 10 secondes ; sinon on réessaie après 1 min, 5 min, 30 min, 2 h et 12 h. Après 20 échecs d'affilée, le webhook est mis en pause et le propriétaire prévenu. Utilise l'id de l'événement pour dédoublonner.

Événements

  • post.createdUn nouveau post (brouillon compris) est créé.
  • post.updatedLe texte, les médias, les réseaux ou la date d'un post changent.
  • post.scheduledUn post est programmé (ou reprogrammé) pour une date.
  • post.approval_requestedUn post est envoyé en validation (client ou responsable).
  • post.approvedLe client ou le responsable valide un post.
  • post.changes_requestedLe client ou le responsable demande des modifications.
  • post.publishedUn post est en ligne sur un réseau (un envoi par réseau, avec le lien).
  • post.failedUne publication a échoué définitivement sur un réseau (raison en français).
  • post.deletedUn post est supprimé (ses publications prévues sont annulées).
  • comment.receivedUn nouveau commentaire arrive dans la boîte de réception.
  • review.receivedUn nouvel avis Google arrive (avec sa note).
  • account.connectedUn compte social est connecté (ou reconnecté).
  • account.expiredLa connexion d'un compte a expiré : il faut le reconnecter.
  • report.readyLe rapport PDF mensuel est généré.

Contenu envoyé

POST → https://your-server/webhooks/selamia
{
  "id": "evt_9mQ2xK…",
  "type": "post.published",
  "createdAt": "2026-10-20T10:30:04.512Z",
  "workspaceId": "d4328…",
  "data": {
    "post": { "id": "21eef5cd-…", "status": "published", "caption": "…", "targets": [ … ] },
    "target": {
      "network": "Instagram",
      "status": "published",
      "permalink": "https://www.instagram.com/p/…",
      "publishedAt": "2026-10-20T10:30:03.981Z"
    }
  }
}

En-têtes : Selamia-Signature (t=horodatage,v1=HMAC-SHA256 de « t.corpsBrut » avec ton secret whsec_), Selamia-Event, Selamia-Event-Id, Selamia-Delivery.

Vérifier la signature (Node.js)

server.mjs
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.SELAMIA_WEBHOOK_SECRET; // whsec_…

// Garde le corps brut : la signature porte sur les octets exacts
app.post("/webhooks/selamia", express.raw({ type: "application/json" }), (req, res) => {
  const header = req.get("Selamia-Signature") ?? "";
  const { t, v1 } = Object.fromEntries(header.split(",").map((p) => p.split("=")));
  const expected = crypto.createHmac("sha256", SECRET).update(`${t}.${req.body}`).digest("hex");
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300; // anti-rejeu : 5 min
  const valid = !!v1 && v1.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
  if (!fresh || !valid) return res.status(400).send("Invalid signature");

  const event = JSON.parse(req.body);
  // Dédoublonne avec event.id, réponds vite, traite en arrière-plan
  if (event.type === "review.received") notifySlack(event.data.item);
  res.sendStatus(200);
});

app.listen(3001);

Serveur MCP pour les agents IA

Selamia parle le Model Context Protocol (Streamable HTTP) à l'adresse https://selamia.com/api/mcp, avec les mêmes clés, droits et règles que l'API. Branche-le à Claude Code, Claude Desktop, Cursor ou tout client MCP, puis demande : « Prépare 3 posts pour Halloween et programme-les sur Instagram et Facebook aux meilleurs moments. »

Claude Code
claude mcp add --transport http selamia https://selamia.com/api/mcp \
  --header "Authorization: Bearer pk_live_…"
Claude Desktop — claude_desktop_config.json
{
  "mcpServers": {
    "selamia": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://selamia.com/api/mcp",
        "--header",
        "Authorization:${SELAMIA_AUTH}"
      ],
      "env": {
        "SELAMIA_AUTH": "Bearer pk_live_…"
      }
    }
  }
}
Cursor, Windsurf, VS Code et autres clients
{
  "mcpServers": {
    "selamia": {
      "url": "https://selamia.com/api/mcp",
      "headers": {
        "Authorization": "Bearer pk_live_…"
      }
    }
  }
}

Outils

  • list_accounts

    Voir les réseaux connectés

  • list_posts

    Lire le calendrier (filtres date / statut)

  • create_post

    Créer un brouillon ou programmer un post

  • schedule_post

    Programmer un brouillon existant

  • generate_caption

    Rédiger une légende dans le ton de la marque

  • get_stats_summary

    Résumé des statistiques de la période

  • list_upcoming_moments

    Temps forts français à venir + idées

  • get_brand_kit

    Identité de la marque (couleurs, ton, contact)

L'agent a exactement les droits de la clé : sans posts:write, il ne peut pas créer de post. Brouillons par défaut, publication seulement sur demande.

Limites et erreurs

120 requêtes par minute et par clé (REST + MCP). Chaque réponse porte X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset ; une 429 porte aussi Retry-After. Les erreurs ont toujours la forme { "error": { "code", "message", "details"? } } : code est stable (anglais), message est en français, prêt à afficher.

422 Unprocessable Content
{
  "error": {
    "code": "unprocessable",
    "message": "Impossible de programmer :\n• Instagram demande au moins une image ou une vidéo.",
    "details": ["Instagram demande au moins une image ou une vidéo."]
  }
}
HTTPcodeDescription
401unauthorized / invalid_api_keyClé absente, invalide ou révoquée
403insufficient_scope / forbiddenDroit manquant sur la clé ou rôle insuffisant
403plan_requiredOffre sans plateforme développeurs
400validation_error / invalid_jsonCorps ou paramètres invalides (détails par champ)
404not_foundRessource absente de cet espace
402limit_reachedQuota de l'offre atteint (posts, crédits IA, stockage)
422unprocessableContenu refusé (règle d'un réseau, validation client…)
429rate_limitedPlus de 120 requêtes / minute
  • Dates en UTC (ISO 8601) ; le fuseau de l'espace est donné par GET /me.
  • Idempotency-Key sur POST /posts : un nouvel essai renvoie le même post.
  • Pagination : passe nextCursor en ?cursor= tant que hasMore vaut true.

Construis sur Selamia dès aujourd'hui

Choisis un modèle ou écris ton idée à Selamia IA : ton premier post peut être prêt en quelques minutes.

Gratuit, sans limite de temps Sans carte bancaire Pilote offert 14 jours