Protección contra SIM swap
Verify puede negarse a enviar el código a un número cuya SIM cambió hace poco. Se activa por aplicación desde la consola.
Qué es un SIM swap
Para quedarse con los códigos de alguien, un atacante convence al operador de pasar el número de esa persona a una SIM nueva. Desde ese momento, los SMS y los WhatsApp dirigidos a esa persona llegan al teléfono del atacante.
Con la protección activada, Verify consulta cuándo cambió por última vez la SIM del número antes de enviar el código. Si cambió dentro del plazo que elegiste, no envía nada y responde con un error.
Cómo activarla
En la consola, en Aplicación → Protección contra SIM swap, elige el plazo: 1 día, 3 días o 7 días. Con Desactivada queda apagada, que es como viene. Solo un administrador puede cambiarla, y el cambio rige desde la siguiente verificación.
Qué cuenta como «dentro del plazo»
El operador informa la fecha del cambio, no la hora. Por eso el plazo cuenta días de calendario e incluye el día del borde:
| Plazo | Se bloquea un cambio de |
|---|---|
| 1 día | hoy o ayer |
| 3 días | hoy o los 3 días anteriores |
| 7 días | hoy o los 7 días anteriores |
Con un plazo de 1 día también se bloquea un cambio hecho ayer a las 23:59. Ningún cambio de las últimas 24 horas pasa.
A qué se aplica
- Solo a teléfonos, por SMS y por WhatsApp. Un correo no tiene SIM y se envía sin esta revisión.
- Al crear y al reenviar, cada vez que se va a enviar un código nuevo. Devolver una verificación que sigue activa no envía nada y no vuelve a consultar. Comprobar un código tampoco consulta.
- Después de los límites: una petición que ya frenó un límite no llega a consultar el cambio de SIM.
La respuesta
Cuando la SIM cambió dentro del plazo, la verificación no se crea y la petición responde 403 con 40014:
{
"type": "https://docs.inalambria.com/verify/errors/40014",
"title": "sim_swap_recent",
"status": 403,
"detail": "La SIM del número cambió hace poco y la aplicación no envía códigos en ese caso.",
"code": 40014,
"hint": "Verificá la identidad de la persona por otro medio antes de volver a intentarlo.",
"request_id": "req_01J9XQ4M7KZ3T8V2W6N5P0QRST"
}Una petición rechazada así no se factura. Reintentarla da el mismo resultado mientras dure el plazo: pide a tu usuario que confirme su identidad por otra vía, por ejemplo verificando su correo.
Si en ese momento no se puede consultar el cambio de SIM, Verify envía el código igual y deja constancia en sus registros.
Probarla en el entorno de pruebas
Con una clave test_, el último cambio de SIM de cada destinatario de prueba es fijo:
| Teléfono | Último cambio de SIM | Con la protección activada |
|---|---|---|
+12025550105 | Hoy | Se rechaza con 40014, con cualquier plazo. |
+12025550101 | 1 de enero de 2020 | Se envía. |
+12025550102 | Sin registro | Se envía. |
+12025550103 | Fuera de cobertura | Se envía. |
+12025550104 | La consulta falla | Se envía. |
Consultar el cambio de SIM por tu cuenta
POST /v1/tools/sim-swap dice cuándo cambió por última vez la SIM de un número, sin crear una verificación. Sirve para revisarlo en otros momentos, como antes de un cambio de contraseña o de una transferencia.
curl https://verify-api.inalambria.com/v1/tools/sim-swap \
-H "Authorization: Bearer $VERIFY_API_KEY" \
--json '{ "to": "+573001234567" }'const response = await fetch('https://verify-api.inalambria.com/v1/tools/sim-swap', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VERIFY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ to: '+573001234567' }),
});
const simSwap = await response.json();sim_swap = requests.post(
"https://verify-api.inalambria.com/v1/tools/sim-swap",
headers={"Authorization": f"Bearer {os.environ['VERIFY_API_KEY']}"},
json={"to": "+573001234567"},
).json(){
"status": "swap_detected",
"last_swap_date": "2026-10-25",
"days_since_swap": 3
}status | Qué significa |
|---|---|
swap_detected | Hay un cambio registrado: last_swap_date trae su fecha y days_since_swap, los días desde entonces. |
unknown | El operador no tiene un cambio registrado para el número. |
out_of_coverage | El operador o el país del número no entrega este dato. |
Con unknown y out_of_coverage, last_swap_date y days_since_swap vienen en null. Con una clave test_ responde lo que dice la tabla de la sección anterior.
Los errores propios de esta consulta:
Updated 4 days ago
