- Accueil
- /
- Centre d'aide
- /
- API ReactIn
- /
- Interagir avec l’Unified Inbox via l’API
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.
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éthode | Chemin | Objectif |
|---|---|---|
| GET | /api/{organizationId}/conversations | Lister les conversations |
| GET | /api/{organizationId}/conversations/{conversationId}/messages | Lister les messages d’une conversation |
| POST | /api/{organizationId}/conversations/{conversationId}/messages | Envoyer 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ètre | Type | Valeur par défaut | Description |
|---|---|---|---|
| linkedinAccountId | string | – | Filtrer par un compte LinkedIn connecté spécifique |
| campaignId | string | – | Filtrer par une campagne spécifique |
| search | string | – | Recherche plein texte sur les noms de conversation/participants |
| cursor | string | – | Curseur de pagination (voir Pagination) |
| limit | number | 30 | É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ètre | Type | Valeur par défaut | Description |
|---|---|---|---|
| cursor | string | – | Curseur de pagination |
| limit | number | 20 | Messages 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
| Champ | Type | Contraintes |
|---|---|---|
| content | string | Requis, 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 :
-
Effectuez la première requête sans curseur.
-
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.
-
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éthode | Limite |
|---|---|
| GET | 30 requêtes / minute |
| POST | 60 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 :
| Statut | Signification | Cause typique |
|---|---|---|
| 200 | OK | Requête réussie |
| 400 | Bad Request | Paramètre de requête, corps ou curseur invalide |
| 401 | Unauthorized | Clé API manquante ou invalide |
| 404 | Not Found | La conversation n’existe pas ou n’appartient pas à votre organisation |
| 409 | Conflict | Compte LinkedIn déconnecté, ou chat pas encore disponible |
| 429 | Too Many Requests | Limite de débit dépassée |
| 500 | Internal 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 :
-
Interrogez GET /conversations et stockez totalUnread pour détecter une nouvelle activité.
-
Pour chaque conversation avec unreadCount > 0, appelez GET /conversations/{id}/messages afin de récupérer le dernier échange.
-
Exécutez votre propre logique (synchronisation CRM, rédaction assistée par IA, routage, alertes).
-
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.