Skip to main content
PUT
http://api.gu1.ai
/
entities
/
upsert
Upsert
curl --request PUT \
  --url http://api.gu1.ai/entities/upsert \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "entity": {},
  "options": {},
  "options.conflictResolution": {},
  "options.deduplicationStrategy": {},
  "options.createRelationships": true
}
'
{
  "success": true,
  "action": "<string>",
  "entity": {},
  "previousEntity": {},
  "confidence": 123,
  "reasoning": "<string>",
  "conflicts": [
    {}
  ]
}

Descripción general

El endpoint upsert crea inteligentemente una nueva empresa o actualiza una existente basándose en estrategias de detección de duplicados configurables. Maneja automáticamente conflictos y previene registros duplicados usando coincidencia exacta, coincidencia difusa o detección de similitud impulsada por IA.

Endpoint

PUT http://api.gu1.ai/entities/upsert

Autenticación

Requiere una clave API válida en el encabezado Authorization:
Authorization: Bearer YOUR_API_KEY

Cuerpo de la solicitud

entity
object
required
Los datos de la empresa (misma estructura que el endpoint Crear empresa)
options
object
Opciones de configuración para el comportamiento del upsert
options.conflictResolution
enum
Cómo manejar conflictos cuando se encuentra una empresa existente:
  • source_wins - Los nuevos datos sobrescriben los datos existentes
  • target_wins - Mantener datos existentes, ignorar nuevos datos
  • manual_review - Marcar para revisión manual sin actualizar
  • smart_merge (predeterminado) - Fusionar inteligentemente ambos conjuntos de datos
options.deduplicationStrategy
enum
Estrategia para detectar empresas duplicadas:
  • exact_match - Coincidencia por externalId y taxId (insensible a mayúsculas)
  • fuzzy_match - Coincidencia de similitud en nombre y taxId (umbral del 80%)
  • ai_similarity - Detección de similitud semántica impulsada por IA
  • hybrid (recomendado) - Coincidencia exacta con respaldo difuso
options.createRelationships
boolean
default:"true"
Si crear automáticamente relaciones entre entidades

Respuesta

success
boolean
Indica si la operación tuvo éxito
action
string
La acción realizada: created o updated
entity
object
El estado final de la empresa después del upsert
previousEntity
object
El estado de la empresa antes de la actualización (null si se creó recientemente)
confidence
number
Puntuación de confianza (0-1) para la coincidencia de detección de duplicados
reasoning
string
Explicación de por qué se creó/actualizó la empresa
conflicts
array
Array de conflictos a nivel de campo detectados durante la fusión (si los hay)

Ejemplos

Upsert simple (comportamiento predeterminado)

curl -X PUT http://api.gu1.ai/entities/upsert \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "entity": {
      "type": "company",
      "externalId": "business_12345",
      "name": "María González",
      "countryCode": "AR",
      "taxId": "20-12345678-9",
      "entityData": {
        "company": {
          "firstName": "María",
          "lastName": "González",
          "dateOfBirth": "1985-03-15",
          "occupation": "Software Engineer",
          "income": 85000
        }
      }
    }
  }'

Upsert con coincidencia difusa

curl -X PUT http://api.gu1.ai/entities/upsert \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "entity": {
      "type": "company",
      "externalId": "business_new_123",
      "name": "Maria Gonzales",
      "countryCode": "AR",
      "taxId": "20-12345678-9",
      "entityData": {
        "company": {
          "firstName": "Maria",
          "lastName": "Gonzales"
        }
      }
    },
    "options": {
      "deduplicationStrategy": "fuzzy_match",
      "conflictResolution": "smart_merge"
    }
  }'

Ejemplos de respuesta

Empresa nueva creada

{
  "success": true,
  "action": "created",
  "entity": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "externalId": "business_12345",
    "type": "company",
    "name": "María González",
    ...
  },
  "previousEntity": null,
  "confidence": 1.0,
  "reasoning": "No existing entity found matching criteria. Created new entity.",
  "conflicts": []
}

Empresa existente actualizada

{
  "success": true,
  "action": "updated",
  "entity": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "externalId": "business_12345",
    "type": "company",
    "name": "María González",
    "entityData": {
      "company": {
        "income": 95000
      }
    },
    ...
  },
  "previousEntity": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "entityData": {
      "company": {
        "income": 85000
      }
    },
    ...
  },
  "confidence": 1.0,
  "reasoning": "Exact match found on externalId. Updated existing entity with smart merge.",
  "conflicts": [
    {
      "field": "entityData.company.income",
      "oldValue": 85000,
      "newValue": 95000,
      "resolution": "source_wins"
    }
  ]
}

Casos de uso

Importación de datos desde CRM

// Importar datos de negocio desde CRM, evitando duplicados
async function importBusiness(crmData) {
  const response = await fetch('http://api.gu1.ai/entities/upsert', {
    method: 'PUT',
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      entity: {
        type: 'company',
        externalId: crmData.businessId,
        name: crmData.fullName,
        countryCode: crmData.country,
        taxId: crmData.taxId,
        entityData: {
          company: {
            firstName: crmData.firstName,
            lastName: crmData.lastName,
            income: crmData.annualIncome
          }
        },
        attributes: {
          source: 'crm_import',
          importDate: new Date().toISOString()
        }
      },
      options: {
        deduplicationStrategy: 'hybrid',
        conflictResolution: 'smart_merge'
      }
    })
  });

  return response.json();
}

Enriquecimiento progresivo de datos

def enrich_company_data(external_id, new_data):
    """Agregar progresivamente datos a la empresa a medida que estén disponibles"""
    response = requests.put(
        'http://api.gu1.ai/entities/upsert',
        headers={
            'Authorization': 'Bearer YOUR_API_KEY',
            'Content-Type': 'application/json'
        },
        json={
            'entity': {
                'type': 'company',
                'externalId': external_id,
                'name': new_data.get('name'),
                'countryCode': new_data.get('country'),
                'entityData': new_data.get('details', {}),
                'attributes': new_data.get('attributes', {})
            },
            'options': {
                'deduplicationStrategy': 'exact_match',
                'conflictResolution': 'smart_merge'  # Fusionar nuevo con existente
            }
        }
    )

    result = response.json()
    if result['action'] == 'updated':
        print(f"Enriched existing company with new data")
    return result

Mejores prácticas

  1. Elige la estrategia correcta:
    • exact_match para datos limpios y estructurados con IDs confiables
    • fuzzy_match para datos ingresados por usuarios con posibles errores tipográficos
    • hybrid para la mayoría de los escenarios de producción
  2. Maneja conflictos con elegancia:
    • Usa smart_merge para resolución automática
    • Usa manual_review para datos críticos
    • Verifica el array conflicts en la respuesta para cambios importantes
  3. Monitorea puntuaciones de confianza:
    • Las puntuaciones por debajo de 0.7 pueden indicar coincidencias débiles
    • Registra las actualizaciones de baja confianza para revisión

Respuestas de error

400 Bad Request

{
  "error": "Invalid tax ID format for country"
}

500 Internal Server Error

{
  "error": "Failed to upsert entity"
}

Próximos pasos