Valix Valix
Características ¿Por qué una API? Ejemplos Precios FAQ Empezar ahora

Cómo validar NIF, NIE, CIF e IBAN en Python

Guía práctica con ejemplos de código usando la API de Valix

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"OK  {item['value']} → {item['detected_type']}")
    else:
        print(f"ERR {item['value']} → {', '.join(item['errors'])}")

Salida:

Total: 5
Válidos: 4
Inválidos: 1

OK  12345678Z → NIF
OK  X1234567L → NIE
OK  A12345674 → CIF
OK  ES9121000418450200051332 → IBAN
ERR 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 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.

¿Usas JavaScript en lugar de Python?

Valix tiene un SDK oficial para JavaScript/TypeScript disponible como paquete npm:

npm install @valix/sdk

Paquete npm @valix/sdk ↗

Precios

Plan Precio Validaciones/mes
Trial Gratis 50/día, sin registro
Starter €19/mes 10.000
Growth €49/mes 100.000
Pro €149/mes 1.000.000

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

Valix

API REST de validación de identificadores fiscales españoles

Producto

Características ¿Por qué una API? Ejemplos Precios FAQ

Legal

Términos de servicio Política de privacidad Política de reembolsos

Contacto

soporte@getvalix.io

© 2026 Valix API. Todos los derechos reservados.