API ReactIn

Suivre les événements de campagne via API

Lisez toute la timeline de prospection d'une campagne — invitations envoyées, acceptées, messages, réponses et leads ignorés — de manière programmatique, pour synchroniser le statut dans votre CRM ou créer vos propres rapports.

3 min de lecture

Chaque lead traité par une campagne génère un événement de campagne — une timeline qui enregistre le moment où l'invitation a été envoyée, où elle a été acceptée, où vos messages sont partis, où le lead a répondu, ou pourquoi il a été ignoré. L'API Campaign Events expose cette timeline de manière programmatique, pour synchroniser le statut de votre prospection dans votre CRM, construire vos propres rapports ou déclencher des workflows lorsqu'un lead répond.

Prérequis

Avant de commencer, vous avez besoin de :

  • Votre Organization ID — identifie l'espace de travail que vous interrogez.

  • Votre Campaign ID — la campagne dont vous voulez lire les événements. Vous le trouverez dans l'URL de la campagne ou ses paramètres.

  • Votre API key d'organisation — un token secret utilisé pour authentifier chaque requête. Vous la trouvez, avec votre Organization ID, dans Paramètres → API Keys de l'app.

⚠️ Cet endpoint n'accepte que votre API key d'organisation ou une clé rattachée à la campagne. Une clé de SmartList/liste (celle générée automatiquement à la création d'une liste « ReactIn API ») ne fonctionne pas ici et retourne 401 Unauthorized.

Gardez votre API key secrète. Ne la committez jamais dans votre code source et ne l'exposez jamais côté client.

URL de base

Tous les endpoints sont servis depuis votre instance ReactIn et rattachés à votre organisation :

https://app.reactin.io/api/{organizationId}/...

Authentification

Authentifiez-vous en envoyant votre API key d'organisation (ou rattachée à la campagne) dans l'en-tête Authorization. Le préfixe Bearer comme le token brut sont acceptés :

Authorization: Bearer YOUR_API_KEY

Une clé manquante ou invalide retourne 401 Unauthorized.

Endpoint

GET /api/{organizationId}/campaigns/{campaignId}/events

Retourne les événements de la campagne, triés du plus récent au plus ancien par date de création (les leads entrés le plus récemment en premier — pas par dernière activité), paginés et filtrables par statut et par date.

Paramètres de requête

ParamètreTypeDéfautDescription
pagenumber1Numéro de page (≥ 1)
pageSizenumber10Événements par page (10–50)
statusstringFiltre par étape atteinte — remonte les événements ayant atteint au moins l'étape donnée (cumulatif, pas seulement l'étape courante exacte). Séparez plusieurs valeurs par une virgule pour les combiner (logique OU).
dateFromstring (ISO 8601)Uniquement les événements créés à partir de cette date
dateTostring (ISO 8601)Uniquement les événements créés jusqu'à cette date

Valeurs de filtre status disponibles. Chacune remonte les événements ayant atteint au moins cette étape :

ValeurSignification
pendingEn file d'attente, aucune action encore effectuée
connection_sentInvitation de connexion envoyée
connection_acceptedInvitation de connexion acceptée
message_sentPremier message envoyé
message_repliedLe lead a répondu
follow_up_sentUn message de relance a été envoyé
skippedLe lead a été ignoré (voir skippedReason)

ℹ️ Le filtre status est cumulatif : ?status=connection_accepted remonte aussi les leads ayant depuis reçu un message ou répondu (leur champ status en réponse vaudra alors message_sent, message_replied, etc.). ?status=skipped n'inclut pas les leads ignorés car déjà dans votre réseau, bien qu'ils affichent "status": "skipped" dans la réponse.

Exemple de requête

curl -s \
  -H "Authorization: Bearer YOUR_API_KEY" \
  "https://app.reactin.io/api/ORG_ID/campaigns/CAMPAIGN_ID/events?status=message_replied,connection_accepted&pageSize=25"

Exemple de réponse

{
  "data": [
    {
      "id": "evt_123",
      "status": "message_replied",
      "createdAt": "2026-05-19T10:48:00.000Z",
      "connectionSentAt": "2026-05-15T09:00:00.000Z",
      "connectionAcceptedAt": "2026-05-16T14:20:00.000Z",
      "messageSentAt": "2026-05-17T08:30:00.000Z",
      "messageRepliedAt": "2026-05-19T10:48:00.000Z",
      "followUpMessageSentAt": null,
      "lead": {
        "firstName": "Jane",
        "lastName": "Doe",
        "email": "jane.doe@example.com",
        "linkedinProfileUrl": "https://www.linkedin.com/in/janedoe"
      },
      "skippedAt": null,
      "skippedReason": null
    }
  ],
  "page": 1,
  "nextPage": 2
}

Champs de la réponse

  • data[] — les événements de cette page.

    • status — la dernière étape atteinte par le lead (uniquement la plus avancée : un lead ayant accepté puis répondu — ou ayant répondu après l'envoi d'une relance — affiche message_replied, et non follow_up_sent). C'est l'étape courante, alors que le filtre status ci-dessus est cumulatif. Pour détecter les réponses de façon fiable, basez-vous sur messageRepliedAt (ou le filtre message_replied) plutôt que de supposer qu'une étape de relance signifie que le lead n'a pas répondu.

    • connectionSentAt, connectionAcceptedAt, messageSentAt, messageRepliedAt, followUpMessageSentAt — horodatages de chaque étape, ou null si elle n'a pas eu lieu.

    • lead — le lead auquel appartient l'événement (firstName, lastName, email, linkedinProfileUrl).

    • skippedAt / skippedReason — renseignés lorsque le lead a été ignoré, sinon null.

  • page — numéro de la page courante.

  • nextPage — le numéro de la page suivante, ou null s'il n'y en a plus.

Limites de débit

Les requêtes sont limitées par organisation (30 requêtes / minute en lecture). Chaque réponse inclut l'état courant de la limite via les en-têtes X-RateLimit-*. Lorsque vous dépassez la limite, vous recevez 429 Too Many Requests avec un en-tête Retry-After (en secondes) — patientez ce délai avant de réessayer.

Gestion des erreurs

StatutSignificationCause typique
200OKRequête réussie
400Bad RequestParamètre de requête invalide (status incorrect, date malformée, pageSize hors limites)
401UnauthorizedAPI key manquante ou invalide
404Not FoundL'organisation ou la campagne n'existe pas dans votre espace de travail
429Too Many RequestsLimite de débit dépassée
500Internal Server ErrorErreur de notre côté — réessayez

En pratique

Une boucle de reporting typique ressemble à ceci :

  1. Interrogez GET /campaigns/{campaignId}/events?status=message_replied régulièrement pour détecter les nouvelles réponses.

  2. Gardez trace des événements déjà traités via leur id, et re-vérifiez-les à chaque poll — le statut et les horodatages d'un lead évoluent dans le temps. N'utilisez pas dateFrom comme curseur incrémental : il filtre sur la date de création de l'événement (l'entrée du lead dans la campagne), pas sur la date de la réponse ou de l'acceptation — une nouvelle réponse sur un lead ancien serait donc manquée.

  3. Parcourez les pages via nextPage jusqu'à ce qu'il vaille null.

  4. Synchronisez chaque événement dans votre CRM ou déclenchez votre propre workflow (alerte, tâche, transfert).