Eme2App connects to the Spanish Tax Agency (Agencia Estatal de Administración Tributaria, AEAT) via its VNifV2 SOAP web service to verify whether a NIF or CIF belongs to a registered taxpayer in the Spanish census. Every validation result is cached in Eme2App’s database, so repeat lookups for already-identified taxpayers are served instantly without a second SOAP call. The service supports individual NIF checks, approximate name searches across cached results, and batch operations that process up to 20,000 taxpayers in a single API request — all under the same JWT-authenticated context.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/eme2dev/Eme2App/llms.txt
Use this file to discover all available pages before exploring further.
Authentication and authorization
All AEAT endpoints are mounted under/api/aeat and require:
- A valid JWT bearer token in the
Authorizationheader. - The token must belong to an active empresa (company) context (
verificarEmpresaActiva). - Caller role must be
adminoruser.
AEAT digital certificate
AEAT’s VNifV2 service requires a valid Spanish digital certificate for mutual TLS authentication. Eme2App resolves the certificate through the following priority chain:Company-specific certificate (preferred)
Upload your empresa’s PFX or P12 certificate via
POST /api/empresa/certificado. Eme2App converts it to PEM internally and stores it encrypted against your empresa_id. Maximum file size is 5 MB.App-level fallback certificate
If no company certificate is found, Eme2App falls back to an application-level certificate stored in
config_sistema.aeat_cert_pem. This is managed by a superadmin and can serve as a shared fallback for all companies.Upload a certificate
Endpoints
GET /api/aeat/cache-check/:nif
Lightweight cache-only lookup. Returns immediately without calling AEAT.
GET /api/aeat/buscar-por-nombre/:q
Approximate name search across all cached validated NIFs.
POST /api/aeat/validar
Single NIF validation — checks cache first, calls AEAT on a cache miss.
POST /api/aeat/validar-masivo
Bulk NIF validation for up to 20,000 taxpayers per request.
GET /api/aeat/cache-check/:nif
Returns a cached result for a NIF without making any SOAP call to AEAT. Only succeeds if the NIF has been previously validated with resultIDENTIFICADO. DNI numbers submitted as 8 digits are auto-completed with the correct control letter before the cache lookup.
This endpoint is designed for high-frequency UI checks (e.g., autocomplete fields) where avoiding AEAT latency is important. It will return
estado: "no_encontrado" for any NIF that has never been validated or whose last result was not IDENTIFICADO — it does not mean the NIF is invalid, only that no cached positive result exists yet. Use POST /api/aeat/validar to perform an authoritative live check.GET /api/aeat/buscar-por-nombre/:q
Searches the local cache of validated NIFs by approximate company or person name. The query string:q must be at least 2 characters. Results are paginated.
| Query param | Type | Default | Description |
|---|---|---|---|
offset | integer | 0 | Number of records to skip |
limit | integer | 10 | Records per page (max 50) |
POST /api/aeat/validar
Validates a single NIF against the live AEAT VNifV2 SOAP service. Before making the SOAP call, Eme2App checks the local cache for an existingIDENTIFICADO result — if found, it is returned immediately without a network request. If the NIF is not cached, or its cached result is not IDENTIFICADO, a real SOAP request is made and a successful result is then written to the cache for future lookups.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
nif | string | ✅ Yes | The NIF/CIF to validate. Dashes, spaces, and lowercase are cleaned automatically. |
nombre | string | Conditional | Required for tipo_nif: 'F' (persona física) and 'N' (NIE). Optional for 'J' (jurídica/CIF). |
tipo_nif | 'F' | 'J' | 'N' | '' | No | NIF type. Auto-detected from the NIF format if omitted. |
pais_id | string | No | Country ID from /api/empresa/paises. Used to route between AEAT (national) and VIES (intra-EU, future). |
For persona física (DNIs) and NIE holders, the
nombre field is mandatory — AEAT requires it for matching in the census. For CIF (sociedades), the name is optional and AEAT can identify the entity by NIF alone.Example — validate a CIF
Example — validate a DNI (persona física)
Successful response
Suggestion response (fuzzy control-letter correction)
When Eme2App detects that the NIF’s control letter is incorrect but finds similar NIFs in the cache, it returns asugerencia state instead of making a potentially wrong SOAP call:
Error responses
| HTTP status | estado | Cause |
|---|---|---|
400 | error | Missing or malformed NIF; nombre missing for tipo F/N |
400 | error | NIF format invalid after normalization |
501 | error | pais_id resolves to an intra-EU territory (VIES not yet implemented) |
502 | error | AEAT connection error or 30-second timeout |
500 | error | No AEAT certificate configured (AEAT_CERT_MISSING) |
POST /api/aeat/validar-masivo
Validates a list of taxpayers against AEAT. Entries are processed sequentially to avoid overwhelming AEAT’s infrastructure. Each item in the response array maps one-to-one to the input array by position.Request body
| Field | Type | Required | Description |
|---|---|---|---|
contribuyentes | array | ✅ Yes | Array of taxpayer objects (1–20,000) |
contribuyentes[].nif | string | ✅ Yes | NIF/CIF to validate |
contribuyentes[].nombre | string | No | Name (required by AEAT for tipo F/N) |
Example
Response
error field and continue processing the rest of the list — the overall request does not abort.
NIF normalization and auto-correction
Eme2App applies several normalization steps before calling AEAT:Automatic NIF normalization rules
Automatic NIF normalization rules
- Whitespace and dashes are stripped; input is uppercased.
- 8-digit DNI (missing control letter): the correct letter is computed using the standard modulo-23 algorithm and appended.
- Short NIFs with 7–8 characters: leading zeros are padded to reach the expected 9-character length for DNI, NIE, and CIF formats.
- Wrong control letter: if Eme2App detects the letter is incorrect, it auto-corrects before the SOAP call and includes a
warningfield in the response so the calling UI can alert the user. - NIFs that cannot be normalized to exactly 9 characters are rejected with
HTTP 400.
Cache vs. live call — quick reference
| Endpoint | Reads cache | Writes cache | Calls AEAT SOAP |
|---|---|---|---|
GET /cache-check/:nif | ✅ | ❌ | ❌ |
GET /buscar-por-nombre/:q | ✅ | ❌ | ❌ |
POST /validar | ✅ (exact) | ✅ (on IDENTIFICADO) | Only on cache miss |
POST /validar-masivo | ✅ per entry | ✅ (on IDENTIFICADO) | Only on cache miss |