SAFTCheck
← Blog
2026-05-11 · 6 min read

How to validate a SAF-T (PT) before submitting to AT

A pre-submission checklist: encoding, BOM, NIF, ATCUD, header dates, per-document date range, block totals, currency, and document status — what AT catches at intake and how to fix it before day 5.

Why pre-validate at all

The AT portal accepts your SAF-T file. Or rejects it with "ficheiro inválido". There is no middle ground and there is no useful feedback. If you submit on day 5 at 23:50 and the file bounces, you have ten minutes to find the bug and re-export from your ERP. That is the wrong time to discover that your invoice numbering reset, your NIF check-digit is wrong, or your encoding got mangled.

Pre-validation closes the gap. You upload the file to a validator that runs the same XSD plus the heuristics AT actually applies on intake — encoding, BOM, NIF Mod-11, ATCUD format, header dates, document totals, currency rates, document status consistency — and you see every issue with a line number before AT does.

What to validate, in order

  1. Encoding. The single most common silent rejection. AT requires Windows-1252; most ERPs export UTF-8. The XSD parser is fine with both, but AT's intake pipeline is not. See the encoding rule.
  2. BOM. If your ERP prepends a UTF-8 byte-order-mark before <?xml ?>, AT rejects. Same for UTF-16 BOMs.
  3. Schema. The XSD validates the structural shape: required elements, attribute types, enumeration values. This is what AT runs first. schema 1.04_01 is the current SAF-T (PT) version for monthly billing.
  4. NIF Mod-11. Every TaxRegistrationNumber and CustomerTaxID / SupplierTaxID needs a valid Portuguese check digit and an allowed prefix. See the NIF rule.
  5. ATCUD format. Eight uppercase alphanumerics, dash, sequence ≥ 1. Mandatory since 2023.
  6. Header dates. StartDate < EndDate, FiscalYear matches the year of StartDate, DateCreated >= EndDate, EndDate not in the future.
  7. Per-document date range. Every Invoice, Payment, WorkDocument, StockMovement date must fall inside the Header's reporting window.
  8. Block totals. SalesInvoices.NumberOfEntries matches the count of children; TotalDebit + TotalCredit matches the summed GrossTotals within 0.01 €.
  9. Currency. Foreign-currency documents need CurrencyCode + CurrencyAmount + ExchangeRate > 0. Missing rate is invisible to the XSD; AT rejects on intake.
  10. Document status. InvoiceStatus in {N, S, A, R, F}; InvoiceStatusDate >= InvoiceDate.

What pre-validation does NOT catch

Be honest with yourself: a validator can confirm the file is well-formed and consistent. It cannot guarantee that AT will accept it. The two things it cannot see:

  • Server-side AT business rules that change without notice. AT occasionally tightens intake rules without updating the public XSD. Schema-change monitors and community advisories help — but new rejection patterns sometimes emerge first in real submissions.
  • Account-level constraints. Submission window already used, taxpayer mid-suspension, certified-software registration mismatch — none of those are file-level issues; they are taxpayer-level.

For the first class, post-rejection feedback loops still matter. For the second, your accountant or AT support is the right channel.

Workflow for the day-5 deadline

  1. Export the monthly SAF-T from your ERP a day early — ideally day 3 of the next month.
  2. Run it through a pre-validator. Fix every error reported. If the encoding rule fires, run the auto-fix and re-validate.
  3. Re-export only when a structural issue is reported. Re-running pre-validation on the same broken file twice gets the same answer.
  4. Submit to AT once the validator returns clean. Save the PDF report as part of your submission folder.

Ready?

Upload your SAF-T XML and see what AT will reject — before you submit. Validate now →

Other posts

Usamos una cookie de sesión para iniciar sesión, una cookie de idioma para la preferencia lingüística y Tawk.to para el widget de chat en vivo (que establece sus propias cookies al abrir el chat). Google Analytics (GA4) se carga solo después de que aceptes, con anonimización de IP; sin rastreadores publicitarios. Consulta nuestra Política de Privacidad.