{"openapi":"3.1.0","info":{"title":"Wando API","version":"1.0.0","description":"API de Wando para leer mensajes, responder por WhatsApp y enviar plantillas. Autenticación por header `X-API-Key` (creá tu key en el panel: Configuración → API Keys). Cada key tiene permisos (scopes): `leer`, `escribir`, `enviar`. Límite: 120 solicitudes por minuto por key. Texto libre solo dentro de la ventana de 24hs de WhatsApp; fuera de ella usá /send-template. Wando también puede avisarte por webhooks salientes firmados: ver https://fatties.wando.online/api-docs#webhooks","contact":{"url":"https://fatties.wando.online/api-docs"}},"servers":[{"url":"https://fatties.wando.online"}],"security":[{"ApiKeyAuth":[]}],"paths":{"/api/v1/mensajes":{"get":{"summary":"Listar mensajes","description":"Lista los mensajes de tu empresa. Por defecto muestra los pendientes. Requiere scope: leer.","tags":["Mensajes"],"parameters":[{"name":"estado","in":"query","schema":{"type":"string","enum":["pendiente","respondido","todos"],"default":"pendiente"}},{"name":"telefono","in":"query","description":"Trae el hilo de UN contacto (formato E164, ej: +5493511234567). Si lo pasás sin `estado`, devuelve la conversación entera y no solo los pendientes.","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}}],"responses":{"200":{"description":"Lista de mensajes","content":{"application/json":{"schema":{"type":"object","properties":{"mensajes":{"type":"array","items":{"$ref":"#/components/schemas/Mensaje"}},"total":{"type":"integer"}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Registrar un mensaje en la bandeja","description":"Registra un mensaje entrante en la bandeja de Wando (aparece como pendiente en el panel). Útil para derivar consultas desde otro canal o sistema propio. Requiere scope: escribir.","tags":["Mensajes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["telefono","texto"],"properties":{"telefono":{"type":"string","description":"Teléfono del contacto"},"texto":{"type":"string","description":"Texto del mensaje"},"nombre":{"type":"string","description":"Nombre del contacto (opcional)"}}}}}},"responses":{"200":{"description":"Mensaje creado","content":{"application/json":{"schema":{"type":"object","properties":{"mensaje":{"$ref":"#/components/schemas/Mensaje"}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/mensajes/{id}":{"get":{"summary":"Detalle de un mensaje","description":"Obtiene el detalle completo de un mensaje por su ID. Requiere scope: leer.","tags":["Mensajes"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"El mensaje","content":{"application/json":{"schema":{"type":"object","properties":{"mensaje":{"$ref":"#/components/schemas/Mensaje"}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Mensaje no encontrado"},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/mensajes/{id}/responder":{"post":{"summary":"Responder un mensaje (texto libre)","description":"Aprueba un mensaje pendiente y envía la respuesta por WhatsApp. Solo funciona dentro de la ventana de 24hs; si el cliente no escribió en las últimas 24hs usá /api/v1/send-template. Requiere scope: enviar.","tags":["Mensajes"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["respuesta"],"properties":{"respuesta":{"type":"string","description":"Texto de la respuesta a enviar"}}}}}},"responses":{"200":{"description":"Respuesta enviada","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"mensaje_id":{"type":"string","format":"uuid"},"estado":{"type":"string"},"enviado_a":{"type":"string"}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Mensaje no encontrado"},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/mensajes/entrante":{"post":{"summary":"Simular un mensaje entrante (testing)","description":"Simula un mensaje entrante de WhatsApp. Solo para testing: no genera sugerencia de IA ni dispara webhooks. Requiere scope: escribir.","tags":["Mensajes"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["telefono","texto"],"properties":{"telefono":{"type":"string"},"texto":{"type":"string"},"nombre":{"type":"string"},"urgencia":{"type":"string","enum":["normal","urgente"]}}}}}},"responses":{"200":{"description":"Mensaje de prueba creado","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"mensaje":{"$ref":"#/components/schemas/Mensaje"},"nota":{"type":"string"}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/conversaciones":{"get":{"summary":"Listar conversaciones con su estado","description":"Estado de las conversaciones: quién la atiende, categoría, etiquetas y si está resuelta. Es lo que necesita un CRM para reflejar la ficha del cliente. Requiere scope: leer.","tags":["Conversaciones"],"parameters":[{"name":"telefono","in":"query","description":"Filtra por un contacto (E164).","schema":{"type":"string"}},{"name":"estado","in":"query","schema":{"type":"string","enum":["abiertas","resueltas","todas"],"default":"abiertas"}},{"name":"limit","in":"query","schema":{"type":"integer","maximum":200,"default":50}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Lista de conversaciones","content":{"application/json":{"schema":{"type":"object","properties":{"conversaciones":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"telefono":{"type":"string"},"canal":{"type":"string","example":"whatsapp"},"leida":{"type":"boolean"},"resuelta":{"type":"boolean"},"categoria":{"type":"string","nullable":true},"asignado_a":{"type":"string","nullable":true},"etiquetas":{"type":"array","items":{"type":"string"}},"total_mensajes":{"type":"integer"},"contacto":{"type":"object","properties":{"nombre":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"id_externo":{"type":"string","nullable":true,"description":"Tu propio ID de cliente, si lo cargaste."}}},"ultimo_mensaje":{"type":"string","nullable":true},"ultimo_mensaje_at":{"type":"string","format":"date-time","nullable":true}}}},"total":{"type":"integer"}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/contactos":{"get":{"summary":"Listar contactos","description":"Lista los contactos únicos de tu empresa con estadísticas. Requiere scope: leer.","tags":["Contactos"],"responses":{"200":{"description":"Lista de contactos","content":{"application/json":{"schema":{"type":"object","properties":{"contactos":{"type":"array","items":{"type":"object","properties":{"telefono":{"type":"string"},"nombre":{"type":"string"},"ultimo_mensaje":{"type":"string"},"fecha_ultimo":{"type":"string","format":"date-time"},"cantidad_mensajes":{"type":"integer"}}}},"total":{"type":"integer"}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/plantillas":{"get":{"summary":"Listar plantillas aprobadas","description":"Lista las plantillas de WhatsApp APROBADAS por Meta. Usala para saber qué podés mandar con /api/v1/send-template y cuántas variables lleva cada una. Requiere scope: leer.","tags":["Plantillas"],"responses":{"200":{"description":"Lista de plantillas","content":{"application/json":{"schema":{"type":"object","properties":{"plantillas":{"type":"array","items":{"$ref":"#/components/schemas/Plantilla"}},"total":{"type":"integer"}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/send-template":{"post":{"summary":"Enviar una plantilla de WhatsApp","description":"Envía una plantilla aprobada a cualquier teléfono. Es la ÚNICA forma de iniciar una conversación o escribir fuera de la ventana de 24hs. Los nombres salen de GET /api/v1/plantillas. Requiere scope: enviar.","tags":["Plantillas"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["telefono","templateName"],"properties":{"telefono":{"type":"string","description":"Teléfono destino (ej: 5491123456789)"},"templateName":{"type":"string","description":"Nombre Meta de la plantilla (campo nombre_meta)"},"languageCode":{"type":"string","default":"es"},"bodyParams":{"type":"array","items":{"type":"string"},"description":"Valores para las variables {{1}}, {{2}}... en orden. El valor especial \"{{contacto.nombre}}\" lo resuelve Wando con el nombre del cliente: ficha del contacto → nombre de perfil de WhatsApp → \"vecino\" (nunca del llamador)."},"templateNameSinNombre":{"type":"string","description":"Opcional. Plantilla gemela sin saludo nominal: si se indica y no hay nombre real (ficha ni WhatsApp), se manda ésta en vez del genérico."},"textoLibreSiVentanaAbierta":{"type":"boolean","default":false,"description":"Si la conversación tiene ventana de 24hs abierta, manda el mismo texto como mensaje común en vez de la plantilla HSM."},"agenteEmail":{"type":"string","description":"Email del usuario de Wando al que se asigna la conversación (opcional)"},"headerImageUrl":{"type":"string","description":"URL de imagen si la plantilla tiene header de imagen"},"headerDocumentUrl":{"type":"string","description":"URL de documento si la plantilla tiene header de documento"},"headerVideoUrl":{"type":"string","description":"URL de video si la plantilla tiene header de video"}}}}}},"responses":{"200":{"description":"Plantilla enviada","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"messageId":{"type":"string"},"enviadoComoTexto":{"type":"boolean"},"templateUsada":{"type":"string","nullable":true},"origenNombre":{"type":"string","enum":["ficha","whatsapp","generico"],"nullable":true}}}}}},"401":{"description":"API key faltante, inválida o vencida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"La key no tiene el permiso (scope) que exige este endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Límite de 120 solicitudes por minuto superado (ver header Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Creá tu key en el panel: Configuración → API Keys. Scopes: leer / escribir / enviar."}},"schemas":{"Mensaje":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"telefono":{"type":"string"},"nombre":{"type":"string"},"mensaje_texto":{"type":"string"},"respuesta_sugerida":{"type":"string"},"tipo":{"type":"string","enum":["Recibido","Enviado"]},"timestamp":{"type":"string","format":"date-time"},"aprobada":{"type":"boolean"},"urgencia":{"type":"string"},"estado":{"type":"string"}}},"Plantilla":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"titulo":{"type":"string"},"nombre_meta":{"type":"string"},"texto":{"type":"string"},"categoria_meta":{"type":"string"},"header_type":{"type":"string"},"meta_status":{"type":"string"},"variable_count":{"type":"integer"}}},"Error":{"type":"object","properties":{"error":{"type":"string"}}}}}}