The Kreyo Blog
Engineering notes on Spanish fiscal compliance APIs.
How we built Kreyo's docs: Starlight, OpenAPI, and llms.txt
Docs as an acquisition channel. Why we moved from Scalar to Starlight, OpenAPI as single source of truth, and what llms.txt actually does.
FacturaE 3.2.2 from JSON: pitfalls of XAdES-EPES signing
What we learned implementing XAdES-EPES for FacturaE: policy URIs, certificate chains, canonicalization, and the bugs that cost us days.
Extracting Spanish invoices with LLMs: what the AEAT spec doesn't cover
Why OCR alone fails on Spanish invoices. How we combine Claude Vision with Tesseract for numeric verification, and the validation rules the spec assumes you know.
Building a B2B fiscal platform in 10 days: what we did and what we cut
The constraints, trade-offs, and technical decisions behind shipping Kreyo's four-product platform in under two weeks.
Designing a fiscal API: five principles we built Kreyo on
Idempotency, explicit errors, progressive disclosure, developer-first DX, and compliance as code. The design principles that shaped every endpoint.
Lifecycle of a Spanish invoice: how PDF, Extract, FacturaE and VeriFactu fit together
From draft to AEAT registration: the complete journey of a Spanish invoice through Kreyo's four products.
From hash to mTLS submission: anatomy of a VeriFactu record
Step by step: how Kreyo chains, signs, and submits a VeriFactu record to AEAT. SHA-256 field ordering, XMLDSig, mutual TLS, and retry logic.
Why Kreyo has no UI
API-first, not dashboard-first. Why we chose to build for developers who integrate, not administrators who click.
How we wrote a NIF/CIF/NIE validator in three languages (and why it's open source)
The algorithm, edge cases, and decision to open-source our fiscal identity validator. C#, TypeScript, and Python implementations compared.
Colaborador Social vs Componente: Why Your Customer Should Own Their Signing Certificate
The legal distinction between SIF component and representative. Why Kreyo signs with your customer's certificate, not ours.
XAdES is not VeriFactu (and VeriFactu is not XAdES)
The confusion between FacturaE's XAdES signing and VeriFactu's XMLDSig. Different specs, different signatures, different use cases.
VeriFactu hash chain explained: field order, SHA-256, and what happens when the chain breaks
How the cryptographic chain works: AEAT's field ordering spec, SHA-256 computation, chain position tracking, and recovery from breaks.