Développeurs & Intégrateurs

Documentation de l'API SMS

Intégrez l'envoi de SMS en masse ou unitaire de manière transparente dans vos applications, scripts et systèmes d'information.

Authentification

Pour des raisons de sécurité, toutes les requêtes adressées à l'API SMS Bammite doivent être authentifiées. L'authentification s'effectue en transmettant votre API Key dans l'en-tête HTTP et votre Private Key dans un second en-tête ou dans le payload, selon votre intégration.

Où trouver mes identifiants ? Connectez-vous à votre Dashboard pour générer votre API Key et votre Private Key. La Private Key n'est affichée qu'une seule fois : copiez-la et conservez-la soigneusement.

Les en-têtes HTTP attendus doivent être formatés ainsi :

X-API-KEY: votre_api_key
X-PRIVATE-KEY: votre_private_key_brute
Note : La X-PRIVATE-KEY doit être transmise en clair (valeur brute, non hashée). C'est le serveur qui la vérifie via bcrypt. Vous pouvez aussi la passer dans le corps JSON sous la clé private_key si vous ne pouvez pas définir d'en-têtes personnalisés.
Attention : Votre API Key et votre Private Key sont strictement personnelles et confidentielles. Ne les divulguez jamais, ne les commitez pas dans des dépôts publics et conservez votre Private Key dans un coffre-fort ou un stockage sécurisé.

Endpoint Principal

L'envoi de SMS s'effectue en soumettant une requête avec la méthode POST au point d'accès unique ci-dessous :

POST https://sms.bammite.com/api.php

Les données envoyées dans le corps de la requête doivent être encodées au format JSON et l'en-tête Content-Type doit être défini sur application/json.

Paramètres de la Requête

Le corps JSON de la requête POST prend en charge les paramètres suivants :

Paramètre Type Requis Description
telephone String Obligatoire Numéro de téléphone du destinataire au format international (avec indicatif pays).
Alias accepté : tel.
Exemple: +221771234567.
message String Obligatoire Texte du SMS à transmettre. Un message standard fait 160 caractères. Au-delà, le message sera segmenté en plusieurs SMS.
Alias accepté : msg.
name String Optionnel Nom d'expéditeur personnalisé (Sender Name). Si omis, le nom lié à votre clé API est utilisé par défaut. Il doit être autorisé sur votre compte.
private_key String Optionnel* Alternative au header X-PRIVATE-KEY. Utilisez-le dans le corps JSON si vous ne pouvez pas définir d'en-têtes HTTP personnalisés.

Exemples d'Intégration

Sélectionnez votre langage de programmation préféré pour afficher un exemple d'intégration prêt à l'emploi. Vous pouvez copier directement le code ou télécharger le fichier d'exemple.

send_sms.sh
# Envoi d'un SMS avec cURL via le terminal
curl -X POST 'https://sms.bammite.com/api.php' \
  -H 'Content-Type: application/json' \
  -H 'X-API-KEY: votre_cle_api' \
  -H 'X-PRIVATE-KEY: votre_private_key' \
  -d '{ "telephone": "+221771234567", "message": "Bonjour depuis l API !", "name": "Bammite" }'
<?php
// Configuration de l'API et des données
$url = "https://sms.bammite.com/api.php";
$data = [
    "telephone" => "+221771234567",
    "message"   => "Bonjour depuis l'API !",
    "name"      => "Bammite" // Optionnel
];

// Initialisation de cURL
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Content-Type: application/json",
    "X-API-KEY: votre_cle_api",
    "X-PRIVATE-KEY: votre_private_key"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

// Exécution de la requête
$response = curl_exec($ch);

if (curl_errno($ch)) {
    echo 'Erreur cURL : ' . curl_error($ch);
} else {
    $result = json_decode($response, true);
    print_r($result);
}

curl_close($ch);
?>
// Envoi d'un SMS avec l'API Fetch (Node.js 18+ ou navigateur)
const url = 'https://sms.bammite.com/api.php';
const apiKey     = 'votre_cle_api';
const privateKey = 'votre_private_key';

const payload = {
  telephone: '+221771234567',
  message:   "Bonjour depuis l'API !",
  name:      'Bammite' // Optionnel
};

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type':  'application/json',
    'X-API-KEY':    apiKey,
    'X-PRIVATE-KEY': privateKey
  },
  body: JSON.stringify(payload)
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Erreur :', error));
import requests

url = "https://sms.bammite.com/api.php"
headers = {
    "Content-Type":  "application/json",
    "X-API-KEY":    "votre_cle_api",
    "X-PRIVATE-KEY": "votre_private_key"
}
payload = {
    "telephone": "+221771234567",
    "message":   "Bonjour depuis l'API !",
    "name":      "Bammite"  # Optionnel
}

try:
    response = requests.post(url, headers=headers, json=payload)
    response.raise_for_status()
    print(response.json())
except requests.exceptions.RequestException as e:
    print(f"Erreur: {e}")
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class BammiteSms {
    public static void main(String[] args) {
        String url        = "https://sms.bammite.com/api.php";
        String apiKey     = "votre_cle_api";
        String privateKey = "votre_private_key";
        String jsonPayload = "{"
                + "\"telephone\":\"+221771234567\","
                + "\"message\":\"Bonjour depuis l'API !\","
                + "\"name\":\"Bammite\""
                + "}";

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .header("Content-Type",  "application/json")
                .header("X-API-KEY",    apiKey)
                .header("X-PRIVATE-KEY", privateKey)
                .POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
                .build();

        client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
                .thenApply(HttpResponse::body)
                .thenAccept(System.out::println)
                .join();
    }
}
require 'net/http'
require 'uri'
require 'json'

uri = URI.parse("https://sms.bammite.com/api.php")
header = {
  'Content-Type'  => 'application/json',
  'X-API-KEY'     => 'votre_cle_api',
  'X-PRIVATE-KEY' => 'votre_private_key'
}
payload = {
  telephone: '+221771234567',
  message:   "Bonjour depuis l'API !",
  name:      'Bammite' # Optionnel
}

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri, header)
request.body = payload.to_json

response = http.request(request)
puts JSON.parse(response.body)
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://sms.bammite.com/api.php"
	payload := map[string]string{
		"telephone": "+221771234567",
		"message":   "Bonjour depuis l'API !",
		"name":      "Bammite", // Optionnel
	}
	jsonValue, _ := json.Marshal(payload)

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonValue))
	if err != nil {
		fmt.Printf("Erreur request: %s\n", err)
		return
	}

	req.Header.Set("Content-Type",  "application/json")
	req.Header.Set("X-API-KEY",    "votre_cle_api")
	req.Header.Set("X-PRIVATE-KEY", "votre_private_key")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("Erreur client: %s\n", err)
		return
	}
	defer resp.Body.Close()

	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
use reqwest::header::{HeaderMap, HeaderValue, CONTENT_TYPE};
use serde_json::json;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let url = "https://sms.bammite.com/api.php";
    let client = reqwest::Client::new();
    
    let mut headers = HeaderMap::new();
    headers.insert(CONTENT_TYPE,    HeaderValue::from_static("application/json"));
    headers.insert("X-API-KEY",    HeaderValue::from_static("votre_cle_api"));
    headers.insert("X-PRIVATE-KEY", HeaderValue::from_static("votre_private_key"));

    let payload = json!({
        "telephone": "+221771234567",
        "message":   "Bonjour depuis l'API !",
        "name":      "Bammite"  // Optionnel
    });

    let res = client.post(url)
        .headers(headers)
        .json(&payload)
        .send()
        .await?
        .text()
        .await?;

    println!("{}", res);
    Ok(())
}
import 'dart:convert';
import 'package:http/http.dart' as http;

void main() async {
  var url = Uri.parse('https://sms.bammite.com/api.php');
  var headers = {
    'Content-Type':  'application/json',
    'X-API-KEY':    'votre_cle_api',
    'X-PRIVATE-KEY': 'votre_private_key',
  };
  var body = jsonEncode({
    'telephone': '+221771234567',
    'message':   "Bonjour depuis l'API !",
    'name':      'Bammite', // Optionnel
  });

  try {
    var response = await http.post(url, headers: headers, body: body);
    if (response.statusCode == 200) {
      print(jsonDecode(response.body));
    } else {
      print('Erreur: ${response.statusCode}');
    }
  } catch (e) {
    print('Erreur: $e');
  }
}
<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <title>Envoi SMS Bammite</title>
</head>
<body>
  <form id="smsForm">
    <label for="phone">Numéro :</label>
    <input id="phone" type="text" value="+221781941351" />
    
    <label for="message">Message :</label>
    <textarea id="message">Bonjour depuis ma page web.</textarea>
    
    <button type="submit">Envoyer</button>
  </form>

<div id="smsResult" style="display:none; margin-top:20px; padding:16px; border-radius:8px; max-width:600px; white-space:pre-wrap; font-family: monospace;"></div>

<script>
const smsResult = document.querySelector('#smsResult');

function renderResult(message, isSuccess = true) {
  smsResult.style.display = 'block';
  smsResult.style.backgroundColor = isSuccess ? '#e6f4ea' : '#fce8e6';
  smsResult.style.color = isSuccess ? '#137333' : '#c5221f';
  smsResult.style.border = isSuccess ? '1px solid #ceead6' : '1px solid #fad2cf';
  smsResult.innerText = message;
}

document.querySelector('#smsForm').addEventListener('submit', async function(event) {
  event.preventDefault();
  renderResult('Envoi en cours…', true);

  try {
    const response = await fetch('https://sms.bammite.com/api.php', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-KEY': 'Votre_cle_api',
        'X-PRIVATE-KEY': 'Votre_private_key'
      },
      body: JSON.stringify({
        telephone: document.querySelector('#phone').value,
        message: document.querySelector('#message').value,
        name: 'attic' // Nom de l'expéditeur (optionnel)
      })
    });

    if (!response.ok) {
      const errorBody = await response.text();
      renderResult(`Erreur HTTP [${response.status} ${response.statusText}]\n${errorBody}`, false);
      return;
    }

    const result = await response.json();
    renderResult(result.message || JSON.stringify(result, null, 2), result.success === true);
  } catch (error) {
    renderResult(`Erreur d'envoi : ${error.message}\n(Vérifiez votre connexion ou les règles CORS si l'appel est fait depuis un navigateur)`, false);
  }
});
</script>
</body>
</html>

Réponses de l'API

L'API renvoie systématiquement une réponse structurée au format JSON. Le code HTTP d'état (status code) renvoie l'état global et l'objet JSON contient les détails.

Exemple de réponse réussie (HTTP 200) :

{
  "success": true,
  "message": "SMS envoyé avec succès",
  "api_response": { ... }
}

Exemple de réponse en cas d'erreur (HTTP 400 ou 401) :

{
  "success": false,
  "message": "Clé API invalide ou inactive"
}

Codes HTTP d'erreur courants

Code HTTP Signification Cause typique
200 OK Requête acceptée Le message est placé dans la file d'attente d'envoi.
400 Bad Request Format invalide Le payload JSON est corrompu, ou le numéro telephone / le champ message est manquant.
401 Unauthorized Authentification échouée La clé API transmise est absente, incorrecte ou inactive.
403 Forbidden Accès interdit Votre solde de crédit est insuffisant pour envoyer le SMS.
429 Too Many Requests Limitation de débit Vous avez dépassé la limite de requêtes par seconde autorisée.

Bonnes Pratiques

  • Sécurisation des clés : N'intégrez jamais de clé API directement dans du code exécuté côté client (comme le JavaScript du navigateur). Privilégiez toujours un appel sécurisé depuis votre serveur (PHP, Node.js, Python, etc.) agissant comme relais.
  • Format des numéros : Pour garantir la distribution correcte des SMS vers d'autres opérateurs nationaux ou transfrontaliers, formatez toujours les numéros avec leur indicatif pays précédé d'un +.
  • Gestion du débit (Throttling) : Prévoyez un mécanisme de temporisation (backoff) si vos scripts envoient un volume important de messages en rafale afin de respecter les limites de requêtes.
  • Longueur des messages : 1 SMS = 160 caractères GSM standard. Les caractères accentués et émoticônes réduisent cette limite à 70 caractères (encodage Unicode). Surveillez la longueur pour optimiser vos coûts.

Support technique

Notre équipe technique est à votre écoute pour vous guider lors de votre intégration ou répondre à vos interrogations.

Email contact@bammite.com (Réponse sous 24h)
Téléphone & WhatsApp +221 78 194 13 51 (Du lundi au samedi, 9h - 18h GMT)