# API Reference ## Información General - **Base URL:** `https://tu-dominio.com/api` - **Autenticación:** Bearer Token (JWT) - **Content-Type:** `application/json` ## Autenticación ### Login ```http POST /auth/login ``` **Request:** ```json { "email": "usuario@empresa.com", "password": "tu_password" } ``` **Response:** ```json { "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...", "token_type": "bearer", "user": { "id": "uuid", "email": "usuario@empresa.com", "name": "Usuario", "role": "admin" } } ``` ### Refresh Token ```http POST /auth/refresh ``` ### Logout ```http POST /auth/logout ``` ### Usuario Actual ```http GET /auth/me ``` --- ## Usuarios ### Listar Usuarios ```http GET /api/users ``` **Query Parameters:** | Parámetro | Tipo | Descripción | |-----------|------|-------------| | role | string | Filtrar por rol (admin, supervisor, agent) | | status | string | Filtrar por estado (online, offline, away) | | page | int | Página (default: 1) | | limit | int | Límite por página (default: 20) | ### Crear Usuario ```http POST /api/users ``` **Request:** ```json { "email": "nuevo@empresa.com", "password": "password123", "name": "Nuevo Usuario", "role": "agent" } ``` ### Obtener Usuario ```http GET /api/users/{user_id} ``` ### Actualizar Usuario ```http PUT /api/users/{user_id} ``` ### Eliminar Usuario ```http DELETE /api/users/{user_id} ``` ### Cambiar Estado ```http PUT /api/users/{user_id}/status ``` **Request:** ```json { "status": "away" } ``` --- ## Cuentas WhatsApp ### Listar Cuentas ```http GET /api/whatsapp/accounts ``` ### Crear Cuenta (Iniciar conexión) ```http POST /api/whatsapp/accounts ``` **Request:** ```json { "name": "Ventas Principal" } ``` **Response:** ```json { "id": "uuid", "name": "Ventas Principal", "status": "disconnected", "qr_code": null } ``` ### Obtener QR Code ```http GET /api/whatsapp/accounts/{account_id}/qr ``` **Response:** ```json { "qr_code": "data:image/png;base64,..." } ``` ### Estado de Cuenta ```http GET /api/whatsapp/accounts/{account_id}/status ``` ### Desconectar Cuenta ```http POST /api/whatsapp/accounts/{account_id}/disconnect ``` ### Reconectar Cuenta ```http POST /api/whatsapp/accounts/{account_id}/reconnect ``` --- ## Contactos ### Listar Contactos ```http GET /api/contacts ``` **Query Parameters:** | Parámetro | Tipo | Descripción | |-----------|------|-------------| | search | string | Buscar por nombre, teléfono o email | | tags | string[] | Filtrar por etiquetas | | has_odoo | boolean | Filtrar sincronizados con Odoo | | page | int | Página | | limit | int | Límite | ### Crear Contacto ```http POST /api/contacts ``` **Request:** ```json { "phone_number": "+525551234567", "name": "Juan Pérez", "email": "juan@email.com", "company": "Empresa ABC", "tags": ["lead", "interesado"], "metadata": { "producto_interes": "Laptop Pro" } } ``` ### Obtener Contacto ```http GET /api/contacts/{contact_id} ``` ### Actualizar Contacto ```http PUT /api/contacts/{contact_id} ``` ### Agregar Etiquetas ```http POST /api/contacts/{contact_id}/tags ``` **Request:** ```json { "tags": ["vip", "cliente"] } ``` ### Sincronizar con Odoo ```http POST /api/contacts/{contact_id}/sync-odoo ``` --- ## Conversaciones ### Listar Conversaciones ```http GET /api/conversations ``` **Query Parameters:** | Parámetro | Tipo | Descripción | |-----------|------|-------------| | status | string | bot, waiting, active, resolved | | queue_id | uuid | Filtrar por cola | | assigned_to | uuid | Filtrar por agente | | priority | string | low, normal, high, urgent | | page | int | Página | | limit | int | Límite | ### Obtener Conversación ```http GET /api/conversations/{conversation_id} ``` **Response:** ```json { "id": "uuid", "contact": { "id": "uuid", "name": "Juan Pérez", "phone_number": "+525551234567" }, "whatsapp_account": { "id": "uuid", "name": "Ventas Principal" }, "status": "active", "priority": "normal", "assigned_to": { "id": "uuid", "name": "María García" }, "queue": { "id": "uuid", "name": "Ventas" }, "current_flow": null, "sla_first_response_met": true, "last_message_at": "2024-01-15T14:30:00Z", "created_at": "2024-01-15T14:25:00Z" } ``` ### Asignar Conversación ```http POST /api/conversations/{conversation_id}/assign ``` **Request:** ```json { "user_id": "uuid" } ``` ### Transferir a Cola ```http POST /api/conversations/{conversation_id}/transfer ``` **Request:** ```json { "queue_id": "uuid" } ``` ### Resolver Conversación ```http POST /api/conversations/{conversation_id}/resolve ``` **Request:** ```json { "resolution_note": "Problema resuelto" } ``` ### Reabrir Conversación ```http POST /api/conversations/{conversation_id}/reopen ``` --- ## Mensajes ### Listar Mensajes de Conversación ```http GET /api/conversations/{conversation_id}/messages ``` **Query Parameters:** | Parámetro | Tipo | Descripción | |-----------|------|-------------| | before | uuid | Mensajes antes de este ID | | limit | int | Límite (default: 50) | ### Enviar Mensaje ```http POST /api/conversations/{conversation_id}/messages ``` **Request (texto):** ```json { "type": "text", "content": "Hola, ¿en qué te puedo ayudar?" } ``` **Request (imagen):** ```json { "type": "image", "media_url": "https://example.com/image.jpg", "content": "Caption opcional" } ``` **Request (botones):** ```json { "type": "buttons", "content": "¿Qué necesitas?", "metadata": { "buttons": [ {"id": "ventas", "text": "Ventas"}, {"id": "soporte", "text": "Soporte"}, {"id": "otro", "text": "Otro"} ] } } ``` **Request (lista):** ```json { "type": "list", "content": "Selecciona una opción:", "metadata": { "button_text": "Ver opciones", "sections": [ { "title": "Productos", "rows": [ {"id": "laptop", "title": "Laptops", "description": "Ver laptops disponibles"}, {"id": "telefono", "title": "Teléfonos", "description": "Ver teléfonos"} ] } ] } } ``` ### Enviar Nota Interna ```http POST /api/conversations/{conversation_id}/notes ``` **Request:** ```json { "content": "Cliente interesado, dar seguimiento" } ``` --- ## Flujos ### Listar Flujos ```http GET /api/flows ``` ### Crear Flujo ```http POST /api/flows ``` **Request:** ```json { "name": "Bienvenida", "description": "Flujo de bienvenida para nuevos contactos", "trigger_type": "welcome", "trigger_value": null, "nodes": { "nodes": [...], "edges": [...], "viewport": {...} }, "is_active": true } ``` ### Obtener Flujo ```http GET /api/flows/{flow_id} ``` ### Actualizar Flujo ```http PUT /api/flows/{flow_id} ``` ### Duplicar Flujo ```http POST /api/flows/{flow_id}/duplicate ``` ### Activar/Desactivar Flujo ```http PUT /api/flows/{flow_id}/toggle ``` ### Probar Flujo ```http POST /api/flows/{flow_id}/test ``` **Request:** ```json { "phone_number": "+525551234567", "initial_message": "Hola" } ``` --- ## Colas ### Listar Colas ```http GET /api/queues ``` ### Crear Cola ```http POST /api/queues ``` **Request:** ```json { "name": "Ventas", "description": "Cola de atención de ventas", "assignment_method": "least_busy", "max_per_agent": 8, "sla_first_response": 180, "sla_resolution": 3600, "business_hours": { "monday": {"start": "09:00", "end": "18:00"}, "tuesday": {"start": "09:00", "end": "18:00"}, "wednesday": {"start": "09:00", "end": "18:00"}, "thursday": {"start": "09:00", "end": "18:00"}, "friday": {"start": "09:00", "end": "17:00"}, "saturday": {"start": "10:00", "end": "14:00"}, "sunday": null }, "fallback_flow_id": "uuid" } ``` ### Obtener Cola ```http GET /api/queues/{queue_id} ``` ### Actualizar Cola ```http PUT /api/queues/{queue_id} ``` ### Agregar Agente a Cola ```http POST /api/queues/{queue_id}/agents ``` **Request:** ```json { "user_id": "uuid", "is_supervisor": false, "skills": ["ventas", "ingles"] } ``` ### Remover Agente de Cola ```http DELETE /api/queues/{queue_id}/agents/{user_id} ``` ### Estadísticas de Cola ```http GET /api/queues/{queue_id}/stats ``` **Response:** ```json { "waiting": 5, "active": 12, "resolved_today": 47, "avg_first_response": 142, "avg_resolution": 1823, "sla_compliance": 0.91, "agents": [ { "user_id": "uuid", "name": "María García", "status": "online", "active_conversations": 5, "resolved_today": 12 } ] } ``` --- ## Respuestas Rápidas ### Listar Respuestas Rápidas ```http GET /api/quick-replies ``` ### Crear Respuesta Rápida ```http POST /api/quick-replies ``` **Request:** ```json { "shortcut": "/saludo", "content": "¡Hola {{contact.name}}! Soy {{agent.name}}, ¿en qué te puedo ayudar?", "queue_id": null } ``` ### Actualizar Respuesta Rápida ```http PUT /api/quick-replies/{id} ``` ### Eliminar Respuesta Rápida ```http DELETE /api/quick-replies/{id} ``` --- ## Odoo ### Probar Conexión ```http POST /api/odoo/test-connection ``` ### Sincronizar Contactos ```http POST /api/odoo/sync-contacts ``` ### Buscar Partner ```http GET /api/odoo/partners/search ``` **Query Parameters:** | Parámetro | Tipo | Descripción | |-----------|------|-------------| | phone | string | Buscar por teléfono | | email | string | Buscar por email | | name | string | Buscar por nombre | ### Buscar Pedidos ```http GET /api/odoo/orders ``` **Query Parameters:** | Parámetro | Tipo | Descripción | |-----------|------|-------------| | partner_id | int | ID del partner en Odoo | | state | string | Estado del pedido | | limit | int | Límite | ### Consultar Stock ```http GET /api/odoo/products/{product_id}/stock ``` ### Crear Lead ```http POST /api/odoo/leads ``` **Request:** ```json { "name": "Interés en Producto X", "contact_name": "Juan Pérez", "phone": "+525551234567", "email": "juan@email.com", "description": "Cliente interesado en laptops", "expected_revenue": 5000 } ``` --- ## WebSocket ### Conexión ```javascript const socket = io('wss://tu-dominio.com', { auth: { token: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...' } }); ``` ### Eventos del Servidor **Nuevo mensaje:** ```javascript socket.on('new_message', (data) => { // data: { conversation_id, message } }); ``` **Estado de mensaje:** ```javascript socket.on('message_status', (data) => { // data: { message_id, status: 'delivered' | 'read' } }); ``` **Conversación asignada:** ```javascript socket.on('conversation_assigned', (data) => { // data: { conversation_id, assigned_to } }); ``` **QR Code:** ```javascript socket.on('qr_code', (data) => { // data: { account_id, qr_code } }); ``` **Estado de conexión WhatsApp:** ```javascript socket.on('connection_status', (data) => { // data: { account_id, status: 'connected' | 'disconnected' } }); ``` ### Eventos del Cliente **Unirse a conversación:** ```javascript socket.emit('join_conversation', { conversation_id: 'uuid' }); ``` **Escribiendo:** ```javascript socket.emit('typing', { conversation_id: 'uuid' }); ``` --- ## Códigos de Error | Código | Descripción | |--------|-------------| | 400 | Bad Request - Datos inválidos | | 401 | Unauthorized - Token inválido o expirado | | 403 | Forbidden - Sin permisos | | 404 | Not Found - Recurso no encontrado | | 409 | Conflict - Conflicto de datos | | 422 | Unprocessable Entity - Validación fallida | | 429 | Too Many Requests - Rate limit excedido | | 500 | Internal Server Error | **Formato de error:** ```json { "detail": { "code": "VALIDATION_ERROR", "message": "El campo email es requerido", "field": "email" } } ```