fr
Guide d'intégration Webhook

Intégration webhook des campagnes Alvio

Chaque campagne Alvio peut recevoir des contacts via une source webhook dédiée. L'écran de campagne fournit l'URL et un jeton secret. Pour une intégration avec Salesforce Flow, consultez le guide OpenAPI Salesforce.

Pour recevoir les événements Alvio → CRM, consultez le guide des souscriptions aux webhooks de campagne : configuration, catalogue des événements, signature, tests et réessais.

Créer la source de campagne

  1. Ouvrez la campagne dans Alvio et activez API/webhook comme source de contacts.
  2. Copiez l'URL du webhook et le jeton x-api-key. Le jeton n'est affiché qu'une fois ; conservez-le dans le gestionnaire de secrets de l'intégration.
  3. Pour tester sans envoi immédiat, utilisez une campagne en brouillon et un contact de test. Une campagne simple active, avec un modèle approuvé, peut envoyer dès la réception ; une séquence active est traitée de manière asynchrone.

Les anciens exemples avec des URL Test/Production partagées et l'en-tête api-key ne décrivent pas les sources actuelles par campagne. Utilisez l'URL et la clé affichées dans la campagne.

Intégrations existantes : cette évolution n'impose aucun changement d'URL, d'en-tête ou de clé à un webhook déjà en service. Gardez sa configuration actuelle. Le nouvel endpoint de suivi décrit ci-dessous requiert une source de campagne avec un jeton x-api-key ; créer ou régénérer ce jeton peut nécessiter de mettre à jour les clients qui utilisent déjà cette source.

Envoyer un contact

curl -X POST '<URL_WEBHOOK_CAMPAGNE>' \
  -H 'Content-Type: application/json' \
  -H 'x-api-key: <CLE_API_CAMPAGNE>' \
  -d '{
    "phone_number": "+33612345678",
    "contact_name": "Jane Doe",
    "contact_email": "jane@example.com",
    "crm_contact_id": "00Q000000000001",
    "salesforce_campaign_id": "701000000000001",
    "salesforce_campaign_member_id": "00v000000000001"
  }'

phone_number est le champ canonique requis pour cette intégration. Privilégiez le format E.164. crm_contact_id est un identifiant stable de Lead ou de Contact ; Alvio l'utilise avec le numéro normalisé pour reconnaître les renvois vers la même campagne. Les identifiants de campagne et de Campaign Member Salesforce sont conservés comme métadonnées. D'autres champs JSON peuvent être transmis, y compris les objets contact, campaign, custom, sales, sdr ou assignees.

Le récepteur accepte également un tableau de contacts ou { "contacts": [...] }. Pour Salesforce External Services, envoyez un objet par action Flow, conformément au schéma OpenAPI.

Données et assignations optionnelles

ChampUsage
crm_deal_idRéférence d'opportunité ou de deal.
lifecycle_stageStade CRM comme lead, customer ou churned ; voir le suivi du cycle de vie.
contactIdentité et entreprise : name, email, company, postal_code, etc.
campaignAcquisition : source, utm_source, ad_id, etc.
custom ou custom_fieldsAttributs libres pour le routage et les modèles.
sales ou sdrPersonne assignée : nom, prenom, email, lien_calendrier, slack_id, phone_number.
assigneesPersonnes supplémentaires, avec les mêmes champs et un role comme sales, sdr ou support.

Vous pouvez combiner sales, sdr et assignees. contact.name ou contact.email peut alimenter les champs d'affichage si contact_name ou contact_email est absent. Les champs additionnels sont conservés comme métadonnées du contact de campagne.

Vérifier le résultat

L'URL générée est une source Hookdeck. Sa réponse HTTP confirme la réception par la source, pas l'envoi d'un message par Alvio. Pour lire l'état de traitement et de livraison, utilisez la même clé de campagne :

curl 'https://www.alvio.ai/api/campaigns/<ID_CAMPAGNE>/contact-results?limit=100&offset=0' \
  -H 'x-api-key: <CLE_API_CAMPAGNE>'

Suivez next_offset jusqu'à null. Lors des passages suivants, repartez de offset=0 : l'état d'un contact déjà présent peut changer. delivery_status décrit le dernier message de la campagne (sent, delivered, read, replied ou failed) ; contact_status, sequence_status et progress_status décrivent l'exécution. Un état de livraison null signifie qu'aucune trace d'envoi n'est encore disponible.

Le contrat OpenAPI 3.0 (opens in a new tab) expose aussi une opération d'entrée directe dans Alvio, avec une réponse de traitement structurée. Elle exige une campagne dotée d'un jeton API. Une réponse HTTP 200 peut contenir errors ou skipped non nuls : vérifiez ces compteurs.

Rendez-vous et rappels urgents

Les champs d'urgence sont disponibles dans les webhooks sortants de campagne, pour toutes les campagnes et tous les clients. MEETING_BOOKED et ESCALATION peuvent signaler un rendez-vous ou un rappel urgent. Les autres types d'événement incluent urgent: false et urgency_reason: null.

Dans les abonnements webhook de la campagne, abonnez votre endpoint aux deux événements avec event_type: "update". MEETING_BOOKED signale un rendez-vous confirmé. ESCALATION signale un transfert au conseiller, notamment une demande de rappel sans créneau réservé dans l'agenda.

Champs d'urgence

ChampTypeSignification
data.urgentbooléentrue si la demande est à traiter en priorité ; sinon false.
data.urgency_reasonchaîne ou nullimmediate_request, within_10_minutes, ou null si non urgent.

Pour MEETING_BOOKED, urgent vaut true si le rendez-vous commence entre 0 et 10 minutes incluses après l'enregistrement de la réservation dans Alvio. Le motif est within_10_minutes. Par exemple, une réservation enregistrée à 9 h pour un début à 9 h 10 est urgente ; un début à 9 h 10 min 01 s ne l'est pas. Un début déjà passé ou invalide ne déclenche pas l'urgence.

La comparaison utilise les instants absolus, indépendamment du fuseau d'affichage. Elle se base sur l'heure de réservation initiale, pas sur l'heure de livraison du webhook : un rendez-vous pris la veille ne devient pas urgent parce que son webhook arrive juste avant l'appel.

Extrait d'un événement dont la réservation a été enregistrée à 9 h :

{
  "event_type": "update",
  "event_name": "MEETING_BOOKED",
  "data": {
    "meeting_type": "callback",
    "booking_status": "confirmed",
    "start": "2026-10-12T09:10:00+02:00",
    "end": "2026-10-12T09:20:00+02:00",
    "timezone": "Europe/Paris",
    "location": "phone",
    "urgent": true,
    "urgency_reason": "within_10_minutes"
  }
}

Rappel immédiat sans rendez-vous confirmé

Pour ESCALATION, lorsque l'agent enregistre une demande structurée de rappel, une demande explicite de rappel maintenant, immédiatement ou dès que possible produit urgent: true avec urgency_reason: "immediate_request". Un rappel explicitement demandé dans les 5 ou 10 prochaines minutes produit urgent: true avec urgency_reason: "within_10_minutes".

{
  "event_type": "update",
  "event_name": "ESCALATION",
  "data": {
    "status": "escalated",
    "reason": "Le prospect demande un rappel immédiat.",
    "urgent": true,
    "urgency_reason": "immediate_request"
  }
}

Sans demande explicite de rappel urgent, les rappels plus tardifs, préférences vagues, questions et demandes de souscription ne sont pas urgents : urgent: false, urgency_reason: null. Une priority élevée sur un transfert ne suffit pas à identifier un rappel urgent : lisez data.urgent.

Une demande de rappel urgent ne crée pas de rendez-vous dans l'agenda et ne garantit pas l'heure d'appel du conseiller. Elle suit la file de traitement habituelle des webhooks : l'urgence ne garantit donc pas une livraison instantanée. La durée des rendez-vous, les horaires d'ouverture et le fuseau horaire suivent la configuration de chaque campagne. L'urgence ne permet pas de contourner un refus ou STOP.

Livraison et compatibilité

Ces exemples sont des extraits : l'enveloppe existante contient aussi event_id, occurred_at, lead, external_references, alvio et source_data. Sa version reste 2026-04-08.

La décision d'urgence est enregistrée avant livraison. Les réessais et renvois conservent le même drapeau et le même motif ; dédupliquez avec event_id. Les anciens événements peuvent ne pas contenir ces champs : leur absence signifie « urgence non renseignée ». Ils ne sont pas réexpédiés pour ajouter l'urgence. Les envois déjà en file conservent leur contenu initial. Si une ancienne réservation ne dispose pas d'une heure de réservation initiale fiable, ou si un transfert ne contient pas de préférence structurée de rappel, l'urgence n'est pas déduite de l'heure de livraison, du texte libre, des données du prospect ou de la priorité du transfert.

Erreurs et sécurité

  • 401 : clé absente ou invalide. Vérifiez qu'elle appartient à la campagne.
  • 400 ou 422 : requête invalide, liste vide ou règle de validation propre à la campagne.
  • 404 : identifiant de campagne inconnu sur l'API directe.
  • 5xx ou délai dépassé : réessayez avec un délai croissant. Gardez un crm_contact_id stable pour identifier les renvois.

Utilisez HTTPS, ne journalisez pas la clé, ne l'exposez pas dans des variables Flow visibles par les utilisateurs et régénérez-la depuis la campagne en cas d'exposition. La nouvelle clé invalide la précédente.