Reactive CRM Guide d'intégration ← Retour au site

Guide d'intégration ReactiveCRM

Documentation technique pour les entreprises (locataires) qui souhaitent créer leur propre intégration avec ReactiveCRM : ingestion de leads et de clients, création de deals, envoi d'événements marketing et export de données.

Ce document couvre uniquement les API les plus couramment utilisées pour les intégrations externes. Les données de référence internes et les endpoints des services d'administration sont intentionnellement exclus.

1. Aperçu de l'intégration

Un flux d'intégration typique ressemble à ceci :

texte
Votre système (backend / proxy côté serveur)
    |
    | 1. POST /api/auth/login  (obtenir les tokens d'accès + de rafraîchissement)
    v
ReactiveCRM
    | 2. Références : GET /api/users/paged, GET /api/statuses, GET /api/stages, GET /api/lead-sources
    |    (obtenir les UUID pour ownerId, authorId, statusId, etc.)
    v
    | 3. Opérations principales :
    |      POST /api/leads/create              — créer un lead
    |      POST /api/clients/create            — créer un client
    |      POST /api/contacts/create           — créer un contact
    |      POST /api/deals/create              — créer un deal
    |      POST /api/dashboard/marketing/events — envoyer un événement marketing
    |      POST /api/leads/import/batch         — importation massive de leads
    v
    | 4. Lecture / export :
    |      GET /api/leads/paged                 — lecture paginée avec filtres
    |      GET /api/export/leads                — export NDJSON de tous les leads

Règle de sécurité clé : n'appelez jamais l'API CRM directement depuis le navigateur d'un utilisateur final. Conservez le token CRM et les identifiants internes dans votre backend (ou une fonction serverless).

2. Authentification

2.1. Obtention des tokens

Les endpoints d'authentification ne nécessitent pas de token :

MéthodeURLDescription
POST/api/auth/loginConnexion avec nom d'utilisateur + mot de passe, retourne les tokens d'accès et de rafraîchissement
POST/api/auth/refreshÉchanger un token de rafraîchissement contre une nouvelle paire de tokens
POST/api/auth/logoutRévoquer un token de rafraîchissement
bash
curl -X POST "$CRM_BASE_URL/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username": "integration", "password": "secret123"}'
json
{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "refreshToken": "a8f3k2m9Qx7Tt1Vv...",
  "tokenType": "Bearer",
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "firstName": "Intégration",
    "lastName": "Bot",
    "tenantId": "660e8400-e29b-41d4-a716-446655440001"
  },
  "tenant": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "name": "Zunga Corp"
  }
}

2.2. Règles de gestion des tokens

2.3. Paramètres de base

texte
CRM_BASE_URL=https://crm.example.com

Tous les exemples ci-dessous supposent les en-têtes :

http
Authorization: Bearer <CRM_ACCESS_TOKEN>
Content-Type: application/json

3. Conventions des API paginées

Tous les endpoints de liste de la forme GET /api/*/paged partagent les mêmes conventions :

ParamètreTypeDéfautDescription
pageentier0Numéro de page, basé sur zéro
sizeentierpar endpointTaille de page
sortchaînecreatedAt,descTri au format champ,direction. Direction : asc ou desc

Structure de réponse paginée

json
{
  "content": [ { "..." } ],
  "page": 0,
  "size": 20,
  "totalElements": 137,
  "totalPages": 7
}

Filtrage par date

Utilisez les paramètres champDe / champÀ pour les plages (ISO 8601) :

texte
createdAtFrom=2026-01-01T00:00:00Z
createdAtTo=2026-01-31T23:59:59Z

Tri

Toujours ?sort=champ,direction :

texte
?sort=createdAt,desc
?sort=name,asc

Certains champs de filtre ont des paramètres de plage dédiés (ex. dealAmountFrom/dealAmountTo).

Sémantique du filtrage

4. Références (obtention des UUID)

Avant de créer des entités, obtenez les UUID des données de référence associées. Les principales :

4.1. Utilisateurs (GET /api/users/paged)

Utilisé pour ownerId, authorId, developingManagerIds.

bash
curl "$CRM_BASE_URL/api/users/paged?page=0&size=50&sort=createdAt,asc" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

Exemple de réponse (fragment content) :

json
[
  {
    "id": "7a786a66-3617-48c1-921d-97f4aaefcd35",
    "firstName": "Roman",
    "lastName": "Posledovskiy",
    "username": "roman",
    "email": "roman@example.com",
    "tenantId": "660e8400-e29b-41d4-a716-446655440001"
  }
]

4.2. Statuts (GET /api/statuses)

Utilisé pour statusId des leads, deals et clients de parties de deals. Retourne un tableau :

bash
curl "$CRM_BASE_URL/api/statuses" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"
json
[
  {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "New",
    "entityType": "LEAD"
  },
  {
    "id": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "name": "In progress",
    "entityType": "STAGE"
  }
]

4.3. Étapes (GET /api/stages)

Utilisé pour le stageId d'un deal :

bash
curl "$CRM_BASE_URL/api/stages" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

4.4. Sources de leads (GET /api/lead-sources)

Retourne un arbre des sources de leads. Utilisé pour le leadSourceId d'un lead :

bash
curl "$CRM_BASE_URL/api/lead-sources" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"
json
[
  {
    "id": "cccc0001-0000-0000-0000-000000000001",
    "name": "Website",
    "children": [
      {
        "id": "cccc0001-0000-0000-0000-000000000002",
        "name": "Feedback form",
        "children": []
      }
    ]
  }
]

5. Leads

5.1. Créer un lead (POST /api/leads/create)

bash
curl -X POST "$CRM_BASE_URL/api/leads/create" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message": "Demande site web : consultation",
    "ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
    "authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
    "leadSourceId": "cccc0001-0000-0000-0000-000000000002",
    "statusId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "quality": "WARM"
  }'

Champs de la requête :

ChampTypeRequisDescription
messagechaînenonMessage / texte de la demande
ownerIduuidouiUtilisateur responsable
authorIduuidouiUtilisateur qui a créé le lead
clientIduuidnonClient associé
contactIduuidnonContact associé
leadSourceIduuidnonNœud de l'arbre des sources de leads
statusIduuidnonStatut
qualityenumnonHOT, WARM, COOL, COLD

Exemple de réponse 201 Created :

json
{
  "id": "22222222-2222-2222-2222-222222222222",
  "message": "Demande site web : consultation",
  "status": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "name": "New"
  },
  "quality": "WARM",
  "dealId": null,
  "createdAt": "2026-09-05T20:00:00Z",
  "updatedAt": "2026-09-05T20:00:00Z",
  "version": 0,
  "author": {
    "id": "7a786a66-3617-48c1-921d-97f4aaefcd35",
    "firstName": "Roman",
    "lastName": "Posledovskiy"
  },
  "owner": {
    "id": "7a786a66-3617-48c1-921d-97f4aaefcd35",
    "firstName": "Roman",
    "lastName": "Posledovskiy"
  }
}

Conservez le id retourné — il est nécessaire pour le leadId de l'événement marketing (voir section 8).

5.2. Lecture paginée (GET /api/leads/paged)

bash
curl "$CRM_BASE_URL/api/leads/paged?page=0&size=20&createdAtFrom=2026-09-01T00:00:00Z&sort=createdAt,desc" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

Filtres clés :

ParamètreTypeModeDescription
statusIduuidexactFiltrer par statut
leadSourceIduuidexactFiltrer par source de lead
qualityenumexactHOT, WARM, COOL, COLD
messagechaîneILIKESous-chaîne dans le message
searchchaîneILIKE (OU)Recherche dans message, contact, email, téléphone
contactEmailchaîneILIKEPar email du contact
contactPhonechaîneILIKEPar téléphone du contact
companychaîneILIKEPar nom d'entreprise
clientIduuidexactPar ID client
createdAtFrom / createdAtTodate-heureplagePar date de création
updatedAtFrom / updatedAtTodate-heureplagePar date de mise à jour
createdByuuidexactPar auteur du lead

Il existe également des filtres pour le deal associé : dealStatusId, dealStageId, dealAmountFrom/dealAmountTo, dealProbabilityFrom/dealProbabilityTo.

Tri : createdAt, updatedAt, message, quality, statut/source, et autres (format champ,direction).

5.3. Obtenir un lead individuel (GET /api/leads/{id})

bash
curl "$CRM_BASE_URL/api/leads/$LEAD_ID" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

5.4. Importation massive de leads (POST /api/leads/import/batch)

Pour l'ingestion massive d'un grand nombre de leads, utilisez l'endpoint batch. Il accepte un tableau de leads, crée un enregistrement d'historique d'importation et permet d'annuler l'ensemble de l'importation.

bash
curl -X POST "$CRM_BASE_URL/api/leads/import/batch" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fileName": "leads-2026-09-05.csv",
    "leads": [
      {
        "message": "Demande #1",
        "ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
        "authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
        "quality": "WARM"
      },
      {
        "message": "Demande #2",
        "ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
        "authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
        "quality": "COOL"
      }
    ]
  }'

Exemple de réponse :

json
{
  "importId": "44444444-4444-4444-4444-444444444444",
  "imported": 2,
  "total": 2,
  "skipped": []
}

Historique et annulation :

bash
# Historique des importations
curl "$CRM_BASE_URL/api/leads/import/history" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

# Annuler une importation
curl -X POST "$CRM_BASE_URL/api/leads/import/rollback/$IMPORT_ID" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

5.5. Lead rapide depuis le site web (POST /api/site/leads)

Pour les formulaires de site web, il existe un endpoint combiné unique qui crée atomiquement le contact, son téléphone principal et son email, le lead, le lien contact-lead et l'événement marketing en une seule requête — avec idempotence via externalId.

Consultez le guide dédié : site-lead-multi-contract.md.

6. Clients et Contacts

6.1. Créer un client (POST /api/clients/create)

bash
curl -X POST "$CRM_BASE_URL/api/clients/create" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "COMPANY",
    "name": "Romashka LLC",
    "taxId": "7700000001",
    "regNumber": "1234567890",
    "country": "RU",
    "phone": "+7-495-000-00-01",
    "email": "info@romashka.ru",
    "website": "https://romashka.ru",
    "ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
    "authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35"
  }'

Champs clés :

ChampTypeS'applique àDescription
typeenumtousINDIVIDUAL ou COMPANY (requis)
namechaînetousNom d'affichage (requis)
firstName / lastNamechaîneINDIVIDUALPrénom/nom
taxIdchaîneCOMPANYID fiscal (INN)
regNumberchaîneCOMPANYNuméro d'enregistrement
legalAddresschaîneCOMPANYAdresse légale
phone / email / websitechaînetousContacts
countrychaînetousCode pays ISO
ownerIduuidtousUtilisateur responsable
authorIduuidtousAuteur
developingManagerIdsuuid[]tousGestionnaires de développement

6.2. Lecture paginée des clients (GET /api/clients/paged)

bash
curl "$CRM_BASE_URL/api/clients/paged?page=0&size=20&type=COMPANY&search=Romashka&sort=name,asc" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

Filtres clés : name, type (INDIVIDUAL/COMPANY), country, taxId, email, phone, lastName (particuliers), search (par nom/ID fiscal/téléphone), createdAtFrom/createdAtTo, createdBy, developingManagerId.

6.3. Vérification des doublons (GET /api/clients/duplicates)

Avant de créer un client, vérifiez si un similaire existe déjà :

bash
# Par ID fiscal et nom
curl "$CRM_BASE_URL/api/clients/duplicates?type=COMPANY&taxId=7700000001&name=Romashka" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

6.4. Créer un contact (POST /api/contacts/create)

bash
curl -X POST "$CRM_BASE_URL/api/contacts/create" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Ivan",
    "lastName": "Petrov",
    "dateOfBirth": "1990-05-15",
    "gender": "MALE",
    "countryCode": "RU",
    "ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
    "authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35"
  }'

Champs : firstName (requis), lastName, patronymicName, dateOfBirth (date), gender (MALE/FEMALE), countryCode, ownerId, authorId.

6.5. Lecture paginée des contacts (GET /api/contacts/paged)

bash
curl "$CRM_BASE_URL/api/contacts/paged?page=0&size=20&search=Petrov&sort=createdAt,desc" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

7. Deals

7.1. Créer un deal (POST /api/deals/create)

bash
curl -X POST "$CRM_BASE_URL/api/deals/create" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Livraison de matériel serveur",
    "clientId": "9f128931-69fd-493a-9a08-be5be0e6603d",
    "statusId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "stageId": "dddd0001-0000-0000-0000-000000000001",
    "probability": 60,
    "amount": 150000.00,
    "ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
    "authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35"
  }'

Champs clés :

ChampTypeRequisDescription
namechaîneouiNom du deal
clientIduuidouiID du client
statusIduuidnonStatut (statut de l'étape)
stageIduuidnonÉtape de vente
probabilityentiernonProbabilité 0-100
amountnombrenonMontant
plannedAmountnombrenonMontant planifié
discountPercententiernonRemise 0-100
startDate / expectedCloseDatedate-heurenonDates
ownerIduuidnonPropriétaire
leadIduuidnonLead associé
contactIduuidnonContact associé
productIdsuuid[]nonProduits (format simplifié)
dealProductstableaunonLignes de deal (format complet)
dealPartiestableaunonParties du deal

7.2. Lecture paginée des deals (GET /api/deals/paged)

bash
curl "$CRM_BASE_URL/api/deals/paged?page=0&size=20&stageKind=OPEN&sort=createdAt,desc" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

Filtres clés : name (ILIKE), clientId, clientName, statusId, stageId, stageKind (OPEN/WON/LOST), ownerId, search, startDateFrom/startDateTo, expectedCloseDateFrom/expectedCloseDateTo, actualCloseDateFrom/actualCloseDateTo, createdAtFrom/createdAtTo.

8. Événements marketing (Attribution)

Pour envoyer des balises UTM, des identifiants publicitaires et des sources de trafic, utilisez :

POST /api/dashboard/marketing/events

bash
curl -X POST "$CRM_BASE_URL/api/dashboard/marketing/events" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "eventType": "lead_submitted",
    "occurredAt": "2026-09-05T20:00:00Z",
    "visitorId": "visitor-8b7f",
    "sessionId": "session-31ac",
    "leadId": "22222222-2222-2222-2222-222222222222",
    "externalId": "site-form-submit-20260905-000123",
    "source": "website",
    "channel": "paid",
    "utmSource": "google",
    "utmMedium": "cpc",
    "utmCampaign": "summer-consulting",
    "utmContent": "banner-a",
    "utmTerm": "crm consultation",
    "gclid": "EAIaIQobChMI-example",
    "landingUrl": "https://www.example.com/consultation",
    "referrer": "https://www.google.com/",
    "metadata": {
      "formName": "consultation",
      "pageType": "landing"
    }
  }'

Exemple de réponse :

json
{
  "accepted": true,
  "duplicate": false,
  "eventId": "33333333-3333-3333-3333-333333333333"
}

Règles :

Pour plus de détails, consultez site-leads-integration-guide.md.

9. Export de données (NDJSON)

Les endpoints d'export retournent tous les enregistrements du locataire au format NDJSON (un objet JSON par ligne, séparés par \n).

EndpointDescription
GET /api/export/leadsTous les leads du locataire
GET /api/export/clientsTous les clients du locataire
GET /api/export/contactsTous les contacts du locataire
bash
curl "$CRM_BASE_URL/api/export/leads" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

Exemple de réponse (flux de lignes) :

texte
{"id":"550e8400-e29b-41d4-a716-446655440001","message":"Demande site web","quality":"WARM","statusName":"New","createdAt":"2026-08-20T10:00:00+03:00","ownerName":"Ivan Ivanov","clientName":"Romashka LLC","contactFirstName":"Petr","contactLastName":"Petrov","leadSourceName":"Paid search"}
{"id":"550e8400-e29b-41d4-a716-446655440002","message":"Appel téléphonique","quality":"COOL","statusName":"In progress","createdAt":"2026-08-19T09:00:00+03:00","ownerName":"Maria Smirnova","clientName":null}

Important : NDJSON n'est pas un tableau JSON valide. Lisez la réponse ligne par ligne via ReadableStream (n'appelez pas JSON.parse() sur l'ensemble de la réponse).

10. Exemple d'intégration de bout en bout

Le scénario suivant crée un lead depuis le site web, lie un contact et un client, crée un deal et envoie un événement marketing.

bash
CRM_BASE_URL=https://crm.example.com
CRM_TOKEN="<access-token>"

# 1. Connexion
curl -s -X POST "$CRM_BASE_URL/api/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username": "integration", "password": "secret123"}' | tee /tmp/login.json

CRM_TOKEN=$(jq -r '.token' /tmp/login.json)

OWNER_ID=$(curl -s "$CRM_BASE_URL/api/users/paged?page=0&size=50" \
  -H "Authorization: Bearer $CRM_TOKEN" | jq -r '.content[0].id')

# 2. Créer un client
curl -s -X POST "$CRM_BASE_URL/api/clients/create" \
  -H "Authorization: Bearer $CRM_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"type\": \"COMPANY\",
    \"name\": \"Romashka LLC\",
    \"taxId\": \"7700000001\",
    \"country\": \"RU\",
    \"ownerId\": \"$OWNER_ID\",
    \"authorId\": \"$OWNER_ID\"
  }" | tee /tmp/client.json

CLIENT_ID=$(jq -r '.id' /tmp/client.json)

# 3. Créer un contact
curl -s -X POST "$CRM_BASE_URL/api/contacts/create" \
  -H "Authorization: Bearer $CRM_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"firstName\": \"Ivan\",
    \"lastName\": \"Petrov\",
    \"countryCode\": \"RU\",
    \"ownerId\": \"$OWNER_ID\",
    \"authorId\": \"$OWNER_ID\"
  }" | tee /tmp/contact.json

CONTACT_ID=$(jq -r '.id' /tmp/contact.json)

# 4. Créer un lead
curl -s -X POST "$CRM_BASE_URL/api/leads/create" \
  -H "Authorization: Bearer $CRM_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"message\": \"Demande site web\",
    \"clientId\": \"$CLIENT_ID\",
    \"contactId\": \"$CONTACT_ID\",
    \"ownerId\": \"$OWNER_ID\",
    \"authorId\": \"$OWNER_ID\",
    \"quality\": \"WARM\"
  }" | tee /tmp/lead.json

LEAD_ID=$(jq -r '.id' /tmp/lead.json)

# 5. Créer un deal lié au lead
curl -s -X POST "$CRM_BASE_URL/api/deals/create" \
  -H "Authorization: Bearer $CRM_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"Consultation pour Ivan Petrov\",
    \"clientId\": \"$CLIENT_ID\",
    \"leadId\": \"$LEAD_ID\",
    \"contactId\": \"$CONTACT_ID\",
    \"amount\": 50000.00,
    \"ownerId\": \"$OWNER_ID\",
    \"authorId\": \"$OWNER_ID\"
  }"

# 6. Envoyer un événement marketing
curl -s -X POST "$CRM_BASE_URL/api/dashboard/marketing/events" \
  -H "Authorization: Bearer $CRM_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"eventType\": \"lead_submitted\",
    \"occurredAt\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\",
    \"leadId\": \"$LEAD_ID\",
    \"externalId\": \"request-$(uuidgen)\",
    \"source\": \"website\",
    \"channel\": \"direct\",
    \"landingUrl\": \"https://www.example.com/form\",
    \"metadata\": {\"formName\": \"consultation\"}
  }"

11. Idempotence et gestion des erreurs

12. Démarrage rapide

  1. Authentifiez-vous via POST /api/auth/login ; stockez token et refreshToken.
  2. Ajoutez Authorization: Bearer <token> à chaque requête. En cas de 401, rafraîchissez via /api/auth/refresh.
  3. Récupérez les références (utilisateurs/statuts/étapes/sources de leads) une fois et mettez en cache les UUID.
  4. Créez les entités dans un ordre logique : client → contact → lead → deal.
  5. Utilisez les endpoints paginés pour les lectures avec filtrage et tri côté serveur.
  6. Pour les exports, utilisez les endpoints NDJSON et lisez le flux ligne par ligne.
  7. Pour l'ingestion massive, utilisez les endpoints batch (/api/leads/import/batch, /api/clients/import/batch) avec support d'annulation.
  8. Envoyez l'attribution marketing via POST /api/dashboard/marketing/events avec un externalId stable.
  9. Ne stockez ni ne passez de données personnelles dans le metadata des événements marketing.
  10. Consultez la documentation détaillée par API : site-leads-integration-guide.md.