Integrazioni server
Per i sistemi dell’associazione stessa — gestionale, tornello, plugin del CMS — un client riservato
con client_id + client_secret. Il secret è mostrato una sola volta e non deve mai raggiungere un browser.
Autenticarsi
Sezione intitolata “Autenticarsi”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 di 1 ora, rinnovato da soloSenza SDK: POST /v1/oauth/token con grant_type=client_credentials e HTTP Basic client_id:client_secret
(o client_id/client_secret nel corpo):
curl -u "vmc_…:vms_…" -d "grant_type=client_credentials&scope=memberships:read" \ https://api.vimine.network/v1/oauth/tokenSugli endpoint di lettura (/v1/memberships/{id}/status, /v1/memberships) è accettato anche HTTP Basic
direttamente, senza passare dal token, per hardware e piattaforme low-code — mai da un browser.
Stato di una tessera
Sezione intitolata “Stato di una tessera”const s = await vimineServer.memberships.status('uuid-della-tessera');// { id, status: 'active', verdict: 'valid', valid_until: '2027-…', membership_type: { cod: 'ORD' } }Nessun dato personale: solo stato e validità. L’id è quello che il socio vede nella propria tessera
(membership.id via Accedi con Vimine) o che il tuo sistema ha ricevuto quando l’ha registrata.
Per verificare una tessera mostrata allo scanner usa invece il token del QR con
/v1/verify/{card_token}: non serve nemmeno autenticarsi.
Registrare soci dal tuo sistema
Sezione intitolata “Registrare soci dal tuo sistema”Con identity:signup e enroll:write il tuo gestionale può creare account e inviare richieste di tesseramento
senza che la persona passi da Vimine: riceverà per e-mail il link per confermare l’indirizzo e scegliere la
password.
// Solo l'account (la persona non è ancora socia)await vimineServer.signup({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi' });
// Account + richiesta di tessera in attesa, che la segreteria approva dal gestionale Vimineconst { statuto, membership_types } = await vimineServer.public.association('tuo-slug');await vimineServer.enroll({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi', codicefiscale: 'RSSMRA80A01H501U', // facoltativo: senza, servono dob + birthplace + birth_country dob: '1980-01-01', birthplace: 'Roma', birth_country: 'IT', gender: 'M', // solo statistico: non viene confrontato con il codice membership_type: membership_types[0].uid, // facoltativo se il tipo è uno solo accept_statuto: { version: statuto.version, sha256: statuto.sha256 }, privacy_notice: privacy_notice && { version: privacy_notice.version, sha256: privacy_notice.sha256 } // obbligatorio se l'associazione ne pubblica una});La risposta è sempre 202 { status: 'accepted' }, qualunque cosa ci sia dietro l’indirizzo: non puoi sapere
se un’e-mail ha già un account Vimine (lo sa solo il suo titolare, per posta). In particolare:
- indirizzo nuovo → account creato e, con
enroll, richiesta di tessera in attesa; mail di benvenuto con la conferma dell’indirizzo; - indirizzo già registrato → con
enrollnon viene scritto nulla: il titolare riceve un link «conferma la richiesta a <associazione>» valido 24 ore, e la richiesta nasce solo quando lo usa. Se è già socio, non succede niente; - errori
422riguardano solo il tuo payload (validation_failedconerrors[].field,statuto_outdated,invalid_type);403 api_disabledse l’associazione non accetta richieste;403 not_availabledurante la beta privata, quando gli account nascono solo su invito.
Una persona si identifica con il codice fiscale oppure con data, luogo e Stato di nascita (dob, birthplace,
birth_country) — mai nessuno dei due: senza codice, ogni dato mancante è una voce required in errors[]. Per chi
è nato all’estero invia sempre birth_country: il suo codice contiene solo lo Stato. Un codice che non concorda con
i dati risponde 422 con una voce codicefiscale_mismatch che porta mismatches, hints e confirmable: quando
confirmable è true la persona può confermarlo, e tu ripeti la chiamata con codicefiscale_confirmed: true. Se
l’associazione raccoglie l’indirizzo dei soci (aps.member_address nel profilo pubblico) aggiungi address. Se
raccoglie i dati di chi esercita la responsabilità genitoriale (aps.collects_guardian_data) e la persona è minorenne
per dob, guardian è obbligatorio — first_name, last_name, relation, e facoltativi codicefiscale, email,
phone — altrimenti 422 con guardian: required. Tutto il percorso è in
Soci senza codice fiscale.
accept_statuto deve indicare lo statuto in vigore: mostralo alla persona sul tuo sito (lo trovi in
association(slug); il testo e il documento in GET /v1/aps/{slug}/statuto) e passa la versione che
ha accettato. Un’associazione che non ha registrato uno statuto leggibile risponde accepting_requests: false e la
richiesta 403 not_available. Lo stesso vale per l’informativa privacy
ai soci (privacy_notice in association(slug), il testo in GET /v1/aps/{slug}/privacy-notice): quando
l’associazione ne pubblica una la richiesta deve indicarne la versione letta, altrimenti 422 (privacy_notice
mancante o privacy_notice_outdated); la presa visione viene registrata a nome della persona, con il tuo client
indicato. Facoltativi ma con la stessa regola: accept_terms e acknowledge_privacy (le condizioni dell’account e
l’informativa della piattaforma, GET /v1/legal/{kind}), se la persona le ha accettate sul tuo sito. Le chiamate sono idempotenti: l’SDK
genera una Idempotency-Key per ogni chiamata, oppure passane una tua ({ idempotencyKey: 'ordine-42' }) per
ripetere in sicurezza dopo un timeout. Le mail sono contingentate (3 al giorno per indirizzo) e mai inviate dalla
sandbox.
Accessi da tornello o scanner
Sezione intitolata “Accessi da tornello o scanner”Con checkins:write un dispositivo agli ingressi registra il passaggio di un socio inviando il token letto dal
QR della tessera (non un identificativo): la risposta è solo il verdetto, senza dati personali. HTTP Basic è
accettato direttamente, per hardware e piattaforme 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/checkinsIl corpo è { "token": "vmt_…" } — il token letto dal QR, di una tessera o dell’iscrizione a un evento; per le sole tessere card è accettato come sinonimo.
Un token malformato o contraffatto è un 422 invalid_card; una tessera di un’altra associazione è «non trovata».
identity_check: 'pending' è una nota per chi è all’ingresso: il socio non ha un codice fiscale verificabile e nessuno
dell’associazione ha ancora visto un documento. Mostrala; non fa parte di verdict e non limita nulla (vedi
il controllo d’identità).
Elenco delle tessere (piani Pro e Network)
Sezione intitolata “Elenco delle tessere (piani Pro e Network)”vimineServer.memberships.list({ status?, updated_since?, limit?, cursor? }) restituisce identificativi, stato e date —
mai dati personali — a pagine (next_cursor). Con updated_since sincronizzi solo ciò che è cambiato. Sui
piani che non lo includono la risposta è 403 plan_limit.
Rotazione del secret
Sezione intitolata “Rotazione del secret”Dalla console (Rigenera secret): il nuovo secret è mostrato una volta, il precedente continua a funzionare per 24 ore, così puoi aggiornare i tuoi sistemi senza interruzioni. Se sospetti una compromissione, revoca il client: tutte le sue sessioni terminano subito.
Sicurezza
Sezione intitolata “Sicurezza”- Un secret sbagliato più volte blocca il client per 15 minuti.
- Ogni token è legato all’associazione del client: una tessera di un’altra associazione è semplicemente «non trovata».
- Una risposta
401con credenziali appena ruotate viene ritentata una volta dall’SDK con un token nuovo. - Le risposte usano
application/problem+json(vedi Permessi, errori e limiti).