Validar RFC
Valida uno o varios RFCs verificando formato y estructura segun las reglas del SAT.
Endpoint
POST https://api.lummy.io/v1/rfc/validate
| Entorno | URL |
|---|---|
| Producción | https://api.lummy.io/v1/rfc/validate |
| Sandbox | https://sandbox.lummy.io/v1/rfc/validate |
Validacion en lote
Puedes validar hasta 10 RFCs en una sola llamada, util para validar catalogos de clientes.
Headers
{
"Authorization": stringrequerido
↳Token de autenticación Bearer (JWT) o API Key para autorizar la solicitud.
}
Body Parameters
{
"rfcs": [requerido
↳Arreglo de RFCs a validar. Máximo 10 elementos. Cada RFC debe tener el formato establecido por el SAT (12 caracteres para personas morales, 13 para personas físicas).
↳Valor máximo: 10
"[item]": stringopcional
]
}
Ejemplos de Codigo
- cURL
- Node.js (TypeScript)
- Python
- PHP (Guzzle)
curl -X POST https://sandbox.lummy.io/rfc/validate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${ACCESS_TOKEN}" \
-d '{
"rfcs": [
"XAXX010101000",
"AAA010101AAA",
"RFC_INVALIDO"
]
}'
import axios from 'axios';
interface RfcValidationResult {
rfc: string;
isValid: boolean;
type: 'MORAL' | 'FISICA' | 'GENERICO' | null;
errors: string[];
inList69?: boolean;
inList69B?: boolean;
}
async function validarRfcs(rfcs: string[]): Promise<RfcValidationResult[]> {
const API_URL = 'https://sandbox.lummy.io/rfc/validate';
const response = await axios.post<RfcValidationResult[]>(
API_URL,
{ rfcs },
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.ACCESS_TOKEN}`,
},
}
);
response.data.forEach(result => {
const status = result.isValid ? '[VALID]' : '[INVALID]';
console.log(`${status} ${result.rfc}: ${result.type || result.errors.join(', ')}`);
});
return response.data;
}
validarRfcs(['XAXX010101000', 'AAA010101AAA', 'RFC_INVALIDO']);
import os
import requests
def validar_rfcs(rfcs):
api_url = "https://sandbox.lummy.io/rfc/validate"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {os.getenv('ACCESS_TOKEN')}",
}
response = requests.post(api_url, json={"rfcs": rfcs}, headers=headers)
response.raise_for_status()
results = response.json()
for result in results:
status = "[VALID]" if result["isValid"] else "[INVALID]"
info = result["type"] or ", ".join(result["errors"])
print(f"{status} {result['rfc']}: {info}")
return results
if __name__ == "__main__":
validar_rfcs(["XAXX010101000", "AAA010101AAA", "RFC_INVALIDO"])
<?php
require 'vendor/autoload.php';
use GuzzleHttp\Client;
function validarRfcs(array $rfcs): array
{
$client = new Client([
'base_uri' => 'https://sandbox.lummy.io',
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . getenv('ACCESS_TOKEN'),
],
]);
$response = $client->post('/rfc/validate', [
'json' => ['rfcs' => $rfcs],
]);
$results = json_decode($response->getBody(), true);
foreach ($results as $result) {
$status = $result['isValid'] ? '[VALID]' : '[INVALID]';
$info = $result['type'] ?? implode(', ', $result['errors']);
echo "{$status} {$result['rfc']}: {$info}\n";
}
return $results;
}
validarRfcs(['XAXX010101000', 'AAA010101AAA', 'RFC_INVALIDO']);
Respuestas
Todas las respuestas siguen el formato estándar StandardResponse.
200 OK
{
"requestId": "abc123-def456",
"data": [
{
"rfc": "XAXX010101000",
"isValid": true,
"type": "GENERICO",
"errors": [],
"inList69": false,
"inList69B": false
},
{
"rfc": "AAA010101AAA",
"isValid": true,
"type": "MORAL",
"errors": [],
"inList69": false,
"inList69B": false
},
{
"rfc": "RFC_INVALIDO",
"isValid": false,
"type": null,
"errors": [
"Longitud invalida: debe tener 12 o 13 caracteres",
"Formato invalido"
]
}
],
"timestamp": "2025-01-20T10:30:00.000Z",
"path": "/rfc/validate",
"method": "POST"
}
Response Body
{
"rfc": string,requerido
↳RFC evaluado en la validación.
"isValid": boolean,requerido
↳Indica si el RFC tiene un formato válido según las reglas del SAT.
"type": string,requerido
↳Tipo de RFC: MORAL (12 caracteres - persona moral/empresa), FISICA (13 caracteres - persona física), GENERICO (RFC genérico para público en general), EXTRANJERO (RFC para extranjeros sin RFC mexicano). Null si el RFC es inválido.
↳Valores permitidos:
"MORAL""FISICA""GENERICO""EXTRANJERO" "errors": [requerido
↳Lista de errores encontrados durante la validación. Puede incluir: longitud inválida, formato inválido, fecha inválida, o dígito verificador incorrecto.
"[item]": stringopcional
],
"inList69": boolean,opcional
↳Indica si el RFC aparece en la lista 69 del SAT (contribuyentes incumplidos). Si es true, se recomienda no facturar a este contribuyente.
"inList69B": booleanopcional
↳Indica si el RFC aparece en la lista 69-B del SAT (operaciones simuladas/EFOS). Si es true, las facturas emitidas a este contribuyente podrían ser consideradas como operaciones inexistentes.
}
Tipos de RFC
| Tipo | Longitud | Ejemplo | Descripcion |
|---|---|---|---|
MORAL | 12 | AAA010101AAA | Persona moral (empresa). |
FISICA | 13 | GARC850101ABC | Persona fisica. |
GENERICO | 13 | XAXX010101000 | RFC generico para publico en general. |
EXTRANJERO | 13 | XEXX010101000 | RFC para extranjeros sin RFC mexicano. |
RFCs Especiales
| RFC | Uso |
|---|---|
XAXX010101000 | Ventas al publico en general. |
XEXX010101000 | Ventas a extranjeros. |
Errores Comunes
| Error | Descripcion |
|---|---|
Longitud invalida | El RFC debe tener 12 (moral) o 13 (fisica) caracteres. |
Formato invalido | No cumple con el patron del SAT. |
Fecha invalida | La fecha de nacimiento/constitucion en el RFC no es valida. |
Digito verificador incorrecto | El ultimo caracter no corresponde al algoritmo de verificacion. |
Notas
- La validacion es sintatica, no verifica si el RFC esta registrado ante el SAT
- Para verificar si un RFC esta activo en el SAT, usa el servicio de Lista Negra (69-B)