Lire les échanges d'une conversation
Retrouver la conversation d'une personne ou d'une fiche, lire son fil tous médias confondus, le corps d'un email, et tous les échanges avec une personne.
Une conversation réunit les échanges avec une ou plusieurs personnes : emails, SMS, messages WhatsApp, chat, notes internes et appels, dans l'ordre où ils ont eu lieu. Vous la lisez avec les droits de l'utilisateur : il lit les conversations où il participe, et celles avec un client dont il voit la fiche d'un correspondant. Un message dont il ne voit pas la source — l'email d'un compte personnel d'un collègue, par exemple — n'y paraît pas.
1Trouver la conversation
| Ce que vous cherchez | L'appel |
|---|---|
| Les conversations partagées avec une personne, ouvertes et fermées | GET https://staging-api.docage.com/Conversations/WithPerson?contactId=…, ou docageUserId pour un collègue |
| Sa conversation par défaut, où se rangent ses emails, SMS et messages WhatsApp | POST https://staging-api.docage.com/Conversations/DefaultWithPerson?contactId=… — créée au besoin |
| Les conversations au sujet d'une fiche (un parcours, une carte…) | GET https://staging-api.docage.com/Conversations/AboutRecord/{entityTypeName}/{entityId} |
| Les conversations de l'utilisateur | GET https://staging-api.docage.com/Conversations/Mine?filter=1 |
filter : 0 ouvertes (d'office), 1 non lues, 2 venues du widget d'un site web, 3 fermées, 4 lues comme équipe, 5
reportées.
Chaque conversation vient avec son résumé : Id, Name (le nom que l'utilisateur lui voit), Participants, UnreadCount (ses
non-lus), LastMessageAtUtc, LastMessagePreview, Status (1 ouverte, 2 fermée) et CanWrite.
GET https://staging-api.docage.com/Conversations/{id}/Summary relit le résumé d'une conversation.
2Lire son fil
GET https://staging-api.docage.com/Conversations/4d1c8e52-0000-4000-8000-000000000101/Messages?take=50
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…curl "https://staging-api.docage.com/Conversations/4d1c8e52-0000-4000-8000-000000000101/Messages?take=50" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…"using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Get, "https://staging-api.docage.com/Conversations/4d1c8e52-0000-4000-8000-000000000101/Messages?take=50");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Conversations/4d1c8e52-0000-4000-8000-000000000101/Messages?take=50", {
headers: {
Authorization: `Bearer ${token}`
}
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;La réponse rend les take messages les plus récents, du plus ancien au plus récent (200 d'office, 500 au plus). Chaque message dit :
Id,Media,Direction(0envoyé,1reçu),Origin, etOccurredAtUtc, l'instant de l'échange, sur lequel le fil se trie ;- son auteur :
AuthorName, etAuthorContactIdouAuthorDocageUserId, ouAuthorAddresspour un auteur sans fiche ; BodyText: le texte d'un message de chat, d'une note, d'un SMS ou d'un message WhatsApp ; pour un email, un aperçu de 200 caractères au plus, avec sonSubject;Status: le statut de l'envoi,nullpour le chat ;- la fiche dont il est la trace :
MailId,SmsMessageId,WhatsAppMessageIdouTelephonyCallId; Files: ses pièces jointes ;- pour un message du chat,
Reactions: les réactions posées, une par émoji, dans l'ordre où elles sont arrivées —Emoji,CountetPeople, qui l'a posé —, une liste vide sans réaction ; etCanReact, vrai quand l'utilisateur peut y réagir (une conversation ouverte, où il écrit). Les deux valentnullpour tout autre message : un autre média, un message système ou supprimé, une réponse de l'assistant IA. Deux émojis qui ne diffèrent que par un sélecteur de variante (U+FE0F) sont le même : comparez-les sans lui.
Media |
Média |
|---|---|
0 |
Chat |
1 |
|
2 |
SMS |
3 |
|
4 |
Note interne |
5 |
Appel |
Status |
Statut |
|---|---|
1 |
En attente |
2 |
Envoyé |
3 |
Remis |
4 |
Lu |
5 |
En erreur |
6 |
Reçu |
7 |
Manqué |
8 |
Programmé |
Origin : 0 un échange, 1 une notification (un code, une invitation), 2 une campagne, 3 l'assistant.
Remonter le fil : before, l'instant (OccurredAtUtc) du plus ancien message de la page, rend ceux d'avant. Rattraper
après une coupure : after, l'instant du plus récent message que vous avez, rend ceux d'après. Les deux bornes sont en UTC.
404 : la conversation est introuvable, ou l'utilisateur ne la lit pas — la même réponse pour les deux. Il en va de même de toute
route qui désigne une conversation par son identifiant.
3Lire un email
GET https://staging-api.docage.com/Conversations/{id}/Messages/{messageId}/Mail rend l'email d'un message : From, To, Cc, Subject, BodyText,
BodyHtml (assaini), Attachments, et pour un email envoyé Delivery — son compte email, ses copies cachées, son statut, ses
ouvertures et ses clics. 404 pour une conversation ou un message inconnu, ou que l'utilisateur ne voit pas : un email qu'il ne voit
pas lui-même, ou arrivé avant lui quand le modèle de la conversation cache ce qui précède son arrivée — la même réponse.
Une pièce jointe se télécharge par GET https://staging-api.docage.com/Conversations/{id}/Messages/{messageId}/Mail/Files/{fileId}.
4Tous les échanges avec une personne
GET https://staging-api.docage.com/Conversations/PersonThread?key=c:9b2d7a46-3c1e-4f0a-8b5d-1a2b3c4d5e6f&take=50
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…curl "https://staging-api.docage.com/Conversations/PersonThread?key=c:9b2d7a46-3c1e-4f0a-8b5d-1a2b3c4d5e6f&take=50" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…"using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Get, "https://staging-api.docage.com/Conversations/PersonThread?key=c:9b2d7a46-3c1e-4f0a-8b5d-1a2b3c4d5e6f&take=50");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Conversations/PersonThread?key=c:9b2d7a46-3c1e-4f0a-8b5d-1a2b3c4d5e6f&take=50", {
headers: {
Authorization: `Bearer ${token}`
}
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;Les messages de toutes les conversations que l'utilisateur partage avec la personne, ou qu'il lit comme équipe, chacun avec le nom
de sa conversation (ConversationName).
key: la clé de la personne —c:suivi de l'identifiant d'un contact,s:d'une société,u:d'un collègue,a:d'une adresse sans fiche.withContacts=true, pour une société : avec les conversations de ses contacts.beforeremonte de même ;takevaut 200 d'office, 500 au plus.
5Chercher un message
- Un mot :
GET https://staging-api.docage.com/Conversations/Search?q=devis&take=30cherche dans les conversations où l'utilisateur participe, du plus récent au plus ancien ; deux caractères au moins, 100 résultats au plus. - Tous les messages, tous médias :
POST https://staging-api.docage.com/Conversations/MessageList
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…
Content-Type: application/json
{
"Filter": {
"OperatorType": "And",
"Operands": [
{ "PropertyName": "Media", "Comparison": "=", "Value": 2 },
{ "PropertyName": "Direction", "Comparison": "=", "Value": 1 },
{ "PropertyName": "OccurredAtUtc", "Comparison": ">=", "Value": "2026-11-02T23:00:00Z" }
]
},
"SortOrder": "OccurredAtUtc_Desc",
"Skip": 0,
"Take": 50,
"Scope": 0
}curl -X POST "https://staging-api.docage.com/Conversations/MessageList" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "Content-Type: application/json" \
-d '{
"Filter": {"OperatorType": "And", "Operands": [{"PropertyName": "Media", "Comparison": "=", "Value": 2}, {"PropertyName": "Direction", "Comparison": "=", "Value": 1}, {"PropertyName": "OccurredAtUtc", "Comparison": ">=", "Value": "2026-11-02T23:00:00Z"}]},
"SortOrder": "OccurredAtUtc_Desc",
"Skip": 0,
"Take": 50,
"Scope": 0
}'using HttpClient client = new();
using HttpRequestMessage request = new(HttpMethod.Post, "https://staging-api.docage.com/Conversations/MessageList");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
request.Content = new StringContent("""
{
"Filter": {
"OperatorType": "And",
"Operands": [
{
"PropertyName": "Media",
"Comparison": "=",
"Value": 2
},
{
"PropertyName": "Direction",
"Comparison": "=",
"Value": 1
},
{
"PropertyName": "OccurredAtUtc",
"Comparison": ">=",
"Value": "2026-11-02T23:00:00Z"
}
]
},
"SortOrder": "OccurredAtUtc_Desc",
"Skip": 0,
"Take": 50,
"Scope": 0
}
""", Encoding.UTF8, "application/json");
using HttpResponseMessage response = await client.SendAsync(request);
string result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
throw new HttpRequestException(result);const response = await fetch("https://staging-api.docage.com/Conversations/MessageList", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"Filter": {"OperatorType": "And", "Operands": [{"PropertyName": "Media", "Comparison": "=", "Value": 2}, {"PropertyName": "Direction", "Comparison": "=", "Value": 1}, {"PropertyName": "OccurredAtUtc", "Comparison": ">=", "Value": "2026-11-02T23:00:00Z"}]},
"SortOrder": "OccurredAtUtc_Desc",
"Skip": 0,
"Take": 50,
"Scope": 0
})
});
const text = await response.text();
if (!response.ok) throw new Error(text);
const result = text ? JSON.parse(text) : null;- Le filtre ne porte que sur
Media,Direction,Origin,Status,OccurredAtUtc,Subject,Preview,ChannelAccountId,IsTeametIsPrivate; le tri, que surMedia,Direction,Origin,Status,OccurredAtUtc,SubjectetChannelAccountId. Une autre propriété est refusée (400). Scope:0tout ce que l'utilisateur lit,1ses conversations,2celles qu'il lit comme équipe.Take: 200 au plus.RequireTotalCountàtrueajoute le nombre de lignes en tout (TotalCount).- Les messages des campagnes y sont : écartez-les par
Origin. - Chaque ligne dit sa conversation (
ConversationId), à lire comme à l'étape 2.
6Marquer lu, être prévenu
- Lire le fil ne le marque pas comme lu :
POST https://staging-api.docage.com/Conversations/{id}/Readmarque lus ses messages, jusqu'à maintenant — quand l'utilisateur les a lus. - Pour recevoir les messages dès qu'ils arrivent, dans une application ouverte au nom de l'utilisateur, voir Temps réel. Pour écrire, voir Écrire par SMS, WhatsApp, chat ou note.
Les pièges
- Une page peut compter moins de
takemessages sans que le fil soit fini : ceux que l'utilisateur ne voit pas en sont retirés après la lecture. Continuez avecbeforejusqu'à une page vide. POST https://staging-api.docage.com/Conversations/DefaultWithPersoncrée la conversation si elle n'existe pas : pour seulement lire,GET https://staging-api.docage.com/Conversations/WithPerson.- Un participant arrivé en cours de route ne voit pas ce qui précède son arrivée, quand le modèle de la conversation le décide : ni
dans le fil, ni par l'identifiant d'un message (
404). - Un email ne montre dans le fil que son objet et un aperçu : son corps se lit à part (étape 3).