API revendeur

Une seule API pour les commandes, le portefeuille et la marketplace

Créez des commandes, suivez la livraison, consultez les soldes et gérez les annonces depuis votre propre système. Points de terminaison REST versionnés, clés avec autorisations, écritures idempotentes et webhooks signés, sur le même moteur qui fait fonctionner cette boutique.

  • REST /v1, JSON en entrée et en sortie
  • Clés Bearer avec autorisations
  • Idempotency-Key sur les écritures
  • Webhooks signés
  • Offre Revendeur

Fonctionnement d’une intégration

Cinq appels, de zéro à une commande livrée

L’API reproduit ce que fait le tableau de bord, dans le même ordre. Rien n’est débité tant que vous ne créez pas une commande, et chaque écriture est idempotente.

  1. Créer une clé

    Dans votre tableau de bord, choisissez les autorisations dont la clé a besoin et, si vous le souhaitez, les IP autorisées à l’utiliser. La clé complète n’est affichée qu’une fois.

  2. Lire le catalogue

    GET /v1/catalog/services renvoie chaque service publié avec le prix déjà exprimé dans la devise et le niveau de votre compte.

  3. Prévisualiser le devis

    POST /v1/orders/preview valide le lien et la quantité et renvoie le montant exact, sans rien créer.

  4. Créer la commande

    POST /v1/orders avec un Idempotency-Key. Le portefeuille est débité et la commande est routée vers le fournisseur de meilleure qualité mesurée.

  5. Écouter les événements

    Enregistrez un point de terminaison https et recevez des événements signés pour les changements de statut, les livraisons partielles, les fins, les remboursements et les recharges.

Créer une commande en une seule requêtebash
curl -X POST https://YOUR-DOMAIN/v1/orders \
  -H "Authorization: Bearer smp_live_xxxxxxxxxx_..." \
  -H "Idempotency-Key: 2b7c1d9e-order-1001" \
  -H "Content-Type: application/json" \
  -d '{"service":"<service_id>","link":"https://instagram.com/p/abc","quantity":1000}'

Remplacez YOUR-DOMAIN par le domaine de cette boutique, la clé par la vôtre et <service_id> par un identifiant du catalogue.

Authentification et limites

Des clés que vous pouvez restreindre, limiter et faire tourner

Une clé est un identifiant côté serveur. Elle ne va jamais dans un navigateur, ne porte que les permissions que vous accordez, et vous pouvez la révoquer ou la remplacer à tout moment sans toucher à vos autres clés.

Clés Bearer

Envoyez Authorization: Bearer smp_live_… ou X-Api-Key. La clé complète n’est affichée qu’une fois et seule son empreinte est conservée. Jusqu’à 20 clés actives par compte, date d’expiration facultative et rotation en un clic.

Liste blanche d’IP

Vous pouvez associer une clé à jusqu’à 20 adresses IP. Les requêtes venant d’une autre adresse sont refusées avec 403 FORBIDDEN.

Limite de requêtes par clé

Chaque clé hérite de la limite de requêtes par minute de votre niveau client. Chaque réponse porte RateLimit-Limit, RateLimit-Remaining et RateLimit-Reset ; au-delà de la limite, vous recevez 429 avec Retry-After.

Limite en vigueur pour le niveau Revendeur1 200 requêtes par minute

Autorisations

Chaque clé ne porte que les autorisations que vous accordez. Un appel hors de ses autorisations est refusé avec 403 FORBIDDEN.

AutorisationCe qu’il fait
catalog:readLister les services et les prix
orders:readLire les commandes
orders:writeCréer des commandes, recharger et annuler
wallet:readLire les soldes
assets:readLister vos annonces et offres
assets:writeCréer et modifier des annonces, la vérification et la disponibilité
transactions:writeEnregistrer les étapes de remise des transactions

Sur chaque réponse

  • X-Request-Id : indiquez-le lorsque vous contactez l’assistance
  • X-Api-Version : la date du contrat avec lequel vous communiquez
  • Cache-Control: no-store, les réponses ne sont jamais mises en cache

Idempotence

Réessayez sans risque, sans jamais débiter deux fois

POST /v1/orders et POST /v1/orders/batch exigent un en-tête Idempotency-Key de 8 à 120 caractères. Répéter un appel avec la même clé renvoie la même commande sans débiter à nouveau. Réutiliser une clé avec un corps différent est refusé avec 409 IDEMPOTENCY_KEY_REUSE. Dans un lot, chaque élément est identifié par la clé du lot et son index.

  • Générez une clé par commande logique (un UUID convient) et enregistrez-la avant l’envoi.
  • En cas d’expiration ou d’erreur réseau, renvoyez avec la même clé : vous obtenez le résultat d’origine.
  • Vous avez modifié le corps ? Utilisez une nouvelle clé. L’ancienne reste liée à la première requête.
Corps d’erreurhttp
HTTP/1.1 409 Conflict
X-Request-Id: req_<hex>

{
  "error": {
    "code": "IDEMPOTENCY_KEY_REUSE",
    "message": "..."
  },
  "request_id": "req_<hex>"
}

Points de terminaison

Tout ce que la boutique peut faire, en HTTP

Tous les chemins sont sous /v1 sur le domaine de cette boutique. Les montants sont toujours des chaînes décimales avec une devise ISO 4217, jamais des nombres flottants. Les schémas complets de requête et de réponse sont dans le fichier OpenAPI.

Spécification OpenAPI (YAML)

Catalogue

MéthodeCheminAutorisationCe qu’il fait
GET/v1/catalog/platformscatalog:readPlateformes qui ont actuellement des services publiés
GET/v1/catalog/servicescatalog:readServices avec le prix dans votre devise et votre niveau ; filtre par plateforme
GET/v1/catalog/services/{id}catalog:readUn service avec son schéma de champs

Commandes

MéthodeCheminAutorisationCe qu’il fait
POST/v1/orders/previeworders:writeValider et chiffrer sans créer ni débiter
POST/v1/ordersIdempotency-Key obligatoireorders:writeCréer une commande : débite le portefeuille et route vers le meilleur fournisseur
GET/v1/ordersorders:readLister les commandes, des plus récentes aux plus anciennes, avec pagination par curseur
POST/v1/orders/batchIdempotency-Key obligatoireorders:writeJusqu’à 100 commandes en un appel, chacune avec son propre résultat
GET/v1/orders/{id}orders:readRécupérer une commande par identifiant
POST/v1/orders/{id}/refillorders:writeDemander une recharge dans la période de garantie
POST/v1/orders/{id}/cancelorders:writeDemander l’annulation ; remboursée dès que le fournisseur confirme

Portefeuille

MéthodeCheminAutorisationCe qu’il fait
GET/v1/wallet/balancewallet:readSoldes par devise : disponible, argent, bonus et réservé

Actifs (vendeurs)

MéthodeCheminAutorisationCe qu’il fait
POST/v1/assetsassets:writeCréer un brouillon d’annonce ; publiée après vérification et modération
GET/v1/assetsassets:readVos annonces
PATCH/v1/assets/{id}assets:writeModifier une annonce (corps complet ; If-Match pour le verrouillage optimiste)
POST/v1/assets/batchassets:writeImporter jusqu’à 1 000 annonces, identifiées par external_ref
POST/v1/assets/{id}/verifyassets:writeDémarrer (method) ou vérifier (verification_id) une vérification de propriété
POST/v1/assets/{id}/availabilityassets:writeMasquer ou afficher une annonce (pas pendant une négociation)

Offres

MéthodeCheminAutorisationCe qu’il fait
GET/v1/offersassets:readOffres reçues sur vos annonces

Transactions

MéthodeCheminAutorisationCe qu’il fait
POST/v1/transactions/{id}/handofftransactions:writeMarquer une étape de procédure, ajouter un élément sécurisé ou terminer la remise
Réponse (201)http
HTTP/1.1 201 Created
X-Request-Id: req_<hex>
X-Api-Version: 2026-09-23
RateLimit-Limit: <limit>  RateLimit-Remaining: <n>  RateLimit-Reset: <seconds>

{
  "id": "SMP-7K2Q9XHT",
  "status": "routing",
  "service": "<service_id>",
  "link": "https://instagram.com/p/abc",
  "quantity": 1000,
  "charge": "<decimal>",
  "refunded": "0",
  "currency": "USD",
  "start_count": null,
  "remains": null,
  "delivered": null,
  "refill_until": null,
  "created_at": "2026-09-23T12:00:00.000Z",
  "updated_at": "2026-09-23T12:00:00.000Z"
}

Webhooks

Événements signés, renvoyés jusqu’à votre accusé de réception

Enregistrez un point de terminaison https sur un domaine public et choisissez les événements souhaités. Chaque envoi est signé avec le secret de votre point de terminaison, affiché une seule fois à sa création.

En-têtes de livraisonhttp
POST /webhooks/orders HTTP/1.1
Content-Type: application/json
Webhook-Id: <event id>
Webhook-Timestamp: 1790000000
Webhook-Signature: t=1790000000,v1=<hex HMAC-SHA256(secret, "1790000000.<body>")>

{ "id": "<event id>", "type": "order.partial", "created_at": "2026-09-23T12:05:00.000Z",
  "data": { "orderId": "SMP-7K2Q9XHT", ... } }
Vérification en Node.jsjs
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verifyWebhook(secret, headers, rawBody) {
  const t = headers['webhook-timestamp'];
  const v1 = (headers['webhook-signature'] ?? '')
    .split(',').find((p) => p.startsWith('v1='))?.slice(3) ?? '';
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300; // 5 minutes
  return fresh && expected.length === v1.length
    && timingSafeEqual(Buffer.from(expected), Buffer.from(v1));
}

Vérifier une signature

  1. Lisez Webhook-Timestamp (t) et le corps brut de la requête exactement tel qu’il a été reçu.
  2. Calculez HMAC-SHA256 avec le secret de votre point de terminaison sur la chaîne « t.body ».
  3. Comparez-le en temps constant à la valeur v1 de Webhook-Signature.
  4. Rejetez les horodatages de plus de 5 minutes et dédoublonnez par Webhook-Id.
  5. Répondez 2xx rapidement et traitez le travail de façon asynchrone.

Nouvelles tentatives et file d’attente

Les événements sont écrits dans une file d’attente, dans la même transaction de base de données que le changement qui les a provoqués, donc rien n’est perdu si un envoi échoue. Les envois échoués sont retentés après 1 min, 5 min, 30 min, 2 h, 6 h, 12 h et 24 h avant d’être marqués comme définitivement en échec.

Événements auxquels vous pouvez vous abonner

  • order.created
  • order.status_changed
  • order.partial
  • order.completed
  • order.refunded
  • order.refill_updated
  • deposit.confirmed
  • offer.created
  • offer.updated
  • reservation.created
  • transaction.updated
  • payout.updated
  • listing.updated
  • dispute.updated

Règles des points de terminaison

  • https:// uniquement, sur un domaine public ; les adresses privées et internes sont refusées.
  • Abonnez-vous à des événements précis ou à tous.
  • Le secret de signature n’est affiché qu’une fois, à la création.

Compatibilité

Ajoutez cette boutique à n’importe quel panneau SMM

POST /api/v2 implémente le contrat commun « SMM API v2 » : envoyez la clé et l’action en champs de formulaire ou en JSON. Mêmes clés, autorisations et limites que /v1 ; seul le format change, et les erreurs sont renvoyées sous la forme { "error": "message" }.

Actions prises en charge

  • services : le catalogue avec tarif, min, max et indicateurs de recharge et d’annulation
  • add : créer une commande (service, lien, quantité, commentaires, noms d’utilisateur, séries, intervalle)
  • status : une commande, ou jusqu’à 100 avec orders=id1,id2
  • balance : solde disponible dans la devise de votre compte
  • refill : demander des recharges pour une ou plusieurs commandes
  • refill_status : statut d’une ou plusieurs recharges
  • cancel : demander l’annulation d’une ou plusieurs commandes

Les panneaux n’envoient pas de clé d’idempotence : elle est donc dérivée du contenu de la commande et de la minute en cours ; la fenêtre de doublons couvre le reste.

Requêtebash
curl -X POST https://YOUR-DOMAIN/api/v2 \
  -d key=smp_live_xxxxxxxxxx_... \
  -d action=add \
  -d service=<service_id> \
  -d link=https://instagram.com/p/abc \
  -d quantity=1000

{ "order": "SMP-7K2Q9XHT" }

Erreurs

Une seule forme pour toutes les erreurs

Chaque réponse non 2xx a le même corps. Intégrez-vous sur le code, pas sur le message : les messages peuvent changer, pas les codes. Le request_id est aussi envoyé dans l’en-tête X-Request-Id.

Corps d’erreurhttp
HTTP/1.1 400 Bad Request
X-Request-Id: req_<hex>

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request.",
    "details": {
      "fields": [{ "path": "quantity", "message": "..." }]
    }
  },
  "request_id": "req_<hex>"
}
CodeHTTPSignification
VALIDATION_ERROR400Corps ou en-têtes invalides ; details.fields liste chaque chemin et problème
UNAUTHORIZED401Clé absente, invalide, révoquée ou expirée
INSUFFICIENT_FUNDS402Solde du portefeuille insuffisant pour le devis
FORBIDDEN403La clé n’a pas l’autorisation, IP non autorisée, sous-utilisateur sans permission ou compte suspendu
NOT_FOUND404Commande, service ou annonce inexistant pour ce compte
CONFLICT409Conflit d’état, comme la limite de clés actives
INVALID_TRANSITION409La commande ou la transaction ne peut pas passer à cet état
DUPLICATE_ORDER409Même service, lien et quantité dans la fenêtre de doublons
IDEMPOTENCY_KEY_REUSE409Idempotency-Key déjà utilisée avec un corps différent
ALREADY_RESERVED409L’actif est réservé par un autre acheteur
POLICY_BLOCKED422Service ou pays bloqué par la politique de la plateforme
MARGIN_GUARD422Aucun fournisseur ne peut traiter cette commande au prix publié
UNPROCESSABLE422La requête est valide mais ne peut pas être exécutée
RATE_LIMITED429Limite par clé atteinte ; attendez les secondes indiquées dans Retry-After
INTERNAL500Erreur inattendue ; contactez l’assistance avec le request_id
PROVIDER_ERROR502Échec du fournisseur ; la commande est retentée ou remboursée
NO_ROUTE503Aucune route fournisseur disponible pour le moment ; réessayez plus tard
NOT_CONFIGURED503Fonctionnalité non configurée sur cette boutique

Qui peut l’utiliser

Disponible sur l’offre Revendeur

Les clés API et les points de terminaison de webhook sont créés par le titulaire du compte sur l’offre Revendeur. Les commandes passées avec une clé sont débitées du portefeuille du compte et apparaissent dans le même tableau de bord que les commandes manuelles. Les sous-utilisateurs ne peuvent pas créer de clés.

Construire une intégration revendeur sur l’API de SocialMediaPRO

Que vous exploitiez un panneau qui a besoin d’un fournisseur fiable, un outil d’agence qui passe des commandes pour des clients, ou un inventaire vendeur qui doit rester synchronisé avec la marketplace, l’intégration suit le même schéma : une clé restreinte, des écritures idempotentes, et des événements que vous vérifiez avant de leur faire confiance.

Un seul contrat, versionné par date

Chaque point de terminaison se trouve sous /v1 sur le domaine de la boutique avec laquelle vous intégrez. Les réponses sont en JSON, les montants sont des chaînes décimales associées à une devise ISO 4217, et les horodatages sont au format ISO 8601. Chaque réponse porte un en-tête X-Api-Version avec la date du contrat avec lequel vous communiquez, et un X-Request-Id que vous pouvez citer à l’assistance. Les erreurs ont toujours le même corps : un objet d’erreur avec un code stable, un message lisible et des détails facultatifs, ainsi que le request_id.

Le fichier OpenAPI 3.1 décrit chaque chemin, chaque schéma et chaque code d’erreur. Importez-le dans votre client HTTP ou votre générateur et vous obtenez des requêtes typées pour le catalogue, les commandes, le portefeuille, les annonces, les offres et les remises de transactions.

Clés, autorisations et le compte qu’elles représentent

Une clé est créée par le titulaire du compte sur l’offre Revendeur et n’est affichée qu’une fois ; seule une empreinte est conservée. Lors de la création, vous choisissez ses autorisations, une liste blanche d’IP facultative (jusqu’à 20 adresses) et une expiration facultative. La rotation crée une nouvelle clé avec les mêmes autorisations et révoque l’ancienne, ce qui permet de renouveler les identifiants sans interruption. Les commandes passées avec une clé sont débitées du portefeuille du compte et apparaissent dans le même tableau de bord que les commandes manuelles, avec leur source marquée comme API.

Chaque clé hérite de la limite de requêtes par minute du niveau de client du compte. Les en-têtes RateLimit-Limit, RateLimit-Remaining et RateLimit-Reset indiquent où vous en êtes ; au-delà de la limite, l’API renvoie 429 avec un en-tête Retry-After, et la bonne réaction est d’attendre exactement ce délai.

Écritures idempotentes et lots

La création de commande est le seul appel qui déplace de l’argent, elle est donc protégée deux fois. D’abord, l’en-tête Idempotency-Key est obligatoire : répéter une requête avec la même clé renvoie la commande d’origine sans second débit, et réutiliser la clé avec un corps différent est refusé avec 409 IDEMPOTENCY_KEY_REUSE. Ensuite, une fenêtre de doublons détecte le même service, le même lien et la même quantité renvoyés dans un court intervalle sans correspondance de clé, et renvoie 409 DUPLICATE_ORDER.

Les lots acceptent jusqu’à 100 commandes par appel. Chaque élément est validé et débité séparément, identifié par la clé du lot et son index, et la réponse liste un résultat par élément, si bien qu’une ligne défectueuse ne bloque jamais les autres. Utilisez d’abord POST /v1/orders/preview lorsque vous voulez le montant exact et le résultat de validation sans rien créer.

  • Générez un UUID par commande logique et enregistrez-le avant l’envoi.
  • En cas d’expiration, renvoyez avec la même clé ; ne générez jamais une nouvelle clé pour la même commande.
  • Considérez les codes 4xx comme définitifs, et les codes 5xx et 429 comme réessayables avec un délai croissant.

Des webhooks auxquels vous pouvez faire confiance

Chaque changement d’état est écrit dans une file d’attente, dans la même transaction de base de données que le changement lui-même, et un distributeur le livre à votre point de terminaison https avec trois en-têtes : Webhook-Id, Webhook-Timestamp et Webhook-Signature. La signature est un HMAC-SHA256 de l’horodatage, d’un point et du corps brut, calculé avec le secret du point de terminaison affiché une seule fois à la création. Vérifiez-la en temps constant, rejetez les horodatages de plus de cinq minutes et dédoublonnez par Webhook-Id, car un événement réessayé porte le même identifiant.

Les envois qui ne reçoivent pas de 2xx sont réessayés après 1 minute, 5 minutes, 30 minutes, 2 heures, 6 heures, 12 heures et 24 heures avant d’être marqués comme définitivement en échec. Répondez vite et traitez de façon asynchrone ; un gestionnaire lent est la cause la plus fréquente de traitement en double.

Panneaux enfants par le point de terminaison SMM v2

Si votre panneau parle déjà le format répandu « SMM API v2 », vous pouvez ajouter cette boutique comme fournisseur en collant l’URL /api/v2 et votre clé. Les actions services, add, status, balance, refill, refill_status et cancel sont prises en charge, les prix reviennent dans la devise et le niveau de votre compte, et les erreurs utilisent la forme plate { "error": "message" } attendue par ces panneaux. L’idempotence est dérivée du contenu de la commande et de la minute en cours, si bien que les doubles envois accidentels dans la même minute sont fusionnés.

Questions fréquentes

Quelle offre faut-il pour utiliser l’API ?

L’offre Revendeur. Les clés API et les points de terminaison de webhook sont créés par le titulaire du compte ; les sous-utilisateurs ne peuvent pas les créer. Les clés sont des identifiants côté serveur et ne doivent jamais être intégrées dans un navigateur ou une application mobile.

Comment authentifier une requête ?

Envoyez la clé dans Authorization: Bearer smp_live_… ou dans un en-tête X-Api-Key. La clé doit porter l’autorisation requise par le point de terminaison, par exemple orders:write pour créer une commande ou catalog:read pour lister les services.

Que se passe-t-il si ma requête expire après la création d’une commande ?

Renvoyez-la avec la même Idempotency-Key. Vous recevez la commande d’origine et rien n’est débité deux fois. Si vous envoyez un corps différent avec la même clé, l’API répond 409 IDEMPOTENCY_KEY_REUSE.

Comment vérifier un webhook ?

Calculez HMAC-SHA256 avec le secret de votre point de terminaison sur la chaîne formée par Webhook-Timestamp, un point et le corps brut, puis comparez-le en temps constant à la valeur v1 de Webhook-Signature. Rejetez les horodatages de plus de 5 minutes et dédoublonnez par Webhook-Id.

Quelle est la limite de requêtes ?

Chaque clé hérite de la limite de requêtes par minute de votre niveau de client, indiquée sur cette page. Les en-têtes RateLimit-* signalent la fenêtre en cours, et une réponse 429 contient Retry-After en secondes.

Les prix de l’API sont-ils les mêmes que sur le site ?

Oui. GET /v1/catalog/services renvoie le prix déjà converti dans la devise de votre compte avec votre remise de niveau, et POST /v1/orders/preview renvoie le montant exact, y compris les remises au volume et les codes promo, avant que vous ne vous engagiez.

Puis-je utiliser l’API pour les annonces de la marketplace ?

Oui. Avec l’autorisation assets:write, vous pouvez créer et modifier des annonces, en importer jusqu’à 1 000 d’un coup, lancer une vérification de propriété et changer la disponibilité ; assets:read liste vos annonces et vos offres, et transactions:write enregistre les étapes de remise d’une transaction.

Prêt à intégrer ?

Avec l’offre Revendeur, créez une clé, téléchargez le fichier OpenAPI et envoyez votre première commande depuis votre propre système.

Nous ne vendons jamais d’avis ni de notes. Certaines plateformes restreignent dans leurs conditions les services d’engagement ou les transferts de comptes ; vous êtes responsable des règles de chaque plateforme que vous utilisez.