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": [
    {}
  ]
}

Visão Geral

O endpoint upsert cria inteligentemente uma nova pessoa ou atualiza uma existente com base em estratégias configuráveis de detecção de duplicatas. Ele lida automaticamente com conflitos e previne registros duplicados usando correspondência exata, correspondência difusa ou detecção de similaridade alimentada por IA.

Endpoint

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

Autenticação

Requer uma chave de API válida no cabeçalho de autorização:
Authorization: Bearer YOUR_API_KEY

Corpo da Requisição

entity
object
required
Os dados da pessoa (mesma estrutura do endpoint Criar Pessoa)
options
object
Opções de configuração para o comportamento do upsert
options.conflictResolution
enum
Como lidar com conflitos quando uma pessoa existente é encontrada:
  • source_wins - Novos dados sobrescrevem dados existentes
  • target_wins - Mantém dados existentes, ignora novos dados
  • manual_review - Sinaliza para revisão manual sem atualizar
  • smart_merge (padrão) - Mescla inteligentemente ambos os conjuntos de dados
options.deduplicationStrategy
enum
Estratégia para detectar pessoas duplicadas:
  • exact_match - Correspondência por externalId e taxId (insensível a maiúsculas/minúsculas)
  • fuzzy_match - Correspondência de similaridade em nome e taxId (limite de 80%)
  • ai_similarity - Detecção de similaridade semântica alimentada por IA
  • hybrid (recomendado) - Correspondência exata com fallback difuso
options.createRelationships
boolean
default:"true"
Se deve criar automaticamente relacionamentos entre entidades

Resposta

success
boolean
Indica se a operação foi bem-sucedida
action
string
A ação realizada: created ou updated
entity
object
O estado final da pessoa após o upsert
previousEntity
object
O estado da pessoa antes da atualização (null se recém-criada)
confidence
number
Pontuação de confiança (0-1) para a correspondência de detecção de duplicatas
reasoning
string
Explicação de por que a pessoa foi criada/atualizada
conflicts
array
Array de conflitos em nível de campo detectados durante a mesclagem (se houver)

Exemplos

Upsert Simples (Comportamento Padrão)

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

Upsert com Correspondência Difusa

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

Exemplos de Resposta

Nova Pessoa Criada

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

Pessoa Existente Atualizada

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

Casos de Uso

Importação de Dados do CRM

// Importar dados de clientes do CRM, evitando duplicatas
async function importCustomer(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: 'person',
        externalId: crmData.customerId,
        name: crmData.fullName,
        countryCode: crmData.country,
        taxId: crmData.taxId,
        entityData: {
          person: {
            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();
}

Enriquecimento Progressivo de Dados

def enrich_person_data(external_id, new_data):
    """Adicionar dados progressivamente à pessoa conforme ficam disponíveis"""
    response = requests.put(
        'http://api.gu1.ai/entities/upsert',
        headers={
            'Authorization': 'Bearer YOUR_API_KEY',
            'Content-Type': 'application/json'
        },
        json={
            'entity': {
                'type': 'person',
                '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'  # Mesclar novo com existente
            }
        }
    )

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

Melhores Práticas

  1. Escolha a Estratégia Certa:
    • exact_match para dados limpos e estruturados com IDs confiáveis
    • fuzzy_match para dados inseridos pelo usuário com possíveis erros de digitação
    • hybrid para a maioria dos cenários de produção
  2. Lidar com Conflitos Graciosamente:
    • Use smart_merge para resolução automática
    • Use manual_review para dados críticos
    • Verifique o array conflicts na resposta para mudanças importantes
  3. Monitorar Pontuações de Confiança:
    • Pontuações abaixo de 0.7 podem indicar correspondências fracas
    • Registre atualizações de baixa confiança para revisão

Respostas de Erro

400 Bad Request

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

500 Internal Server Error

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

Próximos Passos