Un seul appel envoie un message enrichi aux mobiles compatibles et un SMS aux autres. Ce guide donne le contrat réel de l'endpoint : les trois formats, les quatre types de boutons, la mécanique du repli, et la façon de mesurer ce qui est réellement parti en RCS.
Si vous avez déjà intégré /messages/sms, l'authentification et la logique générale sont identiques : mêmes en-têtes X-APP-ID et X-API-KEY, même mécanique de déduplication par external_id, même scheduleAt en UTC.
Trois différences comptent, et la première est celle qui casse les intégrations recopiées d'un endpoint à l'autre :
| /messages/sms | /messages/rcs | |
|---|---|---|
| Destinataires | recipients : un tableau de chaînes | contacts : un tableau d'objets, ou contactlist |
| Contenu | content : du texte | type + data, dont la forme dépend du type |
| Réponse | un credits_used | deux compteurs séparés, rcs et sms |
Le format text est le plus simple, et le bon point de départ pour valider vos identifiants : aucun média à héberger, aucun bouton à concevoir.
curl -X POST https://api.conexteo.com/messages/rcs \
-H "X-APP-ID: VOTRE_APP_ID" \
-H "X-API-KEY: VOTRE_CLE_API" \
-H "Content-Type: application/json" \
-d '{
"name": "Test RCS",
"type": "text",
"data": { "text": "Bonjour, votre commande est prête." },
"fallback": {
"content": "Bonjour, votre commande est prête.",
"sender": "MaBoutique"
},
"contacts": [ { "recipient": "+33612345678" } ]
}'Chiffrer une campagne sans la déclencher. Ajoutez ?resumeBefore=true à l'URL : l'API retourne les crédits que l'envoi consommerait, ventilés entre RCS et SMS, sans envoyer un seul message. Sur une campagne RCS, c'est plus utile que sur un SMS — cela vous donne une estimation du taux de repli avant de payer.
C'est le format qui justifie le RCS. Une carte porte un visuel, un titre, une description et jusqu'à quatre boutons d'action :
{
"name": "Expédition commande",
"type": "card",
"data": {
"title": "Votre commande #4821 est expédiée",
"description": "Livraison prévue demain entre 9 h et 13 h.",
"media_message_url": "https://cdn.exemple.fr/colis.png",
"choices": [
{ "type": "url", "title": "Suivre le colis", "url": "https://…" },
{ "type": "call", "title": "Nous appeler", "phoneNumber": "+33176411075" },
{ "type": "text", "text": "Reporter" }
]
},
"fallback": {
"content": "Votre commande #4821 est expédiée. Suivi : https://…",
"sender": "MaBoutique"
},
"external_id": "order-4821-shipped",
"contacts": [ { "recipient": "+33612345678" } ]
}Trois limites à connaître avant de faire valider la maquette. Le titre d'un bouton est plafonné à 25 caractères — c'est court, et cela se découvre en général une fois les libellés arbitrés. Quatre boutons maximum par carte. Et le média doit être accessible publiquement à l'URL fournie : un fichier derrière une authentification ou une URL signée qui expire produit une carte sans visuel.
Le format d'image le plus piégeux est le WebP : il n'est pas accepté. Les formats admis sont le JPEG, le JPG, le PNG et le GIF pour les images, le MP4 et quelques variantes pour la vidéo. Or beaucoup de chaînes de publication convertissent automatiquement en WebP — y compris certains plugins d'optimisation WordPress. Vérifiez l'extension réellement servie par votre CDN, pas celle du fichier d'origine.
Le carrousel reprend la structure de la carte, en tableau. C'est le format des catalogues produits, des cartes de restaurant et des sélections de biens : le destinataire fait défiler horizontalement, chaque carte gardant ses propres boutons.
{
"type": "carousel",
"data": {
"cards": [
{
"title": "Manteau laine",
"description": "129 € — tailles 36 à 44",
"media_message_url": "https://cdn.exemple.fr/manteau.jpg",
"choices": [
{ "type": "url", "title": "Voir le produit", "url": "https://…" }
]
},
{
"title": "Bottines cuir",
"description": "89 € — tailles 36 à 41",
"media_message_url": "https://cdn.exemple.fr/bottines.jpg",
"choices": [
{ "type": "url", "title": "Voir le produit", "url": "https://…" }
]
}
]
}
}Dix cartes est le maximum. En pratique, en prévoir au moins deux : un carrousel d'une seule carte n'apporte rien de plus qu'une carte simple, et l'affichage y perd. Un carrousel reste facturé comme un seul message, pas comme dix envois — c'est ce qui rend ce format économiquement intéressant sur un catalogue.
| Type | Champs | Ce qu'il déclenche |
|---|---|---|
| text | text (≤ 25 car.) | Une réponse rapide. Le clic vous revient comme un message entrant, sur le webhook reply. |
| url | title (≤ 25), url (≤ 2048) | Ouvre un lien. Combiné au raccourcisseur en mode unique, il donne un suivi de clic par destinataire. |
| call | title (≤ 25), phoneNumber | Compose le numéro. Utile sur les rappels de rendez-vous et le service après-vente. |
| location | title, label, latitude, longitude | Ouvre un point sur la carte. Le format le plus sous-utilisé, et le plus efficace en retrait en magasin. |
Environ 85 % du parc mobile français reçoit le RCS — Android via Google Messages, iPhone depuis iOS 18. Les 15 % restants doivent recevoir autre chose, sinon votre campagne a des trous. C'est le rôle de l'objet fallback : un contenu SMS et un expéditeur, utilisés pour les destinataires non compatibles.
Deux stratégies existent, et le paramètre checkCapability tranche entre les deux :
Le RCS part vers l'ensemble des contacts, et le repli SMS se déclenche au retour de l'opérateur pour ceux qui ne l'ont pas reçu. Aucune préparation, aucune liste à analyser. C'est le mode à utiliser pour un envoi ponctuel ou transactionnel.
Seuls les contacts déjà analysés comme pleinement compatibles reçoivent le RCS ; les autres reçoivent directement le SMS de repli. Cela suppose une liste préalablement analysée, mais rend le résultat prévisible avant l'envoi.
Rédigez le repli comme un vrai message, pas comme une copie tronquée. C'est l'erreur la plus commune : on reprend le titre de la carte, on perd l'image et les boutons, et 15 % des destinataires reçoivent une phrase qui ne veut plus rien dire. Un repli efficace remplace le bouton par un lien court, et l'image par la mention qui comptait. Souvenez-vous que cette fraction du fichier n'a que ce message.
C'est le détail le plus utile de cet endpoint, et celui qu'on oublie de regarder. La réponse ne renvoie pas un compteur, mais deux :
{
"success": true,
"message": "message created",
"message_id": 123456,
"sms": { "credits_used": 158, "sms_count": 158 },
"rcs": { "credits_used": 842, "rcs_count": 842 }
}Sur cet envoi, 842 destinataires ont reçu le message enrichi et 158 le SMS de repli : un taux de compatibilité de 84 %, cohérent avec le parc français. Journalisez ces deux valeurs à chaque campagne : leur évolution dans le temps mesure la progression du RCS sur votre base, ce qu'aucune statistique de marché ne vous dira. Notez que message_id peut être null selon le mode d'envoi : ne le supposez pas toujours présent.
Le tableau contacts n'accepte pas des numéros, mais des objets. Seul recipient est obligatoire ; toute autre propriété que vous ajoutez devient une variable réutilisable dans le message :
"contacts": [
{ "recipient": "+33612345678", "prenom": "Alice", "commande": "4821" },
{ "recipient": "0606060606", "prenom": "Karim", "commande": "4822" }
]
// Ou, si vos listes vivent déjà dans Conexteo :
"contactlist": [1, 2]C'est ici que se casse une intégration recopiée depuis l'endpoint SMS. En SMS, recipients attend un tableau de chaînes. En RCS, contacts attend un tableau d'objets avec une clé recipient. Le code qui marchait en SMS renvoie un 400 en RCS, et le message d'erreur porte sur un champ qu'on croyait avoir rempli. Un million d'entrées maximum, comme pour le SMS.
| Code | Cause la plus probable |
|---|---|
| 200 | Campagne acceptée. Conserver message_id et les deux compteurs. |
| 400 | contacts envoyé comme un tableau de chaînes, data qui ne correspond pas au type déclaré, titre de bouton au-delà de 25 caractères, ou plus de 4 boutons. |
| 401 | App ID et clé API intervertis entre les deux en-têtes — bien plus souvent qu'une clé invalide. |
| 404 | Un identifiant de contactlist qui n'existe pas sur le compte. |
Le RCS n'a pas d'expéditeur alphanumérique libre comme le SMS : c'est un agent vérifié, portant le nom et le logo de votre marque, qui est assigné à votre compte. Sa création passe par une validation de Google : comptez deux à quatre semaines. Conexteo prend en charge le montage et la soumission du dossier. Pendant ce délai, vos envois partent en SMS classique : rien ne bloque le développement, vous pouvez intégrer et tester l'API avant que l'agent ne soit actif — c'est même l'ordre recommandé.
Le RCS remonte plus d'information que le SMS : en plus de la livraison, vous récupérez la lecture et les clics sur les boutons. Trois types d'événements sont poussés sur l'URL que vous déclarez : ack_rcs pour les statuts RCS — remis, lu, échec, repli SMS —, reply pour les réponses entrantes, y compris les clics sur les boutons de réponse rapide, et ack_sms pour les accusés de réception des messages de repli.
Le mode signé n'est pas optionnel en RCS. Contrairement aux accusés SMS, les statuts ack_rcs ne sont disponibles qu'en webhook signé — celui qui porte une signature HMAC et bénéficie des réessais, jusqu'à huit tentatives réparties sur environ dix-huit heures. Si vous ne recevez aucun statut RCS alors que vos campagnes partent, c'est la première chose à vérifier. La mise en œuvre côté serveur est détaillée sur les guides PHP, C# et Python.
Inscription gratuite, messages de test offerts, sans carte bancaire. L'API est accessible immédiatement : vous pouvez intégrer et valider vos payloads pendant que le dossier d'agent suit son cours.
Créer un compte gratuitement →