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"
}
}'
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'
}
})
}
);
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'
}
}
)
{
"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
}
}
Contactos
Fusionar Contactos
Fusiona un contacto duplicado en otro, conservando la información
POST
/
contacts
/
v1
/
{id}
/
merge
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"
}
}'
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'
}
})
}
);
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'
}
}
)
{
"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
}
}
Combina dos contactos en uno solo. Útil para limpiar duplicados y consolidar información.
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.
Path Parameters
string
required
UUID del contacto target (el que permanece)
Body Parameters
string
required
UUID del contacto a fusionar (será eliminado)
object
Estrategia para resolver conflictos de datos
Estrategias de Merge
Nombre
string
default:"prefer_filled"
keep_target: Mantener nombre del targetkeep_source: Usar nombre del sourceprefer_filled: Usar el que no esté vacío (prioridad target)
Tags
string
default:"merge"
merge: Combinar tags de ambos contactosreplace: Usar solo tags del sourcekeep_target: Mantener tags del target
Campos Personalizados
string
default:"merge"
merge: Combinar campos (source sobrescribe si hay conflicto)replace: Usar solo campos del sourcekeep_target: Mantener campos del target
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
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"
}
}'
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'
}
})
}
);
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'
}
}
)
Merge Simple (Estrategia por Defecto)
{
"source_contact_id": "duplicate-uuid"
}
Priorizar Datos del Source
{
"source_contact_id": "duplicate-uuid",
"merge_strategy": {
"name": "keep_source",
"tags": "replace",
"custom_fields": "replace"
}
}
Respuesta Exitosa
{
"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
}
}
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
{
"error": "not_found",
"message": "Uno o ambos contactos no encontrados"
}
{
"error": "validation_error",
"message": "No se puede fusionar un contacto consigo mismo"
}
Webhooks
Cuando fusionas contactos, se dispara el webhookcontact.merged:
{
"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
Búsqueda Avanzada
Encontrar duplicados
Obtener Contacto
Ver contacto fusionado
Listar Contactos
Ver lista actualizada
Operaciones Masivas
Gestionar múltiples contactos
Was this page helpful?