Documentación de la API
Valida constancias de situación fiscal (CSF), consulta el Listado 69-B del SAT y obtén datos fiscales ya normalizados y listos para mapear a los nodos de un CFDI 4.0 (RFC, razón social, código postal, régimen fiscal). Integración típica: menos de 15 minutos.
https://TU-DOMINIO.com
Autenticación
Todos los endpoints de producto (los que consumen crédito) requieren tu API key
en el header Authorization, esquema Bearer. El catálogo
público (/v1/catalogo/*) no requiere autenticación.
Authorization: Bearer vf_live_TU_API_KEY_AQUI
Créditos y saldo
Cada cliente tiene un solo saldo (pool) de créditos. Cada llamada exitosa a un
endpoint de producto consume créditos de ese pool -- distinto según el trabajo
real que hace cada uno (10 para /validaciones-fiscales,
5 para /revalidaciones-fiscales, 1 para
/lista-69b) -- lo verás reflejado en el
campo creditos_consumidos de la respuesta.
Si no tienes saldo, el endpoint responde 402 Payment Required
sin intentar procesar nada.
Probar en vivo
Cada endpoint de esta página también se puede probar de verdad, con peticiones HTTP reales contra tu servidor -- subir el PDF, mandar el RFC, ver la respuesta JSON tal cual la regresa la API -- sin escribir ningún código ni salir del navegador. Pega tu API key una sola vez con el botón Authorize y ya queda lista para cualquier endpoint que pruebes después.
POST /v1/mx/validaciones-fiscales
Sube el PDF de una Constancia de Situación Fiscal (CSF) del SAT. La API extrae
y valida en vivo contra el SAT: RFC, razón social, domicilio fiscal y régimen
fiscal -- este último ya mapeado a la clave de 3 dígitos c_RegimenFiscal
que un CFDI exige, no solo el texto libre que trae el PDF.
Request
| Campo | Tipo | Descripción |
|---|---|---|
archivo | multipart/form-data | El PDF de la CSF. Máximo 8 MB. |
Response 200
| Campo | Tipo | Descripción |
|---|---|---|
identificacion_fiscal | string | RFC extraído y validado contra el SAT. |
razon_social | string | null | |
codigo_postal | string | null | Código postal del domicilio fiscal. |
estado_texto | string | null | |
municipio_texto | string | null | |
colonia | string | null | |
calle | string | null | |
numero_exterior | string | null | |
numero_interior | string | null | |
codigo_regimen_texto | string | null | Texto libre del régimen tal cual lo trae la CSF (ej. "Régimen Simplificado de Confianza"). Se conserva para auditoría. |
regimen_fiscal_codigo | string | null | La clave de 3 dígitos que necesitas para un CFDI (ej. "626"). null si no se pudo mapear con confianza -- en ese caso usa codigo_regimen_texto para resolverlo a mano. |
regimen_fiscal_descripcion | string | null | Descripción oficial del catálogo SAT correspondiente a regimen_fiscal_codigo. |
regimen_fiscal_coincidencia | boolean | false si codigo_regimen_texto vino con datos pero no hubo match en el catálogo (el SAT cambió la redacción, o el régimen ya no está vigente). |
token_validacion | string | null | Úsalo en /revalidaciones-fiscales para volver a consultar sin re-subir el PDF. |
creditos_consumidos | string[] | Claves de los créditos cobrados por esta llamada. |
curl -X POST https://TU-DOMINIO.com/v1/mx/validaciones-fiscales \
-H "Authorization: Bearer vf_live_TU_API_KEY_AQUI" \
-F "archivo=@/ruta/a/constancia.pdf"
import requests
with open("constancia.pdf", "rb") as archivo:
respuesta = requests.post(
"https://TU-DOMINIO.com/v1/mx/validaciones-fiscales",
headers={"Authorization": "Bearer vf_live_TU_API_KEY_AQUI"},
files={"archivo": archivo},
)
datos = respuesta.json()
print(datos["regimen_fiscal_codigo"]) # ej. "626"
const form = new FormData();
form.append("archivo", archivoPdf); // File o Blob
const respuesta = await fetch("https://TU-DOMINIO.com/v1/mx/validaciones-fiscales", {
method: "POST",
headers: { Authorization: "Bearer vf_live_TU_API_KEY_AQUI" },
body: form,
});
const datos = await respuesta.json();
console.log(datos.regimen_fiscal_codigo); // ej. "626"
Ejemplo de respuesta 200
{
"identificacion_fiscal": "AAA080808HL8",
"razon_social": "COMERCIALIZADORA EJEMPLO SA DE CV",
"codigo_postal": "06600",
"estado_texto": "CIUDAD DE MEXICO",
"municipio_texto": "CUAUHTEMOC",
"colonia": "JUAREZ",
"calle": "AV REFORMA",
"numero_exterior": "123",
"numero_interior": null,
"codigo_regimen_texto": "Régimen Simplificado de Confianza",
"regimen_fiscal_codigo": "626",
"regimen_fiscal_descripcion": "Régimen Simplificado de Confianza",
"regimen_fiscal_coincidencia": true,
"token_validacion": "abc123tokendelsat",
"creditos_consumidos": ["VALIDACION_CSF_MX"]
}
POST /v1/mx/revalidaciones-fiscales
Repite la consulta al SAT usando el token_validacion
de una validación anterior -- no necesitas volver a subir el PDF. Ideal para
revalidar periódicamente (ej. cada 15-30 días) sin pedirle al cliente su CSF
de nuevo. Misma forma de respuesta que /validaciones-fiscales.
Request
| Campo | Tipo | Descripción |
|---|---|---|
token_validacion | string | Token regresado por una llamada previa a /validaciones-fiscales. |
curl -X POST https://TU-DOMINIO.com/v1/mx/revalidaciones-fiscales \
-H "Authorization: Bearer vf_live_TU_API_KEY_AQUI" \
-H "Content-Type: application/json" \
-d '{"token_validacion": "abc123tokendelsat"}'
import requests
respuesta = requests.post(
"https://TU-DOMINIO.com/v1/mx/revalidaciones-fiscales",
headers={"Authorization": "Bearer vf_live_TU_API_KEY_AQUI"},
json={"token_validacion": "abc123tokendelsat"},
)
print(respuesta.json())
const respuesta = await fetch("https://TU-DOMINIO.com/v1/mx/revalidaciones-fiscales", {
method: "POST",
headers: {
Authorization: "Bearer vf_live_TU_API_KEY_AQUI",
"Content-Type": "application/json",
},
body: JSON.stringify({ token_validacion: "abc123tokendelsat" }),
});
console.log(await respuesta.json());
regimen_fiscal_codigo y regimen_fiscal_descripcion.
POST /v1/mx/lista-69b
Consulta si un RFC aparece en el Listado 69-B del SAT (Empresas que Facturan Operaciones Simuladas -- EFOS), en cualquiera de sus 4 etapas. Consulta contra una copia local que se actualiza periódicamente, no en vivo contra el SAT (el SAT no publica el CSV en un horario fijo).
Request
| Campo | Tipo | Descripción |
|---|---|---|
rfc | string | RFC a consultar (12-13 caracteres). Se normaliza a mayúsculas. |
Response 200
| Campo | Tipo | Descripción |
|---|---|---|
rfc | string | |
aparece_en_listado | boolean | Deliberadamente NO es un solo semáforo de riesgo: un mismo RFC puede tener historial en más de una situación. |
situaciones_encontradas | string[] | Alguno de: presunto, desvirtuado, definitivo, sentencia_favorable. |
detalle | object[] | Un registro por cada coincidencia: situacion, nombre_contribuyente, datos_originales (fila cruda del SAT). |
listado_actualizado_en | string | null | Fecha ISO 8601 de la última actualización exitosa de la copia local. |
creditos_consumidos | string[] |
curl -X POST https://TU-DOMINIO.com/v1/mx/lista-69b \
-H "Authorization: Bearer vf_live_TU_API_KEY_AQUI" \
-H "Content-Type: application/json" \
-d '{"rfc": "AAA080808HL8"}'
import requests
respuesta = requests.post(
"https://TU-DOMINIO.com/v1/mx/lista-69b",
headers={"Authorization": "Bearer vf_live_TU_API_KEY_AQUI"},
json={"rfc": "AAA080808HL8"},
)
datos = respuesta.json()
print(datos["aparece_en_listado"])
const respuesta = await fetch("https://TU-DOMINIO.com/v1/mx/lista-69b", {
method: "POST",
headers: {
Authorization: "Bearer vf_live_TU_API_KEY_AQUI",
"Content-Type": "application/json",
},
body: JSON.stringify({ rfc: "AAA080808HL8" }),
});
const datos = await respuesta.json();
console.log(datos.aparece_en_listado);
Ejemplo de respuesta 200
{
"rfc": "AAA080808HL8",
"aparece_en_listado": true,
"situaciones_encontradas": ["presunto", "desvirtuado"],
"detalle": [
{
"situacion": "desvirtuado",
"nombre_contribuyente": "EJEMPLO SA DE CV",
"datos_originales": { "No": "12345", "Oficio Global de Presunción": "500-05-2018-27105 de fecha 27 de septiembre de 2018" }
}
],
"listado_actualizado_en": "2026-08-27T06:52:57.421759+00:00",
"creditos_consumidos": ["VAL_LISTA_NEGRA_69B"]
}
GET /v1/catalogo/regimenes-fiscales
Catálogo oficial de regímenes fiscales del SAT (c_RegimenFiscal).
No requiere autenticación. Útil cuando regimen_fiscal_coincidencia
te regresó false y necesitas dejar que un humano elija el régimen
correcto de una lista.
curl https://TU-DOMINIO.com/v1/catalogo/regimenes-fiscales
import requests
respuesta = requests.get("https://TU-DOMINIO.com/v1/catalogo/regimenes-fiscales")
print(respuesta.json())
const respuesta = await fetch("https://TU-DOMINIO.com/v1/catalogo/regimenes-fiscales");
console.log(await respuesta.json());
Ejemplo de respuesta 200
[
{ "codigo": "601", "descripcion": "General de Ley Personas Morales" },
{ "codigo": "612", "descripcion": "Personas Físicas con Actividades Empresariales y Profesionales" },
{ "codigo": "626", "descripcion": "Régimen Simplificado de Confianza" }
]
Manejo de errores
Todos los errores regresan un cuerpo JSON con un solo campo detail
describiendo qué pasó.
| Código | Cuándo ocurre |
|---|---|
401 | Falta el header Authorization, o la API key es inválida/revocada/expirada. |
402 | Saldo de créditos insuficiente. No se cobra ni se procesa nada. |
403 | La cuenta del cliente no está activa. |
413 | El PDF excede el máximo permitido (8 MB). |
415 | El archivo enviado no es un PDF válido. |
422 | El documento no pudo procesarse o validarse (ver detail para la causa específica), o el body de la petición no cumple la validación esperada. |
500 | Error interno. Si persiste, contáctanos con el id de la respuesta si está disponible. |
{
"detail": "Falta la API key (header 'Authorization: Bearer ')."
}