Socios sin código fiscal
Para inscribirse en una asociación no hace falta un código fiscal italiano (codice fiscale). Lo que hace falta es que la persona esté identificada, y en Vimine lo está de una de estas dos formas:
- con un código fiscal, o
- con sus datos de nacimiento:
dob+birthplace+birth_country(ISO 3166-1 alpha-2).
Nunca sin ninguno de los dos. El resto de esta guía es lo que cambia, campo por campo, para una integración que inscribe a personas — estudiantes de intercambio, voluntarios recién llegados, socios que viven en el extranjero.
Identificar a una persona
Sección titulada «Identificar a una persona»POST /v1/enroll y POST /v1/signup aceptan los mismos campos:
| Campo | |
|---|---|
codicefiscale |
opcional. Cuando está presente, se valida y se coteja con el nombre, los apellidos, la fecha y el lugar de nacimiento |
dob |
fecha de nacimiento, YYYY-MM-DD |
birthplace |
el comune (el municipio) para quien nació en Italia; la ciudad, como texto libre, para quien nació en el extranjero |
birth_country |
país de nacimiento, dos letras (IT, FR, SN…) |
gender |
solo demográfico: ya no se coteja con el código |
// Sin código fiscal: fecha, lugar y país de nacimientoawait vimineServer.enroll({ email: 'marie.dupont@example.org', first_name: 'Marie', last_name: 'Dupont', dob: '1985-03-10', birthplace: 'Lyon', birth_country: 'FR', accept_statuto: { version: statuto.version, sha256: statuto.sha256 }});En /v1/enroll, sin código, cada dato de nacimiento que falte es un 422 validation_failed con una entrada en
errors[]:
{ "code": "validation_failed", "errors": [{ "field": "birth_country", "code": "required" }] }/v1/signup solo crea la cuenta: ahí los datos de nacimiento siguen siendo opcionales, y harán falta cuando la
persona solicite un carné.
Nacidos en el extranjero: envía birth_country
Sección titulada «Nacidos en el extranjero: envía birth_country»El código fiscal de una persona nacida en Italia contiene el comune de nacimiento; el de una persona nacida en el
extranjero contiene solo el país. Por eso, para estas personas el cotejo compara birth_country y trata
birthplace — la ciudad — como texto libre. Enviar birth_country es lo que permite que una persona nacida en el
extranjero con un código válido pase la comprobación: sin él, «Lyon» se buscaría entre los comuni italianos y el
código resultaría incoherente. (Un formulario que hasta ahora enviaba el nombre italiano del país como lugar de
nacimiento — birthplace: 'Francia' — sigue pasando; birth_country es la forma preferible.)
Lo mismo vale para la comprobación pública, que ahora dice también lo que contiene el código:
const r = await publicApi().validateFiscalCode({ code: 'DPNMRA85C50Z110U', first_name: 'Marie', last_name: 'Dupont', date: '1985-03-10', place: 'Lyon', country: 'FR'});// { valid: true, error: null, mismatches: [], hints: [], birth_date: '1985-03-10', birth_country: 'FR' }birth_date y birth_country se leen del propio código: puedes usarlos para rellenar el formulario de antemano. Este
endpoint sigue comparando gender, cuando lo envías; la inscripción y el perfil no.
Un código que no coincide, y la confirmación
Sección titulada «Un código que no coincide, y la confirmación»Un código mal escrito (estructura o carácter de control) es invalid_codicefiscale: hay que corregirlo, nunca se
puede confirmar. En cambio, un código bien formado que no coincide con los datos introducidos responde 422 con
una entrada más completa:
{ "code": "validation_failed", "errors": [{ "field": "codicefiscale", "code": "codicefiscale_mismatch", "mismatches": ["place"], "hints": [], "confirmable": true }]}mismatches— lo que no coincide:lastName,firstName,date,place;hints—names_swappedcuando el código coincide al intercambiar apellidos y nombre: ofrecer el intercambio suele bastar;confirmable— si la persona puede confirmar que ese es el código de su tarjeta sanitaria. Ocurre: comuni que ya no existen, transliteraciones, nombres registrados en otro orden.
Cuando confirmable es true, pregunta a la persona y repite la solicitud con codicefiscale_confirmed: true.
Cuando no coinciden ni el nombre, ni los apellidos, ni la fecha, ya nada vincula ese código con esa persona:
confirmable es false y la única salida es corregirlo.
import { VimineError } from '@vimine/sdk/server';
try { await vimineServer.enroll(input);} catch (err) { const entry = err instanceof VimineError && err.errors?.find((e) => e.code === 'codicefiscale_mismatch'); if (!entry) throw err; if (entry.confirmable && (await askThePerson(entry.mismatches, entry.hints))) { await vimineServer.enroll({ ...input, codicefiscale_confirmed: true }); }}No envíes codicefiscale_confirmed por iniciativa propia: es una declaración de la persona, y se registra como tal.
Añadir el código más tarde
Sección titulada «Añadir el código más tarde»Quien se inscribió sin código puede añadirlo cuando lo tenga, desde su propio perfil:
const me = await vimine.me.update({ codicefiscale: 'DPNMRA85C50Z110U' });me.codicefiscale_check; // 'matched'PATCH /v1/me acepta birth_country y codicefiscale_confirmed, que es solo de escritura; codicefiscale también
puede volver a ponerse a null. GET /v1/me dice cómo está identificada la persona:
codicefiscale_check |
|
|---|---|
matched |
un código fiscal que coincide con los datos de nacimiento de la persona |
mismatch_confirmed |
un código que no coincide, confirmado por la persona |
absent |
ningún código: la identifican la fecha, el lugar y el país de nacimiento |
null |
todavía no identificada: no puede solicitar un carné |
matched significa coherente, no verificado en el registro tributario: un código fiscal sigue siendo un dato
declarado.
identification_required
Sección titulada «identification_required»Una cuenta puede existir sin estar identificada — por ejemplo, alguien que se registró solo para iniciar sesión. Cuando esa persona solicita un carné, la API lo dice e indica lo que falta:
POST /v1/me/membership→422 identification_required, conerrors[]= los datos de nacimiento que faltan ({ field: 'birthplace', code: 'required' }…). Envía a la persona a completar su perfil conPATCH /v1/me(permisoprofile:write) y repite la solicitud.POST /v1/enroll/confirm— el enlace «confirma tu solicitud» que recibe el titular de una cuenta existente →409 identification_required, con el mismoerrors[]. Pide los datos de nacimiento en la página y vuelve a enviar el token conidentification:
await publicApi().confirmEnrollment(token, { dob: '1985-03-10', birthplace: 'Lyon', birth_country: 'FR' });// POST /v1/enroll/confirm { token, identification: { dob, birthplace, birth_country, codicefiscale?, codicefiscale_confirmed? } }Los datos de nacimiento viajan en el cuerpo de la petición, nunca en el enlace: en el enlace nunca hay nada
personal. identification solo completa los campos vacíos del perfil, no sobrescribe lo que ya hay; si los datos no
cuadran, la respuesta es un 422 validation_failed como el de arriba.
La admisión no cambia: los pending_reasons son los que diga el modelo de admisión de la asociación, para todo el
mundo (consulta Admisión y activación).
En la entrada: la comprobación de identidad
Sección titulada «En la entrada: la comprobación de identidad»Un código fiscal que coincide con los datos de nacimiento se puede contrastar con ellos; los datos de nacimiento
solos, o un código confirmado por la persona, no. Para estos socios, la asociación mira un documento una vez, la
primera vez que la persona se presenta. Quien integra un escáner lo ve en POST /v1/checkins (permiso
checkins:write), en las respuestas para un carné:
const r = await vimineServer.checkins.create('vmt_…');// { kind: 'card', verdict: 'valid', …, identity_check: 'pending' }if (r.identity_check === 'pending') show('Primera entrada: pide un documento');identity_check |
|
|---|---|
pending |
el socio no tiene un código fiscal comprobable y nadie de la asociación ha mirado todavía un documento: muéstralo a quien atiende la entrada |
verified |
alguien de la asociación ha mirado un documento |
flagged |
alguien lo ha mirado y no coincidía: se encarga la secretaría |
null |
nada que comprobar |
Es una nota, no forma parte de verdict y no restringe nada: un carné valid con
identity_check: 'pending' entra. El resultado se registra desde la consola de la asociación, no desde la API. La
verificación pública GET /v1/verify/{card_token} nunca la incluye: quien comprueba un carné desde fuera solo ve el
estado y la caducidad.
La dirección
Sección titulada «La dirección»Algunas asociaciones guardan la dirección de sus socios en su libro de socios, otras no. La decisión es de la asociación y vale para todos los socios o para ninguno; el perfil público la declara:
GET https://api.vimine.network/v1/aps/{slug}→ { "aps": { …, "member_address": "optional" } }member_address |
|
|---|---|
none |
no la pidas: un address enviado de todas formas no se guarda |
optional |
pídela, sin hacerla obligatoria |
required |
sin address, la inscripción responde 422 con { field: 'address', code: 'required' } |
await vimineServer.enroll({ …, address: { kind: 'residence', line: 'Via Roma 1', postal_code: '20121', city: 'Milano', province: 'MI', country: 'IT' }});line y city son obligatorios dentro de address; kind es residence (el valor por defecto) o domicile,
cuando difiere de la residencia; country es IT si se omite; province solo afecta a las direcciones italianas.
/v1/signup no tiene address: la dirección pertenece a la inscripción, no a la cuenta.
Una asociación no puede exigir el código
Sección titulada «Una asociación no puede exigir el código»No existe la opción «código fiscal obligatorio». Una asociación no puede exigir un código fiscal a todos los solicitantes: quien no lo tiene se identifica con sus datos de nacimiento, en todas partes. Si tu formulario lo hace obligatorio, es una decisión de tu formulario — y deja fuera a personas que la asociación podría acoger.
Qué ha cambiado (versión 2026-09-19)
Sección titulada «Qué ha cambiado (versión 2026-09-19)»Todo es aditivo: un formulario que siempre envía un código fiscal sigue funcionando sin cambios. Lo que una integración existente puede notar:
codicefiscaleya no es obligatorio enPOST /v1/enroll; sin código, hacen faltadob,birthplaceybirth_country(422requiredpor cada uno que falte);- nuevos campos opcionales
birth_country,codicefiscale_confirmed(enroll, signup,PATCH /v1/me) yaddress(enroll); genderya no se coteja con el código: ya no llega un422solo por el sexo;- un código que no coincide sigue respondiendo
codicefiscale_mismatch, ahora conhintsyconfirmablejunto amismatches; un código mal formado sigue siendoinvalid_codicefiscale; GET/PATCH /v1/metienen ahora un esquema declarado (Me), conbirth_countryycodicefiscale_check;- un error nuevo,
identification_required:422enPOST /v1/me/membership,409enPOST /v1/enroll/confirm(que aceptaidentificationen el cuerpo); POST /v1/validate/fiscal-codeaceptacountryy responde tambiénhints,birth_date,birth_country;erroresinvalid,mismatchonull;POST /v1/checkinsañadeidentity_checka las respuestas para un carné;GET /v1/verify/{card_token}sigue igual;- el perfil público añade
aps.member_address.