SAMII OS

API partenaires — v1

Lire et écrire des commandes, des rendez-vous et des clients dans un espace SAMII depuis n'importe quel système externe, et recevoir en temps réel tout ce qui s'y passe. Un marchand branche son espace ; une agence branche tout son portefeuille avec une seule clé. REST, JSON, jeton Bearer — rien à installer, un nœud HTTP standard suffit.

Base

https://samii.souverain-store.com/api/v1

Toutes les réponses sont en JSON. Les erreurs renvoient un objet { "erreur": "…" } avec un code HTTP explicite (400 requête invalide, 401 clé refusée, 429 limite atteinte, 500 erreur interne).

Authentification

Chaque appel porte une clé dans l'en-tête Authorization. Elle se génère depuis la page API & Webhooks — dans le QG pour un marchand, dans la tour de contrôle pour une agence. Une clé ne donne accès qu'aux espaces de son propriétaire : tout ce qui est lu ou écrit y est automatiquement borné, et cette limite est appliquée côté serveur à chaque requête.

Authorization: Bearer sk_samii_xxxxxxxxxxxxxxxxxxxxxxxx

Nous ne stockons jamais la clé en clair, seulement son empreinte SHA-256 : elle s'affiche une seule fois, à la création. Une clé perdue se remplace, elle ne se retrouve pas. Le propriétaire peut révoquer n'importe quelle clé en un clic — l'accès est coupé immédiatement.

Deux portées de clé

Clé marchand — générée par un marchand depuis son QG. Elle désigne son espace : il n'y a rien à préciser dans les appels.

Clé agence — générée par un compte agence depuis sa tour de contrôle. Elle couvre tout son portefeuille : une agence branche son automatisation une seule fois pour l'ensemble de ses clients, au lieu de reconstruire un flux par boutique. L'espace visé se désigne alors par un en-tête :

Authorization: Bearer sk_samii_…
X-SAMII-Espace: WS-a1b2c3        (ou ?espace=WS-a1b2c3)

L'appartenance de cet espace au portefeuille est revérifiée en base à chaque appel, jamais déduite de la clé : viser l'espace d'un marchand qui n'est pas au portefeuille renvoie 403, pas des données. Un client qui quitte l'agence sort du périmètre de la clé immédiatement, sans qu'il y ait quoi que ce soit à révoquer.

Sans en-tête, une clé d'agence n'atteint aucune donnée client : seuls /moi et /espaces répondent, et c'est précisément là qu'on découvre les identifiants à viser.

GET /espaces

Les espaces que la clé peut atteindre. Une clé marchand renvoie le sien, une clé d'agence renvoie tout le portefeuille — le même flux n8n fonctionne donc dans les deux cas sans être réécrit.

{
  "espaces": [
    { "id": "WS-a1b2c3", "nom": "Resto Yasmine", "metier": "restaurant",
      "metierLabel": "Restaurant", "parcours": "commandes", "pays": "DZ", "devise": "DZD" },
    { "id": "WS-d4e5f6", "nom": "Cabinet Dr K.", "metier": "sante",
      "metierLabel": "Santé", "parcours": "rendez-vous", "pays": "MA", "devise": "MAD" }
  ],
  "total": 2
}

Permissions

Chaque clé porte la liste de ce qu'elle a le droit de faire. C'est le propriétaire de l'espace qui coche, à la création — pas l'intégrateur. Une clé de lecture ne peut rien écrire, même si l'appel est parfaitement formé.

PermissionDonne accès à
espaces:lireGET /moi, GET /espaces
commandes:lireGET /commandes
commandes:ecrirePOST /commandes
rendezvous:lireGET /rendez-vous
rendezvous:ecrirePOST /rendez-vous
clients:lireGET /clients

Un appel hors permission renvoie 403 en nommant ce qui manque, pour que vous puissiez corriger sans nous écrire :

{
  "erreur": "Cette clé n'a pas la permission nécessaire.",
  "porteeRequise": "commandes:ecrire",
  "aide": "Ajoutez « Créer et modifier des commandes » aux permissions de la clé…"
}

Traçabilité

Chaque appel est enregistré — méthode, chemin, code de réponse, clé utilisée — et le propriétaire de l'espace le voit depuis sa page API & Webhooks, refus compris. Demander un accès à un marchand est plus simple quand il peut vérifier lui-même ce qui en est fait.

Limite d'appels

120 requêtes par minute et par clé. La limite est comptée par clé, pas par adresse IP : plusieurs partenaires derrière la même instance n8n mutualisée ne se pénalisent pas entre eux. Les en-têtes standard RateLimit-* sont renvoyés à chaque réponse.

Vérifier sa clé

GET /moi

Premier appel à faire. Retourne l'espace auquel la clé donne accès.

curl https://samii.souverain-store.com/api/v1/moi \
  -H "Authorization: Bearer sk_samii_…"
{
  "portee": "marchand",
  "espace": {
    "id": "WS-a1b2c3",
    "nom": "Boutique Amine",
    "metier": "boutique",
    "metierLabel": "Boutique / prêt-à-porter",
    "parcours": "commandes",
    "pays": "DZ",
    "devise": "DZD"
  }
}

parcours vaut commandes ou rendez-vous selon le métier du marchand : c'est ce qui te dit quelle ressource utiliser. Un restaurant ou une boutique travaille en commandes ; un cabinet, un salon ou un garage travaille en rendez-vous.

Commandes

GET /commandes

ParamètreDescription
limiteNombre de résultats, 50 par défaut, 200 au maximum.
statutFiltre facultatif : en attente, confirmée, expédiée, livrée, annulée.
curl "https://samii.souverain-store.com/api/v1/commandes?statut=confirmée&limite=20" \
  -H "Authorization: Bearer sk_samii_…"
{
  "commandes": [
    {
      "id": "TG-482913",
      "nom_client": "Yacine B.",
      "telephone": "+213…",
      "adresse": "Bab Ezzouar, Alger",
      "produit": "Veste cuir noir — L",
      "statut": "confirmée",
      "montant": 8500,
      "source": "telegram",
      "date_commande": "2026-08-24T09:12:44.000Z",
      "confirme_le": "2026-08-24T09:19:02.000Z"
    }
  ],
  "total": 1
}

source indique par quel canal la commande est arrivée : telegram, whatsapp, shopify, woocommerce, api

POST /commandes

ChampDescription
nomClientObligatoire. Nom du client.
telephoneNuméro de contact.
adresseAdresse de livraison.
produitDescription libre de ce qui est commandé.
montantNombre, dans la devise de l'espace.
curl -X POST https://samii.souverain-store.com/api/v1/commandes \
  -H "Authorization: Bearer sk_samii_…" \
  -H "Content-Type: application/json" \
  -d '{
    "nomClient": "Yacine B.",
    "telephone": "+213555000111",
    "adresse": "Bab Ezzouar, Alger",
    "produit": "Veste cuir noir — L",
    "montant": 8500
  }'
{ "commande": { "id": "API-9F3A1C22B7", "statut": "en attente" } }

La commande apparaît immédiatement dans le QG du marchand, comme n'importe quelle autre, et déclenche l'événement commande.creee sur les webhooks abonnés.

Rendez-vous

GET /rendez-vous

curl "https://samii.souverain-store.com/api/v1/rendez-vous?limite=50" \
  -H "Authorization: Bearer sk_samii_…"

POST /rendez-vous

ChampDescription
clientNomObligatoire.
dateRdvObligatoire. Date ISO 8601, ex. 2026-09-12T14:30:00Z.
telephoneNuméro de contact.
motifObjet du rendez-vous.
curl -X POST https://samii.souverain-store.com/api/v1/rendez-vous \
  -H "Authorization: Bearer sk_samii_…" \
  -H "Content-Type: application/json" \
  -d '{
    "clientNom": "Sofia M.",
    "telephone": "+212600112233",
    "motif": "Consultation",
    "dateRdv": "2026-09-12T14:30:00Z"
  }'

Clients

GET /clients

Les clients de l'espace, agrégés par numéro : nombre de commandes, total dépensé, date du dernier achat. Triés du plus gros au plus petit — de quoi alimenter une segmentation, une relance ou un tableau de bord externe.

{
  "clients": [
    { "nom": "Yacine B.", "telephone": "+213…", "commandes": 7,
      "total_depense": 54200, "derniere_commande": "2026-08-21T17:40:00.000Z" }
  ],
  "total": 1
}

Webhooks temps réel

Plutôt que d'interroger l'API en boucle, déclare une URL et laisse SAMII te prévenir. Le marchand ajoute ton URL depuis son QG, page API & Webhooks, et choisit les événements qu'il veut envoyer.

ÉvénementDéclenché quand
commande.creeeUne commande est enregistrée, quel que soit le canal.
commande.confirmeeLe client ou le marchand confirme la commande.
commande.annuleeLa commande est annulée.
rendezvous.creeUn rendez-vous est pris.
rendezvous.confirmeLe rendez-vous est confirmé.
rendezvous.annuleLe rendez-vous est annulé — sans lui, votre agenda garde un créneau que le marchand a libéré.
message.recuUn client écrit sur un canal connecté (WhatsApp…).

Un point important : les événements sont émis quelle que soit l'origine. Une commande prise par SAMII dans une conversation WhatsApp déclenche exactement le même webhook qu'une commande créée par l'API. Pour ton automatisation, la provenance ne change rien — c'est ce qui permet de brancher un flux une fois et de couvrir tous les canaux du marchand.

Corps envoyé

POST https://ton-n8n.com/webhook/samii
X-SAMII-Event: commande.creee
X-SAMII-Espace: WS-a1b2c3
X-SAMII-Signature: sha256=9c1f…

{
  "evenement": "commande.creee",
  "workspaceId": "WS-a1b2c3",
  "espace": { "id": "WS-a1b2c3", "nom": "Resto Yasmine" },
  "donnees": {
    "id": "TG-482913",
    "nomClient": "Yacine B.",
    "telephone": "+213555000111",
    "produit": "Veste cuir noir — L",
    "montant": 8500,
    "source": "telegram"
  },
  "emisLe": "2026-08-24T09:12:44.512Z"
}

Une seule URL pour toute une agence

Un webhook déclaré par un compte agence reçoit les événements de tous ses clients. Le bloc espace du corps, et l'en-tête X-SAMII-Espace, disent duquel il s'agit — de quoi router dans un seul flux n8n plutôt que d'en dupliquer un par boutique. Un webhook déclaré par un marchand ne reçoit que le sien.

Vérifier la signature

Chaque appel est signé en HMAC-SHA256 sur le corps brut, avec le secret affiché à la création du webhook. Vérifie-la avant de traiter l'événement : c'est ce qui garantit que l'appel vient bien de nous.

const crypto = require("crypto");

function signatureValide(corpsBrut, entete, secret) {
    const attendue = "sha256=" + crypto
        .createHmac("sha256", secret)
        .update(corpsBrut)
        .digest("hex");
    return crypto.timingSafeEqual(Buffer.from(entete), Buffer.from(attendue));
}

Nouvelles tentatives

L'appel est en « meilleur effort », avec un délai d'attente de 8 secondes : une commande ne doit jamais échouer parce qu'un système externe est momentanément hors service. Le code HTTP de ta dernière réponse est visible par le marchand. Après 20 échecs consécutifs, le webhook se désactive tout seul et le marchand doit le réactiver — une URL morte n'est pas rappelée indéfiniment.

Brancher n8n en trois minutes

Le même schéma fonctionne à l'identique avec Make, Zapier, Pipedream ou un appel serveur direct.

Nous écrire

Un endpoint qui te manque, un événement à ajouter, un volume particulier : info@souverain-store.com. Cette API est faite pour les intégrateurs — si ton flux a besoin de quelque chose qui n'est pas là, dis-le-nous, c'est exactement le retour qu'on cherche.