Cómo validar NIF, NIE, CIF e IBAN en Python
Si has desarrollado alguna vez un formulario o backend para el mercado español, probablemente hayas tenido que validar identificadores fiscales como el NIF, NIE, CIF o IBAN. Cada uno tiene su propio algoritmo, casos especiales y reglas de validación — e implementarlos correctamente desde cero es más complicado de lo que parece.
En este artículo te muestro cómo validar los cuatro tipos con una sola llamada API usando Python, sin tener que implementar ni mantener los algoritmos de validación.
El problema de implementar la validación tú mismo
Los identificadores fiscales españoles son más complejos de lo que aparentan:
- NIF: 8 dígitos + 1 letra, validado con un algoritmo módulo-23
- NIE: Empieza por X, Y o Z, luego sigue el algoritmo del NIF con sustitución
- CIF: Letra + 7 dígitos + carácter de control (puede ser letra o dígito según el tipo de entidad)
- IBAN: ES + 2 dígitos de control + BBAN de 20 dígitos, validado con MOD-97
La mayoría de implementaciones que encontrarás online tienen bugs sutiles — validación incorrecta de la letra del CIF, casos especiales del NIE que no se contemplan, o errores en el dígito de control del IBAN. Equivocarse significa aceptar identificadores inválidos o rechazar identificadores válidos.
Una alternativa más sencilla: usar una API
Valix es una API REST que valida identificadores fiscales españoles usando los algoritmos oficiales. Gestiona NIF, NIE, CIF e IBAN, detecta el tipo automáticamente y devuelve una respuesta JSON estructurada.
Puedes probarla gratis — sin registro ni API key para el endpoint de prueba.
Primeros pasos
Solo necesitas requests:
pip install requests
Trial: Valida sin registro
El endpoint trial permite hasta 5 identificadores por llamada y 50 validaciones diarias por IP — sin API key.
import requests
def validar_identificadores_trial(identificadores: list[str]) -> dict:
"""
Valida identificadores fiscales españoles con el endpoint trial de Valix.
Sin API key. Máximo 5 identificadores por llamada, 50/día por IP.
"""
url = "https://api.getvalix.io/v1/validate/trial"
payload = {
"items": [
{"value": identificador, "type": "AUTO"}
for identificador in identificadores
]
}
response = requests.post(url, json=payload)
response.raise_for_status()
return response.json()
# Ejemplo de uso
identificadores = [
"12345678Z", # NIF
"X1234567L", # NIE
"A12345674", # CIF
"ES9121000418450200051332" # IBAN
]
resultado = validar_identificadores_trial(identificadores[:5])
for item in resultado["results"]:
estado = "✓ válido" if item["valid"] else "✗ inválido"
print(f"{item['value']} → {item['detected_type']} {estado}")
Salida:
12345678Z → NIF ✓ válido
X1234567L → NIE ✓ válido
A12345674 → CIF ✓ válido
ES9121000418450200051332 → IBAN ✓ válido
Producción: Validación batch con API key
Para uso en producción, el endpoint batch soporta hasta 100 identificadores por llamada. Obtén tu API key en getvalix.io.
import requests
import os
def validar_batch(identificadores: list[str], api_key: str) -> dict:
"""
Valida hasta 100 identificadores fiscales españoles en una sola llamada.
Requiere API key de getvalix.io.
"""
url = "https://api.getvalix.io/v1/validate/batch"
headers = {
"x-api-key": api_key,
"Content-Type": "application/json"
}
payload = {
"items": [
{"value": identificador, "type": "AUTO"}
for identificador in identificadores
]
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
return response.json()
# Carga la API key desde variable de entorno (nunca la hardcodees)
api_key = os.environ.get("VALIX_API_KEY")
identificadores = [
"12345678Z",
"X1234567L",
"A12345674",
"ES9121000418450200051332",
"99999999R", # NIF inválido
]
resultado = validar_batch(identificadores, api_key)
print(f"Total: {resultado['total']}")
print(f"Válidos: {resultado['valid_count']}")
print(f"Inválidos: {resultado['invalid_count']}")
print()
for item in resultado["results"]:
if item["valid"]:
print(f"✓ {item['value']} → {item['detected_type']}")
else:
print(f"✗ {item['value']} → {', '.join(item['errors'])}")
Salida:
Total: 5
Válidos: 4
Inválidos: 1
✓ 12345678Z → NIF
✓ X1234567L → NIE
✓ A12345674 → CIF
✓ ES9121000418450200051332 → IBAN
✗ 99999999R → Formato inválido
Estructura de la respuesta
Cada resultado incluye:
{
"index": 0,
"value": "12345678Z",
"requested_type": "AUTO",
"detected_type": "NIF",
"valid": true,
"formatted": "12345678Z",
"errors": []
}
-
detected_type: el tipo de identificador detectado (NIF, NIE, CIF, IBAN) -
valid: resultado booleano -
formatted: versión normalizada del identificador -
errors: lista de mensajes de error si es inválido
Para CIF, la respuesta incluye además entity_type con el tipo de entidad mercantil (por ejemplo "Sociedad Anónima").
Gestión de errores
import requests
from requests.exceptions import HTTPError
def validar_con_manejo_errores(identificadores: list[str], api_key: str) -> dict | None:
try:
return validar_batch(identificadores, api_key)
except HTTPError as e:
if e.response.status_code == 401:
print("API key inválida o ausente")
elif e.response.status_code == 429:
print("Límite mensual de validaciones alcanzado")
elif e.response.status_code == 400:
error_data = e.response.json()
print(f"Petición incorrecta: {error_data.get('error')}")
else:
print(f"Error de API: {e}")
return None
Validación por tipo específico
Si ya conoces el tipo de identificador, puedes pasarlo explícitamente en lugar de usar AUTO:
payload = {
"items": [
{"value": "12345678Z", "type": "NIF"},
{"value": "X1234567L", "type": "NIE"},
{"value": "A12345674", "type": "CIF"},
{"value": "ES9121000418450200051332", "type": "IBAN"}
]
}
Útil cuando tu fuente de datos ya proporciona el tipo, o cuando quieres forzar la validación de un tipo concreto.
Precios
- Trial: Gratis, 50 validaciones/día, sin registro
- Starter: €19/mes — 10.000 validaciones/mes
- Growth: €49/mes — 100.000 validaciones/mes
- Pro: €149/mes — 1.000.000 validaciones/mes
Resumen
Validar correctamente los identificadores fiscales españoles requiere implementar múltiples algoritmos complejos con casos especiales difíciles de contemplar. Usar Valix te da:
- Validación precisa basada en algoritmos oficiales
- Detección automática del tipo de identificador
- Procesamiento batch de hasta 100 identificadores por llamada
- Trial gratuito sin registro
Pruébalo en getvalix.io — el endpoint trial no requiere registro.
Top comments (0)