Reactive CRM Guía de Integración ← Volver al sitio

Guía de Integración de ReactiveCRM

Documentación técnica para empresas (inquilinos) que desean crear su propia integración con ReactiveCRM: ingesta de leads y clientes, creación de negocios, envío de eventos de marketing y exportación de datos.

Este documento cubre únicamente las API más utilizadas para integraciones externas. Los datos de referencia internos y los endpoints de servicios de administración quedan intencionalmente fuera del alcance.

1. Descripción general de la integración

Un flujo de integración típico se ve así:

texto
Su sistema (backend / proxy del lado del servidor)
    |
    | 1. POST /api/auth/login  (obtener tokens de acceso + actualización)
    v
ReactiveCRM
    | 2. Referencias: GET /api/users/paged, GET /api/statuses, GET /api/stages, GET /api/lead-sources
    |    (obtener UUIDs para ownerId, authorId, statusId, etc.)
    v
    | 3. Operaciones principales:
    |      POST /api/leads/create              — crear un lead
    |      POST /api/clients/create            — crear un cliente
    |      POST /api/contacts/create           — crear un contacto
    |      POST /api/deals/create              — crear un negocio
    |      POST /api/dashboard/marketing/events — enviar un evento de marketing
    |      POST /api/leads/import/batch         — importación masiva de leads
    v
    | 4. Lectura / exportación:
    |      GET /api/leads/paged                 — lectura paginada con filtros
    |      GET /api/export/leads                — exportación NDJSON de todos los leads

Regla de seguridad clave: nunca llame a la API del CRM directamente desde el navegador de un usuario final. Mantenga el token del CRM y los identificadores internos en su backend (o en una función serverless).

2. Autenticación

2.1. Obtención de tokens

Los endpoints de autenticación no requieren un token:

MétodoURLDescripción
POST/api/auth/loginInicio de sesión con usuario + contraseña, devuelve tokens de acceso y actualización
POST/api/auth/refreshIntercambiar un token de actualización por un nuevo par de tokens
POST/api/auth/logoutRevocar un token de actualización
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": "Integración",
    "lastName": "Bot",
    "tenantId": "660e8400-e29b-41d4-a716-446655440001"
  },
  "tenant": {
    "id": "660e8400-e29b-41d4-a716-446655440001",
    "name": "Zunga Corp"
  }
}

2.2. Reglas de manejo de tokens

2.3. Configuración base

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

Todos los ejemplos a continuación asumen los encabezados:

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

3. Convenciones de API paginada

Todos los endpoints de listado de la forma GET /api/*/paged comparten las mismas convenciones:

ParámetroTipoPredeterminadoDescripción
pageentero0Número de página, basado en cero
sizeenteropor endpointTamaño de página
sortcadenacreatedAt,descOrdenamiento en formato campo,dirección. Dirección: asc o desc

Estructura de respuesta paginada

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

Filtrado por fecha

Use los parámetros campoDesde / campoHasta para rangos (ISO 8601):

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

Ordenamiento

Siempre ?sort=campo,dirección:

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

Algunos campos de filtro tienen parámetros de rango dedicados (p. ej., dealAmountFrom/dealAmountTo).

Semántica de filtrado

4. Referencias (obtención de UUIDs)

Antes de crear entidades, obtenga los UUIDs de los datos de referencia relacionados. Los principales son:

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

Se utiliza para ownerId, authorId, developingManagerIds.

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

Ejemplo de respuesta (fragmento de 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. Estados (GET /api/statuses)

Se utiliza para statusId de leads, negocios y clientes de partes de negocios. Devuelve un array:

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. Etapas (GET /api/stages)

Se utiliza para el stageId de un negocio:

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

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

Devuelve un árbol de fuentes de leads. Se utiliza para el leadSourceId de 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. Crear 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": "Consulta desde el sitio web: asesoría",
    "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"
  }'

Campos de la solicitud:

CampoTipoRequeridoDescripción
messagecadenanoMensaje / texto de la consulta
ownerIduuidsíUsuario responsable
authorIduuidsíUsuario que creó el lead
clientIduuidnoCliente relacionado
contactIduuidnoContacto relacionado
leadSourceIduuidnoNodo del árbol de fuentes de leads
statusIduuidnoEstado
qualityenumnoHOT, WARM, COOL, COLD

Ejemplo de respuesta 201 Created:

json
{
  "id": "22222222-2222-2222-2222-222222222222",
  "message": "Consulta desde el sitio web: asesoría",
  "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"
  }
}

Guarde el id devuelto — es necesario para el leadId del evento de marketing (consulte la sección 8).

5.2. Lectura paginada (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"

Filtros clave:

ParámetroTipoModoDescripción
statusIduuidexactoFiltrar por estado
leadSourceIduuidexactoFiltrar por fuente de lead
qualityenumexactoHOT, WARM, COOL, COLD
messagecadenaILIKESubcadena en el mensaje
searchcadenaILIKE (OR)Buscar en mensaje, contacto, correo, teléfono
contactEmailcadenaILIKEPor correo del contacto
contactPhonecadenaILIKEPor teléfono del contacto
companycadenaILIKEPor nombre de empresa
clientIduuidexactoPor ID de cliente
createdAtFrom / createdAtTofecha-horarangoPor fecha de creación
updatedAtFrom / updatedAtTofecha-horarangoPor fecha de actualización
createdByuuidexactoPor autor del lead

También hay filtros para el negocio relacionado: dealStatusId, dealStageId, dealAmountFrom/dealAmountTo, dealProbabilityFrom/dealProbabilityTo.

Ordenamiento: createdAt, updatedAt, message, quality, estado/fuente y otros (formato campo,dirección).

5.3. Obtener un lead individual (GET /api/leads/{id})

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

5.4. Importación masiva de leads (POST /api/leads/import/batch)

Para la ingesta masiva de un gran número de leads, use el endpoint de lote. Acepta un array de leads, crea un registro de historial de importación y permite revertir toda la importación.

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": "Consulta #1",
        "ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
        "authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
        "quality": "WARM"
      },
      {
        "message": "Consulta #2",
        "ownerId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
        "authorId": "7a786a66-3617-48c1-921d-97f4aaefcd35",
        "quality": "COOL"
      }
    ]
  }'

Ejemplo de respuesta:

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

Historial y reversión:

bash
# Historial de importación
curl "$CRM_BASE_URL/api/leads/import/history" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

# Revertir una importación
curl -X POST "$CRM_BASE_URL/api/leads/import/rollback/$IMPORT_ID" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

5.5. Lead rápido desde el sitio web (POST /api/site/leads)

Para formularios del sitio web, existe un único endpoint combinado que crea atómicamente el contacto, su teléfono principal y correo electrónico, el lead, el enlace contacto-lead y el evento de marketing en una sola solicitud — con idempotencia mediante externalId.

Consulte la guía dedicada: site-lead-multi-contract.md.

6. Clientes y Contactos

6.1. Crear un cliente (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"
  }'

Campos clave:

CampoTipoAplica aDescripción
typeenumtodosINDIVIDUAL o COMPANY (requerido)
namecadenatodosNombre para mostrar (requerido)
firstName / lastNamecadenaINDIVIDUALNombre/apellido
taxIdcadenaCOMPANYID fiscal (INN)
regNumbercadenaCOMPANYNúmero de registro
legalAddresscadenaCOMPANYDirección legal
phone / email / websitecadenatodosContactos
countrycadenatodosCódigo de país ISO
ownerIduuidtodosUsuario responsable
authorIduuidtodosAutor
developingManagerIdsuuid[]todosGerentes de desarrollo

6.2. Lectura paginada de clientes (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"

Filtros clave: name, type (INDIVIDUAL/COMPANY), country, taxId, email, phone, lastName (personas), search (por nombre/ID fiscal/teléfono), createdAtFrom/createdAtTo, createdBy, developingManagerId.

6.3. Verificación de duplicados (GET /api/clients/duplicates)

Antes de crear un cliente, verifique si ya existe uno similar:

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

6.4. Crear un contacto (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"
  }'

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

6.5. Lectura paginada de contactos (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. Negocios

7.1. Crear un negocio (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": "Entrega de hardware de servidor",
    "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"
  }'

Campos clave:

CampoTipoRequeridoDescripción
namecadenasíNombre del negocio
clientIduuidsíID del cliente
statusIduuidnoEstado (estado de etapa)
stageIduuidnoEtapa de ventas
probabilityenteronoProbabilidad 0-100
amountnúmeronoMonto
plannedAmountnúmeronoMonto planificado
discountPercententeronoDescuento 0-100
startDate / expectedCloseDatefecha-horanoFechas
ownerIduuidnoPropietario
leadIduuidnoLead relacionado
contactIduuidnoContacto relacionado
productIdsuuid[]noProductos (formato simplificado)
dealProductsarraynoLíneas de negocio (formato completo)
dealPartiesarraynoPartes del negocio

7.2. Lectura paginada de negocios (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"

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

8. Eventos de Marketing (Atribución)

Para enviar etiquetas UTM, identificadores de anuncios y fuentes de tráfico, use:

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"
    }
  }'

Ejemplo de respuesta:

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

Reglas:

Para más detalles, consulte site-leads-integration-guide.md.

9. Exportación de datos (NDJSON)

Los endpoints de exportación devuelven todos los registros del inquilino en formato NDJSON (un objeto JSON por línea, separados por \n).

EndpointDescripción
GET /api/export/leadsTodos los leads del inquilino
GET /api/export/clientsTodos los clientes del inquilino
GET /api/export/contactsTodos los contactos del inquilino
bash
curl "$CRM_BASE_URL/api/export/leads" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN"

Ejemplo de respuesta (flujo de líneas):

texto
{"id":"550e8400-e29b-41d4-a716-446655440001","message":"Consulta desde el sitio 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":"Llamada telefónica","quality":"COOL","statusName":"In progress","createdAt":"2026-08-19T09:00:00+03:00","ownerName":"Maria Smirnova","clientName":null}

Importante: NDJSON no es un array JSON válido. Lea la respuesta línea por línea a través de ReadableStream (no llame a JSON.parse() en toda la respuesta).

10. Ejemplo de integración de extremo a extremo

El siguiente escenario crea un lead desde el sitio web, vincula un contacto y un cliente, crea un negocio y envía un evento de marketing.

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

# 1. Iniciar sesión
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. Crear un cliente
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. Crear un contacto
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. Crear un lead
curl -s -X POST "$CRM_BASE_URL/api/leads/create" \
  -H "Authorization: Bearer $CRM_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"message\": \"Consulta desde el sitio 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. Crear un negocio vinculado al lead
curl -s -X POST "$CRM_BASE_URL/api/deals/create" \
  -H "Authorization: Bearer $CRM_TOKEN" \
  -H "Content-Type: application/json" \
  -d "{
    \"name\": \"Asesoría para Ivan Petrov\",
    \"clientId\": \"$CLIENT_ID\",
    \"leadId\": \"$LEAD_ID\",
    \"contactId\": \"$CONTACT_ID\",
    \"amount\": 50000.00,
    \"ownerId\": \"$OWNER_ID\",
    \"authorId\": \"$OWNER_ID\"
  }"

# 6. Enviar un evento de 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. Idempotencia y manejo de errores

12. Inicio rápido

  1. Autentíquese mediante POST /api/auth/login; almacene token y refreshToken.
  2. Agregue Authorization: Bearer <token> a cada solicitud. Ante 401, actualice mediante /api/auth/refresh.
  3. Obtenga referencias (usuarios/estados/etapas/fuentes de leads) una vez y almacene en caché los UUIDs.
  4. Cree entidades en un orden lógico: cliente → contacto → lead → negocio.
  5. Use endpoints paginados para lecturas con filtrado y ordenamiento del lado del servidor.
  6. Para exportaciones, use endpoints NDJSON y lea el flujo línea por línea.
  7. Para ingesta masiva, use endpoints por lotes (/api/leads/import/batch, /api/clients/import/batch) con soporte de reversión.
  8. Envíe atribución de marketing mediante POST /api/dashboard/marketing/events con un externalId estable.
  9. Nunca almacene ni pase PII en el metadata del evento de marketing.
  10. Consulte la documentación detallada por API: site-leads-integration-guide.md.