API ReactIn

Interagir avec l’Unified Inbox via l’API

L’Unified Inbox de ReactIn rassemble en un seul endroit toutes les conversations LinkedIn générées par vos campagnes.

6 min de lecture

L’API Unified Inbox expose ces mêmes données de façon programmatique, ce qui vous permet de synchroniser les conversations dans votre CRM, de créer des workflows de réponse personnalisés, de déclencher des alertes sur les nouveaux messages ou d’envoyer des réponses depuis vos propres outils.

Ce guide couvre l’authentification, chacun des endpoints disponibles, la pagination, les limites de débit et la gestion des erreurs — avec des exemples curl prêts à copier-coller.

Prérequis

Avant de commencer, vous avez besoin de deux éléments :

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

  • Votre API Key — un token secret utilisé pour authentifier chaque requête.

Les deux sont disponibles dans l’application sous Settings → API Keys.

Gardez votre clé API secrète. Elle accorde un accès complet en lecture/écriture à l’inbox de votre organisation. Ne la committez jamais dans un système de gestion de versions et ne l’exposez jamais dans du code côté client. Si elle fuite, régénérez-la depuis cette même page.

URL de base

Tous les endpoints sont servis sous votre instance ReactIn : https://app.reactin.io/api

Chaque chemin est rattaché à votre organisation : https://app.reactin.io/api/{organizationId}/...

Authentification

Authentifiez-vous en envoyant votre clé API dans l’en-tête Authorization. Le préfixe Bearer comme un token brut sont acceptés : Authorization: Bearer YOUR_API_KEY

Une clé manquante ou invalide renvoie 401 Unauthorized.

Endpoints

L’API Unified Inbox comporte trois endpoints :

MéthodeCheminObjectif
GET/api/{organizationId}/conversationsLister les conversations
GET/api/{organizationId}/conversations/{conversationId}/messagesLister les messages d’une conversation
POST/api/{organizationId}/conversations/{conversationId}/messagesEnvoyer un message

1. Lister les conversations

GET /api/{organizationId}/conversations

Renvoie les conversations liées aux comptes LinkedIn connectés de votre organisation, triées du plus récent au plus ancien (le message le plus récent en haut). Seules les conversations comportant au moins un message et rattachées à l’une de vos campagnes sont renvoyées.

Paramètres de requête

ParamètreTypeValeur par défautDescription
linkedinAccountIdstringFiltrer par un compte LinkedIn connecté spécifique
campaignIdstringFiltrer par une campagne spécifique
searchstringRecherche plein texte sur les noms de conversation/participants
cursorstringCurseur de pagination (voir Pagination)
limitnumber30Éléments par page (1–100)

Vous trouverez l’ID d’une campagne dans l’URL de la campagne ou dans ses paramètres, et l’ID d’un compte LinkedIn dans votre liste de comptes connectés.

Exemple de requête

curl -s \

  -H "Authorization: Bearer YOUR_API_KEY" \

  "https://app.reactin.io/api/ORG_ID/conversations?limit=20&search=acme"

Exemple de réponse

{

 "items": [

    {

      "id": "conv_a1b2c3",

      "name": "Jane Doe",

      "lastMessage": {

        "id": "msg_998877",

        "userId": "li_account_42",

        "text": "Thanks, that works for me!",

        "timestamp": "2026-05-19T10:48:00.000Z"

      },

      "unreadCount": 2,

      "isDisconnected": false,

      "participantsToDisplay": [

        {

          "id": "participant_77",

          "name": "Jane Doe",

          "avatarUrl": "https://media.linkedin.com/...",

          "linkedinUrl": "https://www.linkedin.com/in/janedoe",

          "headline": "Head of Growth at Acme",

          "company": "Acme",

          "leadId": "lead_55"

        }

      ]

    }

  ],

  "nextCursor":"conv_a1b2c5",

  "totalUnread": 7

}

Champs de la réponse

  • items[] — les conversations de cette page.

    • lastMessage — le message le plus récent, ou null s’il n’y en a aucun.

    • unreadCount — messages non lus dans cette conversation.

    • isDisconnected — true si le compte LinkedIn sous-jacent est déconnecté (vous ne pouvez pas y envoyer de messages).

    • participantsToDisplay[] — les contacts LinkedIn de la conversation. leadId est renseigné lorsque le contact correspond à un lead dans votre espace de travail ReactIn.

  • nextCursor — passez cette valeur en tant que cursor pour récupérer la page suivante, ou null lorsqu’il n’y en a plus.

  • totalUnread — total des messages non lus sur l’ensemble des conversations (pas seulement cette page).

2. Lister les messages d’une conversation

GET /api/{organizationId}/conversations/{conversationId}/messages

Renvoie les messages d’une conversation, triés du plus récent au plus ancien.

Vous pouvez copier l’ID d’une conversation depuis l’Unified Inbox — ouvrez la conversation et utilisez l’ID présent dans l’URL.

Paramètres de requête

ParamètreTypeValeur par défautDescription
cursorstringCurseur de pagination
limitnumber20Messages par page (1–100)

Exemple de requête

curl -s \

  -H "Authorization: Bearer YOUR_API_KEY" \

  "https://app.reactin.io/api/ORG_ID/conversations/conv_a1b2c3/messages?limit=50"

Exemple de réponse

{

   "items": [

    {

      "id": "msg_998877",

      "userId": "li_account_42",

      "text": "Thanks, that works for me!",

      "timestamp": "2026-05-19T10:48:00.000Z",

      "readAt": null,

      "metadata": {

        "campaignEvent": {

          "id": "evt_123",

          "campaign": { "id": "camp_9", "name": "Q2 Outreach" }

        },

        "sentFromInboxByUserId": null,

        "sentFromInboxByUserName": null,

        "sentFromInboxByUserEmail": null

      }

    }

  ],

  "nextCursor": "msg_998800",

  "conversation": {

    "id": "conv_a1b2c3",

    "name": "Jane Doe",

    "lastMessage": { "...": "..." },

    "unreadCount": 2,

    "participantsToDisplay": [ { "...": "..." } ]

  }

}

Champs de la réponse

  • items[] — les messages de cette page.

    • userId — l’expéditeur. Pour les messages envoyés par votre compte LinkedIn, il s’agit du provider ID du compte ; pour les messages entrants, il s’agit du provider ID du contact.

    • metadata.campaignEvent — renseigné lorsque le message a été généré par une étape de campagne ; null sinon.

    • metadata.sentFromInboxByUser* — renseigné lorsqu’un membre de l’équipe a envoyé le message depuis l’interface de l’Unified Inbox. Les messages envoyés via cette API ont ces champs à null, ce qui vous permet de distinguer le trafic API des réponses manuelles.

  • nextCursor — curseur pour la page suivante (plus ancienne), ou null.

  • conversation — les métadonnées de la conversation parente, pour vous éviter un appel séparé.

3. Envoyer un message

POST /api/{organizationId}/conversations/{conversationId}/messages

Envoie un message LinkedIn dans une conversation existante. Le message est délivré via le compte LinkedIn propriétaire de la conversation.

Corps de la requête

ChampTypeContraintes
contentstringRequis, 1–10 000 caractères (limite de LinkedIn)

Exemple de requête

curl -s -X POST \

  -H "Authorization: Bearer YOUR_API_KEY" \

  -H "Content-Type: application/json" \

  -d '{"content":"Hi Jane, following up on our chat — does Thursday work?"}' \

  "https://app.reactin.io/api/ORG_ID/conversations/conv_a1b2c3/messages"

Exemple de réponse

Le message créé est renvoyé, avec la même structure que dans la liste des messages :

{

  "id": "msg_998900",

  "userId": "li_account_42",

  "text": "Hi Jane, following up on our chat — does Thursday work?",

  "timestamp": "2026-05-19T11:02:00.000Z",

  "readAt": null,

  "metadata": {

    "campaignEvent": null,

    "sentFromInboxByUserId": null,

    "sentFromInboxByUserName": null,

    "sentFromInboxByUserEmail": null

  }

}

Notes

  • Le compte LinkedIn de la conversation doit être connecté. Envoyer vers un compte déconnecté renvoie 409 Conflict.

  • Une conversation ne peut recevoir de messages qu’une fois qu’elle dispose d’un fil de discussion côté LinkedIn. Si le chat n’est pas encore prêt (aucun message entrant reçu), l’API renvoie 409 Conflict — elle devient apte à l’envoi après la première réponse.

  • Les messages envoyés via l’API contournent les limites d’envoi quotidiennes de votre organisation ; utilisez donc cet endpoint de manière responsable.

Pagination

Tous les endpoints de listing utilisent une pagination basée sur un curseur :

  1. Effectuez la première requête sans curseur.

  2. Si la réponse contient un nextCursor non-null, passez-le en tant que paramètre de requête cursor lors de la requête suivante.

  3. Arrêtez-vous lorsque nextCursor est null.

# Page 1

curl -H "Authorization: Bearer YOUR_API_KEY" \

  "https://app.reactin.io/api/ORG_ID/conversations?limit=30"

# Page 2 — réutilisez nextCursor de la réponse précédente

curl -H "Authorization: Bearer YOUR_API_KEY" \

  "https://app.reactin.io/api/ORG_ID/conversations?limit=30&cursor=2026-05-19T10:48:00.000Z%7Cconv_a1b2c3"

Traitez le curseur comme une chaîne opaque — ne le construisez pas et ne l’analysez pas vous-même. Pensez à l’encoder pour l’URL (le caractère | devient %7C).

Limites de débit

Les requêtes sont soumises à une limite de débit par organisation :

MéthodeLimite
GET30 requêtes / minute
POST60 requêtes / minute

Chaque réponse inclut l’état actuel de la limite :

X-RateLimit-Limit: 30

X-RateLimit-Remaining: 28

X-RateLimit-Reset: 1747650000

Lorsque vous dépassez la limite, vous recevez 429 Too Many Requests avec un en-tête Retry-After (en secondes). Patientez et réessayez après ce délai.

Gestion des erreurs

L’API renvoie des codes de statut HTTP standards :

StatutSignificationCause typique
200OKRequête réussie
400Bad RequestParamètre de requête, corps ou curseur invalide
401UnauthorizedClé API manquante ou invalide
404Not FoundLa conversation n’existe pas ou n’appartient pas à votre organisation
409ConflictCompte LinkedIn déconnecté, ou chat pas encore disponible
429Too Many RequestsLimite de débit dépassée
500Internal Server ErrorÉchec de la livraison LinkedIn

Les réponses d’erreur incluent un corps JSON avec un message lisible par un humain, par exemple :

{ "message": "Cannot send message: the LinkedIn account is disconnected" }

Mise en pratique

Une boucle d’intégration typique ressemble à ceci :

  1. Interrogez GET /conversations et stockez totalUnread pour détecter une nouvelle activité.

  2. Pour chaque conversation avec unreadCount > 0, appelez GET /conversations/{id}/messages afin de récupérer le dernier échange.

  3. Exécutez votre propre logique (synchronisation CRM, rédaction assistée par IA, routage, alertes).

  4. Répondez éventuellement avec POST /conversations/{id}/messages.

Comme nextCursor est stable et que le tri est du plus récent au plus ancien, vous pouvez arrêter de paginer dès que vous atteignez un message déjà traité — inutile de parcourir tout l’historique à chaque fois.

Prochaines étapes

  • Récupérez votre Organization ID et votre API Key dans Settings → API Keys.

  • Essayez l’appel GET /conversations ci-dessus pour confirmer que l’authentification fonctionne.

  • Construisez à partir de là : une synchronisation CRM, un notificateur Slack sur les nouvelles réponses, ou un assistant de rédaction de réponses par IA.