Aller au contenu principal

Documentation de l'API SMS Gateway

Envoyez des messages SMS et des codes OTP en utilisant l'API REST Chinqit SMS Gateway.

Démarrage rapide

Envoyez votre premier SMS en 2 étapes :

Étape 1 : Envoyer un message

curl -X POST https://sms.chinqit.com/messages/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"message": "Hello from SMS Gateway!"
}'

Étape 2 : Envoyer et vérifier un OTP

# Envoyer OTP
curl -X POST https://sms.chinqit.com/otp/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"language": "en"
}'

# Vérifier OTP
curl -X POST https://sms.chinqit.com/otp/verify \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"otp": "123456"
}'

Authentification

Toutes les requêtes API nécessitent une authentification à l'aide de votre clé API fournie par Chinqit.

Utilisation de la clé API

Incluez votre clé API dans l'en-tête de la requête :

X-API-Key: YOUR_API_KEY

Exemple

curl -X POST https://sms.chinqit.com/messages/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"phoneNumber": "+22238089336", "message": "Hello"}'

URL de base

Toutes les requêtes API doivent être envoyées à :

  • Production : https://sms.chinqit.com

Format de numéro de téléphone (Mauritanie)

Tous les endpoints acceptent les numéros de téléphone mauritaniens dans les formats suivants :

  • Format canonique : +222XXXXXXXX (ex : +22238089336)
  • Avec indicatif pays : 222XXXXXXXX (ex : 22238089336) - normalisé automatiquement en +222XXXXXXXX
  • Format local : XXXXXXXX (ex : 38089336) - normalisé automatiquement en +222XXXXXXXX

Règles :

  • Le numéro local à 8 chiffres (XXXXXXXX) doit commencer par 2, 3 ou 4
  • L'API normalise automatiquement tous les formats acceptés en +222XXXXXXXX avant stockage ou envoi
  • Les numéros de téléphone sont stockés et utilisés au format normalisé (+222XXXXXXXX) pour garantir la cohérence
  • Les formats invalides (mauvaise longueur, mauvais préfixe, contient des espaces/tirets) retourneront une erreur 400 Bad Request

Exemples :

  • +22238089336 → normalisé en +22238089336
  • 22238089336 → normalisé en +22238089336
  • 38089336 → normalisé en +22238089336
  • 12345678 → Erreur : doit commencer par 2, 3 ou 4
  • +222 27 63 56 42 → Erreur : espaces non autorisés
  • +1234567890 → Erreur : pas un numéro mauritanien valide

Endpoints

Envoyer un SMS

Envoyer un message SMS à un numéro de téléphone.

Endpoint : POST /messages/send

Requête :

{
"phoneNumber": "+1234567890",
"message": "Your message text here"
}

Paramètres :

ParamètreTypeRequisDescription
phoneNumberstringOuiNuméro de téléphone du destinataire (format Mauritanie). Formats acceptés : +222XXXXXXXX, 222XXXXXXXX ou XXXXXXXX. L'API normalise et stocke sous +222XXXXXXXX. Voir Format de numéro de téléphone pour plus de détails.
messagestringOuiContenu du message SMS (minimum 1 caractère)

Réponse :

{
"success": true,
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"queued": true
}

Exemple :

curl -X POST https://sms.chinqit.com/messages/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"message": "Hello from SMS Gateway!"
}'

JavaScript :

const response = await fetch("https://sms.chinqit.com/messages/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
message: "Hello from SMS Gateway!",
}),
});

const data = await response.json();
console.log("Message ID:", data.messageId);

Python :

import requests

response = requests.post(
'https://sms.chinqit.com/messages/send',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'phoneNumber': '+22238089336',
'message': 'Hello from SMS Gateway!'
}
)

data = response.json()
print(f"Message ID: {data['messageId']}")

PHP :

<?php
$ch = curl_init('https://sms.chinqit.com/messages/send');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'phoneNumber' => '+22238089336',
'message' => 'Hello from SMS Gateway!'
]));

$response = curl_exec($ch);
$data = json_decode($response, true);
echo "Message ID: " . $data['messageId'];
curl_close($ch);
?>

Note : Les messages sont mis en file d'attente et traités de manière asynchrone. L'API retourne immédiatement avec un messageId que vous pouvez utiliser pour suivre votre message.


Envoyer un OTP

Envoyer un code à usage unique (OTP) par SMS ou WhatsApp.

Endpoint : POST /otp/send

Requête :

{
"phoneNumber": "+22238089336",
"hash": "ABC123XYZ45",
"language": "en",
"channel": "sms"
}

Paramètres :

ParamètreTypeRequisDescription
phoneNumberstringOuiNuméro de téléphone pour envoyer l'OTP (format Mauritanie). Formats acceptés : +222XXXXXXXX, 222XXXXXXXX ou XXXXXXXX. L'API normalise et stocke sous +222XXXXXXXX. Voir Format de numéro de téléphone pour plus de détails.
hashstringNonHash SMS Retriever de 11 caractères (canal SMS uniquement). Lorsqu'il est fourni, le hash sera ajouté au message OTP sur une nouvelle ligne. Voir Guide SMS Retriever pour les détails d'implémentation.
languagestringNonCode de langue : fr (par défaut), en ou ar
channelstringNonCanal de communication : sms (par défaut) ou whatsapp

Réponse :

{
"success": true,
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"expiresIn": 600
}

Exemple de canal SMS :

curl -X POST https://sms.chinqit.com/otp/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"language": "en",
"channel": "sms"
}'

Exemple de canal WhatsApp :

curl -X POST https://sms.chinqit.com/otp/send \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"language": "en",
"channel": "whatsapp"
}'

JavaScript :

// Envoyer un OTP par SMS
const smsResponse = await fetch("https://sms.chinqit.com/otp/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
language: "en",
channel: "sms",
}),
});

// Envoyer un OTP par WhatsApp
const whatsappResponse = await fetch("https://sms.chinqit.com/otp/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
language: "en",
channel: "whatsapp",
}),
});

const data = await whatsappResponse.json();
console.log("OTP expires in:", data.expiresIn, "seconds");

Python :

import requests

# Envoyer un OTP par SMS
sms_response = requests.post(
'https://sms.chinqit.com/otp/send',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'phoneNumber': '+22238089336',
'language': 'en',
'channel': 'sms'
}
)

# Envoyer un OTP par WhatsApp
whatsapp_response = requests.post(
'https://sms.chinqit.com/otp/send',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'phoneNumber': '+22238089336',
'language': 'en',
'channel': 'whatsapp'
}
)

data = whatsapp_response.json()
print(f"OTP expires in: {data['expiresIn']} seconds")

Détails de l'OTP :

  • Code numérique à 6 chiffres
  • Valide pendant 10 minutes
  • Maximum 3 tentatives de vérification
  • Disponible par SMS ou WhatsApp

Exemple de hash SMS Retriever (OTP SMS) :

Pour activer la consommation automatique de SMS à l'aide de l'API SMS Retriever d'Android, incluez un hash de 11 caractères dans votre requête /otp/send. Le hash sera ajouté à votre message OTP :

const response = await fetch("https://sms.chinqit.com/otp/send", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
channel: "sms",
language: "en",
hash: "ABC123XYZ45", // Hash de 11 caractères
}),
});

Le SMS résultant sera :

Your verification code is: 123456
ABC123XYZ45

Vérifier un OTP

Vérifier un code OTP qui a été envoyé à un numéro de téléphone.

Endpoint : POST /otp/verify

Requête :

{
"phoneNumber": "+22238089336",
"otp": "123456",
"channel": "sms"
}

Paramètres :

ParamètreTypeRequisDescription
phoneNumberstringOuiNuméro de téléphone auquel l'OTP a été envoyé (format Mauritanie). Formats acceptés : +222XXXXXXXX, 222XXXXXXXX ou XXXXXXXX. L'API normalise et stocke sous +222XXXXXXXX. Voir Format de numéro de téléphone pour plus de détails.
otpstringOuiCode OTP à 6 chiffres à vérifier
channelstringNonCanal de communication utilisé : sms (par défaut) ou whatsapp

Réponse (Succès) :

{
"success": true,
"message": "OTP verified successfully",
"verified": true
}

Réponse (Invalide) :

{
"success": false,
"message": "Invalid OTP",
"retriesLeft": 2
}

Exemple :

curl -X POST https://sms.chinqit.com/otp/verify \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+22238089336",
"otp": "123456",
"channel": "sms"
}'

JavaScript :

const response = await fetch("https://sms.chinqit.com/otp/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": "YOUR_API_KEY",
},
body: JSON.stringify({
phoneNumber: "+22238089336",
otp: "123456",
channel: "sms",
}),
});

const data = await response.json();
if (data.verified) {
console.log("OTP verified successfully");
} else {
console.log("Invalid OTP. Retries left:", data.retriesLeft);
}

Gestion des erreurs

Format de réponse d'erreur

Toutes les erreurs suivent ce format :

{
"success": false,
"message": "Error description",
"errors": [] // Optionnel : Erreurs de validation
}

Codes de statut HTTP

CodeDescription
200Succès
400Mauvaise requête - Erreur de validation
401Non autorisé - Clé API manquante
403Interdit - Clé API invalide
404Non trouvé
429Trop de requêtes - Limite de taux dépassée
500Erreur interne du serveur
502Passerelle incorrecte - Erreur du fournisseur (canal WhatsApp)

Erreurs courantes

Erreur de validation (400) :

{
"success": false,
"message": "Validation failed",
"errors": [
{
"path": ["message"],
"message": "String must contain at least 1 character(s)"
}
]
}

Numéro de téléphone invalide (400) :

{
"success": false,
"message": "Validation failed",
"errors": [
{
"path": ["phoneNumber"],
"message": "Phone number must be a valid Mauritania number. Accepted formats: +222XXXXXXXX, 222XXXXXXXX, or XXXXXXXX (where XXXXXXXX starts with 2, 3, or 4)."
}
]
}

Limite de taux dépassée (429) :

{
"success": false,
"message": "Rate limit exceeded. Please try again later."
}

Erreur du fournisseur WhatsApp (502) :

{
"success": false,
"message": "WhatsApp OTP send failed",
"error": "Error details from WhatsApp API"
}

Limites de taux

Envoi d'OTP

Par numéro de téléphone par clé API :

  • 3 requêtes par minute
  • 10 requêtes par heure
  • 20 requêtes par jour

Exemples de code

Exemple JavaScript complet

class SMSGateway {
constructor(apiKey, baseUrl = "https://sms.chinqit.com") {
this.apiKey = apiKey;
this.baseUrl = baseUrl;
}

async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
const response = await fetch(url, {
...options,
headers: {
"Content-Type": "application/json",
"X-API-Key": this.apiKey,
...options.headers,
},
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.message || "API request failed");
}

return response.json();
}

async sendMessage(phoneNumber, message) {
return this.request("/messages/send", {
method: "POST",
body: JSON.stringify({
phoneNumber,
message,
}),
});
}

async sendOTP(phoneNumber, language = "fr", channel = "sms") {
return this.request("/otp/send", {
method: "POST",
body: JSON.stringify({
phoneNumber,
language,
channel,
}),
});
}

async verifyOTP(phoneNumber, otp, channel = "sms") {
const response = await this.request("/otp/verify", {
method: "POST",
body: JSON.stringify({ phoneNumber, otp, channel }),
});
return response.verified === true;
}
}

// Utilisation
const client = new SMSGateway("YOUR_API_KEY");

// Envoyer un message
const result = await client.sendMessage("+22238089336", "Hello!");
console.log("Message ID:", result.messageId);

// Envoyer et vérifier un OTP par SMS
const smsOtpResult = await client.sendOTP("+22238089336", "en", "sms");
const smsVerified = await client.verifyOTP("+22238089336", "123456", "sms");
console.log("SMS OTP verified:", smsVerified);

// Envoyer et vérifier un OTP par WhatsApp
const whatsappOtpResult = await client.sendOTP(
"+22238089336",
"en",
"whatsapp",
);
const whatsappVerified = await client.verifyOTP(
"+22238089336",
"123456",
"whatsapp",
);
console.log("WhatsApp OTP verified:", whatsappVerified);

Exemple Python complet

import requests
from typing import Optional, Dict

class SMSGateway:
def __init__(self, api_key: str, base_url: str = 'https://sms.chinqit.com'):
self.api_key = api_key
self.base_url = base_url
self.headers = {
'Content-Type': 'application/json',
'X-API-Key': api_key
}

def _request(self, method: str, endpoint: str, data: Optional[Dict] = None):
url = f'{self.base_url}{endpoint}'
response = requests.request(method, url, json=data, headers=self.headers)
response.raise_for_status()
return response.json()

def send_message(self, phone_number: str, message: str):
return self._request('POST', '/messages/send', {
'phoneNumber': phone_number,
'message': message
})

def send_otp(self, phone_number: str, language: str = 'fr', channel: str = 'sms'):
return self._request('POST', '/otp/send', {
'phoneNumber': phone_number,
'language': language,
'channel': channel
})

def verify_otp(self, phone_number: str, otp: str, channel: str = 'sms'):
response = self._request('POST', '/otp/verify', {
'phoneNumber': phone_number,
'otp': otp,
'channel': channel
})
return response.get('verified', False)

# Utilisation
client = SMSGateway('YOUR_API_KEY')

# Envoyer un message
result = client.send_message('+22238089336', 'Hello!')
print(f"Message ID: {result['messageId']}")

# Envoyer et vérifier un OTP par SMS
sms_otp_result = client.send_otp('+22238089336', 'en', 'sms')
sms_verified = client.verify_otp('+22238089336', '123456', 'sms')
print(f"SMS OTP verified: {sms_verified}")

# Envoyer et vérifier un OTP par WhatsApp
whatsapp_otp_result = client.send_otp('+22238089336', 'en', 'whatsapp')
whatsapp_verified = client.verify_otp('+22238089336', '123456', 'whatsapp')
print(f"WhatsApp OTP verified: {whatsapp_verified}")

Cas d'usage courants

Inscription d'utilisateur avec OTP

// Étape 1 : Envoyer un OTP par SMS
const smsOtpResult = await client.sendOTP("+22238089336", "en", "sms");

// Étape 2 : L'utilisateur saisit l'OTP (depuis votre interface)
const userOTP = "123456"; // Obtenir depuis la saisie utilisateur

// Étape 3 : Vérifier l'OTP
try {
const verified = await client.verifyOTP("+22238089336", userOTP, "sms");
if (verified) {
// Procéder à l'inscription
console.log("OTP verified, user can register");
}
} catch (error) {
// Gérer l'OTP invalide/expiré
console.error("OTP verification failed:", error.message);
}

Inscription d'utilisateur avec OTP WhatsApp

// Étape 1 : Envoyer un OTP par WhatsApp
const whatsappOtpResult = await client.sendOTP("+1234567890", "en", "whatsapp");

// Étape 2 : L'utilisateur saisit l'OTP (depuis votre interface)
const userOTP = "123456"; // Obtenir depuis la saisie utilisateur

// Étape 3 : Vérifier l'OTP
try {
const verified = await client.verifyOTP("+22238089336", userOTP, "whatsapp");
if (verified) {
// Procéder à l'inscription
console.log("WhatsApp OTP verified, user can register");
}
} catch (error) {
// Gérer l'OTP invalide/expiré ou les erreurs du fournisseur
console.error("WhatsApp OTP verification failed:", error.message);
}

Envoi de messages en masse

async function sendBulkMessages(recipients, message) {
const results = [];

for (const phoneNumber of recipients) {
try {
// Ajouter un délai pour respecter les limites de taux
if (results.length > 0) {
await new Promise((resolve) => setTimeout(resolve, 5000));
}

const result = await client.sendMessage(phoneNumber, message);
results.push({
phoneNumber,
messageId: result.messageId,
status: "queued",
});
} catch (error) {
results.push({ phoneNumber, error: error.message, status: "failed" });
}
}

return results;
}

// Utilisation
const recipients = ["+22238089336", "+22234567890", "+22241234567"];
const results = await sendBulkMessages(recipients, "Bulk message");
console.log(results);

Bonnes pratiques

Sécurité

  • ✅ Ne jamais commiter les clés API dans le contrôle de version
  • ✅ Utiliser des variables d'environnement ou une gestion sécurisée des secrets
  • ✅ Faire pivoter les clés API périodiquement
  • ✅ Utiliser HTTPS pour toutes les requêtes API

Gestion des erreurs

  • ✅ Toujours vérifier le champ success dans les réponses
  • ✅ Implémenter une logique de nouvelle tentative avec backoff exponentiel pour les erreurs transitoires (429, 500, 502)
  • ✅ Gérer les limites de taux avec élégance
  • ✅ Enregistrer les erreurs pour le débogage et la surveillance

Performance

  • ✅ Stocker le messageId à des fins de suivi
  • ✅ Utiliser async/await ou des promesses pour les appels non bloquants
  • ✅ Implémenter une gestion appropriée des délais d'attente
  • ✅ Ne pas envoyer de messages en double

Bonnes pratiques OTP

  • ✅ Toujours vérifier les OTP côté serveur
  • ✅ Ne pas exposer les codes OTP dans les logs
  • ✅ Gérer les limites de taux avec élégance
  • ✅ Choisir le canal approprié (SMS ou WhatsApp) en fonction de la préférence de l'utilisateur
  • ✅ Gérer les erreurs du fournisseur WhatsApp (502) avec un repli sur SMS si nécessaire

Support


Besoin d'aide ? Contactez le support Chinqit ou consultez le guide de dépannage.