La V2 du webhook de sortie restructure en profondeur le payload que Pinpo envoie à vos systèmes à chaque événement. Le format V1 — avec son objet insightPinpo profondément imbriqué et ses champs HTML mélangés — est remplacé par une structure plate, lisible et directement exploitable.
Qu'est-ce qui change entre la V1 et la V2 ?
Qu'est-ce qui change entre la V1 et la V2 ?
**La structure est aplatie : **
En V1, les données étaient enfouies dans un objet
insightPinpoimbriqué sur plusieurs niveaux (insightPinpo.report.qualificationForm[0].formResponse.value).En V2, les informations essentielles sont accessibles au premier niveau du payload (
segmentation,engaged,formFields).
**La conversation est structurée : **En V1, la conversation n'était disponible qu'en HTML brut (
conversationDisplay).En V2, elle est fournie sous forme d'un tableau d'objets typés (
conversation) avecsender,contentettimestamp, en plus du rendu HTML.
Les données extraites sont simplifiées :Le
qualificationFormV1 (avecformQuestion,formResponse,state,lastModifiedAt) est remplacéen V2 par un tableau
formFieldsavec trois champs :key,label,value.
**Les champs de synthèse sont séparés: **En V1, le champ
resumecontenait un bloc HTML mélangeant segmentation, données extraites et conversation.En V2, chaque élément dispose de son propre champ structuré et de sa propre version HTML (
segmentationDisplay,formFieldsDisplay,conversationDisplay).
**De nouveaux champs apparaissent : **La V2 ajoute l'objetqualificationavec les dates du cycle de vie, le canal utilisé, les champs personnalisés, les tags et un lien direct vers le détail de la qualification.
Comment comprendre le format du JSON V2 par rapport au JSON V1 ?
Comment comprendre le format du JSON V2 par rapport au JSON V1 ?
Identification et métadonnées
Identification et métadonnées
Segmentation et statut
Segmentation et statut
Données extraites
Données extraites
Avant (V1) — **insightPinpo.report.qualificationForm** :
[
{
"formQuestion": {
"id": "project",
"question": "Le lead a un projet d'achat dans le neuf",
"type": "boolean"
},
"formResponse": {
"value": true
},
"note": null,
"state": "add",
"lastModifiedAt": "2024-03-04T10:02:00.000Z"
}
]
Après (V2) — **formFields** :
[
{
"key": "budget",
"label": "Budget",
"value": "10000"
}
]
Conversation
Conversation
Avant (V1) : La conversation n'était disponible qu'en HTML brut dans insightPinpo.report.conversationDisplay.
Après (V2) : La conversation est fournie sous deux formes :
{
"conversation": [
{
"sender": "agent",
"content": "Hello, I'm Alicia from Pinpo...",
"timestamp": "2026-02-23T10:05:00.000Z"
},
{
"sender": "contact",
"content": "Yes, I want to know more about it",
"timestamp": "2026-02-23T10:06:00.000Z"
}
],
"conversationDisplay": "<ul>...</ul>"
}
Contact
Contact
Commercial (salesperson)
Commercial (salesperson)
Champs supprimés en V2
Champs supprimés en V2
Exemple complet : Avant / Après
Exemple complet : Avant / Après
Payload de sortie V1
{
"id": "SNkSwfNMIV",
"externalId": "externalIdLead",
"leadTypology": {
"key": "hot-with-meeting",
"value": "Chaud avec RDV"
},
"contact": {
"firstName": "John",
"lastName": "Doe",
"phone": "33606060606",
"mail": "[email protected]",
"externalId": "abcd1234",
"gender": "male"
},
"resume": "Lead chaud
<b><u>Détail Insight PINPO</u></b>:...",
"insightPinpo": {
"details": [
{ "key": "engaged", "title": "Engagé", "value": true },
{ "key": "temperature", "title": "Température", "value": { "key": "hot", "display": "Lead chaud", "emoji": { "..." } } },
{ "key": "qualificationStatus", "title": "Statut de la qualification", "value": "Clôturée" }
],
"report": {
"qualificationForm": [
{
"formQuestion": { "id": "project", "question": "Le lead a un projet d'achat dans le neuf", "type": "boolean" },
"formResponse": { "value": true },
"state": "add",
"lastModifiedAt": "2024-03-04T10:02:00.000Z"
}
],
"qualificationFormDisplay": "<ul>...</ul>",
"conversationDisplay": "<ul>...</ul>",
"conversationUrl": "https://pinpo.app.link/e/ezSMLbOx4Bb"
},
"lastActivity": "2023-08-07T14:55:05.195Z",
"requestDate": "2023-08-07T12:54:12.425Z",
"trigger": "lead:change",
"idScenario": "idAssistant"
}
}
Payload de sortie V2 équivalent
{
"agentId": "c74a151b-cc63-428f-a96a-7cfe3c9c578d",
"eventType": "done",
"engaged": true,
"summary": "Contact engaged - Hot - 3 data extracted",
"segmentation": "hot",
"segmentationDisplay": "🔥 Hot",
"tags": "",
"tagsDisplay": "",
"conversation": [
{
"sender": "agent",
"content": "Bonjour, je suis Marion, Cheffe de projet chez ...",
"timestamp": "2023-08-07T12:54:00.000Z"
},
{
"sender": "contact",
"content": "Oui",
"timestamp": "2023-08-07T14:39:00.000Z"
}
],
"conversationDisplay": "<ul>...</ul>",
"formFields": [
{ "key": "project", "label": "Le lead a un projet d'achat dans le neuf", "value": "true" },
{ "key": "optinContact", "label": "Mise en relation souhaitée avec un conseiller", "value": "true" },
{ "key": "buyHorizon", "label": "Horizon d'achat", "value": "3 mois" },
{ "key": "meetingTime", "label": "Date et heure du RDV", "value": "2024-03-05T10:00:00.000Z" }
],
"formFieldsDisplay": "<ul>...</ul>",
"qualification": {
"id": "SNkSwfNMIV",
"externalId": "externalIdLead",
"source": "",
"customFields": {},
"test": false,
"channel": "sms",
"importedAt": "2023-08-07T12:54:12.425Z",
"engagedAt": "2023-08-07T12:54:00.000Z",
"lastActivityAt": "2023-08-07T14:55:05.195Z"
},
"contact": {
"firstname": "John",
"lastname": "Doe",
"gender": "male",
"phone": "+33606060606",
"mail": "[email protected]",
"externalId": "abcd1234"
},
"salesperson": {},
"detailsUrl": "https://app.pinpo.ai/app/qualifications?tab=qualifications&detail=SNkSwfNMIV"
}
Checklist de migration (sortie)
Checklist de migration (sortie)
Étape | Action |
1 | Remplacer la lecture de |
2 | Remplacer |
3 | Remplacer |
4 | Remplacer |
5 | Remplacer la lecture de |
6 | Adapter le parsing : |
7 | Remplacer |
8 | Remplacer |
9 | Remplacer |
10 | Remplacer |
11 | Remplacer |
12 | Adapter la casse des champs contact : |
13 | Supprimer tout parsing de |
14 | Supprimer toute dépendance à |
15 | Intégrer les nouveaux champs si pertinent : |
16 | Le tag |
17 | Le tag wrong-phone devient une réponse booléenne dans le |
18 | Le tag rgpd devient une réponse booléenne dans le |
19 | Le tag opt-out devient une réponse booléenne dans le |
Conseil : Si vous faisiez du parsing du HTML du champ resume ou de conversationDisplay pour en extraire des données, la V2 vous simplifie la vie. Les données structurées (conversation, formFields, segmentation) vous évitent tout parsing HTML. Profitez de la migration pour supprimer ce code fragile.
🌟 - Bonnes pratiques
Utilisez les champs structurés plutôt que les champs **
Display**. Les champsconversation,formFieldsetsegmentationsont faits pour être traités programmatiquement. Les champsDisplay(HTML) sont destinés à l'affichage humain uniquement.Ne cherchez pas l'objet **
insightPinpo**. Il n'existe plus. Si votre code y fait référence, il cassera. Faites un rechercher/remplacer global dans votre codebase.Exploitez les nouvelles dates. Les champs
importedAt,engagedAtetlastActivityAtvous permettent de mesurer les délais de traitement sans calcul supplémentaire.Gérez le champ **
salesperson** en sortie. En V1, les données du commercial n'étaient pas renvoyées dans le webhook. En V2, elles le sont. Utilisez-les pour router la qualification vers le bon commercial dans votre CRM.Testez avec un webhook de test. Configurez un webhook pointant vers un outil de capture (comme webhook.site ou un endpoint Make/Zapier temporaire) pour visualiser le payload V2 complet avant d'adapter votre code de production.
Migrez entrée et sortie en même temps. Si vous migrez l'API d'import (entrée) en V2, migrez le webhook (sortie) dans le même mouvement. Maintenir un mix V1/V2 entre entrée et sortie complexifie inutilement votre intégration.
