TF Fiscal
Documentación

Primeros pasos

Convenciones generales

Las dos formas de respuesta (respuestas simples vs. sobre de la plataforma), formas de error, tipificación de errores, referencia de estados HTTP, idempotencia, límites de tasa, localización, tipos de datos, la estructura de la clave de acceso de la NF-e y los enlaces de descarga de archivos.

Convenciones compartidas por los endpoints de la Open API de TF Fiscal.

Formas de respuesta

La API tiene dos formas de respuesta, y cuál recibe depende del endpoint y de la capa que produjo la respuesta.

Respuestas simples (endpoints estándar)

Todos los endpoints estándar (empresas, NF-e, CT-e, DC-e, verificación, consulta de registro, registro de webhook) responden sin sobre:

Grupo de endpointsForma de éxito
Registro de empresa, registro de webhookObjeto simple ({ "empresaId": ... }, { "webHookId": ... })
Vinculación de certificado, emisión y cancelación de NF-e / CT-e / DC-eHTTP 200 sin cuerpo; el resultado llega de forma asíncrona
Consulta de NF-e / CT-e / DC-e, registro de carta de corrección y de eventosObjeto simple: el documento, el protocolo o la lista de eventos
Verificación por XML, consulta por chaveObjeto simple: la factura interpretada (la verificación por XML añade el bloque validation)
Consulta de CNPJ, consulta de CPFObjeto simple: el registro

Los errores de negocio y de solicitud de los endpoints estándar vienen en dos formas de error, según la familia del endpoint.

Familia de emisión (empresas, NF-e, CT-e, DC-e, registro de webhook; HTTP 400 / 404): un array de errores, cada uno con codigo y mensagem. Los fallos de validación del cuerpo producen una entrada por campo:

json
[
{ "codigo": "NFe0001", "mensagem": "A Nota fiscal nao foi encontrada. Por favor, verifique se o id foi informado corretamente" }
]

codigo es una cadena: los tres códigos GW001 (ciudad / estado inválido), CER0005 (contraseña del certificado incorrecta) y NFe0001 (factura no encontrada) conservan sus valores alfanuméricos, igual que los códigos DCe* de la familia DC-e; todas las demás entradas llevan el código de error de la plataforma como cadena numérica.

Familias de verificación y consulta de registro (HTTP 400, y 422 / 428 / 451 / 503 en la consulta de registro): un objeto simple con code y message:

json
{ "code": 10015004, "message": "Invoice not found" }
CampoTipoDescripción
codeintegerCódigo de error de la plataforma
messagestringExplicación legible, localizada

Sobre de la plataforma

Lo usan el endpoint de echo (POST /openapi/demo/echo) en toda respuesta, el endpoint de descarga de archivos en sus fallos y el gateway de la plataforma para los errores de la capa de autenticación en cualquier endpoint (HTTP 401 / 403 / 429), producidos antes de que la solicitud llegue al endpoint:

json
{ "success": true, "message": "OK", "data": { } }
json
{ "success": false, "errorType": 1, "code": 10009003, "message": "Signature error" }
CampoTipoPresenciaDescripción
successbooleansiemprefalse en todo error
errorTypeintegeren errorClase del error, vea Tipificación de errores
codeintegeren errorCódigo de error de la plataforma, vea Códigos de error
messagestringsiempreExplicación legible, localizada
dataobject | nullen éxitoCarga del endpoint; no se rellena en errores

Manejar ambas formas

Su manejador de errores debe aceptar el sobre y las formas de error simples. Una regla robusta:

  1. Trate HTTP 400 o superior como fallo y, además, success: false cuando el cuerpo sea un sobre.
  2. Interprete el cuerpo como JSON. Si es un array, lea codigo de cada entrada; si es un objeto, lea code.
  3. Ramifique por el código, nunca por el texto de message / mensagem (están localizados).

Tipificación de errores (errorType)

Los errores en sobre llevan un campo errorType que clasifica el origen del fallo:

errorTypeClaseSignificado
1Error de APIRechazo de autenticación, autorización o de negocio por TF Fiscal
2Rechazo de la SEFAZLa autoridad fiscal brasileña rechazó la operación
3Fallo del sistemaFallo inesperado de la plataforma; es seguro reintentar con backoff
4Fallo de validaciónLa validación de los campos de la solicitud falló

Referencia rápida de estados HTTP

HTTPEscenarioForma del cuerpo
200Solicitud aceptada; en la verificación por XML esto incluye una validación fallida (revise el bloque validation)Datos simples, o sin cuerpo
400Solicitud inválida o regla de negocio violada[{codigo, mensagem}] (emisión) o {code, message} (verificación / consulta de registro)
404empresaId / id del documento no encontrado (familia de emisión)[{codigo, mensagem}]
401Fallo de autenticación (token / sign / timestamp), o enlace de descarga inválido o vencidoSobre de la plataforma
403Aplicación deshabilitada / no vigente / integrador deshabilitado / no suscritoSobre de la plataforma
422 / 428 / 451Consulta de CPF retenida por ley (titular de 16 a 17 años / edad no verificable / titular menor de 16); no reintente{code, message}, sin campos personales
429Límite de tasa excedidoSobre de la plataforma
503Fuente de datos upstream no disponible (consulta de registro, 10016020) o archivo aún no renderizado (descarga, 10009037); reintente tras Retry-After{code, message} o sobre de la plataforma
5xxFallo del lado de la plataformaReintente con backoff; si persiste, contacte a la plataforma con el timestamp y la ruta del fallo

Idempotencia

  • La emisión de NF-e es idempotente por el id de la solicitud que usted genera: reenviar el mismo id reutiliza la tarea original. Si el intento anterior fue denegado (Negada), reenviar el mismo id con los campos corregidos emite de nuevo con la nueva carga, sin necesidad de un nuevo id. Cambiar campos clave como el destinatario mientras el intento anterior sigue en proceso o ya fue autorizado se rechaza con codigo 10004032.
  • La emisión de CT-e y DC-e también es idempotente por id: un mensaje idéntico reutiliza la tarea original, un mensaje distinto bajo el mismo id se rechaza (10017030 para CT-e, 10019030 para DC-e), y un fallo terminal (Falha) reabre la tarea con el nuevo mensaje.
  • La verificación por XML es idempotente por la clave de acceso (chave): reenviar mientras una verificación está en curso devuelve el progreso actual, y los veredictos terminales se reutilizan durante 24 horas. Para forzar una nueva verificación, envíe la cabecera forceRevalidate: true en el endpoint de XML (la cabecera no forma parte de la firma). La consulta por chave es un GET fijo y no tiene canal de reverificación; para forzar una nueva verificación, reenvíe por el endpoint de XML. Un REJECTED del nivel 1 no tiene registro de nivel 2; la reverificación exige reenviar el XML.
  • Las entregas de webhook son idempotentes por event_id: cada reintento y cada destino de un mismo evento llevan el mismo valor, así que deduplique por él. Vea Webhooks.

Límite de tasa y backoff

  • Cuota por aplicación: excederla devuelve HTTP 429 con el código 10009006. Los límites se aplican por aplicación y por grupo de endpoints. Retroceda y reintente (empiece en 1 s, duplique hasta 30 s, añada jitter) y suavice su tasa de llamadas.
  • Anti-flood por CNPJ: si una empresa acumula demasiadas tareas de emisión pendientes, los nuevos envíos se rechazan con codigo 10004002 hasta que la cola se vacíe; reintente más tarde.
  • Ventana del timestamp: las solicitudes con timestamp fuera de ±300 s del reloj del servidor se rechazan (10009001), lo que también limita el replay de solicitudes capturadas.
  • 401 y 403 son errores de configuración; reintentarlos sin corregir solo consume cuota.
  • Las descargas de archivos cuentan contra el límite de la aplicación en su propio grupo y no se facturan.

Localización de las respuestas

Los campos message, mensagem y *Description siguen el idioma de la solicitud: la cabecera Language (zh / en / pt / es) tiene precedencia, luego Accept-Language (admite pt-BR y valores q). Sin cabecera de idioma, las respuestas usan por defecto portugués (pt). Las cabeceras de idioma no forman parte de la firma.

Las cargas de webhook solo llevan valores de enumeración independientes del idioma; no hay campos *Description en ellas. Para decisiones programáticas use siempre códigos y campos de enumeración (code, codigo, status, validationStatus, errors[].code, situacao.codigo), nunca texto descriptivo.

Horas y tipos de datos

  • Las horas producidas por la plataforma (dataCriacao, dataAutorizacao de los documentos emitidos, occurred_at de webhook, verifiedAt, serverTime del echo) son ISO-8601 UTC con el sufijo Z, en todos los entornos.
  • Las horas extraídas de un documento de terceros por la API de verificación (dataEmissao, dataAutorizacao) se devuelven tal cual, con el desfase horario del documento, por ejemplo 2026-07-23T11:20:05-03:00.
  • La cabecera timestamp de la solicitud es tiempo Unix en segundos, no milisegundos.
  • Los identificadores son cadenas aunque sean numéricos (empresaId, webHookId, event_id), para evitar pérdida de precisión numérica en JavaScript. Trate todos los ids como cadenas opacas; el id de documento que usted genera también es una cadena.
  • Los números de documento (numero) y las series (serie) son cadenas. Los importes y cantidades son números JSON.
  • Las variables de ruta como cnpj, cpf y chave son cadenas solo de dígitos sin caracteres de formato; la fecha de nacimiento del CPF (nascimento) es DDMMYYYY.

La clave de acceso de la NF-e (chave)

La chave de acesso es el identificador nacionalmente único de 44 dígitos de una NF-e. Aparece como chaveAcesso en las respuestas de consulta y verificación y como variable de ruta de la consulta por chave. Su estructura:

PosicionesLongitudCampoSignificado
1 a 22cUFCódigo IBGE del estado emisor (p. ej. 35 = SP)
3 a 64AAMMAño y mes de emisión (AAMM)
7 a 2014CNPJCNPJ del emisor
21 a 222modModelo del documento fiscal (55 = NF-e)
23 a 253serieSerie de la factura
26 a 349nNFNúmero de la factura
351tpEmisTipo de emisión
36 a 438cNFCódigo numérico aleatorio
441cDVDígito verificador (módulo 11)

Notas:

  • Almacene y transmita siempre la chave como una cadena de 44 caracteres (los ceros a la izquierda son significativos).
  • La consulta por chave valida longitud, caracteres y dígito verificador localmente antes de intentar cualquier consulta; una chave malformada devuelve HTTP 400 con el código 10015104.
  • Las claves de CT-e (modelo 57) y DC-e (modelo 99) comparten el mismo diseño de 44 dígitos con su propio valor de mod.

Enlaces de descarga de archivos

Los enlaces de descarga en las respuestas de consulta y en las cargas de callback (linkDanfe, linkDownloadXml, linkDacce y sus equivalentes de CT-e / DC-e) tienen la forma https://api.v2.tffiscal.com/openapi/files/{kind}/{ref}?token=.... No necesitan cabeceras de firma: basta un GET simple que siga la redirección 302. El token está vinculado a la ruta, al integrador y a la aplicación, así que use el enlace exactamente como se devolvió. Los enlaces son válidos 7 días por defecto y cada consulta emite enlaces nuevos; un enlace vencido devuelve 401 con 10009036. Detalles: Descarga de archivos.