{"openapi":"3.0.0","paths":{"/me":{"get":{"operationId":"MeController_me","summary":"Contexto de la API key: organización, plan y la propia key","parameters":[],"responses":{"200":{"description":""}},"tags":["Cuenta"],"security":[{"api-key":[]}]}},"/messages":{"post":{"operationId":"MessagesController_send","summary":"Envía un mensaje de WhatsApp (texto, plantilla, imagen o documento)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMessageDto"},"examples":{"template":{"summary":"Plantilla (template)","description":"Envía una plantilla aprobada en Meta con sus parámetros de body.","value":{"channelId":12,"to":"+521 55 1234 5678","type":"template","template":{"name":"recordatorio_cita","language":"es_MX","parameters":{"nombre":"Juan","fecha":"3 de agosto"}}}},"text":{"summary":"Texto (text)","description":"Mensaje de texto libre a un contacto existente (dentro de la ventana de 24h).","value":{"channelId":12,"contactId":345,"type":"text","text":"Hola, ¿en qué podemos ayudarte?"}},"image":{"summary":"Imagen (image)","description":"Imagen por URL con caption opcional en el campo text.","value":{"channelId":12,"to":"+521 55 1234 5678","type":"image","mediaUrl":"https://cdn.sofiachat.com/media/promo-agosto.jpg","text":"Nuestra promoción de agosto"}}}}}},"responses":{"201":{"description":""}},"tags":["Mensajes"],"security":[{"api-key":[]}]}},"/messages/{id}":{"get":{"operationId":"MessagesController_getOne","summary":"Estado de un mensaje por id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Mensajes"],"security":[{"api-key":[]}]}},"/conversations/{id}/messages":{"get":{"operationId":"ConversationsController_listMessages","summary":"Historial de mensajes de una conversación (más recientes primero)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","description":"Número de página","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Cantidad de elementos por página","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"before","required":false,"in":"query","description":"Sólo mensajes creados antes de esta fecha ISO 8601","schema":{"example":"2026-08-25T00:00:00Z","type":"string"}},{"name":"after","required":false,"in":"query","description":"Sólo mensajes creados después de esta fecha ISO 8601","schema":{"example":"2026-08-01T00:00:00Z","type":"string"}}],"responses":{"200":{"description":""}},"tags":["Conversaciones"],"security":[{"api-key":[]}]}},"/contacts":{"get":{"operationId":"ContactsController_list","summary":"Lista contactos de la organización","parameters":[{"name":"page","required":false,"in":"query","description":"Número de página","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Cantidad de elementos por página","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Búsqueda de texto en nombre, apellido, teléfono o email","schema":{"example":"Juan","type":"string"}},{"name":"groupId","required":false,"in":"query","description":"Filtrar por contactos que pertenecen a este grupo","schema":{"example":3,"type":"number"}},{"name":"optedOut","required":false,"in":"query","description":"Filtrar por estado de opt-out: true solo dados de baja, false solo activos","schema":{"example":false,"type":"boolean"}}],"responses":{"200":{"description":""}},"tags":["Contactos"],"security":[{"api-key":[]}]},"post":{"operationId":"ContactsController_create","summary":"Crea un contacto (wa_identified se deriva del teléfono en el servidor)","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactDto"}}}},"responses":{"201":{"description":""}},"tags":["Contactos"],"security":[{"api-key":[]}]}},"/contacts/{id}":{"get":{"operationId":"ContactsController_getOne","summary":"Obtiene un contacto por id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Contactos"],"security":[{"api-key":[]}]},"patch":{"operationId":"ContactsController_update","summary":"Actualiza un contacto","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactDto"}}}},"responses":{"200":{"description":""}},"tags":["Contactos"],"security":[{"api-key":[]}]},"delete":{"operationId":"ContactsController_remove","summary":"Elimina un contacto (soft delete)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Contactos"],"security":[{"api-key":[]}]}},"/contacts/{id}/opt-out":{"post":{"operationId":"ContactsController_optOut","summary":"Marca opt-out (baja) del contacto","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"201":{"description":""}},"tags":["Contactos"],"security":[{"api-key":[]}]}},"/contacts/{id}/opt-in":{"post":{"operationId":"ContactsController_optIn","summary":"Revierte el opt-out del contacto","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"201":{"description":""}},"tags":["Contactos"],"security":[{"api-key":[]}]}},"/contacts/import":{"post":{"operationId":"ContactsController_import","summary":"Importa contactos desde un archivo xlsx/csv; retorna created/updated/errors","parameters":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/ImportConfirmDto"}}}},"responses":{"201":{"description":""}},"tags":["Contactos"],"security":[{"api-key":[]}]}},"/contact-fields":{"get":{"operationId":"ContactFieldsController_list","summary":"Lista los campos personalizados de contacto","parameters":[],"responses":{"200":{"description":""}},"tags":["Campos de contacto"],"security":[{"api-key":[]}]},"post":{"operationId":"ContactFieldsController_create","summary":"Crea un campo personalizado de contacto","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactFieldDto"}}}},"responses":{"201":{"description":""}},"tags":["Campos de contacto"],"security":[{"api-key":[]}]}},"/contact-fields/{id}":{"patch":{"operationId":"ContactFieldsController_update","summary":"Actualiza un campo (la key es inmutable)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactFieldDto"}}}},"responses":{"200":{"description":""}},"tags":["Campos de contacto"],"security":[{"api-key":[]}]},"delete":{"operationId":"ContactFieldsController_remove","summary":"Elimina un campo (soft delete)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Campos de contacto"],"security":[{"api-key":[]}]}},"/contact-groups":{"get":{"operationId":"ContactGroupsController_list","summary":"Lista los grupos de contactos con su conteo de miembros","parameters":[],"responses":{"200":{"description":""}},"tags":["Grupos de contactos"],"security":[{"api-key":[]}]},"post":{"operationId":"ContactGroupsController_create","summary":"Crea un grupo de contactos","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateContactGroupDto"}}}},"responses":{"201":{"description":""}},"tags":["Grupos de contactos"],"security":[{"api-key":[]}]}},"/contact-groups/{id}":{"get":{"operationId":"ContactGroupsController_getOne","summary":"Obtiene un grupo por id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Grupos de contactos"],"security":[{"api-key":[]}]},"patch":{"operationId":"ContactGroupsController_update","summary":"Actualiza un grupo de contactos","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactGroupDto"}}}},"responses":{"200":{"description":""}},"tags":["Grupos de contactos"],"security":[{"api-key":[]}]},"delete":{"operationId":"ContactGroupsController_remove","summary":"Elimina un grupo (soft delete)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Grupos de contactos"],"security":[{"api-key":[]}]}},"/contact-groups/{id}/contacts":{"post":{"operationId":"ContactGroupsController_addContacts","summary":"Agrega contactos a un grupo","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupContactsDto"}}}},"responses":{"201":{"description":""}},"tags":["Grupos de contactos"],"security":[{"api-key":[]}]},"delete":{"operationId":"ContactGroupsController_removeContacts","summary":"Quita contactos de un grupo","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GroupContactsDto"}}}},"responses":{"200":{"description":""}},"tags":["Grupos de contactos"],"security":[{"api-key":[]}]}},"/tags":{"get":{"operationId":"TagsController_list","summary":"Lista los tags de conversación de la organización","parameters":[],"responses":{"200":{"description":""}},"tags":["Etiquetas"],"security":[{"api-key":[]}]},"post":{"operationId":"TagsController_create","summary":"Crea un tag de conversación","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateConversationTagDto"}}}},"responses":{"201":{"description":""}},"tags":["Etiquetas"],"security":[{"api-key":[]}]}},"/tags/{id}":{"get":{"operationId":"TagsController_getOne","summary":"Obtiene un tag por id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Etiquetas"],"security":[{"api-key":[]}]},"patch":{"operationId":"TagsController_update","summary":"Actualiza un tag de conversación","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConversationTagDto"}}}},"responses":{"200":{"description":""}},"tags":["Etiquetas"],"security":[{"api-key":[]}]},"delete":{"operationId":"TagsController_remove","summary":"Elimina un tag de conversación (soft delete)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Etiquetas"],"security":[{"api-key":[]}]}},"/templates":{"get":{"operationId":"TemplatesController_list","summary":"Lista las plantillas de la organización (opcional por canal/estado)","parameters":[{"name":"channelId","required":false,"in":"query","description":"Filtra por canal (integración de WhatsApp)","schema":{"example":12,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filtra por estado de la plantilla","schema":{"example":"approved","enum":["pending","approved","rejected","paused","disabled"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Plantillas"],"security":[{"api-key":[]}]},"post":{"operationId":"TemplatesController_create","summary":"Crea una plantilla y la envía a Meta para aprobación","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateDto"}}}},"responses":{"201":{"description":""}},"tags":["Plantillas"],"security":[{"api-key":[]}]}},"/templates/sync":{"post":{"operationId":"TemplatesController_sync","summary":"Sincroniza las plantillas de un canal con Meta","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncTemplatesV1Dto"}}}},"responses":{"201":{"description":""}},"tags":["Plantillas"],"security":[{"api-key":[]}]}},"/templates/{id}":{"get":{"operationId":"TemplatesController_getOne","summary":"Obtiene una plantilla por id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Plantillas"],"security":[{"api-key":[]}]},"delete":{"operationId":"TemplatesController_remove","summary":"Elimina una plantilla (solo pending/rejected/disabled)","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Plantillas"],"security":[{"api-key":[]}]}},"/campaigns":{"get":{"operationId":"CampaignsController_list","summary":"Lista las campañas de la organización","parameters":[{"name":"page","required":false,"in":"query","description":"Número de página","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Cantidad de elementos por página","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filtrar por estado de la campaña","schema":{"example":"running","enum":["draft","scheduled","running","paused","completed","failed","cancelled"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Campañas"],"security":[{"api-key":[]}]},"post":{"operationId":"CampaignsController_create","summary":"Crea una campaña","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampaignDto"}}}},"responses":{"201":{"description":""}},"tags":["Campañas"],"security":[{"api-key":[]}]}},"/campaigns/{id}":{"get":{"operationId":"CampaignsController_getOne","summary":"Obtiene una campaña por id","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Campañas"],"security":[{"api-key":[]}]}},"/campaigns/{id}/recipients":{"get":{"operationId":"CampaignsController_recipients","summary":"Lista los destinatarios de una campaña","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}},{"name":"page","required":false,"in":"query","description":"Número de página","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Cantidad de elementos por página","schema":{"minimum":1,"maximum":100,"default":50,"example":50,"type":"number"}},{"name":"status","required":false,"in":"query","description":"Filtrar por estado del destinatario","schema":{"example":"delivered","enum":["pending","sending","sent","delivered","read","failed","skipped"],"type":"string"}}],"responses":{"200":{"description":""}},"tags":["Campañas"],"security":[{"api-key":[]}]}},"/campaigns/{id}/send":{"post":{"operationId":"CampaignsController_send","summary":"Inicia el envío de una campaña","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"201":{"description":""}},"tags":["Campañas"],"security":[{"api-key":[]}]}},"/campaigns/{id}/cancel":{"post":{"operationId":"CampaignsController_cancel","summary":"Cancela una campaña","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"201":{"description":""}},"tags":["Campañas"],"security":[{"api-key":[]}]}},"/chat-users":{"get":{"operationId":"ChatUsersController_list","summary":"Lista los chat users con conversaciones en la organización","parameters":[{"name":"page","required":false,"in":"query","description":"Número de página","schema":{"minimum":1,"default":1,"example":1,"type":"number"}},{"name":"limit","required":false,"in":"query","description":"Cantidad de elementos por página","schema":{"minimum":1,"maximum":100,"default":20,"example":20,"type":"number"}},{"name":"search","required":false,"in":"query","description":"Búsqueda de texto en nombre, email o teléfono","schema":{"example":"Juan","type":"string"}},{"name":"type","required":false,"in":"query","description":"Filtra por canal del chat user","schema":{"example":"whatsapp","enum":["chat_web","whatsapp","messenger","slack","telegram"],"type":"string"}},{"name":"sortBy","required":false,"in":"query","description":"Campo de ordenamiento: name|email|phone|last_login|created_at|last_activity","schema":{"example":"last_activity","type":"string"}},{"name":"sortOrder","required":false,"in":"query","description":"Dirección del ordenamiento: ASC|DESC","schema":{"example":"DESC","type":"string"}},{"name":"needHuman","required":false,"in":"query","description":"Sólo chat users que requieren intervención humana","schema":{"example":true,"type":"boolean"}},{"name":"hasUnreadMessages","required":false,"in":"query","description":"Sólo chat users con mensajes sin leer","schema":{"example":false,"type":"boolean"}},{"name":"dateFrom","required":false,"in":"query","description":"Fecha inicial del rango (ISO 8601)","schema":{"example":"2026-08-01T00:00:00Z","type":"string"}},{"name":"dateTo","required":false,"in":"query","description":"Fecha final del rango (ISO 8601)","schema":{"example":"2026-08-25T00:00:00Z","type":"string"}},{"name":"includeMessages","required":false,"in":"query","description":"Si true, incluye los mensajes de cada chat user","schema":{"example":false,"type":"boolean"}}],"responses":{"200":{"description":""}},"tags":["Usuarios de chat"],"security":[{"api-key":[]}]}},"/chat-users/{id}":{"get":{"operationId":"ChatUsersController_getOne","summary":"Obtiene la información completa de un chat user","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"responses":{"200":{"description":""}},"tags":["Usuarios de chat"],"security":[{"api-key":[]}]},"patch":{"operationId":"ChatUsersController_update","summary":"Actualiza campos estándar y/o personalizados de un chat user","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkUpdateChatUserDto"}}}},"responses":{"200":{"description":""}},"tags":["Usuarios de chat"],"security":[{"api-key":[]}]}}},"info":{"title":"Sofia Chat API","description":"API externa de Sofia Chat para integraciones servidor-a-servidor.\n\n## Autenticación\nTodas las peticiones requieren el header `X-API-Key` con una API key válida de la organización.\n\n```\nX-API-Key: <tu_api_key>\n```\n\n## Scopes\nCada API key tiene scopes que autorizan las operaciones:\n- `read`: acceso de lectura (endpoints GET).\n- `write`: acceso de escritura (endpoints POST, PATCH y DELETE).\n\n## Rate limit\nEl límite se aplica por API key (no por IP):\n- 300 peticiones/min en endpoints de lectura.\n- 60 peticiones/min en endpoints de escritura (`write`).\n\nAl superarlo la API responde `429 Too Many Requests`.","version":"1.0","contact":{}},"tags":[],"servers":[{"url":"https://api-v2.sofiachat.com/api/v1"}],"components":{"securitySchemes":{"api-key":{"type":"apiKey","in":"header","name":"X-API-Key"}},"schemas":{"TemplatePayloadDto":{"type":"object","properties":{"name":{"type":"string","description":"Nombre de la plantilla aprobada en Meta","example":"recordatorio_cita"},"language":{"type":"string","description":"Código de idioma de la plantilla, p.ej. es o en_US","example":"es_MX"},"parameters":{"type":"object","additionalProperties":{"type":"string"},"description":"Parámetros del body. NAMED: { nombre: valor }. POSITIONAL: { '1': valor, '2': valor }.","example":{"nombre":"Juan","fecha":"3 de agosto"}}},"required":["name","language"]},"CreateMessageDto":{"type":"object","properties":{"channelId":{"type":"number","description":"ID de la integración (canal) de WhatsApp de la organización","example":12},"to":{"type":"string","description":"Teléfono destino (se normaliza a E.164). Exactamente uno de to/contactId/chatUserId.","example":"+521 55 1234 5678"},"contactId":{"type":"number","description":"ID de contacto de la organización","example":345},"chatUserId":{"type":"number","description":"ID de ChatUser existente","example":678},"type":{"type":"string","enum":["text","template","image","document"],"description":"Tipo de mensaje a enviar","example":"text"},"text":{"type":"string","description":"Texto del mensaje (type=text) o caption (image/document)","example":"Hola, ¿en qué podemos ayudarte?"},"template":{"description":"Payload de la plantilla (obligatorio cuando type=template)","allOf":[{"$ref":"#/components/schemas/TemplatePayloadDto"}]},"mediaUrl":{"type":"string","description":"URL del media (type=image|document)","example":"https://cdn.sofiachat.com/media/promo-agosto.jpg"},"assignToHuman":{"type":"boolean","description":"Si true, la conversación pasa a intervención humana (HITL)","example":false},"metadata":{"type":"object","additionalProperties":true,"description":"Metadatos libres que se guardan junto al mensaje","example":{"source":"crm","ticketId":"A-1001"}}},"required":["channelId","type"]},"CreateContactDto":{"type":"object","properties":{"phone":{"type":"string","description":"Teléfono en formato E.164 (se normaliza en el servidor)","example":"+521 55 1234 5678"},"first_name":{"type":"string","description":"Nombre","example":"Juan"},"last_name":{"type":"string","description":"Apellido","example":"Pérez"},"email":{"type":"string","description":"Email","example":"juan.perez@example.com"},"custom_fields":{"type":"object","description":"Valores de campos custom, keyed por el key del ContactField","example":{"empresa":"ACME"}}},"required":["phone"]},"UpdateContactDto":{"type":"object","properties":{"phone":{"type":"string","description":"Teléfono en formato E.164 (se normaliza en el servidor)","example":"+521 55 1234 5678"},"first_name":{"type":"string","description":"Nombre","example":"Juan"},"last_name":{"type":"string","description":"Apellido","example":"Pérez"},"email":{"type":"string","description":"Email","example":"juan.perez@example.com"},"custom_fields":{"type":"object","description":"Valores de campos custom (reemplaza el objeto completo)","example":{"empresa":"ACME"}}}},"ImportConfirmDto":{"type":"object","properties":{"groupId":{"type":"number","description":"Grupo al que agregar todos los contactos importados (nuevos y existentes)","example":3},"updateExisting":{"type":"boolean","description":"true: los duplicados actualizan el contacto existente; false: se saltan","example":true}},"required":["updateExisting"]},"CreateContactFieldDto":{"type":"object","properties":{"key":{"type":"string","description":"Key del campo: slug en minúsculas (a-z, 0-9, guion bajo)","example":"empresa"},"label":{"type":"string","description":"Etiqueta visible del campo","example":"Empresa"},"type":{"type":"string","enum":["text","number","date","boolean"],"description":"Tipo de dato del campo","default":"text","example":"text"},"position":{"type":"number","description":"Posición para ordenar los campos","default":0,"example":0}},"required":["key","label"]},"UpdateContactFieldDto":{"type":"object","properties":{"label":{"type":"string","description":"Etiqueta visible del campo","example":"Empresa"},"type":{"type":"string","enum":["text","number","date","boolean"],"description":"Tipo de dato del campo","example":"text"},"position":{"type":"number","description":"Posición para ordenar los campos","example":0}}},"CreateContactGroupDto":{"type":"object","properties":{"name":{"type":"string","description":"Nombre del grupo","example":"Clientes VIP"},"description":{"type":"string","description":"Descripción del grupo","example":"Clientes con plan anual"}},"required":["name"]},"UpdateContactGroupDto":{"type":"object","properties":{"name":{"type":"string","description":"Nombre del grupo","example":"Clientes VIP"},"description":{"type":"string","description":"Descripción del grupo","example":"Clientes con plan anual"}}},"GroupContactsDto":{"type":"object","properties":{"contactIds":{"description":"IDs de contactos a agregar/quitar del grupo","example":[1,2,3],"type":"array","items":{"type":"number"}}},"required":["contactIds"]},"CreateConversationTagDto":{"type":"object","properties":{"name":{"type":"string","description":"Nombre único del tag dentro de la organización","example":"Soporte"},"color":{"type":"string","description":"Color en formato hexadecimal #RRGGBB","example":"#3B82F6"},"description":{"type":"object","description":"Descripción opcional","example":"Conversaciones derivadas al equipo de soporte"}},"required":["name","color"]},"UpdateConversationTagDto":{"type":"object","properties":{"name":{"type":"object","description":"Nombre único del tag dentro de la organización","example":"Soporte"},"color":{"type":"object","description":"Color en formato hexadecimal #RRGGBB","example":"#3B82F6"},"description":{"type":"object","description":"Descripción opcional","example":"Conversaciones derivadas al equipo de soporte"}}},"SyncTemplatesV1Dto":{"type":"object","properties":{"channelId":{"type":"number","description":"ID del canal (integración de WhatsApp) a sincronizar con Meta","example":12}},"required":["channelId"]},"TemplateButtonDto":{"type":"object","properties":{"type":{"type":"string","enum":["QUICK_REPLY","URL"],"description":"Tipo de botón","example":"URL"},"text":{"type":"string","description":"Texto visible del botón (máx 25 caracteres)","example":"Confirmar cita"},"url":{"type":"string","description":"URL destino (solo botones de tipo URL)","example":"https://sofiachat.com/citas"}},"required":["type","text"]},"CreateTemplateDto":{"type":"object","properties":{"integrationId":{"type":"number","description":"ID de la integración de WhatsApp dueña de la plantilla","example":12},"name":{"type":"string","description":"Nombre de la plantilla (se normaliza a minúsculas y guiones bajos)","example":"recordatorio_cita"},"language":{"type":"string","description":"Código de idioma de Meta","example":"es_MX"},"category":{"type":"string","enum":["UTILITY","MARKETING","AUTHENTICATION"],"description":"Categoría de Meta","example":"UTILITY"},"bodyText":{"type":"string","description":"Texto del cuerpo con placeholders con nombre","example":"Hola {{nombre}}, tu cita es el {{fecha}}."},"bodyExamples":{"type":"object","description":"Ejemplo por cada placeholder del cuerpo","example":{"nombre":"Juan","fecha":"3 de agosto"}},"footerText":{"type":"string","description":"Pie de página (máx 60 caracteres, sin placeholders)","example":"Equipo de Sofia Chat"},"buttons":{"description":"Botones de la plantilla (máx 10)","type":"array","items":{"$ref":"#/components/schemas/TemplateButtonDto"}}},"required":["integrationId","name","language","category","bodyText"]},"CreateCampaignDto":{"type":"object","properties":{"name":{"type":"string","description":"Nombre de la campaña","example":"Promo julio clientes VIP"},"integrationId":{"type":"number","description":"Integración de WhatsApp desde la que se envía","example":12},"templateId":{"type":"number","description":"Plantilla aprobada por Meta que se enviará","example":87},"conversationTagId":{"type":"number","description":"Tag que se estampa en cada conversación generada (los agentes filtran por tag)","example":4},"parameterMapping":{"type":"object","description":"ParameterMapping que consume TemplateMessageBuilder","example":{"body":[{"source":"contact_field","field":"first_name"}]}},"scheduledAt":{"type":"string","description":"Fecha/hora de envío programado en UTC (ISO 8601). Sin ella la campaña queda en draft","example":"2026-08-30T15:00:00Z"},"groupIds":{"description":"Grupos de contactos destinatarios","example":[1,2],"type":"array","items":{"type":"number"}},"contactIds":{"description":"Contactos destinatarios individuales","example":[345,346],"type":"array","items":{"type":"number"}}},"required":["name","integrationId","templateId","conversationTagId"]},"StandardFieldsDto":{"type":"object","properties":{"name":{"type":"string","description":"Nombre del usuario","example":"Juan Pérez"},"email":{"type":"string","description":"Email del usuario","example":"juan.perez@example.com"},"phone":{"type":"string","description":"Teléfono del usuario","example":"+521 55 1234 5678"},"address":{"type":"string","description":"Dirección del usuario","example":"Av. Reforma 123, CDMX"},"avatar":{"type":"string","description":"URL del avatar del usuario","example":"https://cdn.sofiachat.com/avatars/juan.png"}}},"BulkUpdateChatUserDto":{"type":"object","properties":{"standardFields":{"description":"Campos estándar editables del usuario (name, email, phone, address, avatar)","allOf":[{"$ref":"#/components/schemas/StandardFieldsDto"}]},"customFields":{"type":"object","description":"Campos personalizados del usuario (clave-valor)","example":{"empresa":"Mi Empresa SA","ciudad":"Buenos Aires","edad":"30"}}}}}}}