Importar contactos al directorio en bloque (remitentes y destinatarios)
Importación masiva del directorio — pensada para migrar contactos desde una hoja de cálculo, otra plataforma o una lista fotografiada, típicamente a través de un asistente de IA. Requiere scope addresses:write (es el mismo alcance de POST /senders / POST /recipients: una importación son esos dos creates en bloque).
Dos carriles de entrada, mutuamente excluyentes:
- contacts: arreglo de filas {type: 'sender'|'recipient', name, phone, street, number?, colonia, city?, state?, postal_code, email?, company?, rfc?} — el mismo vocabulario de campos que POST /senders / POST /recipients (los destinatarios además aceptan sender_id?, alias?, referencia?, delivery_instructions?). El cliente (p. ej. el modelo) debe mapear los datos del usuario TAL CUAL, nunca inventar valores.
- raw_csv: el contenido del CSV del usuario, VERBATIM (UTF-8, BOM opcional, máx. 256KB). El servidor lo interpreta de forma determinista: delimitador coma/punto y coma/tabulador (detectado), fila de encabezado obligatoria con las columnas de la plantilla tipo,nombre,telefono,calle,numero,colonia,ciudad,estado,codigo_postal,email,empresa,rfc (coincidencia insensible a mayúsculas y acentos, cualquier orden; columnas desconocidas → 422, nunca adivinadas). tipo acepta remitente/destinatario (o sender/recipient).
Dos fases sin estado: dry_run: true (el DEFAULT — el modo seguro) valida todo y devuelve la vista previa normalizada sin escribir nada; dry_run: false re-valida e inserta. La seguridad ante reintentos viene del DEDUPE POR CONTENIDO, no de claims: una fila idéntica (tupla normalizada nombre+teléfono+dirección+CP — el MISMO dedupe de POST /senders) a un contacto existente visible se reporta duplicate y se omite, así que repetir un commit jamás duplica el directorio.
Validación por fila (nunca aborta el lote completo): codigo_postal de 5 dígitos y existente en el catálogo SEPOMEX; si ciudad/estado vienen, deben ser coherentes con el CP (un desajuste nombra el valor esperado) y si faltan se AUTOCOMPLETAN del catálogo; telefono se normaliza a 10 dígitos (se toleran espacios, guiones y el prefijo +52/521); email con formato válido cuando venga. Cada fila responde status: ok|duplicate|invalid con issues[] en español nombrando campo y motivo.
Padre de los destinatarios: un destino siempre pertenece a un remitente. Orden de resolución: sender_id explícito de la fila → el PRIMER remitente válido del mismo lote → el remitente más reciente del directorio. Sin candidato, la fila es invalid con instrucciones.
Topes: máximo 200 filas por llamada (más → 422 pidiendo trocear el lote) y 256KB de raw_csv.
Conteos (invariantes): received = valid + invalid, valid = filas ok + duplicates; en commit además created y skipped con received = created + skipped + invalid — imposible perder filas en silencio.
Con una llave ek_test_ la importación escribe en el directorio del sandbox (mismas reglas, mismos formatos de respuesta). La visibilidad/destino de las filas es la misma de POST /senders: llaves de cliente y llaves admin sin X-PDV-ID escriben como el usuario de la llave; una llave admin con X-PDV-ID validado escribe en el directorio de ese punto de venta.
Request
- Base URL: https://api.enviadores.com.mx/api/v1
- URL: https://api.enviadores.com.mx/api/v1/contacts/import
- Auth: HTTP bearer
Headers
Solo llaves de cuentas admin: el punto de venta cuyo fondo se carga/consulta. Requiere que la llave tenga una allowlist de PDVs configurada por un administrador (pdv_allowlist); sin allowlist, todo PDV real es denegado por defecto. Validado además contra los PDV activos. Cualquier violación → 403 PDV_NOT_ALLOWED. El valor personal_account equivale a omitir el header.
Request body
Response
Resultado por fila + resumen. En dry_run nada se escribió; en commit, created/skipped reportan lo insertado/omitido.
Changes
No recorded changes to this operation across all 1 revision of this API.