Vous cherchez Sinch Engage ? Vous êtes maintenant sur le site principal de Sinch. Retourner à Sinch Engage

Développeurs

Envoyer des SMS avec l’API de conversation de Sinch en curl, Node.js et Python

Image pour Envoyer des SMS avec l’API de conversation de Sinch en curl, Node.js et Python

Le API de conversation est la méthode pour envoyer des SMS avec Sinch. Chaque message passe par un seul point de terminaison, POST https://{region}.conversation.api.sinch.com/v1/projects/{project_id}/messages:send, et ce même point de terminaison couvre RCS, WhatsApp et les autres canaux de messagerie. La requête que vous rédigez aujourd’hui pour un message texte aura la même structure lorsque vous ajouterez un deuxième canal par la suite. Cet article configure une application d’API de conversation avec le canal SMS et envoie un message de trois façons différentes : avec curl, avec le SDK Node.js et avec le SDK Python. Choisissez celle qui correspond à votre stack. Il s’agit à chaque fois d’un petit script unique que vous pouvez exécuter depuis votre terminal.

Ce dont vous aurez besoin

  • Un compte Sinch (S’inscrire). Les nouveaux comptes sont fournis avec un numéro de test.
  • Un téléphone capable de recevoir des SMS. Les comptes d’essai peuvent limiter les numéros auxquels vous pouvez envoyer des messages. Vérifiez donc le destinataire dans les paramètres de votre compte depuis le tableau de bord.
  • Vous avez besoin de curl et de jq pour la version shell, de Node.js 20 ou supérieur pour Node.js, ou de Python 3.9 ou supérieur pour Python.

Configurer une application d’API de conversation

L’API de conversation envoie des messages depuis une application. L’application contient les canaux que vous avez connectés, et le canal SMS relie l’application à l’abonnement du service SMS auquel appartient votre numéro.

  1. Dans le tableau de bord Sinch, ouvrez API de conversation dans le menu de gauche. Acceptez les conditions et cliquez sur OBTENIR L’ACCÈS si vous ne l’avez jamais utilisée auparavant.
  2. Accédez à Paramètres, puis à Clés d’accès, et créez une clé d’accès. Copiez l’ID de la clé et le secret de la clé. Le secret ne s’affiche qu’une seule fois.
  3. Accédez à API de conversation, puis à Applications, et créez une application. Choisissez la région qui correspond à votre abonnement de service SMS : US, EU ou Brésil. Copiez l’ID de l’application.
  4. Dans l’application, cliquez sur CONFIGURER LE CANAL sur la ligne SMS, choisissez votre abonnement dans la liste déroulante et confirmez.

Voici d’où provient chaque valeur :

Variable d’environnementOù la trouver
SINCH_PROJECT_IDParamètres, Paramètres du projet
SINCH_KEY_ID, SINCH_KEY_SECRETParamètres, Clés d’accès
SINCH_APP_IDAPI de conversation, Applications. L’ID de l’application, pas l’ID du projet
SINCH_SMS_SENDERNuméros, Vos numéros. Le numéro attribué à l’abonnement, au format E.164
SINCH_REGIONLa région dans laquelle vous avez créé l’application : us, eu ou br

Exportez-les dans votre shell :

                                

                                    export SINCH_PROJECT_ID="YOUR_PROJECT_ID"
export SINCH_KEY_ID="YOUR_KEY_ID"
export SINCH_KEY_SECRET="YOUR_KEY_SECRET"
export SINCH_APP_ID="YOUR_APP_ID"
export SINCH_SMS_SENDER="+12025550123"
export SINCH_REGION="us"
                                
                            

Conservez le secret de la clé en dehors de votre système de contrôle de version. En production, chargez-le depuis un gestionnaire de secrets.

Envoyer un SMS avec curl

Deux requêtes. La première échange votre clé d’accès contre un jeton OAuth 2.0 provenant de https://auth.sinch.com/oauth2/token, qui reste valide pendant environ une heure. La seconde envoie le message au point de terminaison messages:send dans la région de votre application.

Enregistrez ceci sous le nom send-sms.sh :

                                

                                    #!/usr/bin/env bash
# Send one SMS with the Sinch Conversation API using curl and jq.
# Usage: bash send-sms.sh +15551234567 "Hello from Sinch"
set -euo pipefail

: "${SINCH_PROJECT_ID:?Set SINCH_PROJECT_ID}"
: "${SINCH_KEY_ID:?Set SINCH_KEY_ID}"
: "${SINCH_KEY_SECRET:?Set SINCH_KEY_SECRET}"
: "${SINCH_APP_ID:?Set SINCH_APP_ID}"
: "${SINCH_SMS_SENDER:?Set SINCH_SMS_SENDER}"
region="${SINCH_REGION:-us}"

to="${1:?Usage: send-sms.sh  }"
text="${2:?Usage: send-sms.sh  }"

if [[ ! "$to" =~ ^\+[1-9][0-9]{1,14}$ ]]; then
  echo "Use E.164 format for the number, for example +15551234567. Got: $to" >&2
  exit 1
fi

access_token=$(curl --silent --show-error --fail-with-body \
  https://auth.sinch.com/oauth2/token \
  --user "$SINCH_KEY_ID:$SINCH_KEY_SECRET" \
  --data grant_type=client_credentials | jq -r .access_token)

body=$(jq -n \
  --arg app_id "$SINCH_APP_ID" \
  --arg to "$to" \
  --arg text "$text" \
  --arg sender "$SINCH_SMS_SENDER" \
  '{
    app_id: $app_id,
    recipient: { identified_by: { channel_identities: [{ channel: "SMS", identity: $to }] } },
    message: { text_message: { text: $text } },
    channel_properties: { SMS_SENDER: $sender }
  }')

curl --silent --show-error --fail-with-body \
  "https://$region.conversation.api.sinch.com/v1/projects/$SINCH_PROJECT_ID/messages:send" \
  --header "Authorization: Bearer $access_token" \
  --header "Content-Type: application/json" \
  --data "$body"
echo
                                
                            

Créer le corps de la requête avec jq évite que les guillemets et les retours à la ligne de votre message ne cassent le JSON. Exécutez-le avec votre propre numéro :

                                

                                    bash send-sms.sh +15551234567 "Hello from the Sinch Conversation API"
                                
                            
                                

                                    {"message_id":"01M613QSW2Q112R8FYHW29E5K9","accepted_time":"2026-10-28T11:18:46.402Z"}
                                
                            

Le corps de la requête comporte trois parties que vous utiliserez à chaque envoi :

  • recipient.identified_by.channel_identities indique qui reçoit le message et sur quel canal. Pour les SMS, l’identité est le numéro de téléphone.
  • message.text_message.text représente le message. Le même objet message transporte les médias, les cartes et les autres types sur les canaux qui les prennent en charge.
  • channel_properties.SMS_SENDER est le numéro d’où provient le message. Vous pouvez l’omettre si votre abonnement dispose d’un expéditeur par défaut. Définissez-le tout de même tant que vous utilisez le numéro de test.

Envoyer un SMS avec Node.js

Le Le SDK Node.js de Sinch gère le jeton pour vous. Installez-le avec TypeScript et tsx :

                                

                                    npm init -y
npm pkg set type=module
npm install @sinch/sdk-core@1.7.0
npm install --save-dev typescript@5.9 tsx @types/node@24
mkdir -p src
                                
                            

Enregistrez ceci sous le nom src/send-sms.ts :

                                

                                    import { SinchClient } from "@sinch/sdk-core";

function requireEnv(name: string): string {
  const value = process.env[name];
  if (!value) {
    throw new Error(`Set the ${name} environment variable`);
  }
  return value;
}

const [to, text] = process.argv.slice(2);
if (!to || !text) {
  throw new Error('Usage: npm run send --  ""');
}
if (!/^\+[1-9]\d{1,14}$/.test(to)) {
  throw new Error(`Use E.164 format for the number, for example +15551234567. Got: ${to}`);
}

const sinchClient = new SinchClient({
  projectId: requireEnv("SINCH_PROJECT_ID"),
  keyId: requireEnv("SINCH_KEY_ID"),
  keySecret: requireEnv("SINCH_KEY_SECRET"),
  conversationRegion: process.env.SINCH_REGION ?? "us",
});

const response = await sinchClient.conversation.messages.sendTextMessage({
  sendMessageRequestBody: {
    app_id: requireEnv("SINCH_APP_ID"),
    recipient: {
      identified_by: {
        channel_identities: [{ channel: "SMS", identity: to }],
      },
    },
    message: { text_message: { text } },
    channel_properties: { SMS_SENDER: requireEnv("SINCH_SMS_SENDER") },
  },
});

console.log(`Accepted message ${response.message_id} at ${response.accepted_time?.toISOString()}`);
                                
                            

Ajoutez un script à package.json et exécutez-le :

                                

                                    npm pkg set scripts.send="tsx src/send-sms.ts"
npm run send -- +15551234567 "Hello from the Sinch Node.js SDK"
                                
                            
                                

                                    Accepted message 01M613R541V5R0CMSY5BNP4DSA at 2026-10-28T11:18:57.921Z
                                
                            

Le corps de la requête utilise le même JSON que la version curl, avec les mêmes noms de champs en snake_case. sendTextMessage est le raccourci typé pour un message texte. conversationRegion est défini sur us par défaut. Vous devez donc le définir si votre application est en eu ou en br.

Envoyer un SMS avec Python

Le Le SDK Python de Sinch prend en charge l’API de conversation à partir de la version 2.0. Installez-le dans un environnement virtuel :

                                

                                    python3 -m venv .venv
source .venv/bin/activate
pip install sinch==2.3.0
                                
                            

Enregistrez ceci sous le nom send_sms.py :

                                

                                    import os
import re
import sys

from sinch import SinchClient
from sinch.core.exceptions import SinchException


def require_env(name: str) -> str:
    value = os.environ.get(name)
    if not value:
        sys.exit(f"Set the {name} environment variable")
    return value


if len(sys.argv) != 3:
    sys.exit('Usage: python send_sms.py  ""')

to, text = sys.argv[1], sys.argv[2]
if not re.fullmatch(r"\+[1-9]\d{1,14}", to):
    sys.exit(f"Use E.164 format for the number, for example +15551234567. Got: {to}")

sinch_client = SinchClient(
    project_id=require_env("SINCH_PROJECT_ID"),
    key_id=require_env("SINCH_KEY_ID"),
    key_secret=require_env("SINCH_KEY_SECRET"),
    conversation_region=os.environ.get("SINCH_REGION", "us"),
)

try:
    response = sinch_client.conversation.messages.send_text_message(
        app_id=require_env("SINCH_APP_ID"),
        text=text,
        recipient_identities=[{"channel": "SMS", "identity": to}],
        channel_properties={"SMS_SENDER": require_env("SINCH_SMS_SENDER")},
    )
except SinchException as error:
    sys.exit(f"Sinch API error: {error}")

print(f"Accepted message {response.message_id} at {response.accepted_time}")
                                
                            
                                

                                    python send_sms.py +15551234567 "Hello from the Sinch Python SDK"
                                
                            
                                

                                    Accepted message 01M613R7AK2SST6VXH24HVF278 at 2026-10-28 11:19:00.179000+00:00
                                
                            

Le SDK Python utilise des arguments nommés au lieu d’un corps de requête. Définissez conversation_region à chaque fois : le client Python n’a pas de région par défaut pour l’API de conversation.

Accepté ne signifie pas livré

Une réponse 200 avec un message_id signifie que Sinch a accepté le message. La confirmation que le téléphone l’a bien reçu arrive plus tard, sous la forme d’un rapport de livraison envoyé à un webhook sur votre application. Pour les SMS, le statut du rapport passe de QUEUED_ON_CHANNEL à DELIVERED ou FAILED. Le numéro de téléphone dans le rapport est renvoyé sans le + initial. Normalisez donc les numéros avant d’associer les rapports aux destinataires.

Pour obtenir des rapports, ajoutez un webhook à l’application avec le déclencheur MESSAGE_DELIVERY. Dans le tableau de bord, ouvrez l’application et ajoutez-le sous Webhooks. Avec l’API, obtenez un jeton et effectuez une requête :

                                

                                    SINCH_ACCESS_TOKEN=$(curl --silent --show-error --fail-with-body \
  https://auth.sinch.com/oauth2/token \
  --user "$SINCH_KEY_ID:$SINCH_KEY_SECRET" \
  --data grant_type=client_credentials | jq -r .access_token)

curl --silent --show-error --fail-with-body \
  "https://$SINCH_REGION.conversation.api.sinch.com/v1/projects/$SINCH_PROJECT_ID/webhooks" \
  --header "Authorization: Bearer $SINCH_ACCESS_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "app_id": "YOUR_APP_ID",
    "target": "https://example.com/sinch/callbacks",
    "target_type": "HTTP",
    "triggers": ["MESSAGE_DELIVERY", "MESSAGE_INBOUND"]
  }'
                                
                            

MESSAGE_INBOUND vous envoie également les réponses. Un rapport en échec inclut un motif reason avec un code qui vous en indique la cause. C’est ici qu’apparaît un numéro d’expéditeur rejeté ou un destinataire auquel votre compte ne peut pas envoyer de message. Sinch réessaie d’appeler un webhook qui ne répond pas avec un code 2xx. Le gestionnaire doit donc pouvoir gérer la réception du même rapport deux fois.

Pourquoi la requête se présente ainsi

Certains choix dans ces scripts méritent d’être expliqués, car la documentation présente d’autres options.

OAuth 2.0 au lieu de l’authentification de base

L’API de conversation accepte également l’ID et le secret de votre clé en tant qu’authentification de base directement sur messages:send. Le guide de démarrage l’utilise pour le premier appel. L’authentification de base est fortement limitée en termes de fréquence et est conçue pour les tests. La requête de jeton représente un appel supplémentaire, mais les SDK la font pour vous et c’est ce que vous exécuterez en production. Le script curl l’utilise donc dès le départ.

identified_by au lieu de contact_id

Vous pouvez adresser un message à un numéro de téléphone avec identified_by, ou à un contact préalablement enregistré par l’API avec contact_id. Les applications créées après le 16 avril 2025 sont par défaut en mode Dispatch. Ce mode n’enregistre pas les contacts, de sorte que contact_id n’a aucun élément vers lequel pointer. identified_by fonctionne dans les deux modes. Passez l’application en mode Conversation si vous souhaitez que les contacts et l’historique des conversations soient enregistrés.

Définir SMS_SENDER à chaque fois

Sans SMS_SENDER, le message est envoyé depuis l’expéditeur par défaut de l’abonnement, s’il y en a un. Vous devez le définir pour le numéro de test sur un nouveau compte. Un expéditeur rejeté par le réseau ne fait pas échouer la requête HTTP : cela s’affiche plus tard sous la forme d’un rapport de livraison FAILED. Le fait de le définir explicitement rend l’expéditeur visible dans votre code plutôt que dans un paramètre du tableau de bord.

Diriger votre agent de codage vers la bonne API

Les agents de codage se sont formés sur des années d’exemples sur le web, dont beaucoup utilisent l’ancienne API SMS (XMS) autonome. Cette API a atteint sa fin de commercialisation le 15 avril 2026, et elle reste disponible uniquement pour les intégrations déjà développées dessus. Tout nouveau projet doit utiliser l’API de conversation, même sur un compte qui a déjà utilisé l’API SMS par le passé. Si vous avez du code basé sur l’API SMS, Migrer de l’API SMS de Sinch vers l’API de conversation en fait la correspondance champ par champ.

Si vous demandez à un agent d’« envoyer un SMS avec Sinch » et qu’il écrit du code pour /xms/v1/, précisez-lui l’API que vous souhaitez. Une ligne dans le fichier AGENTS.md ou CLAUDE.md de votre projet permet de le faire pour chaque session :

                                

                                    ## Sinch
- Send SMS with the Sinch Conversation API (`/v1/projects/{project_id}/messages:send`), not the SMS API (`/xms/v1/`).
- Use `@sinch/sdk-core` (Node.js) or `sinch` (Python), with project ID, key ID, and key secret.
                                
                            

Le Les skills d’agent Sinch vont plus loin. Elles fournissent à votre agent les structures de requête de l’API de conversation, les règles du canal SMS et les étapes de configuration. Le Les plugins Sinch pour Claude Code, Cursor et l’interface de ligne de commande Gemini regroupent ces skills avec le serveur MCP Sinch, qui envoie également des SMS via l’API de conversation.

Résolution de problèmes

  • 404 depuis messages:send. La région dans l’URL ne correspond pas à la région de l’application. Une application créée dans l’UE n’est joignable que sur eu.conversation.api.sinch.com. Vérifiez la région dans les paramètres de l’application et définissez SINCH_REGION en conséquence.
  • 401 depuis le point de terminaison du jeton. L’ID de la clé ou le secret est incorrect, ou bien vous avez utilisé un ID de projet à la place de l’ID de la clé. Les clés d’accès se trouvent sous Paramètres, Clés d’accès. Si vous avez perdu le secret, créez une nouvelle clé.
  • 400 mentionnant le canal. Le canal SMS n’est pas configuré sur l’application, ou le canal n’est pas associé à un abonnement. Ouvrez l’application et vérifiez la ligne SMS.
  • L’API a accepté le message mais rien n’est arrivé. Consultez le rapport de livraison pour le message_id. Sur un compte d’essai, vérifiez que le destinataire correspond à un numéro auquel le compte peut envoyer des messages. Pour les numéros américains, le trafic provenant d’un code long à 10 chiffres nécessite l’enregistrement d’une 10DLC marque et d’une campagne.
  • L’application se trouve dans une région différente de celle du numéro. L’application doit se trouver dans la même région que l’abonnement du service SMS. S’ils ne correspondent pas, créez une nouvelle application dans la bonne région et configurez-y le canal SMS.

Prochaines étapes

À partir d’ici, la même requête permet d’envoyer des messages vers d’autres canaux. Ajoutez RCS ou WhatsApp à l’application, donnez au destinataire une identité pour chaque canal dans channel_identities, et définissez channel_priority_order sur la requête, par exemple ["RCS", "SMS"]. Le page des concepts clés explique à quel moment l’API de conversation bascule vers le canal suivant. Si vous avez du code basé sur l’API SMS autonome, Migrer de l’API SMS de Sinch vers l’API de conversation couvre les lots, les rapports de livraison et les messages entrants.

Ressources complémentaires