Live
Black Hat USADark ReadingBlack Hat AsiaAI Business2 New Orleans city attorneys resign after ChatGPT was used to help prepare federal court filing - WWLTV.comGoogle News: ChatGPTI Brute-Forced 2 Million Hashes to Get a Shiny Legendary Cat in My Terminal. It Has Max SNARK and a Propeller Hat.DEV CommunityHave to do enough for my talk, "Is AI Getting Reports Wrong? Try Google LookML, Your Data Dictionary!" at Google NEXT 2026DEV CommunityOpenAI Foundation: $1 Billion Investment To Scale AI-Driven Philanthropy Across Health, Jobs, And Safety - Pulse 2.0GNews AI AGITaming the Ingredient Sourcing Nightmare with AI AutomationDEV Community# 🚀 How to Build a High-Performance Landing Page with Next.js 15 and Tailwind v4DEV CommunityPrediction: Nvidia's Vera Rubin Platform Will Create at Least 2 New Artificial Intelligence (AI) Millionaire-Maker Stocks by the End of 2026 - The Motley FoolGoogle News: AIClaude Code Architecture Explained: Agent Loop, Tool System, and Permission Model (Rust Rewrite Analysis)DEV CommunityMarietta high school student designs AI software to streamline employee scheduling - CBS NewsGoogle News: AIThe Data Structure That's Okay With Being WrongDEV CommunityHow to Auto-Index Your URLs with Google Search Console APIDEV CommunityThe Indestructible FutureLessWrong AIBlack Hat USADark ReadingBlack Hat AsiaAI Business2 New Orleans city attorneys resign after ChatGPT was used to help prepare federal court filing - WWLTV.comGoogle News: ChatGPTI Brute-Forced 2 Million Hashes to Get a Shiny Legendary Cat in My Terminal. It Has Max SNARK and a Propeller Hat.DEV CommunityHave to do enough for my talk, "Is AI Getting Reports Wrong? Try Google LookML, Your Data Dictionary!" at Google NEXT 2026DEV CommunityOpenAI Foundation: $1 Billion Investment To Scale AI-Driven Philanthropy Across Health, Jobs, And Safety - Pulse 2.0GNews AI AGITaming the Ingredient Sourcing Nightmare with AI AutomationDEV Community# 🚀 How to Build a High-Performance Landing Page with Next.js 15 and Tailwind v4DEV CommunityPrediction: Nvidia's Vera Rubin Platform Will Create at Least 2 New Artificial Intelligence (AI) Millionaire-Maker Stocks by the End of 2026 - The Motley FoolGoogle News: AIClaude Code Architecture Explained: Agent Loop, Tool System, and Permission Model (Rust Rewrite Analysis)DEV CommunityMarietta high school student designs AI software to streamline employee scheduling - CBS NewsGoogle News: AIThe Data Structure That's Okay With Being WrongDEV CommunityHow to Auto-Index Your URLs with Google Search Console APIDEV CommunityThe Indestructible FutureLessWrong AI

Why We Built an API for Spanish Fiscal ID Validation Instead of Just Implementing It

DEV Communityby A. Garrido BuildsApril 1, 20265 min read0 views
Source Quiz

<p>A few months ago I was integrating fiscal identifier validation into a project. I googled it, found a 30-line JavaScript function, copied it, tested it with four cases, and it worked. I dropped it into the codebase and forgot about it.</p> <p>Three months later, a user emailed us: their CIF wasn't validating. It was a perfectly valid CIF.</p> <p>That's when I understood there's a difference between <strong>implementing</strong> validation and <strong>maintaining it correctly</strong>.</p> <h2> The problem isn't that it's hard </h2> <p>Validating a NIF seems straightforward: 8 digits, one letter, modulo 23. Any developer can implement it in ten minutes.</p> <p>The problems appear when you scratch the surface:</p> <p><strong>NIF:</strong> the basic algorithm works, but there are special f

A few months ago I was integrating fiscal identifier validation into a project. I googled it, found a 30-line JavaScript function, copied it, tested it with four cases, and it worked. I dropped it into the codebase and forgot about it.

Three months later, a user emailed us: their CIF wasn't validating. It was a perfectly valid CIF.

That's when I understood there's a difference between implementing validation and maintaining it correctly.

The problem isn't that it's hard

Validating a NIF seems straightforward: 8 digits, one letter, modulo 23. Any developer can implement it in ten minutes.

The problems appear when you scratch the surface:

NIF: the basic algorithm works, but there are special formats — K, L and M NIFs for specific cases — that most implementations simply ignore.

NIE: starts with X, Y or Z, then follows the NIF algorithm with substitution. Most regex you'll find online accept 7 or 8 digits interchangeably, when the correct format depends on the prefix.

CIF: this is where almost everything breaks. The control character can be a letter or a digit depending on the entity type (first letter of the CIF). Most implementations accept either for all types — which is incorrect. Additionally, when (10 - sum % 10) % 10 === 0, the control character should be J in certain cases — an edge case that produces silent bugs that are extremely hard to track down.

IBAN: the MOD-97 algorithm requires arithmetic with very large numbers. In JavaScript you need BigInt, and in environments where it's unavailable or poorly implemented, it fails without a visible error.

None of these bugs surface in development. They surface in production, with real identifiers from real users.

The silent bug is the worst kind of bug

When a validation fails visibly — throws an exception, returns an error — you catch it and fix it. The real problem with fiscal validation bugs is that they accept invalid identifiers without warning.

A user enters a CIF with an incorrect control digit. Your code says "valid". The data goes into the database. Months later, when you try to use that data for a fiscal operation, the problem surfaces — but now you have no idea where it came from.

The maintenance nobody budgets for

Even if you implement everything correctly today, there's another problem: the rules can change.

Spain has updated fiscal identifier formats in the past. NIE formats have evolved. When that happens, someone has to update the code — and that someone might not be the person who wrote it, or be on the same team, or remember why each decision was made.

With an API, that's the API maintainer's problem. You consume the endpoint, they keep the algorithms up to date.

What we built

We built Valix — a REST API that validates NIF, NIE, CIF and IBAN using the official Spanish algorithms, with automatic type detection and a structured JSON response.

import requests

response = requests.post( "https://api.getvalix.io/v1/validate/trial", json={ "items": [ {"value": "12345678Z", "type": "AUTO"}, {"value": "X1234567L", "type": "AUTO"}, {"value": "A12345674", "type": "AUTO"}, {"value": "ES9121000418450200051332", "type": "AUTO"} ] } )

result = response.json() for item in result["results"]: status = "valid" if item["valid"] else f"invalid: {', '.join(item['errors'])}" print(f"{item['value']} → {item['detected_type']} — {status}")`

Enter fullscreen mode

Exit fullscreen mode

Output:

12345678Z → NIF — valid X1234567L → NIE — valid A12345674 → CIF — valid ES9121000418450200051332 → IBAN — valid

Enter fullscreen mode

Exit fullscreen mode

The trial endpoint requires no registration or API key — 50 validations per day per IP so you can test it before committing to anything.

When does it make sense to implement it yourself?

Being honest: if your validation volume is very low, you're always validating the same identifier type, and you have exhaustive tests with real-world cases, implementing it internally can make sense.

But if you're validating identifiers from production users, mixing types (NIF + NIE + CIF + IBAN), or simply don't want to spend time maintaining this — an API is the more sensible choice.

Resources

  • API and documentation: getvalix.io

  • Code examples in Python, JavaScript, PHP and cURL: github.com/getvalix/valix-examples

  • JavaScript/TypeScript SDK: npm @valix/sdk

Disclaimer: I'm the author of Valix.

Was this article helpful?

Sign in to highlight and annotate this article

AI
Ask AI about this article
Powered by AI News Hub · full article context loaded
Ready

Conversation starters

Ask anything about this article…

Daily AI Digest

Get the top 5 AI stories delivered to your inbox every morning.

More about

availableupdateproduct

Knowledge Map

Knowledge Map
TopicsEntitiesSource
Why We Buil…availableupdateproductgithubDEV Communi…

Connected Articles — Knowledge Graph

This article is connected to other articles through shared AI topics and tags.

Knowledge Graph100 articles · 164 connections
Scroll to zoom · drag to pan · click to open

Discussion

Sign in to join the discussion

No comments yet — be the first to share your thoughts!

More in Releases

缓存架构深度指南:如何设计高性能缓存系统
ReleasesFresh

缓存架构深度指南:如何设计高性能缓存系统

<h1> 缓存架构深度指南:如何设计高性能缓存系统 </h1> <blockquote> <p>在现代分布式系统中,缓存是提升系统性能的核心组件。本文将深入探讨缓存架构的设计原则、策略与实战技巧。</p> </blockquote> <h2> 为什么要使用缓存? </h2> <p>在软件系统中,缓存的本质是<strong>用空间换时间</strong>。通过将频繁访问的数据存储在高速存储介质中,减少对慢速数据源的访问次数,从而显著提升系统响应速度。</p> <p>典型场景:</p> <ul> <li>数据库查询结果缓存</li> <li>API响应缓存</li> <li>会话状态缓存</li> <li>计算结果缓存</li> </ul> <h2> 缓存架构设计原则 </h2> <h3> 1. 缓存层级策略 </h3> <p>现代系统通常采用多级缓存架构:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>┌─────────────────────────────────────────────┐ │ CDN (边缘缓存) │ ├─────────────────────────────────────────────┤ │ Redis/Memcached │ ├─────────────────────────────────────────────┤ │ 本地缓存 │ ├─────────────────────────────────────────────┤ │ 数据库 │ └─────────────────────────────────────────────┘ </code></pre> </div> <p><strong>原则<