Sincronizar contactos
Cómo mantener tu base y la nuestra iguales sin crear duplicados ni pisar lo que cargó un agente.
Usá tu propio identificador
Mandá tu clave primaria en external_id y después dirigite al contacto por ella. Es lo que te deja cambiarle el teléfono a alguien sin perderle el rastro: la gente cambia de número, el id de tu CRM no.
Este pedido crea el contacto si no existe y lo reemplaza si existe. Se puede reintentar sin miedo: responde 201 la primera vez y 200 después, siempre con el contacto en el cuerpo.
curl -X PUT \
https://api.dialsprint.com/api/v1/contacts/by-external-id/crm-8837 \
-H "Authorization: Bearer $DIALSPRINT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Juan Pérez",
"phones": ["+5491155550000"],
"company": "Ejemplo SRL"
}'PATCH suma, no reemplaza
Un PATCH sólo toca lo que nombra. Un campo que no mandás queda como estaba, y un campo simple con null se borra.
Las listas (teléfonos, etiquetas, campos de varios valores) son aditivas: lo que mandás se suma. Para sacar algo hay que pedirlo explícitamente.
Es a propósito. Los agentes cargan teléfonos y etiquetas desde la app todos los días; una sincronización nocturna que reemplazara la lista borraría el teléfono que un agente consiguió ayer.
curl -X PATCH \
https://api.dialsprint.com/api/v1/contacts/01M2XEM2ESR7K9A0AR29EDT9WJ \
-H "Authorization: Bearer $DIALSPRINT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"tags": ["interesado"],
"remove_tags": ["plan-30"]
}'Un teléfono pertenece a un solo contacto
Si intentás crear un contacto con un número que ya existe, la respuesta es 409 con el contact_id del dueño: con ese id, recuperarte es un solo PATCH.
Si tu external_id apunta a un contacto y el teléfono a otro, también es 409 y no se escribe nada. Un número no se muda de contacto solo.
El teléfono se guarda como se disca
Cada teléfono se normaliza al formato internacional y, en los países donde tenemos cargado el plan oficial de numeración, se guarda como se disca: si el plan dice que es un celular y le falta el prefijo que la red exige para llamar a un celular, se lo agregamos. Por eso el teléfono que vuelve en la respuesta puede no ser exactamente el que mandaste: guardate el de la respuesta.
Al buscar un contacto por teléfono, la forma con prefijo y la forma sin él encuentran al mismo contacto. Un teléfono que el contacto ya tenía guardado no cambia.
Traé sólo lo que cambió
Todavía no mandamos webhooks, así que la forma de enterarte es preguntar por lo modificado desde tu última corrida. Guardate el momento en que arrancaste y usalo la próxima vez.
curl -G https://api.dialsprint.com/api/v1/contacts \
-H "Authorization: Bearer $DIALSPRINT_API_KEY" \
--data-urlencode "updated_since=2026-09-19T00:00:00Z" \
--data-urlencode "per_page=100"Los campos personalizados
Los seis campos del sistema van como clave de primer nivel. Los campos que creó tu empresa se direccionan por su id, dentro de fields.
Pedí el catálogo una vez, guardate el mapa de id a nombre y listo. El campo key de cada uno te dice exactamente dónde va su valor en el cuerpo del pedido.
{
"data": [
{
"id": "01M2X8YQ4T0000000000000001",
"slug": null,
"internal_name": "name",
"name": "Nombre",
"type": "text",
"is_system": true,
"key": "name"
},
{
"id": "01M2X8YQ4T0000000000000099",
"slug": null,
"internal_name": null,
"name": "Monto",
"type": "number",
"is_system": false,
"key": "fields.01M2X8YQ4T0000000000000099"
}
]
}Reintentos sin duplicar
Si tu proceso se corta después de mandar el pedido y antes de leer la respuesta, no sabés si escribiste. Mandá Idempotency-Key con algo único por operación y el reintento te devuelve la respuesta de la primera, sin escribir de nuevo.
La clave se recuerda 24 horas. Si la reutilizás con otro cuerpo te avisamos en vez de adivinar, porque eso es un bug en tu lado y esconderlo no ayuda a nadie.
curl https://api.dialsprint.com/api/v1/contacts \
-H "Authorization: Bearer $DIALSPRINT_API_KEY" \
-H "Idempotency-Key: sync-2026-09-20-fila-118" \
-H "Content-Type: application/json" \
-d '{ "name": "Juan Pérez", "phones": ["+5491155550000"] }'Dejarle una nota al agente
La nota aparece en la ficha que el agente mira antes de discar, así que es la forma más barata de poner contexto donde se usa. El autor queda como la clave, no como una persona que no escribió nada.
curl https://api.dialsprint.com/api/v1/contacts/01M2XE.../notes \
-H "Authorization: Bearer $DIALSPRINT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "body": "Pagó 2 de 5 cuotas. Confirmar antes de llamar." }'Archivar, nunca borrar
No hay borrado, y la razón tiene dientes: al borrar un contacto se van sus teléfonos, y con ellos la baja de SMS que el cliente pidió. Un sistema que borra y recrea para sincronizar la resucitaría.
Archivar lo saca de todo camino de discado y lo deja legible. Se sigue viendo en GET /contacts con su archived_at: una sincronización que no lo ve lo vuelve a crear.
curl -X POST https://api.dialsprint.com/api/v1/contacts/01M2XE.../archive \
-H "Authorization: Bearer $DIALSPRINT_API_KEY"