Integraciones de servidor
Para los sistemas de la propia asociación — un programa de gestión, un torniquete, un plugin de CMS — un cliente
confidencial con client_id + client_secret. El secreto se muestra una sola vez y nunca debe llegar a un
navegador.
Autenticarse
Sección titulada «Autenticarse»import { VimineServer } from '@vimine/sdk/server';
const vimineServer = new VimineServer({ clientId: 'vmc_…', clientSecret: process.env.VIMINE_SECRET, scopes: ['memberships:read']});const token = await vimineServer.token(); // client_credentials — token de 1 hora, que se renueva soloSin el SDK: POST /v1/oauth/token con grant_type=client_credentials y HTTP Basic client_id:client_secret (o
client_id/client_secret en el cuerpo):
curl -u "vmc_…:vms_…" -d "grant_type=client_credentials&scope=memberships:read" \ https://api.vimine.network/v1/oauth/tokenEn los endpoints de lectura (/v1/memberships/{id}/status, /v1/memberships) también se acepta HTTP Basic
directamente, sin pasar por un token, para hardware y plataformas low-code — nunca desde un navegador.
Estado de un carné
Sección titulada «Estado de un carné»const s = await vimineServer.memberships.status('membership-uuid');// { id, status: 'active', verdict: 'valid', valid_until: '2027-…', membership_type: { cod: 'ORD' } }Sin datos personales: solo el estado y la validez. El id es el que el socio ve en su propio carné
(membership.id mediante Iniciar sesión con Vimine) o el que tu sistema recibió cuando lo registró.
Para verificar un carné mostrado en la entrada, usa en cambio el token del QR con
/v1/verify/{card_token}: no necesita ninguna autenticación.
Inscribir socios desde tu sistema
Sección titulada «Inscribir socios desde tu sistema»Con identity:signup y enroll:write, tu back office puede crear cuentas y enviar solicitudes de inscripción sin
que la persona pase por Vimine: recibe por correo el enlace para confirmar su dirección y elegir una contraseña.
// Solo la cuenta (la persona todavía no es socia)await vimineServer.signup({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi' });
// Cuenta + solicitud de inscripción pendiente, que la secretaría aprueba en el back office de Vimineconst { statuto, membership_types } = await vimineServer.public.association('your-slug');await vimineServer.enroll({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi', codicefiscale: 'RSSMRA80A01H501U', // opcional: sin él, hacen falta dob + birthplace + birth_country dob: '1980-01-01', birthplace: 'Roma', birth_country: 'IT', gender: 'M', // solo demográfico: no se coteja con el código membership_type: membership_types[0].uid, // opcional cuando hay exactamente un tipo accept_statuto: { version: statuto.version, sha256: statuto.sha256 }, privacy_notice: privacy_notice && { version: privacy_notice.version, sha256: privacy_notice.sha256 } // obligatorio cuando la asociación publica una});La respuesta es siempre 202 { status: 'accepted' }, haya lo que haya detrás de la dirección: no puedes saber si
un correo ya tiene una cuenta de Vimine (solo se le avisa a su titular, por correo). En concreto:
- dirección nueva → cuenta creada y, con
enroll, una solicitud de inscripción pendiente; correo de bienvenida con la confirmación de la dirección; - dirección ya registrada → con
enrollno se escribe nada: el titular recibe un enlace «confirma tu solicitud a <asociación>» válido 24 horas, y la solicitud solo se crea cuando lo usa. Si ya es socio, no pasa nada; - los errores
422se refieren solo a tu payload (validation_failedconerrors[].field,statuto_outdated,invalid_type);403 api_disabledcuando la asociación no acepta solicitudes;403 not_availabledurante la beta privada, mientras las cuentas solo se crean por invitación.
Una persona se identifica con un código fiscal o con su fecha, lugar y país de nacimiento (dob, birthplace,
birth_country) — nunca sin ninguno de los dos: sin código, cada dato de nacimiento que falte es una entrada
required en errors[]. Para una persona nacida en el extranjero envía siempre birth_country: su código solo
contiene el país. Un código que no coincide con los datos de nacimiento responde 422 con una entrada
codicefiscale_mismatch que lleva mismatches, hints y confirmable: cuando confirmable es true, la persona
puede confirmarlo, y repites la llamada con codicefiscale_confirmed: true. Cuando la asociación recoge la dirección
de sus socios (aps.member_address en el perfil público), añade address. Cuando recoge los datos de quien ejerce la
responsabilidad parental (aps.collects_guardian_data) y la persona es menor según dob, guardian es obligatorio —
first_name, last_name, relation y, opcionalmente, codicefiscale, email, phone —; si no, 422 con
guardian: required. El recorrido completo está en Socios sin código fiscal.
accept_statuto debe nombrar el estatuto en vigor: muéstraselo a la persona en tu sitio (está en
association(slug); el texto y el documento, en GET /v1/aps/{slug}/statuto) y pasa la versión
que ha aceptado. Una asociación que no ha registrado ningún estatuto legible responde accepting_requests: false, y
la solicitud 403 not_available. Lo mismo vale para la política de privacidad de la asociación para sus socios
(privacy_notice en association(slug), el texto en GET /v1/aps/{slug}/privacy-notice): cuando la asociación
publica una, la solicitud debe nombrar la versión que la persona ha leído; si no, 422 (privacy_notice ausente o
privacy_notice_outdated); el acuse de recibo se registra a nombre de la persona, con tu cliente indicado.
Opcionales, con la misma regla: accept_terms y acknowledge_privacy (las condiciones de la cuenta y la política de
privacidad de la plataforma, GET /v1/legal/{kind}) cuando la persona las ha aceptado en tu sitio. Las llamadas son
idempotentes: el SDK genera una Idempotency-Key por llamada, o pasa la tuya ({ idempotencyKey: 'order-42' })
para repetir sin riesgos después de un timeout. Los correos tienen un límite (3 por dirección y día) y nunca se envían
desde el sandbox.
Check-in en la entrada
Sección titulada «Check-in en la entrada»Con checkins:write, un dispositivo en la entrada registra el paso de un socio enviando el token leído del QR del
carné (no un identificador): la respuesta es solo el veredicto, sin datos personales. Se acepta HTTP Basic
directamente, para hardware y plataformas low-code.
const r = await vimineServer.checkins.create('vmt_…'); // { verdict: 'valid' | 'expired' | 'not_yet_valid' | 'statuto_required' | 'inactive', status, membership_id, valid_until, identity_check, checked_in_at }curl -u "vmc_…:vms_…" -H "Content-Type: application/json" -d '{"token":"vmt_…"}' https://api.vimine.network/v1/checkinsEl cuerpo es { "token": "vmt_…" } — el token leído del QR, de un carné o de una inscripción a un evento; solo para
los carnés, card se acepta como alias.
Un token mal formado o falsificado es un 422 invalid_card; un carné de otra asociación es «no encontrado».
identity_check: 'pending' es una nota para quien atiende la entrada: el socio no tiene un código fiscal comprobable
y nadie de la asociación ha mirado todavía un documento. Muéstrala; no forma parte de verdict y no restringe nada
(consulta la comprobación de identidad).
Listar las inscripciones (planes Pro y Network)
Sección titulada «Listar las inscripciones (planes Pro y Network)»vimineServer.memberships.list({ status?, updated_since?, limit?, cursor? }) devuelve ids, estados y fechas —
nunca datos personales — por páginas (next_cursor). Con updated_since sincronizas solo lo que ha cambiado. En
los planes que no lo incluyen, la respuesta es 403 plan_limit.
Rotación del secreto
Sección titulada «Rotación del secreto»Desde la consola (Regenerar secreto): el secreto nuevo se muestra una sola vez y el anterior sigue funcionando durante 24 horas, para que puedas actualizar tus sistemas sin interrupciones. Si sospechas que está comprometido, revoca el cliente: todas sus sesiones terminan de inmediato.
Seguridad
Sección titulada «Seguridad»- Un secreto erróneo, repetido, bloquea el cliente durante 15 minutos.
- Cada token está vinculado a la asociación del cliente: un carné de otra asociación es simplemente «no encontrado».
- El SDK repite una vez, con un token nuevo, un
401recibido con credenciales recién regeneradas. - Las respuestas usan
application/problem+json(consulta Permisos, errores y límites).