> ## Documentation Index
> Fetch the complete documentation index at: https://docs.whaapy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Fusionar Contactos

> Fusiona un contacto duplicado en otro, conservando la información

Combina dos contactos en uno solo. Útil para limpiar duplicados y consolidar información.

<Info>
  El contacto **target** (el de la URL) es el que permanece. El contacto **source** (el del body) será eliminado y sus datos fusionados al target.
</Info>

***

## Path Parameters

<ParamField path="id" type="string" required>
  UUID del contacto **target** (el que permanece)
</ParamField>

***

## Body Parameters

<ParamField body="source_contact_id" type="string" required>
  UUID del contacto a fusionar (será eliminado)
</ParamField>

<ParamField body="merge_strategy" type="object">
  Estrategia para resolver conflictos de datos
</ParamField>

***

## Estrategias de Merge

### Nombre

<ParamField body="merge_strategy.name" type="string" default="prefer_filled">
  * `keep_target`: Mantener nombre del target
  * `keep_source`: Usar nombre del source
  * `prefer_filled`: Usar el que no esté vacío (prioridad target)
</ParamField>

### Tags

<ParamField body="merge_strategy.tags" type="string" default="merge">
  * `merge`: Combinar tags de ambos contactos
  * `replace`: Usar solo tags del source
  * `keep_target`: Mantener tags del target
</ParamField>

### Campos Personalizados

<ParamField body="merge_strategy.custom_fields" type="string" default="merge">
  * `merge`: Combinar campos (source sobrescribe si hay conflicto)
  * `replace`: Usar solo campos del source
  * `keep_target`: Mantener campos del target
</ParamField>

***

## Comportamiento Automático

Además de la estrategia configurable, el merge automáticamente:

* **Transfiere todas las conversaciones** del source al target
* **Fusiona external\_ids** (IDs de CRMs externos)
* **Concatena las notas** (separadas por `---`)
* **Aplica prefer\_filled** para: email, avatar\_url, company, address, city, state, postal\_code
* **Elimina (soft delete)** el contacto source

***

## Ejemplos

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.whaapy.com/contacts/v1/target-uuid/merge \
    -H "Authorization: Bearer wha_TU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "source_contact_id": "duplicate-uuid",
      "merge_strategy": {
        "name": "prefer_filled",
        "tags": "merge",
        "custom_fields": "merge"
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const targetId = 'target-uuid';
  const response = await fetch(
    `https://api.whaapy.com/contacts/v1/${targetId}/merge`,
    {
      method: 'POST',
      headers: {
        'Authorization': 'Bearer wha_TU_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        source_contact_id: 'duplicate-uuid',
        merge_strategy: {
          name: 'prefer_filled',
          tags: 'merge',
          custom_fields: 'merge'
        }
      })
    }
  );
  ```

  ```python Python theme={null}
  import requests

  target_id = 'target-uuid'
  response = requests.post(
      f'https://api.whaapy.com/contacts/v1/{target_id}/merge',
      headers={
          'Authorization': 'Bearer wha_TU_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'source_contact_id': 'duplicate-uuid',
          'merge_strategy': {
              'name': 'prefer_filled',
              'tags': 'merge',
              'custom_fields': 'merge'
          }
      }
  )
  ```
</RequestExample>

### Merge Simple (Estrategia por Defecto)

<RequestExample>
  ```json Request theme={null}
  {
    "source_contact_id": "duplicate-uuid"
  }
  ```
</RequestExample>

### Priorizar Datos del Source

<RequestExample>
  ```json Request theme={null}
  {
    "source_contact_id": "duplicate-uuid",
    "merge_strategy": {
      "name": "keep_source",
      "tags": "replace",
      "custom_fields": "replace"
    }
  }
  ```
</RequestExample>

***

## Respuesta Exitosa

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "contact": {
      "id": "target-uuid",
      "phone_number": "+5215512345678",
      "name": "Juan Pérez",
      "email": "juan@email.com",
      "tags": ["cliente", "premium", "vip"],
      "custom_fields": { 
        "company": "Acme", 
        "source_field": "value",
        "role": "CEO"
      },
      "external_ids": {
        "hubspot": "abc123",
        "salesforce": "xyz789"
      },
      "notes": "Notas originales...\n\n---\n\nNotas del contacto fusionado...",
      "funnel_stage": { "id": "stage-uuid", "name": "Qualified" },
      "updated_at": "2026-01-28T12:00:00Z"
    },
    "merged_from": {
      "id": "duplicate-uuid",
      "deleted": true
    },
    "changes": {
      "tags_added": ["vip"],
      "custom_fields_added": ["source_field", "role"],
      "conversations_transferred": 2
    }
  }
  ```
</ResponseExample>

### Campos de la Respuesta

| Campo                               | Descripción                                             |
| ----------------------------------- | ------------------------------------------------------- |
| `contact`                           | El contacto target actualizado con los datos fusionados |
| `merged_from.id`                    | UUID del contacto source que fue eliminado              |
| `merged_from.deleted`               | Siempre `true`                                          |
| `changes.tags_added`                | Tags que se agregaron del source                        |
| `changes.custom_fields_added`       | Campos personalizados agregados del source              |
| `changes.conversations_transferred` | Número de conversaciones transferidas                   |

***

## Errores

<ResponseExample>
  ```json 404 Not Found theme={null}
  {
    "error": "not_found",
    "message": "Uno o ambos contactos no encontrados"
  }
  ```
</ResponseExample>

<ResponseExample>
  ```json 400 Bad Request theme={null}
  {
    "error": "validation_error",
    "message": "No se puede fusionar un contacto consigo mismo"
  }
  ```
</ResponseExample>

***

## Webhooks

Cuando fusionas contactos, se dispara el webhook `contact.merged`:

```json theme={null}
{
  "event": "contact.merged",
  "data": {
    "target_contact_id": "target-uuid",
    "source_contact_id": "duplicate-uuid",
    "changes": {
      "tags_added": ["vip"],
      "custom_fields_added": ["source_field"],
      "conversations_transferred": 2
    },
    "merged_at": "2026-01-28T12:00:00Z"
  }
}
```

***

## Próximos Pasos

<CardGroup cols={2}>
  <Card title="Búsqueda Avanzada" icon="magnifying-glass" href="/api-reference/contacts/search">
    Encontrar duplicados
  </Card>

  <Card title="Obtener Contacto" icon="user" href="/api-reference/contacts/get">
    Ver contacto fusionado
  </Card>

  <Card title="Listar Contactos" icon="list" href="/api-reference/contacts/list">
    Ver lista actualizada
  </Card>

  <Card title="Operaciones Masivas" icon="layer-group" href="/api-reference/contacts/bulk">
    Gestionar múltiples contactos
  </Card>
</CardGroup>
