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
Tu API key es un secreto -- trátala como una contraseña. Úsala solo desde tu backend, nunca la incluyas en código de frontend/cliente ni en apps móviles.

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

CampoTipoDescripción
archivomultipart/form-dataEl PDF de la CSF. Máximo 8 MB.

Response 200

CampoTipoDescripción
identificacion_fiscalstringRFC extraído y validado contra el SAT.
razon_socialstring | null
codigo_postalstring | nullCódigo postal del domicilio fiscal.
estado_textostring | null
municipio_textostring | null
coloniastring | null
callestring | null
numero_exteriorstring | null
numero_interiorstring | null
codigo_regimen_textostring | nullTexto libre del régimen tal cual lo trae la CSF (ej. "Régimen Simplificado de Confianza"). Se conserva para auditoría.
regimen_fiscal_codigostring | nullLa 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_descripcionstring | nullDescripción oficial del catálogo SAT correspondiente a regimen_fiscal_codigo.
regimen_fiscal_coincidenciabooleanfalse 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_validacionstring | nullÚsalo en /revalidaciones-fiscales para volver a consultar sin re-subir el PDF.
creditos_consumidosstring[]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

CampoTipoDescripción
token_validacionstringToken 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());
La respuesta tiene exactamente los mismos campos que /validaciones-fiscales, incluidos 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

CampoTipoDescripción
rfcstringRFC a consultar (12-13 caracteres). Se normaliza a mayúsculas.

Response 200

CampoTipoDescripción
rfcstring
aparece_en_listadobooleanDeliberadamente NO es un solo semáforo de riesgo: un mismo RFC puede tener historial en más de una situación.
situaciones_encontradasstring[]Alguno de: presunto, desvirtuado, definitivo, sentencia_favorable.
detalleobject[]Un registro por cada coincidencia: situacion, nombre_contribuyente, datos_originales (fila cruda del SAT).
listado_actualizado_enstring | nullFecha ISO 8601 de la última actualización exitosa de la copia local.
creditos_consumidosstring[]
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ódigoCuándo ocurre
401Falta el header Authorization, o la API key es inválida/revocada/expirada.
402Saldo de créditos insuficiente. No se cobra ni se procesa nada.
403La cuenta del cliente no está activa.
413El PDF excede el máximo permitido (8 MB).
415El archivo enviado no es un PDF válido.
422El 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.
500Error interno. Si persiste, contáctanos con el id de la respuesta si está disponible.
{
  "detail": "Falta la API key (header 'Authorization: Bearer ')."
}