{"openapi":"3.0.0","paths":{"/auth/signup":{"post":{"operationId":"AuthController_signup","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Crear cuenta de usuario","tags":["Auth"]}},"/auth/login":{"post":{"operationId":"AuthController_login","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Iniciar sesión","tags":["Auth"]}},"/auth/refresh":{"post":{"operationId":"AuthController_refresh","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Renovar tokens (rotación)","tags":["Auth"]}},"/auth/logout":{"post":{"operationId":"AuthController_logout","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshDto"}}}},"responses":{"204":{"description":""}},"summary":"Cerrar sesión (revoca el refresh token)","tags":["Auth"]}},"/auth/forgot-password":{"post":{"operationId":"AuthController_forgotPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordDto"}}}},"responses":{"200":{"description":""}},"summary":"Solicita un email de recuperación de contraseña. Por seguridad SIEMPRE responde 200 — no revela si el email existe o no en el sistema.","tags":["Auth"]}},"/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordDto"}}}},"responses":{"200":{"description":""}},"summary":"Canjea el token recibido por email + nueva contraseña. Si el token es inválido/expirado lanza 401. Tras éxito se revocan todas las sesiones activas del usuario (logout en todos los dispositivos).","tags":["Auth"]}},"/auth/impersonate-redeem":{"post":{"operationId":"AuthController_impersonateRedeem","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImpersonateRedeemDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Canjea un ImpersonationToken (creado por staff via /admin/impersonate) por una sesión válida del target user. El JWT resultante lleva el flag `impersonatedBy` para que el frontend muestre banner persistente.","tags":["Auth"]}},"/users/me":{"get":{"operationId":"UsersController_me","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Obtener mi perfil","tags":["Users"]},"patch":{"operationId":"UsersController_update","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateUserDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualizar mi perfil","tags":["Users"]}},"/users/me/change-password":{"post":{"operationId":"UsersController_changePassword","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangePasswordDto"}}}},"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Cambiar contraseña (revoca sesiones existentes)","tags":["Users"]}},"/health/live":{"get":{"operationId":"HealthController_live","parameters":[],"responses":{"200":{"description":""}},"summary":"Liveness check: el proceso está vivo (uptime). Público, para load balancers.","tags":["Health"]}},"/health/ready":{"get":{"operationId":"HealthController_ready","parameters":[],"responses":{"200":{"description":""}},"summary":"Readiness check: valida conexión a Postgres y Redis. 503 si alguno falla.","tags":["Health"]}},"/health":{"get":{"operationId":"HealthController_root","parameters":[],"responses":{"200":{"description":""}},"summary":"Ping raíz del servicio (status + nombre + timestamp). Público.","tags":["Health"]}},"/organizations":{"get":{"operationId":"OrganizationsController_list","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Listar organizaciones del usuario actual","tags":["Organizations"]},"post":{"operationId":"OrganizationsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrganizationDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crear organización (queda como owner)","tags":["Organizations"]}},"/organizations/slug-suggest":{"get":{"operationId":"OrganizationsController_slugSuggest","parameters":[{"name":"name","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Sugiere un slug disponible para un nombre dado","tags":["Organizations"]}},"/organizations/slug-available":{"get":{"operationId":"OrganizationsController_slugAvailable","parameters":[{"name":"slug","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Verifica si un slug está disponible","tags":["Organizations"]}},"/organizations/{id}":{"get":{"operationId":"OrganizationsController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Obtener organización por id","tags":["Organizations"]},"patch":{"operationId":"OrganizationsController_update","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrganizationDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualizar organización (requiere organizations:write)","tags":["Organizations"]}},"/organizations/{orgId}/memberships":{"get":{"operationId":"MembershipsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista los miembros de la organización con su rol y alcance.","tags":["Memberships"]}},"/organizations/{orgId}/memberships/me":{"get":{"operationId":"MembershipsController_me","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Devuelve la membresía del usuario actual en la organización.","tags":["Memberships"]}},"/organizations/{orgId}/memberships/{id}":{"patch":{"operationId":"MembershipsController_setRole","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetRoleDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Cambia el rol asignado a un miembro.","tags":["Memberships"]},"delete":{"operationId":"MembershipsController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina a un miembro de la organización.","tags":["Memberships"]}},"/organizations/{orgId}/memberships/{id}/waba-scope":{"put":{"operationId":"MembershipsController_setWabaScope","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetWabaScopeDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Define a qué WABAs tiene acceso un miembro.","tags":["Memberships"]}},"/organizations/{orgId}/roles":{"get":{"operationId":"RolesController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los roles de la organización.","tags":["Roles"]},"post":{"operationId":"RolesController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Crea un rol personalizado en la organización.","tags":["Roles"]}},"/organizations/{orgId}/roles/{id}":{"patch":{"operationId":"RolesController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Actualiza el nombre o los datos de un rol.","tags":["Roles"]},"delete":{"operationId":"RolesController_delete","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina un rol de la organización.","tags":["Roles"]}},"/organizations/{orgId}/roles/{id}/permissions":{"put":{"operationId":"RolesController_setPermissions","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Reemplaza el conjunto de permisos de un rol.","tags":["Roles"]}},"/permissions":{"get":{"operationId":"PermissionsController_list","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista el catálogo de permisos disponibles en el sistema.","tags":["Permissions"]}},"/organizations/{orgId}/api-keys":{"get":{"operationId":"ApiKeysController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista las API keys de la organización (sin el secret).","tags":["API Keys"]},"post":{"operationId":"ApiKeysController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crear API key. Devuelve `secret` UNA sola vez.","tags":["API Keys"]}},"/organizations/{orgId}/api-keys/{id}":{"patch":{"operationId":"ApiKeysController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateApiKeyDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Editar API key: scopes y/o nombre. El secret NO se puede tocar — para rotar, revocar y crear otra.","tags":["API Keys"]},"delete":{"operationId":"ApiKeysController_revoke","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Revoca una API key de forma permanente.","tags":["API Keys"]}},"/organizations/{orgId}/invitations":{"get":{"operationId":"InvitationsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista las invitaciones de la organización.","tags":["Invitations"]},"post":{"operationId":"InvitationsController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvitationDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crear invitación. Devuelve `token` UNA sola vez (enviar por email).","tags":["Invitations"]}},"/organizations/{orgId}/invitations/{id}":{"delete":{"operationId":"InvitationsController_cancel","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Cancela una invitación pendiente. Falla si ya fue aceptada.","tags":["Invitations"]}},"/organizations/{orgId}/invitations/{id}/resend":{"post":{"operationId":"InvitationsController_resend","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Reenvía una invitación: rota el token, refresca la expiración y vuelve a mandar el email. Falla si ya fue aceptada.","tags":["Invitations"]}},"/invitations/accept":{"post":{"operationId":"InvitationsController_accept","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptInvitationDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Aceptar invitación con el token recibido","tags":["Invitations"]}},"/two-factor/enroll":{"post":{"operationId":"TwoFactorController_enroll","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Inicia el alta de 2FA y devuelve el secreto/QR TOTP.","tags":["Two-Factor"]}},"/two-factor/verify":{"post":{"operationId":"TwoFactorController_verify","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Verifica el código TOTP y activa el 2FA.","tags":["Two-Factor"]}},"/two-factor/disable":{"post":{"operationId":"TwoFactorController_disable","parameters":[],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Desactiva el 2FA del usuario.","tags":["Two-Factor"]}},"/organizations/{orgId}/audit":{"get":{"operationId":"AuditController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"action","required":false,"in":"query","schema":{"type":"string"}},{"name":"resource","required":false,"in":"query","schema":{"type":"string"}},{"name":"actorUserId","required":false,"in":"query","schema":{"type":"string"}},{"name":"dateFrom","required":false,"in":"query","schema":{"type":"string"}},{"name":"dateTo","required":false,"in":"query","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Cliente final: lista de logs de SU organización con filtros.","tags":["Audit"]}},"/organizations/{orgId}/audit/export":{"get":{"operationId":"AuditController_exportCsv","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"action","required":false,"in":"query","schema":{"type":"string"}},{"name":"resource","required":false,"in":"query","schema":{"type":"string"}},{"name":"actorUserId","required":false,"in":"query","schema":{"type":"string"}},{"name":"dateFrom","required":false,"in":"query","schema":{"type":"string"}},{"name":"dateTo","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Exporta el audit log en CSV (requiere audit_advanced).","tags":["Audit"]}},"/admin/audit":{"get":{"operationId":"AuditController_listAdmin","parameters":[{"name":"orgId","required":false,"in":"query","schema":{"type":"string"}},{"name":"action","required":false,"in":"query","schema":{"type":"string"}},{"name":"resource","required":false,"in":"query","schema":{"type":"string"}},{"name":"actorUserId","required":false,"in":"query","schema":{"type":"string"}},{"name":"dateFrom","required":false,"in":"query","schema":{"type":"string"}},{"name":"dateTo","required":false,"in":"query","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Admin staff: cross-org audit con todos los filtros.","tags":["Audit"]}},"/admin/audit/export":{"get":{"operationId":"AuditController_adminExportCsv","parameters":[{"name":"orgId","required":false,"in":"query","schema":{"type":"string"}},{"name":"action","required":false,"in":"query","schema":{"type":"string"}},{"name":"resource","required":false,"in":"query","schema":{"type":"string"}},{"name":"dateFrom","required":false,"in":"query","schema":{"type":"string"}},{"name":"dateTo","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Admin staff: export CSV cross-org (sin feature gate, siempre permitido).","tags":["Audit"]}},"/notifications":{"get":{"operationId":"NotificationsController_list","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista las notificaciones del usuario autenticado.","tags":["Notifications"]}},"/notifications/{id}/read":{"patch":{"operationId":"NotificationsController_read","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Marca una notificación como leída.","tags":["Notifications"]}},"/organizations/{orgId}/waba":{"get":{"operationId":"WabaController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"includeArchived","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista las WABAs de la organización.","tags":["WABA"]}},"/organizations/{orgId}/waba/{id}":{"get":{"operationId":"WabaController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de una WABA.","tags":["WABA"]},"delete":{"operationId":"WabaController_archive","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Archiva (soft-delete) la WABA. Conversaciones, mensajes y cargos se conservan.","tags":["WABA"]}},"/organizations/{orgId}/waba/connect-test-number":{"post":{"operationId":"WabaController_connectTestNumber","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectTestNumberDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Conecta manualmente un número de prueba con un permanent access token de Meta (sin Embedded Signup).","tags":["WABA"]}},"/organizations/{orgId}/waba/{id}/restore":{"post":{"operationId":"WabaController_restore","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Restaura una WABA archivada y vuelve a suscribir webhooks.","tags":["WABA"]}},"/organizations/{orgId}/waba/{id}/purge":{"delete":{"operationId":"WabaController_purge","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"HARD delete: borra permanentemente la WABA y todo lo asociado. Bloquea si hay cargos pendientes de facturar.","tags":["WABA"]}},"/embedded-signup/initiate":{"post":{"operationId":"EmbeddedSignupController_initiate","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitiateSignupDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Inicia una sesión de Embedded Signup; el frontend redirige a Facebook con el sessionId.","tags":["Embedded Signup"]}},"/embedded-signup/callback":{"post":{"operationId":"EmbeddedSignupController_callback","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallbackDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Intercambia el `code` de Facebook por un access token y lo persiste cifrado. No importa nada todavía.","tags":["Embedded Signup"]}},"/embedded-signup/{id}/discover":{"get":{"operationId":"EmbeddedSignupController_discover","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Lista los Businesses → WABAs → números visibles para el usuario, sin persistir.","tags":["Embedded Signup"]}},"/embedded-signup/{id}/complete":{"post":{"operationId":"EmbeddedSignupController_complete","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompleteImportDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Persiste solo las WABAs/números seleccionados por el usuario y suscribe webhooks.","tags":["Embedded Signup"]}},"/embedded-signup/{id}":{"get":{"operationId":"EmbeddedSignupController_get","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Embedded Signup"]}},"/organizations/{orgId}/phone-numbers":{"post":{"operationId":"PhoneNumbersController_addNew","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddPhoneNumberDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Agrega un nuevo número de teléfono a la WABA via Meta Cloud API.","tags":["Phone Numbers"]},"get":{"operationId":"PhoneNumbersController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"wabaId","required":false,"in":"query","schema":{"type":"string"}},{"name":"includeArchived","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista los números de teléfono de la organización.","tags":["Phone Numbers"]}},"/organizations/{orgId}/phone-numbers/{id}":{"get":{"operationId":"PhoneNumbersController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de un número de teléfono.","tags":["Phone Numbers"]},"delete":{"operationId":"PhoneNumbersController_archive","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Archiva (soft-delete) el número.","tags":["Phone Numbers"]}},"/organizations/{orgId}/phone-numbers/sync":{"post":{"operationId":"PhoneNumbersController_sync","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Sincroniza con Meta: archiva números que ya no existen ahí y restaura los que volvieron.","tags":["Phone Numbers"]}},"/organizations/{orgId}/phone-numbers/{id}/restore":{"post":{"operationId":"PhoneNumbersController_restore","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Restaura un número archivado.","tags":["Phone Numbers"]}},"/organizations/{orgId}/phone-numbers/{id}/purge":{"delete":{"operationId":"PhoneNumbersController_purge","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"HARD delete del número. Bloquea si hay cargos pendientes.","tags":["Phone Numbers"]}},"/organizations/{orgId}/phone-numbers/{phoneId}/registration/request-code":{"post":{"operationId":"PhoneNumberRegistrationController_requestCode","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestCodeDto"}}}},"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"tags":["Phone Number Registration"]}},"/organizations/{orgId}/phone-numbers/{phoneId}/registration/verify-code":{"post":{"operationId":"PhoneNumberRegistrationController_verifyCode","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCodeDto"}}}},"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"tags":["Phone Number Registration"]}},"/organizations/{orgId}/phone-numbers/{phoneId}/registration/register":{"post":{"operationId":"PhoneNumberRegistrationController_register","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterDto"}}}},"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"tags":["Phone Number Registration"]}},"/organizations/{orgId}/phone-numbers/{phoneId}/registration/deregister":{"post":{"operationId":"PhoneNumberRegistrationController_deregister","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"tags":["Phone Number Registration"]}},"/organizations/{orgId}/whatsapp-links":{"get":{"operationId":"WhatsAppLinksController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneNumberId","required":false,"in":"query","schema":{"type":"string"}},{"name":"includeArchived","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los enlaces Click-to-WhatsApp de la organización.","tags":["WhatsApp Links"]},"post":{"operationId":"WhatsAppLinksController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLinkDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea un enlace Click-to-WhatsApp con su URL pública.","tags":["WhatsApp Links"]}},"/organizations/{orgId}/whatsapp-links/{id}":{"get":{"operationId":"WhatsAppLinksController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de un enlace Click-to-WhatsApp por su id.","tags":["WhatsApp Links"]},"patch":{"operationId":"WhatsAppLinksController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateLinkDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza un enlace Click-to-WhatsApp.","tags":["WhatsApp Links"]},"delete":{"operationId":"WhatsAppLinksController_archive","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Toggle archivado del enlace (soft-delete reversible).","tags":["WhatsApp Links"]}},"/organizations/{orgId}/whatsapp-links/{id}/stats":{"get":{"operationId":"WhatsAppLinksController_stats","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Devuelve las estadísticas de clicks de un enlace.","tags":["WhatsApp Links"]}},"/organizations/{orgId}/whatsapp-links/{id}/qr":{"get":{"operationId":"WhatsAppLinksController_qr","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"format","required":false,"in":"query","schema":{"type":"string"}},{"name":"size","required":false,"in":"query","schema":{}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Genera el código QR del enlace en formato PNG o SVG (?format, ?size).","tags":["WhatsApp Links"]}},"/m/{slug}":{"get":{"operationId":"WhatsAppLinksController_redirect[0]","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Redirect público de Click-to-WhatsApp. Resuelve el slug, registra el click y responde 302 hacia wa.me con el mensaje pre-llenado.","tags":["WhatsApp Links"]}},"/p/{slug}":{"get":{"operationId":"WhatsAppLinksController_redirect[1]","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Redirect público de Click-to-WhatsApp. Resuelve el slug, registra el click y responde 302 hacia wa.me con el mensaje pre-llenado.","tags":["WhatsApp Links"]}},"/push/config":{"get":{"operationId":"PushController_config","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"VAPID public key y disponibilidad del servicio.","tags":["Push Notifications"]}},"/push/subscribe":{"post":{"operationId":"PushController_subscribe","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Guarda la suscripción Push del browser del usuario.","tags":["Push Notifications"]},"delete":{"operationId":"PushController_unsubscribe","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnsubscribeDto"}}}},"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina una suscripción Push (logout en device, toggle off).","tags":["Push Notifications"]}},"/push/subscriptions":{"get":{"operationId":"PushController_list","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los devices del usuario con push habilitado.","tags":["Push Notifications"]}},"/push/test":{"post":{"operationId":"PushController_test","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Envía una notificación de prueba al usuario actual.","tags":["Push Notifications"]}},"/organizations/{orgId}/phone-numbers/{phoneId}/profile":{"get":{"operationId":"ProfilesController_get","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Obtiene el perfil de negocio del número.","tags":["Business Profiles"]},"put":{"operationId":"ProfilesController_upsert","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertProfileDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea o actualiza el perfil de negocio del número.","tags":["Business Profiles"]}},"/organizations/{orgId}/phone-numbers/{phoneId}/profile/picture":{"post":{"operationId":"ProfilesController_uploadPicture","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Sube una foto de perfil (JPG/PNG, máx. 5 MB) y la aplica al número en Meta.","tags":["Business Profiles"]}},"/organizations/{orgId}/templates":{"get":{"operationId":"TemplatesController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"wabaId","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista las plantillas de la organización, opcionalmente filtradas por WABA.","tags":["Templates"]},"post":{"operationId":"TemplatesController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTemplateDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Crea una plantilla y la envía a Meta para aprobación.","tags":["Templates"]}},"/organizations/{orgId}/templates/{id}":{"get":{"operationId":"TemplatesController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de una plantilla por su id.","tags":["Templates"]},"patch":{"description":"Meta solo permite editar plantillas aprobadas o rechazadas; name/language/category no son editables. Cuotas de Meta: 1 edición/24h, máximo 10/mes por plantilla.","operationId":"TemplatesController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTemplateDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Edita una plantilla en Meta. Solo se permiten APPROVED o REJECTED, y solo los `components`.","tags":["Templates"]},"delete":{"operationId":"TemplatesController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Borra una plantilla — primero en Meta y luego en la BD local.","tags":["Templates"]}},"/organizations/{orgId}/templates/sync":{"post":{"operationId":"TemplatesController_sync","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Sincroniza plantillas desde Meta para todos los WABA de la organización","tags":["Templates"]}},"/organizations/{orgId}/templates/upload-header-media":{"post":{"operationId":"TemplatesController_uploadHeaderMedia","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Sube imagen/video/PDF para usar como Header de plantilla. Devuelve header_handle.","tags":["Templates"]}},"/organizations/{orgId}/contacts":{"get":{"operationId":"ContactsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"q","required":false,"in":"query","schema":{"type":"string"}},{"name":"channel","required":false,"in":"query","schema":{"type":"string"}},{"name":"identifiedOnly","required":false,"in":"query","schema":{"type":"string"}},{"name":"tagId","required":false,"in":"query","schema":{"type":"string"}},{"name":"optInStatus","required":false,"in":"query","schema":{"type":"string"}},{"name":"country","required":false,"in":"query","schema":{"type":"string"}},{"name":"language","required":false,"in":"query","schema":{"type":"string"}},{"name":"createdSince","required":false,"in":"query","schema":{"type":"string"}},{"name":"hasConversations","required":false,"in":"query","schema":{"type":"string"}},{"name":"lastActivityDaysGt","required":false,"in":"query","schema":{"type":"string"}},{"name":"page","required":false,"in":"query","schema":{"type":"string"}},{"name":"pageSize","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Lista y filtra contactos (búsqueda, canal, etiqueta, opt-in, país, actividad). Paginado.","tags":["Contacts"]},"post":{"operationId":"ContactsController_upsert","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertContactDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea o actualiza un contacto (upsert por waId).","tags":["Contacts"]}},"/organizations/{orgId}/contacts/bulk-tag":{"post":{"operationId":"ContactsController_bulkTag","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Agrega o quita una etiqueta a varios contactos de una vez.","tags":["Contacts"]}},"/organizations/{orgId}/contacts/bulk-delete":{"post":{"operationId":"ContactsController_bulkDelete","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina varios contactos de una vez.","tags":["Contacts"]}},"/organizations/{orgId}/contacts/bulk-opt-in-status":{"post":{"operationId":"ContactsController_bulkOptInStatus","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Cambia el estado de opt-in (UNKNOWN/OPTED_IN/OPTED_OUT) de varios contactos.","tags":["Contacts"]}},"/organizations/{orgId}/contacts/import":{"post":{"operationId":"ContactsController_importCsv","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"defaultCountry","required":false,"in":"query","schema":{"type":"string"}},{"name":"defaultOptIn","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Importa contactos desde un archivo CSV (multipart/form-data, campo file).","tags":["Contacts"]}},"/organizations/{orgId}/contacts/{id}":{"get":{"operationId":"ContactsController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Detalle de un contacto por id.","tags":["Contacts"]},"patch":{"operationId":"ContactsController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateContactDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza campos de un contacto (nombre, atributos, idioma, etc.).","tags":["Contacts"]},"delete":{"operationId":"ContactsController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina un contacto por id.","tags":["Contacts"]}},"/organizations/{orgId}/tags":{"get":{"operationId":"TagsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista las etiquetas de la organización.","tags":["Tags"]},"post":{"operationId":"TagsController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTagDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea una etiqueta (nombre y color opcional).","tags":["Tags"]}},"/organizations/{orgId}/tags/{id}":{"delete":{"operationId":"TagsController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina una etiqueta.","tags":["Tags"]}},"/organizations/{orgId}/contacts/{contactId}/opt-ins":{"get":{"operationId":"OptInsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"contactId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista el historial de opt-ins/opt-outs de un contacto.","tags":["Opt-ins"]},"post":{"operationId":"OptInsController_record","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"contactId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordOptInDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Registra un opt-in o opt-out de un contacto.","tags":["Opt-ins"]}},"/organizations/{orgId}/conversations":{"get":{"operationId":"ConversationsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string"}},{"name":"phoneNumberId","required":false,"in":"query","schema":{"type":"string"}},{"name":"assigneeUserId","required":false,"in":"query","schema":{"type":"string"}},{"name":"tagId","required":false,"in":"query","schema":{"type":"string"}},{"name":"unreadOnly","required":false,"in":"query","schema":{"type":"string"}},{"name":"handoffPending","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista conversaciones del inbox con filtros por estado, número, asignado, etiqueta y no leídas.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/messaging-settings":{"get":{"operationId":"ConversationsController_getMessagingSettings","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Obtiene los ajustes de mensajería de la org (read receipts, indicador de escritura).","tags":["Conversations"]},"patch":{"operationId":"ConversationsController_updateMessagingSettings","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza los ajustes de mensajería de la org (read receipts, indicador de escritura).","tags":["Conversations"]}},"/organizations/{orgId}/conversations/unread-counts":{"get":{"operationId":"ConversationsController_unreadCounts","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneNumberId","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Devuelve los conteos de no leídas por estado para los badges del inbox.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/search":{"get":{"operationId":"ConversationsController_search","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"q","required":false,"in":"query","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","schema":{"type":"string"}},{"name":"direction","required":false,"in":"query","schema":{"type":"string"}},{"name":"hasAttachment","required":false,"in":"query","schema":{"type":"string"}},{"name":"sentByMe","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Busca dentro del contenido de los mensajes de la org con filtros por fecha, dirección y adjunto.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/workload":{"get":{"operationId":"ConversationsController_workload","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista métricas de carga y performance reciente por agente (requiere reports:read).","tags":["Conversations"]}},"/organizations/{orgId}/conversations/workload/settings":{"get":{"operationId":"ConversationsController_getWorkloadSettings","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Obtiene la configuración del panel de workload (thresholds de SLA y staleness).","tags":["Conversations"]},"patch":{"operationId":"ConversationsController_patchWorkloadSettings","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Actualiza parcialmente la configuración del panel de workload (thresholds).","tags":["Conversations"]}},"/organizations/{orgId}/conversations/workload/agent/{userId}":{"get":{"operationId":"ConversationsController_agentWorkloadDetail","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"userId","required":true,"in":"path","schema":{"type":"string"}},{"name":"days","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Detalle de workload de un agente: agregados y tenencias de los últimos N días.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/activity-trends":{"get":{"operationId":"ConversationsController_activityTrends","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"days","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Serie temporal de conversaciones entrantes y cerradas por día (?days=N).","tags":["Conversations"]}},"/organizations/{orgId}/conversations/activity-heatmap":{"get":{"operationId":"ConversationsController_activityHeatmap","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"days","required":false,"in":"query","schema":{"type":"string"}},{"name":"metric","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Heatmap día-de-semana × hora de actividad (?metric=volume|late|avgResponse).","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}":{"get":{"operationId":"ConversationsController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de una conversación por su id.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/messages":{"get":{"operationId":"ConversationsController_messages","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}},{"name":"before","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los mensajes de una conversación con paginación por cursor.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/status":{"patch":{"operationId":"ConversationsController_updateStatus","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Cambia el estado de la conversación (open/closed/snoozed); al cerrar acepta category y resolución.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/request-handoff":{"post":{"operationId":"ConversationsController_requestHandoff","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Solicita handoff a un asesor humano: marca pendiente, calla la automatización y notifica.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/categorize":{"patch":{"operationId":"ConversationsController_categorize","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Asigna o corrige category y resolución de la conversación sin cambiar su estado.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/read":{"post":{"operationId":"ConversationsController_markAsRead","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Marca la conversación como leída.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/unread":{"post":{"operationId":"ConversationsController_markAsUnread","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Marca la conversación como no leída.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/typing":{"post":{"operationId":"ConversationsController_typing","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Envía el indicador de \"escribiendo\" al contacto de la conversación.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/assign":{"patch":{"operationId":"ConversationsController_assign","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Asigna la conversación a un usuario o la libera (userId null).","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/claim":{"post":{"operationId":"ConversationsController_claim","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"El usuario actual toma posesión de la conversación (autoasignación).","tags":["Conversations"]}},"/organizations/{orgId}/conversations/bulk-assign":{"post":{"operationId":"ConversationsController_bulkAssign","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Reasigna en lote varias conversaciones a un usuario o las libera.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/snooze":{"patch":{"operationId":"ConversationsController_snooze","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Pospone la conversación hasta una fecha, o cancela el snooze (until null).","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/pin":{"patch":{"operationId":"ConversationsController_setPinned","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Fija o desfija la conversación en el inbox.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/tags":{"post":{"operationId":"ConversationsController_addTag","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Agrega una etiqueta a la conversación.","tags":["Conversations"]}},"/organizations/{orgId}/conversations/{id}/tags/{tagId}":{"delete":{"operationId":"ConversationsController_removeTag","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"tagId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Quita una etiqueta de la conversación.","tags":["Conversations"]}},"/organizations/{orgId}/messages":{"post":{"operationId":"MessagesController_send","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Envía un mensaje de WhatsApp (texto, media o plantilla) a un contacto.","tags":["Messages"]}},"/organizations/{orgId}/messages/{messageId}/edit":{"patch":{"operationId":"MessagesController_edit","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EditMessageDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Edita el texto de un mensaje ya enviado.","tags":["Messages"]}},"/organizations/{orgId}/messages/{messageId}":{"delete":{"operationId":"MessagesController_deleteMessage","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Elimina un mensaje (lo oculta del inbox como tombstone).","tags":["Messages"]}},"/organizations/{orgId}/messages/{messageId}/restore":{"post":{"operationId":"MessagesController_restore","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Revierte el tombstone de un mensaje y lo vuelve a mostrar en el inbox.","tags":["Messages"]}},"/organizations/{orgId}/messages/upload":{"post":{"operationId":"MessagesController_uploadMedia","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneNumberId","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Sube un archivo a Meta como media adjunto y devuelve el mediaId para usar al enviar.","tags":["Messages"]}},"/organizations/{orgId}/messages/{messageId}/media":{"get":{"operationId":"MessagesController_getMedia","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Descarga y proxyea el media de un mensaje (sirve desde caché S3 o desde Meta).","tags":["Messages"]}},"/organizations/{orgId}/media/{id}":{"get":{"operationId":"MediaController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Obtiene los metadatos de un archivo de medios por su ID.","tags":["Media"]}},"/organizations/{orgId}/media/{id}/url":{"get":{"operationId":"MediaController_signedUrl","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Devuelve una URL firmada de descarga del archivo de medios.","tags":["Media"]}},"/organizations/{orgId}/stickers":{"get":{"operationId":"StickersController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista la librería de stickers de la org.","tags":["Stickers"]}},"/organizations/{orgId}/stickers/upload":{"post":{"operationId":"StickersController_upload","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Sube un sticker propio (cualquier imagen → webp 512×512).","tags":["Stickers"]}},"/organizations/{orgId}/stickers/from-message/{messageId}":{"post":{"operationId":"StickersController_stealFromMessage","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"\"Roba\" un sticker entrante de un mensaje del cliente a la librería.","tags":["Stickers"]}},"/organizations/{orgId}/stickers/{id}/send":{"post":{"operationId":"StickersController_send","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendStickerDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Envía un sticker de la librería a una conversación.","tags":["Stickers"]}},"/organizations/{orgId}/stickers/{id}":{"delete":{"operationId":"StickersController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Borra un sticker de la librería.","tags":["Stickers"]}},"/webhooks/meta":{"get":{"operationId":"WebhooksInboundController_verify","parameters":[{"name":"hub.mode","required":true,"in":"query","schema":{"type":"string"}},{"name":"hub.verify_token","required":true,"in":"query","schema":{"type":"string"}},{"name":"hub.challenge","required":true,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"string"}}}}},"summary":"Verificación de webhook (Meta envía hub.challenge en GET una sola vez).","tags":["Webhooks (Meta)"]},"post":{"operationId":"WebhooksInboundController_receive","parameters":[],"responses":{"200":{"description":""}},"summary":"Webhook entrante de Meta. Validación HMAC X-Hub-Signature-256.","tags":["Webhooks (Meta)"]}},"/organizations/{orgId}/bot/auto-replies":{"get":{"operationId":"AutoRepliesController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneNumberId","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista las respuestas automáticas del bot (filtrable por número).","tags":["Bot auto-replies"]},"post":{"operationId":"AutoRepliesController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAutoReplyDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea una respuesta automática del bot.","tags":["Bot auto-replies"]}},"/organizations/{orgId}/bot/auto-replies/{id}":{"patch":{"operationId":"AutoRepliesController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAutoReplyDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza una respuesta automática del bot.","tags":["Bot auto-replies"]},"delete":{"operationId":"AutoRepliesController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina una respuesta automática del bot.","tags":["Bot auto-replies"]}},"/organizations/{orgId}/messages/{messageId}/reactions":{"put":{"operationId":"ReactionsController_set","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetReactionDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Añade o reemplaza la reacción del agente en un mensaje. WhatsApp Cloud API solo\npermite una reacción por usuario por mensaje, así que sustituye la previa si\nexiste (semántica de upsert).","tags":["Reactions"]},"delete":{"operationId":"ReactionsController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"messageId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Remueve la reacción del agente actual del mensaje.","tags":["Reactions"]}},"/organizations/{orgId}/web-chat/channels":{"get":{"operationId":"WebChatController_listChannels","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"summary":"Lista los canales de web chat de la org.","tags":["WebChat"]},"post":{"operationId":"WebChatController_createChannel","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateChannelDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Crea un canal de web chat.","tags":["WebChat"]}},"/organizations/{orgId}/web-chat/channels/{id}":{"patch":{"operationId":"WebChatController_updateChannel","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateChannelDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Actualiza un canal de web chat.","tags":["WebChat"]},"delete":{"operationId":"WebChatController_deleteChannel","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Elimina un canal de web chat.","tags":["WebChat"]}},"/organizations/{orgId}/web-chat/channels/{id}/snippet":{"get":{"operationId":"WebChatController_getSnippet","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Devuelve el snippet de instalación del widget para el canal.","tags":["WebChat"]}},"/organizations/{orgId}/web-chat/channels/{id}/identity-secret":{"post":{"operationId":"WebChatController_rotateIdentitySecret","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Genera o rota el secreto HMAC de identidad (se muestra una sola vez).","tags":["WebChat"]},"delete":{"operationId":"WebChatController_clearIdentitySecret","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"summary":"Revoca el secreto HMAC de identidad del canal.","tags":["WebChat"]}},"/organizations/{orgId}/conversations/{convId}/web-chat/send":{"post":{"operationId":"WebChatController_sendMessage","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"convId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageDto"}}}},"responses":{"201":{"description":""}},"summary":"Envía un mensaje del agente a una conversación de web chat.","tags":["WebChat"]}},"/organizations/{orgId}/conversations/{convId}/web-chat/media":{"post":{"operationId":"WebChatController_uploadWebChatMedia","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"convId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Sube un archivo a S3 para web chat y devuelve su mediaAssetId.","tags":["WebChat"]}},"/web-chat/{token}/sessions":{"post":{"operationId":"WebChatPublicController_createSession","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSessionDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Público (widget): crea sesión del visitante (anónima, identificada o verify-OTP).","tags":["WebChatPublic"]}},"/web-chat/{token}/sessions/resend-otp":{"post":{"operationId":"WebChatPublicController_resendOtp","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResendOtpDto"}}}},"responses":{"201":{"description":""}},"summary":"Público (widget): reenvía el código OTP de verificación por email.","tags":["WebChatPublic"]}},"/web-chat/{token}/history":{"get":{"operationId":"WebChatPublicController_getHistory","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Público (widget): historial reciente del visitante (requiere visitor JWT).","tags":["WebChatPublic"]}},"/web-chat/{token}/sessions/link-email":{"post":{"operationId":"WebChatPublicController_linkEmail","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkEmailDto"}}}},"responses":{"201":{"description":""}},"summary":"Público (widget): vincula un email al visitante (requiere visitor JWT).","tags":["WebChatPublic"]}},"/web-chat/{token}/upload":{"post":{"operationId":"WebChatPublicController_upload","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Público (widget): sube un adjunto y devuelve su mediaAssetId (requiere visitor JWT).","tags":["WebChatPublic"]}},"/web-chat/{token}/messages":{"post":{"operationId":"WebChatPublicController_sendMessage","parameters":[{"name":"token","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Público (widget): envía un mensaje con adjunto del visitante (requiere visitor JWT).","tags":["WebChatPublic"]}},"/organizations/{orgId}/webhooks-outbound":{"get":{"operationId":"WebhooksOutboundController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los webhooks salientes de la organización (sin el secret).","tags":["Webhooks (outbound)"]},"post":{"operationId":"WebhooksOutboundController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOutboundDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea un webhook saliente suscrito a eventos.","tags":["Webhooks (outbound)"]}},"/organizations/{orgId}/webhooks-outbound/{id}":{"patch":{"operationId":"WebhooksOutboundController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOutboundDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza un webhook saliente (URL, eventos, formato, estado).","tags":["Webhooks (outbound)"]},"delete":{"operationId":"WebhooksOutboundController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina un webhook saliente.","tags":["Webhooks (outbound)"]}},"/organizations/{orgId}/webhooks-outbound/{id}/deliveries":{"get":{"operationId":"WebhooksOutboundController_deliveries","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista el historial de entregas de un webhook saliente.","tags":["Webhooks (outbound)"]}},"/organizations/{orgId}/webhooks-outbound/{id}/secret":{"get":{"operationId":"WebhooksOutboundController_getSecret","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Revela el secret de firma del webhook (no aparece en el listado).","tags":["Webhooks (outbound)"]}},"/organizations/{orgId}/plan-limits":{"get":{"operationId":"PlanLimitsController_get","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Plan actual + uso vs cuotas. Frontend lo usa para barras de progreso.","tags":["Plan & límites"]}},"/pricing":{"get":{"operationId":"PricingController_list","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista las tarifas de mensajería vigentes.","tags":["Pricing"]}},"/organizations/{orgId}/usage/daily":{"get":{"operationId":"UsageController_daily","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"metric","required":false,"in":"query","schema":{"type":"string"}},{"name":"since","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Devuelve el consumo diario por métrica desde una fecha.","tags":["Usage"]}},"/organizations/{orgId}/billing/periods":{"get":{"operationId":"BillingController_periods","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista los periodos de facturación de la organización.","tags":["Billing"]}},"/organizations/{orgId}/billing/usage":{"get":{"operationId":"BillingController_usage","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Devuelve el consumo del periodo de facturación en curso.","tags":["Billing"]}},"/organizations/{orgId}/billing/estimated-next-charge":{"get":{"operationId":"BillingController_estimatedNextCharge","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Estima cuánto pagaría la organización si se cerrara hoy el periodo abierto. NO persiste.","tags":["Billing"]}},"/organizations/{orgId}/billing/coupons/validate":{"post":{"operationId":"BillingController_validateCoupon","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemCouponDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Valida un cupón sin consumirlo (previsualización del descuento).","tags":["Billing"]}},"/organizations/{orgId}/billing/coupons/redeem":{"post":{"operationId":"BillingController_redeemCoupon","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedeemCouponDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Valida y redime un cupón a nombre de la organización.","tags":["Billing"]}},"/organizations/{orgId}/invoices":{"get":{"operationId":"InvoicesController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista las facturas de la organización.","tags":["Invoices"]}},"/organizations/{orgId}/invoices/{id}":{"get":{"operationId":"InvoicesController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de una factura por su ID.","tags":["Invoices"]}},"/organizations/{orgId}/invoices/{id}/pdf":{"get":{"operationId":"InvoicesController_getPdfUrl","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Genera (si falta) el PDF de la factura y devuelve URL de descarga firmada.","tags":["Invoices"]}},"/admin/credit-notes":{"post":{"operationId":"CreditNotesController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCreditNoteDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Emite una nota crédito a favor de una organización. Solo se debería emitir cuando hubo un error nuestro.","tags":["Notas crédito (admin)"]},"get":{"operationId":"CreditNotesController_list","parameters":[{"name":"orgId","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista notas crédito (filtro opcional por organización).","tags":["Notas crédito (admin)"]}},"/admin/credit-notes/{id}":{"get":{"operationId":"CreditNotesController_getOne","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Detalle de una nota crédito.","tags":["Notas crédito (admin)"]}},"/admin/credit-notes/{id}/void":{"post":{"operationId":"CreditNotesController_voidNote","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Anula una nota crédito (revierte el crédito al wallet si fue aplicada).","tags":["Notas crédito (admin)"]}},"/admin/credit-notes/{id}/pdf":{"get":{"operationId":"CreditNotesController_getPdf","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Genera (si falta) el PDF de la nota crédito y devuelve URL firmada para descarga.","tags":["Notas crédito (admin)"]}},"/admin/credit-notes/{id}/regenerate-pdf":{"post":{"operationId":"CreditNotesController_regeneratePdf","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Regenera el PDF de una nota crédito (tras tweaks de layout).","tags":["Notas crédito (admin)"]}},"/organizations/{orgId}/wallet":{"get":{"operationId":"WalletController_balance","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Devuelve el saldo actual de la billetera de la organización.","tags":["Wallet"]}},"/organizations/{orgId}/wallet/transactions":{"get":{"operationId":"WalletController_transactions","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los movimientos de la billetera (paginado por cursor).","tags":["Wallet"]}},"/organizations/{orgId}/wallet/recharge":{"post":{"operationId":"MercadoPagoController_createRecharge","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRechargeDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Crea preference de recarga de saldo. Devuelve URL de checkout.","tags":["Pagos (Mercado Pago)"]}},"/webhooks/mercado-pago":{"post":{"operationId":"MercadoPagoController_webhook","parameters":[{"name":"id","required":false,"in":"query","schema":{}},{"name":"type","required":false,"in":"query","schema":{}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Webhook IPN de Mercado Pago. Valida firma y procesa pagos.","tags":["Pagos (Mercado Pago)"]}},"/organizations/{orgId}/billing/invoices/{invoiceId}/pay":{"post":{"operationId":"MercadoPagoController_createInvoicePayment","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"invoiceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Crea preference MP para pagar una factura. Devuelve URL de checkout.","tags":["Pagos (Mercado Pago)"]}},"/organizations/{orgId}/billing/payment-methods":{"get":{"operationId":"PaymentMethodsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista las tarjetas guardadas de la organización (sin exponer tokens MP).","tags":["Pagos (Tarjetas guardadas)"]},"post":{"operationId":"PaymentMethodsController_add","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddCardDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Guarda una tarjeta nueva tokenizando el `token` que viene del frontend.","tags":["Pagos (Tarjetas guardadas)"]}},"/organizations/{orgId}/billing/payment-methods/{id}":{"delete":{"operationId":"PaymentMethodsController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Borra una tarjeta de MP y de la BD.","tags":["Pagos (Tarjetas guardadas)"]}},"/organizations/{orgId}/billing/payment-methods/{id}/default":{"post":{"operationId":"PaymentMethodsController_setDefault","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Marca una tarjeta como default; las otras quedan en isDefault=false.","tags":["Pagos (Tarjetas guardadas)"]}},"/organizations/{orgId}/billing/preferences":{"get":{"operationId":"PaymentMethodsController_preferences","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Estado actual de cobro automático (autoPayEnabled + autoPayMethodId).","tags":["Pagos (Tarjetas guardadas)"]}},"/organizations/{orgId}/billing/auto-pay":{"patch":{"operationId":"PaymentMethodsController_setAutoPay","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetAutoPayDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Activa o desactiva el cobro automático mensual.","tags":["Pagos (Tarjetas guardadas)"]}},"/organizations/{orgId}/billing/alert-settings":{"get":{"operationId":"WalletAlertsController_get","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Devuelve configuración actual de alertas de saldo bajo y auto-recarga.","tags":["Billing (Alertas de saldo)"]},"patch":{"operationId":"WalletAlertsController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAlertSettingsDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Actualiza configuración de alertas de saldo bajo y auto-recarga.","tags":["Billing (Alertas de saldo)"]}},"/organizations/{orgId}/integrations":{"get":{"operationId":"IntegrationsController_overview","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Vista resumida: API keys + webhooks outbound configurados","tags":["Integrations"]}},"/organizations/{orgId}/integrations/catalog":{"get":{"operationId":"IntegrationsController_catalog","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Catálogo de integraciones disponibles + flag de instalación per-org. Frontend lo usa para renderizar la lista en Settings → Integraciones.","tags":["Integrations"]}},"/organizations/{orgId}/integrations/catalog/{integrationId}":{"get":{"operationId":"IntegrationsController_getInstallation","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"integrationId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Detalle de una instalación específica (sin config descifrada).","tags":["Integrations"]},"patch":{"operationId":"IntegrationsController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"integrationId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInstallationDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Actualiza config o toggle enabled de una instalación.","tags":["Integrations"]},"delete":{"operationId":"IntegrationsController_uninstall","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"integrationId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Desinstala la integración (borra fila + config cifrada).","tags":["Integrations"]}},"/organizations/{orgId}/integrations/install":{"post":{"operationId":"IntegrationsController_install","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallIntegrationDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Instala una integración del catálogo en la organización.","tags":["Integrations"]}},"/organizations/{orgId}/reports/summary":{"get":{"operationId":"ReportsController_summary","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Resumen general del dashboard de la organización.","tags":["Reports"]}},"/organizations/{orgId}/reports/messaging":{"get":{"operationId":"ReportsController_messaging","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"since","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Métricas de mensajería agregadas desde una fecha.","tags":["Reports"]}},"/organizations/{orgId}/reports/billing":{"get":{"operationId":"ReportsController_billing","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Resumen de facturación y consumo de la organización.","tags":["Reports"]}},"/organizations/{orgId}/reports/customers":{"get":{"operationId":"ReportsController_customers","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"since","required":false,"in":"query","schema":{"type":"string"}},{"name":"until","required":false,"in":"query","schema":{"type":"string"}},{"name":"category","required":false,"in":"query","schema":{"type":"string"}},{"name":"resolutionOutcome","required":false,"in":"query","schema":{"type":"string"}},{"name":"q","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista contactos con métricas agregadas de conversaciones (paginado).","tags":["Reports"]}},"/organizations/{orgId}/reports/customers/{contactId}":{"get":{"operationId":"ReportsController_customer","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"contactId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Detalle de un contacto con métricas históricas y timeline.","tags":["Reports"]}},"/public/leads":{"post":{"operationId":"LeadsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateLeadDto"}}}},"responses":{"201":{"description":""}},"summary":"Sink público para el formulario de contacto de la landing.","tags":["Leads"]}},"/admin/stats":{"get":{"operationId":"AdminController_stats","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Métricas globales del sistema.","tags":["Admin (Mosend staff)"]}},"/admin/health":{"get":{"operationId":"AdminController_health","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Estado operacional vivo: queues, sockets, errores, recursos.","tags":["Admin (Mosend staff)"]}},"/admin/organizations":{"get":{"operationId":"AdminController_listOrgs","parameters":[{"name":"q","required":false,"in":"query","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Listar todas las organizaciones del sistema. Soporta búsqueda y filtros.","tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}":{"get":{"operationId":"AdminController_getOrgDetail","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Detalle completo de una organización (miembros, WABAs, números, uso, auditoría).","tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}/suspend":{"patch":{"operationId":"AdminController_suspend","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}/reactivate":{"patch":{"operationId":"AdminController_reactivate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}/plan/preview":{"post":{"operationId":"AdminController_previewPlanChange","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Calcula prorrateo y violations de un cambio de plan sin persistir.","tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}/plan":{"patch":{"operationId":"AdminController_assignPlan","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Asigna o cambia el plan de una organización.","tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}/addons":{"get":{"operationId":"AdminController_getOrgAddons","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Add-ons contratados por una organización.","tags":["Admin (Mosend staff)"]},"patch":{"operationId":"AdminController_setOrgAddon","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminSetAddonDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Override de staff de los add-ons de una organización (cortesía/soporte, sin cargo al wallet).","tags":["Admin (Mosend staff)"]}},"/admin/pricing-rules":{"get":{"operationId":"AdminController_listRules","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]},"post":{"operationId":"AdminController_createRule","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePricingRuleDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]}},"/admin/pricing-rules/{id}":{"delete":{"operationId":"AdminController_deleteRule","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]},"patch":{"operationId":"AdminController_updateRule","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePricingRuleDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]}},"/admin/billing/overview":{"get":{"operationId":"AdminController_billingOverview","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"KPIs globales del sistema de facturación: MRR, ARR, dunning, etc.","tags":["Admin (Mosend staff)"]}},"/admin/billing/invoices":{"get":{"operationId":"AdminController_listInvoices","parameters":[{"name":"status","required":false,"in":"query","schema":{"type":"string"}},{"name":"orgId","required":false,"in":"query","schema":{"type":"string"}},{"name":"from","required":false,"in":"query","schema":{"type":"string"}},{"name":"to","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Listado global de facturas con filtros.","tags":["Admin (Mosend staff)"]}},"/admin/billing/payments":{"get":{"operationId":"AdminController_listPayments","parameters":[{"name":"method","required":false,"in":"query","schema":{"type":"string"}},{"name":"status","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Listado global de pagos.","tags":["Admin (Mosend staff)"]}},"/admin/billing/wallets":{"get":{"operationId":"AdminController_listWallets","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Saldos por organización ordenados por balance.","tags":["Admin (Mosend staff)"]}},"/admin/billing/wallets/{id}/transactions":{"get":{"operationId":"AdminController_listWalletTransactions","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Movimientos del saldo de una organización (DEPOSIT/DEBIT/REFUND/ADJUSTMENT).","tags":["Admin (Mosend staff)"]}},"/admin/billing/wallet-transactions":{"get":{"operationId":"AdminController_listAllWalletTransactions","parameters":[{"name":"type","required":false,"in":"query","schema":{"type":"string"}},{"name":"source","required":false,"in":"query","schema":{"type":"string"}},{"name":"orgId","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Movimientos de saldo de TODAS las organizaciones (filtros opcionales).","tags":["Admin (Mosend staff)"]}},"/admin/billing/wallets/{id}/adjust":{"post":{"operationId":"AdminController_adjustWallet","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdjustWalletDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Ajusta saldo manualmente (positivo o negativo). Queda en audit.","tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}/billing/close":{"post":{"operationId":"AdminController_forceClosePeriod","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Fuerza el cierre del periodo abierto y emite factura.","tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}/recent-media-messages":{"get":{"operationId":"AdminController_recentMediaMessages","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los últimos mensajes con media de una organización (image/video/audio/etc) con su estado de caché.","tags":["Admin (Mosend staff)"]}},"/admin/messages/{id}/diagnose-media":{"get":{"operationId":"AdminController_diagnoseMessageMedia","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Diagnostica un mensaje con media: payload, wabaId, token mascarado, intento directo a Meta.","tags":["Admin (Mosend staff)"]}},"/admin/users/{id}/impersonate":{"post":{"operationId":"AdminController_impersonateUser","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Genera un ImpersonationToken (single-use, 5 min) para que el staff pueda abrir una sesión como `userId`. Devuelve `{ token, redeemUrl }`. El frontend admin abre redeemUrl en una nueva tab — el dashboard detecta el flag impersonatedBy en el JWT y muestra banner persistente.","tags":["Admin (Mosend staff)"]}},"/admin/roles/reseed-system":{"post":{"operationId":"AdminController_reseedSystemRoles","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Re-aplica el catálogo de permisos del sistema a los roles isSystem=true (owner/admin/agent/billing/viewer). Idempotente: solo borra y recrea RolePermission para esos 5 roles, no toca roles custom de organizaciones.","tags":["Admin (Mosend staff)"]}},"/admin/messages/{id}/refresh-media":{"post":{"operationId":"AdminController_refreshMessageMedia","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Dispara el cache del media en S3 para un mensaje (útil tras restaurar permisos o token).","tags":["Admin (Mosend staff)"]}},"/admin/wabas/rebind-token":{"post":{"operationId":"AdminController_rebindWabaToken","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Reemplaza el access token de una WABA con uno nuevo (system user del BM cliente). Caso de uso: WABA con BSP externo (ej. Twilio) donde queremos enviar desde Mosend usando un system user del BM dueño, sin desplazar al BSP existente. Validamos contra Meta que el token tenga acceso a la WABA antes de persistir.","tags":["Admin (Mosend staff)"]}},"/admin/billing/invoices/{id}/regenerate-pdf":{"post":{"operationId":"AdminController_regenerateInvoicePdf","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Regenera el PDF de una factura ya emitida (útil tras ajustes de layout).","tags":["Admin (Mosend staff)"]}},"/admin/billing/invoices/{id}/mark-paid":{"post":{"operationId":"AdminController_markInvoicePaid","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarkInvoicePaidDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Registra un pago manual contra una factura (transferencia, etc).","tags":["Admin (Mosend staff)"]}},"/admin/billing/invoices/{id}/void":{"post":{"operationId":"AdminController_voidInvoice","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Anula una factura. Si estaba pagada, devuelve el monto al saldo.","tags":["Admin (Mosend staff)"]}},"/admin/organizations/{id}/billing/config":{"patch":{"operationId":"AdminController_updateBillingConfig","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateBillingConfigDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Configura ciclo de facturación y markup override de una org.","tags":["Admin (Mosend staff)"]}},"/admin/plans":{"get":{"operationId":"AdminController_listPlans","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista todos los planes (incluye internos/no-públicos).","tags":["Admin (Mosend staff)"]}},"/admin/plans/{id}":{"get":{"operationId":"AdminController_getPlan","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]},"patch":{"operationId":"AdminController_updatePlan","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePlanDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Edita atributos del plan (limits, features, flags).","tags":["Admin (Mosend staff)"]}},"/admin/plans/{id}/prices":{"post":{"operationId":"AdminController_upsertPlanPrice","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertPlanPriceDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea o actualiza un precio (upsert por currency+interval).","tags":["Admin (Mosend staff)"]}},"/admin/plans/{id}/prices/{priceId}":{"delete":{"operationId":"AdminController_deletePlanPrice","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"priceId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]}},"/admin/roadmap":{"get":{"operationId":"AdminController_listRoadmap","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]}},"/admin/roadmap/{id}":{"patch":{"operationId":"AdminController_updateRoadmapItem","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]}},"/admin/ai-providers":{"get":{"operationId":"AdminController_listAiProviders","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Listar proveedores IA configurados (sin exponer la API key).","tags":["Admin (Mosend staff)"]}},"/admin/ai-providers/{provider}":{"patch":{"operationId":"AdminController_updateAiProvider","parameters":[{"name":"provider","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualizar config de un proveedor IA (apiKey, models, markup).","tags":["Admin (Mosend staff)"]}},"/admin/ai-usage":{"get":{"operationId":"AdminController_aiUsage","parameters":[{"name":"days","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Resumen de uso IA por org en los últimos N días.","tags":["Admin (Mosend staff)"]}},"/admin/me/role":{"get":{"operationId":"AdminController_meRole","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"tags":["Admin (Mosend staff)"]}},"/admin/billing/mp/reconcile":{"post":{"operationId":"AdminController_reconcileMp","parameters":[{"name":"hours","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Ejecuta reconciliación manual con MP (busca pagos huérfanos).","tags":["Admin (Mosend staff)"]}},"/admin/billing/mp/reprocess-payment":{"post":{"operationId":"AdminController_reprocessMpPayment","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReprocessPaymentDto"}}}},"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Reprocesa un Payment de MP por id (idempotente).","tags":["Admin (Mosend staff)"]}},"/admin/billing/wallet-alerts/run":{"post":{"operationId":"AdminController_runWalletAlerts","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Ejecuta manualmente checkAndAlert + tryAutoRecharge (solo staff).","tags":["Admin (Mosend staff)"]}},"/admin/webhooks/inbound":{"get":{"operationId":"AdminController_listInboundWebhooks","parameters":[{"name":"type","required":false,"in":"query","schema":{"type":"string"}},{"name":"since","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}},{"name":"orgId","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista WebhookEvents recientes (headers/payload redactados).","tags":["Admin (Mosend staff)"]}},"/admin/webhooks/inbound/{id}":{"get":{"operationId":"AdminController_getInboundWebhook","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Detalle de un WebhookEvent.","tags":["Admin (Mosend staff)"]}},"/admin/coupons":{"get":{"operationId":"AdminController_listCoupons","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista cupones con conteo de redenciones.","tags":["Admin (Mosend staff)"]},"post":{"operationId":"AdminController_createCoupon","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCouponDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea un cupón de descuento.","tags":["Admin (Mosend staff)"]}},"/admin/coupons/{id}":{"patch":{"operationId":"AdminController_updateCoupon","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCouponDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza un cupón.","tags":["Admin (Mosend staff)"]},"delete":{"operationId":"AdminController_deleteCoupon","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Borra un cupón (soft-delete si tiene redenciones).","tags":["Admin (Mosend staff)"]}},"/organizations/{orgId}/bot/flows":{"get":{"operationId":"FlowsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneNumberId","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los flujos del bot de la org (filtrable por número).","tags":["Bot flows"]},"post":{"operationId":"FlowsController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFlowDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea un flujo del bot.","tags":["Bot flows"]}},"/organizations/{orgId}/bot/flows/{id}":{"get":{"operationId":"FlowsController_get","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de un flujo del bot.","tags":["Bot flows"]},"patch":{"operationId":"FlowsController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateFlowDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza un flujo del bot (config y/o su JSON).","tags":["Bot flows"]},"delete":{"operationId":"FlowsController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina un flujo del bot.","tags":["Bot flows"]}},"/organizations/{orgId}/bot/flows/{id}/publish":{"post":{"operationId":"FlowsController_publish","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Publica el flujo para que quede activo.","tags":["Bot flows"]}},"/organizations/{orgId}/bot/flows/{id}/unpublish":{"post":{"operationId":"FlowsController_unpublish","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Despublica el flujo (lo desactiva).","tags":["Bot flows"]}},"/organizations/{orgId}/bot/flows/{id}/duplicate":{"post":{"operationId":"FlowsController_duplicate","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Duplica un flujo existente.","tags":["Bot flows"]}},"/organizations/{orgId}/bot/flows/{id}/test-run":{"post":{"operationId":"FlowsController_testRun","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRunDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Ejecuta el flujo en sandbox y devuelve el trace de pasos.","tags":["Bot flows"]}},"/organizations/{orgId}/bot/config":{"get":{"operationId":"BotConfigController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista la configuración del bot por número activo de la org.","tags":["Bot config"]}},"/organizations/{orgId}/bot/config/{phoneId}":{"get":{"operationId":"BotConfigController_getByPhone","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Obtiene la configuración del bot de un número.","tags":["Bot config"]},"put":{"operationId":"BotConfigController_upsert","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertBotConfigDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea o actualiza la configuración del bot de un número.","tags":["Bot config"]}},"/organizations/{orgId}/bot/config/{phoneId}/toggle":{"patch":{"operationId":"BotConfigController_toggle","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Activa o desactiva el bot de un número (crea config con defaults si no existe).","tags":["Bot config"]}},"/organizations/{orgId}/bot/events":{"get":{"operationId":"BotEventsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"phoneNumberId","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista los eventos recientes del bot (filtrable por número y límite).","tags":["Bot events"]}},"/organizations/{orgId}/bot/ai-providers":{"get":{"operationId":"OrgAiProvidersController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"summary":"Lista los 4 proveedores soportados (Anthropic, OpenAI, OpenRouter, Groq) con su estado para esta org. La API key nunca se devuelve.","tags":["Bot · AI providers (BYOK)"]}},"/organizations/{orgId}/bot/ai-providers/{provider}":{"put":{"operationId":"OrgAiProvidersController_upsert","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"provider","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertOrgAiProviderDto"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"summary":"Crea o actualiza la config del proveedor para esta org. Recibe apiKey en plaintext, se persiste cifrada con AES-GCM.","tags":["Bot · AI providers (BYOK)"]},"delete":{"operationId":"OrgAiProvidersController_remove","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"provider","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":""}},"summary":"Elimina la config del proveedor. La org vuelve a usar fallback (si existe) o queda sin key.","tags":["Bot · AI providers (BYOK)"]}},"/organizations/{orgId}/bot/ai-providers/{provider}/test":{"post":{"operationId":"OrgAiProvidersController_test","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"provider","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"summary":"Verifica que la API key funciona haciendo un ping mínimo al proveedor. Persiste el resultado en lastTestedAt/lastTestError.","tags":["Bot · AI providers (BYOK)"]}},"/organizations/{orgId}/bot/knowledge":{"get":{"operationId":"KnowledgeController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista los documentos del knowledge base del bot.","tags":["Bot · Knowledge"]},"post":{"operationId":"KnowledgeController_upload","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadOptsDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Sube un documento. Multipart: file + opcional title, tags (coma).","tags":["Bot · Knowledge"]}},"/organizations/{orgId}/bot/knowledge/{id}":{"get":{"operationId":"KnowledgeController_getOne","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de un documento del knowledge base.","tags":["Bot · Knowledge"]},"delete":{"operationId":"KnowledgeController_delete","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina un documento del knowledge base (chunks y objeto S3).","tags":["Bot · Knowledge"]}},"/organizations/{orgId}/bot/knowledge/{id}/title":{"patch":{"operationId":"KnowledgeController_updateTitle","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTitleDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Renombra un documento del knowledge base.","tags":["Bot · Knowledge"]}},"/organizations/{orgId}/bot/knowledge/{id}/tags":{"patch":{"operationId":"KnowledgeController_updateTags","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTagsDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Re-etiqueta un documento (afecta qué bots lo usan).","tags":["Bot · Knowledge"]}},"/organizations/{orgId}/bot/knowledge/{id}/reprocess":{"post":{"operationId":"KnowledgeController_reprocess","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Re-extrae texto + regenera embeddings.","tags":["Bot · Knowledge"]}},"/organizations/{orgId}/contact-lists":{"get":{"operationId":"ContactListsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista las listas de contactos de la organización.","tags":["Contact lists"]},"post":{"operationId":"ContactListsController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea una nueva lista de contactos.","tags":["Contact lists"]}},"/organizations/{orgId}/contact-lists/{id}":{"get":{"operationId":"ContactListsController_get","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Obtiene el detalle de una lista de contactos por su id.","tags":["Contact lists"]},"patch":{"operationId":"ContactListsController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza nombre, descripción o color de una lista de contactos.","tags":["Contact lists"]},"delete":{"operationId":"ContactListsController_archive","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Archiva una lista de contactos.","tags":["Contact lists"]}},"/organizations/{orgId}/contact-lists/{id}/members":{"get":{"operationId":"ContactListsController_listMembers","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista los contactos miembros de una lista.","tags":["Contact lists"]},"post":{"operationId":"ContactListsController_addMembers","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Agrega contactos a una lista por sus ids.","tags":["Contact lists"]}},"/organizations/{orgId}/contact-lists/{id}/members/{contactId}":{"delete":{"operationId":"ContactListsController_removeMember","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"contactId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Quita un contacto de una lista.","tags":["Contact lists"]}},"/organizations/{orgId}/contact-lists/{id}/add-by-tag":{"post":{"operationId":"ContactListsController_addByTag","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Agrega a la lista todos los contactos que tengan alguna de las etiquetas indicadas.","tags":["Contact lists"]}},"/organizations/{orgId}/broadcasts":{"get":{"operationId":"BroadcastsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista las difusiones (broadcasts) de la organización.","tags":["Broadcasts"]},"post":{"operationId":"BroadcastsController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea una difusión (DRAFT, o SCHEDULED si pasás scheduledAt). No envía nada todavía.","tags":["Broadcasts"]}},"/organizations/{orgId}/broadcasts/{id}":{"get":{"operationId":"BroadcastsController_get","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Detalle de una difusión, incluyendo conteos agregados (counts: total/sent/delivered/read/failed/replied).","tags":["Broadcasts"]}},"/organizations/{orgId}/broadcasts/{id}/recipients":{"get":{"operationId":"BroadcastsController_recipients","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}},{"name":"filter","required":false,"in":"query","schema":{"type":"string"}},{"name":"cursor","required":false,"in":"query","schema":{"type":"string"}},{"name":"limit","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Destinatarios de la difusión, filtrables por estado (para el detalle).","tags":["Broadcasts"]}},"/organizations/{orgId}/broadcasts/{id}/send":{"post":{"operationId":"BroadcastsController_send","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Dispara el envío: resuelve audiencia (dedup + opt-outs), valida cuota y manda. Bloquea hasta terminar.","tags":["Broadcasts"]}},"/organizations/{orgId}/broadcasts/{id}/cancel":{"post":{"operationId":"BroadcastsController_cancel","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Cancela una difusión DRAFT/SCHEDULED. Lo ya enviado no se desmanda.","tags":["Broadcasts"]}},"/organizations/{orgId}/quick-replies":{"get":{"operationId":"QuickRepliesController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista las respuestas rápidas de la organización.","tags":["Quick replies"]},"post":{"operationId":"QuickRepliesController_create","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Crea una respuesta rápida (atajo, título y cuerpo).","tags":["Quick replies"]}},"/organizations/{orgId}/quick-replies/{id}":{"patch":{"operationId":"QuickRepliesController_update","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Actualiza una respuesta rápida.","tags":["Quick replies"]},"delete":{"operationId":"QuickRepliesController_archive","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Archiva una respuesta rápida.","tags":["Quick replies"]}},"/organizations/{orgId}/quick-replies/{id}/use":{"post":{"operationId":"QuickRepliesController_incrementUse","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}},{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Incrementa el contador de uso de una respuesta rápida.","tags":["Quick replies"]}},"/plans":{"get":{"operationId":"PlansController_list","parameters":[],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}}},"security":[{"bearer":[]}],"summary":"Lista pública de planes activos con sus precios.","tags":["Plans"]}},"/plans/{slug}":{"get":{"operationId":"PlansController_getOne","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Detalle público de un plan por su slug.","tags":["Plans"]}},"/plans/quote/{slug}":{"get":{"operationId":"PlansController_quote","parameters":[{"name":"slug","required":true,"in":"path","schema":{"type":"string"}},{"name":"currency","required":false,"in":"query","schema":{"type":"string"}},{"name":"interval","required":false,"in":"query","schema":{"type":"string"}},{"name":"coupon","required":false,"in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Precio final con cupón aplicado (informativo, no cobra).","tags":["Plans"]}},"/plans/organizations/{orgId}/preview-change":{"post":{"operationId":"PlansController_previewChange","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Previsualiza el efecto de un cambio de plan: prorrateo + cupón + saldo final.","tags":["Plans"]}},"/plans/organizations/{orgId}/cancel-subscription":{"post":{"operationId":"PlansController_cancelSubscription","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Cancela la suscripción de pago. Baja el plan a free, mantiene los datos. No emite reembolsos por servicios ya prestados.","tags":["Plans"]}},"/plans/organizations/{orgId}/plan":{"patch":{"operationId":"PlansController_changePlan","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Cambia el plan de una organización (self-service: upgrade/downgrade).","tags":["Plans"]}},"/organizations/{orgId}/billing/addons":{"get":{"operationId":"AddonsController_list","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Catálogo de add-ons del plan + cantidades contratadas.","tags":["Add-ons"]},"patch":{"operationId":"AddonsController_apply","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddonChangeDto"}}}},"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Contrata o reduce un add-on. Los aumentos exigen saldo suficiente en el wallet.","tags":["Add-ons"]}},"/organizations/{orgId}/billing/addons/preview":{"post":{"operationId":"AddonsController_preview","parameters":[{"name":"orgId","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddonChangeDto"}}}},"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Previsualiza el prorrateo y el impacto en el wallet.","tags":["Add-ons"]}},"/passkeys/registration/options":{"post":{"operationId":"PasskeysController_registrationOptions","parameters":[],"responses":{"201":{"description":"","content":{"application/json":{"schema":{"type":"object"}}}}},"security":[{"bearer":[]}],"summary":"Genera las opciones WebAuthn para registrar una nueva passkey.","tags":["Passkeys"]}},"/passkeys/registration/verify":{"post":{"operationId":"PasskeysController_registrationVerify","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Verifica y guarda la passkey recién registrada.","tags":["Passkeys"]}},"/passkeys":{"get":{"operationId":"PasskeysController_list","parameters":[],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Lista las passkeys registradas del usuario.","tags":["Passkeys"]}},"/passkeys/{id}":{"patch":{"operationId":"PasskeysController_rename","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Renombra una passkey del usuario.","tags":["Passkeys"]},"delete":{"operationId":"PasskeysController_remove","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":""}},"security":[{"bearer":[]}],"summary":"Elimina una passkey del usuario.","tags":["Passkeys"]}},"/auth/passkey/login/options":{"post":{"operationId":"PasskeysController_loginOptions","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Genera las opciones WebAuthn para iniciar sesión con passkey.","tags":["Passkeys"]}},"/auth/passkey/login/verify":{"post":{"operationId":"PasskeysController_loginVerify","parameters":[],"responses":{"201":{"description":""}},"security":[{"bearer":[]}],"summary":"Verifica la passkey y emite los tokens de sesión.","tags":["Passkeys"]}}},"info":{"title":"Mosend WB API","description":"Tech Provider de Meta para WhatsApp Business Cloud API","version":"0.9.0","contact":{"name":"Mosend","url":"https://developer.mosend.dev","email":"soporte@mosend.dev"}},"tags":[],"servers":[{"url":"https://api.mosend.dev","description":"Producción"}],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"},"apiKey":{"type":"apiKey","in":"header","name":"X-Api-Key"}},"schemas":{"SignupDto":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"password":{"type":"string","minLength":8,"maxLength":128},"name":{"type":"string","minLength":2,"maxLength":80}},"required":["email","password","name"]},"LoginDto":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"password":{"type":"string","maxLength":128},"twoFactorCode":{"type":"string","maxLength":64}},"required":["email","password"]},"RefreshDto":{"type":"object","properties":{"refreshToken":{"type":"string"}},"required":["refreshToken"]},"ForgotPasswordDto":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]},"ResetPasswordDto":{"type":"object","properties":{"token":{"type":"string"},"password":{"type":"string","minLength":8,"maxLength":128}},"required":["token","password"]},"ImpersonateRedeemDto":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]},"UpdateUserDto":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":80},"locale":{"type":"string","maxLength":8}}},"ChangePasswordDto":{"type":"object","properties":{"currentPassword":{"type":"string","minLength":8,"maxLength":128},"newPassword":{"type":"string","minLength":8,"maxLength":128}},"required":["currentPassword","newPassword"]},"CreateOrganizationDto":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":80},"slug":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{0,38}[a-z0-9]$"},"billingEmail":{"type":"string","maxLength":254,"format":"email"},"country":{"type":"string","maxLength":2},"currency":{"type":"string","maxLength":3},"timezone":{"type":"string","maxLength":64}},"required":["name","slug","billingEmail"]},"UpdateOrganizationDto":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":80},"billingEmail":{"type":"string","maxLength":254,"format":"email"},"country":{"type":"string","maxLength":2},"currency":{"type":"string","maxLength":3},"timezone":{"type":"string","maxLength":64},"businessHoursSchedule":{"type":"object","nullable":true}}},"SetRoleDto":{"type":"object","properties":{}},"SetWabaScopeDto":{"type":"object","properties":{}},"CreateApiKeyDto":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":80},"scopes":{"uniqueItems":true,"type":"array","items":{"type":"string"}},"phoneNumberIds":{"description":"Restricción opcional a un subconjunto de phone-numbers de la org. Vacío\no ausente = la key opera sobre TODOS los phone-numbers (default). Si\ntrae UUIDs, la key SOLO puede enviar/leer de esos números.","uniqueItems":true,"type":"array","items":{"type":"string","format":"uuid"}}},"required":["name"]},"UpdateApiKeyDto":{"type":"object","properties":{"name":{"type":"string","minLength":2,"maxLength":80},"scopes":{"uniqueItems":true,"type":"array","items":{"type":"string"}},"phoneNumberIds":{"uniqueItems":true,"type":"array","items":{"type":"string","format":"uuid"}}}},"CreateInvitationDto":{"type":"object","properties":{"email":{"type":"string","format":"email"},"roleId":{"type":"string","format":"uuid"}},"required":["email","roleId"]},"AcceptInvitationDto":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]},"VerifyDto":{"type":"object","properties":{}},"ConnectTestNumberDto":{"type":"object","properties":{"wabaId":{"type":"string","minLength":8,"maxLength":64},"phoneNumberId":{"type":"string","minLength":8,"maxLength":64},"accessToken":{"type":"string","minLength":20,"maxLength":2048},"wabaName":{"type":"string","maxLength":120}},"required":["wabaId","phoneNumberId","accessToken"]},"InitiateSignupDto":{"type":"object","properties":{"organizationId":{"type":"string","format":"uuid"}},"required":["organizationId"]},"SdkSessionInfoDto":{"type":"object","properties":{"business_id":{"type":"string"},"waba_id":{"type":"string"},"phone_number_id":{"type":"string"}}},"CallbackDto":{"type":"object","properties":{"sessionId":{"type":"string","format":"uuid"},"code":{"type":"string"},"sessionInfo":{"$ref":"#/components/schemas/SdkSessionInfoDto"},"coexistence":{"type":"boolean","description":"True si el frontend invocó FB.login con extras.setup.coexistence=true.\nMarca el PhoneNumber resultante como `coexistenceMode=true` para que el\nUI muestre badge \"Coexistencia con app móvil\" y para futuras decisiones\n(ej. no marcar como leído si Meta avisa que la app móvil ya respondió)."}},"required":["sessionId","code"]},"CompleteImportDto":{"type":"object","properties":{"wabaMetaIds":{"minItems":1,"type":"array","items":{"type":"string"}},"phoneMetaIds":{"type":"array","items":{"type":"string"}}},"required":["wabaMetaIds"]},"AddPhoneNumberDto":{"type":"object","properties":{}},"RequestCodeDto":{"type":"object","properties":{}},"VerifyCodeDto":{"type":"object","properties":{}},"RegisterDto":{"type":"object","properties":{}},"CreateLinkDto":{"type":"object","properties":{"phoneNumberId":{"type":"string","format":"uuid"},"name":{"type":"string","maxLength":120},"campaignTag":{"type":"string","maxLength":80},"prefilledMessage":{"type":"string","maxLength":1024},"metadata":{"type":"object"}},"required":["phoneNumberId","name"]},"UpdateLinkDto":{"type":"object","properties":{"name":{"type":"string","maxLength":120},"campaignTag":{"type":"string","maxLength":80},"prefilledMessage":{"type":"string","maxLength":1024},"metadata":{"type":"object"}}},"SubscribeDto":{"type":"object","properties":{}},"UnsubscribeDto":{"type":"object","properties":{}},"UpsertProfileDto":{"type":"object","properties":{}},"TemplateButtonDto":{"type":"object","properties":{"type":{"type":"string"},"text":{"type":"string"},"url":{"type":"string"},"phone_number":{"type":"string"},"example":{"type":"array","items":{"type":"string"}},"flow_id":{"type":"string"},"flow_action":{"type":"string"},"flow_name":{"type":"string"},"navigate_screen":{"type":"string"},"flow_json":{"type":"object"},"otp_type":{"type":"string","description":"Sub-tipo del botón OTP (plantillas AUTHENTICATION):\n COPY_CODE | ONE_TAP | ZERO_TAP — exigido por Meta cuando type='OTP'."},"autofill_text":{"type":"string"},"supported_apps":{"type":"string"},"package_name":{"type":"string"},"signature_hash":{"type":"string"},"copy_code_text":{"type":"string"},"catalog_action":{"type":"string"},"zero_tap_terms_accepted":{"type":"boolean"}},"required":["type"]},"TemplateCardDto":{"type":"object","properties":{"components":{"type":"array","items":{"$ref":"#/components/schemas/TemplateComponentDto"}}},"required":["components"]},"TemplateComponentDto":{"type":"object","properties":{"type":{"type":"string"},"format":{"type":"string"},"text":{"type":"string"},"example":{"type":"object"},"buttons":{"type":"array","items":{"$ref":"#/components/schemas/TemplateButtonDto"}},"cards":{"description":"Tarjetas del carrusel (cuando type=CAROUSEL).","type":"array","items":{"$ref":"#/components/schemas/TemplateCardDto"}},"limited_time_offer":{"type":"object","properties":{"text":{"type":"string"},"has_expiration":{"type":"boolean"}},"required":[]},"has_expiration":{"type":"boolean"},"add_security_recommendation":{"type":"string"},"code_expiration_minutes":{"type":"string"}},"required":["type"]},"CreateTemplateDto":{"type":"object","properties":{"wabaId":{"type":"string","format":"uuid"},"name":{"type":"string","minLength":1,"maxLength":512},"language":{"type":"string","maxLength":8},"category":{"type":"string","enum":["MARKETING","UTILITY","AUTHENTICATION"]},"components":{"type":"array","items":{"$ref":"#/components/schemas/TemplateComponentDto"}}},"required":["wabaId","name","language","category","components"]},"UpdateTemplateDto":{"type":"object","properties":{"components":{"type":"array","items":{"$ref":"#/components/schemas/TemplateComponentDto"}}},"required":["components"]},"UpsertContactDto":{"type":"object","properties":{"waId":{"type":"string","pattern":"^\\d{8,15}$"},"name":{"type":"string","maxLength":80},"language":{"type":"string","maxLength":8},"attributes":{"type":"object"}},"required":["waId"]},"UpdateContactDto":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"language":{"type":"string","maxLength":8},"attributes":{"type":"object"},"optInStatus":{"type":"object"}}},"CreateTagDto":{"type":"object","properties":{}},"RecordOptInDto":{"type":"object","properties":{}},"SendMessageDto":{"type":"object","properties":{"type":{"type":"string","description":"Tipo de mensaje. Si no se especifica, default 'text'.","enum":["text","image","video","audio","document"]},"body":{"type":"string","description":"Texto del mensaje (requerido si type='text'; opcional como caption en otros).","maxLength":4096},"mediaAssetId":{"type":"string","description":"Id del MediaAsset previamente subido vía /web-chat/media. Requerido cuando type != 'text'.","format":"uuid"},"replyToMessageId":{"type":"string","description":"UUID del Message al que el agente responde (cita visible en widget)."}}},"EditMessageDto":{"type":"object","properties":{}},"SendStickerDto":{"type":"object","properties":{}},"CreateAutoReplyDto":{"type":"object","properties":{}},"UpdateAutoReplyDto":{"type":"object","properties":{}},"SetReactionDto":{"type":"object","properties":{"emoji":{"type":"string","minLength":1,"maxLength":16,"description":"Emoji unicode para reaccionar al mensaje. Si está vacío se interpreta como remover la reacción.","example":"👍"}},"required":["emoji"]},"CreateChannelDto":{"type":"object","properties":{"name":{"type":"string","maxLength":100},"color":{"type":"string"},"welcomeMessage":{"type":"string","maxLength":500},"allowedDomains":{"type":"array","items":{"type":"string"}},"precaptureEnabled":{"type":"boolean"},"botEnabled":{"type":"boolean"},"enabled":{"type":"boolean"}},"required":["name"]},"UpdateChannelDto":{"type":"object","properties":{"name":{"type":"string","maxLength":100},"color":{"type":"string"},"welcomeMessage":{"type":"string","maxLength":500},"allowedDomains":{"type":"array","items":{"type":"string"}},"precaptureEnabled":{"type":"boolean"},"botEnabled":{"type":"boolean"},"enabled":{"type":"boolean"},"identityRequired":{"type":"boolean","description":"Si true, exige firma HMAC al recibir identidad pasada por el host site."},"operatingHours":{"type":"object","nullable":true},"offlineAction":{"type":"object"},"offlineMessage":{"type":"string","nullable":true,"maxLength":500},"prechatFields":{"nullable":true,"type":"array","items":{"type":"object"}},"departments":{"nullable":true,"type":"array","items":{"type":"object"}},"proactiveTriggers":{"nullable":true,"type":"array","items":{"type":"object"}},"linkEmailBannerEnabled":{"type":"boolean"}}},"CreateSessionDto":{"type":"object","properties":{"visitorId":{"type":"string"},"mode":{"type":"string","enum":["anonymous","identified","verify-otp","host-identified"]},"name":{"type":"string","maxLength":200},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"otp":{"type":"string"},"userId":{"type":"string","maxLength":200},"hash":{"type":"string","description":"HMAC-SHA256 hex de `userId || email`, firmado con `WebChatChannel.identitySecret`.","maxLength":128},"attributes":{"type":"object","description":"Atributos custom del host (plan, role, etc.) — van a visitor.metadata.host."},"departmentId":{"type":"string","maxLength":40},"prechat":{"type":"object","description":"Respuestas del prechat dinámico: { fieldId: value }."},"url":{"type":"string","description":"Datos del navegador / contexto.","maxLength":500},"referer":{"type":"string","maxLength":500},"title":{"type":"string","maxLength":200},"lang":{"type":"string","maxLength":20},"utm":{"type":"object","properties":{"source":{"type":"string"},"medium":{"type":"string"},"campaign":{"type":"string"},"term":{"type":"string"},"content":{"type":"string"}},"required":[]}},"required":["visitorId","mode"]},"ResendOtpDto":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]},"LinkEmailDto":{"type":"object","properties":{"email":{"type":"string","format":"email"},"name":{"type":"string","maxLength":200}},"required":["email"]},"CreateOutboundDto":{"type":"object","properties":{}},"UpdateOutboundDto":{"type":"object","properties":{}},"RedeemCouponDto":{"type":"object","properties":{}},"CreateCreditNoteDto":{"type":"object","properties":{}},"CreateRechargeDto":{"type":"object","properties":{}},"AddCardDto":{"type":"object","properties":{"token":{"type":"string","minLength":10,"maxLength":256},"email":{"type":"string","format":"email"},"firstName":{"type":"string","minLength":1,"maxLength":80},"lastName":{"type":"string","minLength":1,"maxLength":80}},"required":["token","email"]},"SetAutoPayDto":{"type":"object","properties":{"enabled":{"type":"boolean"},"methodId":{"type":"string","format":"uuid"}},"required":["enabled"]},"UpdateAlertSettingsDto":{"type":"object","properties":{"lowBalanceThreshold":{"type":"number","nullable":true,"description":"Umbral de saldo bajo en la moneda del wallet. Si está set y el saldo\ncae al o por debajo, el cron envía una alerta. `null` desactiva la alerta.","minimum":0},"autoRechargeEnabled":{"type":"boolean","description":"Activa/desactiva auto-recarga. Para activar, requiere `autoRechargeAmount`\n> 0, `autoRechargeCurrency` (3 chars), y que la org tenga\n`autoPayMethodId` (tarjeta default registrada)."},"autoRechargeAmount":{"type":"number","nullable":true,"description":"Monto a cobrar a la tarjeta default cada vez que se dispara la auto-recarga.","minimum":0},"autoRechargeCurrency":{"type":"string","nullable":true,"description":"Moneda ISO-4217 de 3 chars (USD, COP, MXN, ...).","minLength":3,"maxLength":3}}},"InstallIntegrationDto":{"type":"object","properties":{"slug":{"type":"string","maxLength":80},"config":{"type":"object"}},"required":["slug"]},"UpdateInstallationDto":{"type":"object","properties":{"config":{"type":"object"},"enabled":{"type":"boolean"}}},"CreateLeadDto":{"type":"object","properties":{}},"AdminSetAddonDto":{"type":"object","properties":{}},"CreatePricingRuleDto":{"type":"object","properties":{}},"AdjustWalletDto":{"type":"object","properties":{"delta":{"type":"number"},"reason":{"type":"string","maxLength":500}},"required":["delta","reason"]},"MarkInvoicePaidDto":{"type":"object","properties":{"amount":{"type":"number","minimum":0.01},"description":{"type":"string","maxLength":500}},"required":["amount"]},"UpdateBillingConfigDto":{"type":"object","properties":{"billingCycleDay":{"type":"number","enum":[1,15]},"markupOverride":{"type":"number","nullable":true}}},"UpdatePlanDto":{"type":"object","properties":{}},"UpsertPlanPriceDto":{"type":"object","properties":{}},"UpdatePricingRuleDto":{"type":"object","properties":{}},"ReprocessPaymentDto":{"type":"object","properties":{}},"CreateCouponDto":{"type":"object","properties":{}},"UpdateCouponDto":{"type":"object","properties":{}},"CreateFlowDto":{"type":"object","properties":{}},"UpdateFlowDto":{"type":"object","properties":{}},"TestRunDto":{"type":"object","properties":{}},"UpsertBotConfigDto":{"type":"object","properties":{}},"UpsertOrgAiProviderDto":{"type":"object","properties":{"apiKey":{"type":"string","nullable":true,"description":"Key en plaintext. Opcional al actualizar (mantiene la actual si no se pasa).","minLength":8,"maxLength":512},"enabled":{"type":"boolean"},"defaultModel":{"type":"string","nullable":true,"description":"Override del modelo default. Null o '' para borrar el override.","maxLength":120}}},"UploadOptsDto":{"type":"object","properties":{}},"UpdateTitleDto":{"type":"object","properties":{}},"UpdateTagsDto":{"type":"object","properties":{}},"AddonChangeDto":{"type":"object","properties":{}}}}}