VimineServer
import { VimineServer } from '@vimine/sdk/server';const vimineServer = new VimineServer({ clientId: 'vmc_…', clientSecret: process.env.VIMINE_SECRET });Pour les systèmes propres à l’association : un client confidentiel qui s’authentifie avec client_credentials,
lit l’état des cartes et pilote sa sandbox. Node ≥ 18. Le secret ne doit jamais atteindre un navigateur.
| Option | Type | Par défaut | |
|---|---|---|---|
clientId |
string |
— | obligatoire |
clientSecret |
string |
— | obligatoire ; vms_… ou vms_test_… |
scopes |
Scope[] |
tous ceux enregistrés | un sous-ensemble à demander |
apiUrl |
string |
https://api.vimine.network |
|
fetch |
typeof fetch |
globalThis.fetch |
Méthodes
Section intitulée « Méthodes »Un jeton d’accès client (client_credentials, HTTP Basic), mis en cache jusqu’à 30 secondes avant son expiration
(1 heure) ; une seule requête même en cas d’appels concurrents.
request(path, init?)
Section intitulée « request(path, init?) »Un appel authentifié avec Authorization: Bearer ; JSON en entrée et en sortie ; erreurs sous forme de
VimineError. Un 401 (identifiants régénérés ou révoqués) est réessayé une fois avec un nouveau
jeton.
memberships.status(id)
Section intitulée « memberships.status(id) »État d’une adhésion de l’association, sans données personnelles (memberships:read) :
const s = await vimineServer.memberships.status('membership-uuid');// { id, status: 'active', verdict: 'valid', valid_until: '2027-03-31T22:59:59.000Z', membership_type: { cod: 'ORD' } }signup(input, opts?)
Section intitulée « signup(input, opts?) »Crée un compte Vimine pour une personne (identity:signup) : elle reçoit l’e-mail pour confirmer son adresse et
choisir un mot de passe. Répond toujours { status: 'accepted' } — que l’adresse ait déjà eu un compte ne vous est pas
révélé (son titulaire en est informé, par e-mail). opts.idempotencyKey (générée si elle est absente).
await vimineServer.signup({ email: 'mario.rossi@example.org', first_name: 'Mario', last_name: 'Rossi', phone: '+39 …' });enroll(input, opts?)
Section intitulée « enroll(input, opts?) »Envoie une demande d’adhésion pour une personne (enroll:write) : une nouvelle adresse obtient un compte et une
demande en attente ; le titulaire d’un compte existant reçoit plutôt un lien de confirmation (rien n’est écrit tant
qu’il ne l’utilise pas). accept_statuto (la version en vigueur) est obligatoire ; privacy_notice aussi quand
l’association publie une notice d’information à ses membres (association(slug).privacy_notice) : la personne la lit
sur votre site et vous passez la version affichée. Voir Intégrations serveur.
La personne est identifiée par codicefiscale ou par dob + birthplace + birth_country — jamais ni l’un ni
l’autre (422, une entrée required pour chaque donnée manquante). Un code en désaccord avec les données de naissance
est une entrée codicefiscale_mismatch dans err.errors, avec mismatches, hints et confirmable : quand
confirmable vaut true et que la personne confirme, répétez avec codicefiscale_confirmed: true. address
(MemberAddress) quand l’association recueille l’adresse de ses membres (aps.member_address). Voir
Membres sans code fiscal.
// avec un code fiscalawait vimineServer.enroll({ ...person, codicefiscale: 'RSSMRA80A01H501U', accept_statuto: { version: 3 }, privacy_notice: { version: 2 } }, { idempotencyKey: 'order-42' });// sans : date, lieu et pays de naissanceawait vimineServer.enroll({ ...person, dob: '1985-03-10', birthplace: 'Lyon', birth_country: 'FR', accept_statuto: { version: 3 }, privacy_notice: { version: 2 } });checkins.create(token)
Section intitulée « checkins.create(token) »Enregistre un passage à l’entrée à partir du jeton lu sur le QR (checkins:write). Une carte répond { kind: 'card', verdict, status, membership_id, valid_until, valid_from, identity_check, checked_in_at } — identity_check: 'pending' est une indication à afficher à la personne qui tient l’entrée, elle ne fait pas partie de verdict et ne restreint rien (guide) ; le QR d’une inscription à un événement répond { kind: 'registration', verdict, registration_id, event, first, membership_verdict, … } (voir Événements et inscriptions).
events.list(params?) · events.get(slug) — les événements publiés de l’association, y compris ceux réservés aux membres (n’importe quel jeton client).
registrations
Section intitulée « registrations »registrations.listForEvent(slug, { status?, limit?, cursor? }) |
les inscriptions d’un événement : identifiant, état, type, adhésion, entrée — sans données personnelles (registrations:read, formules avec listes via l’API) |
registrations.guest(slug, { email, first_name, last_name, registration_type, note? }, opts?) |
inscrit un invité sans compte à un événement public ; toujours { status: 'accepted' } ; Idempotency-Key générée (voir invités) |
memberships.list(params?)
Section intitulée « memberships.list(params?) »Les adhésions de l’association (memberships:read, formules avec listes) : { items: [{ id, status, verdict, membership_type, issued_at, valid_until, updated_at }], next_cursor } ; params : status, updated_since, limit, cursor.
sandbox.members() · sandbox.reset()
Section intitulée « sandbox.members() · sandbox.reset() »Clients de test seulement : les membres synthétiques de la sandbox et la réinitialisation
(nouveau mot de passe commun, renvoyé une fois). Un client de production reçoit 403.
Les endpoints publics, sans identifiants : voir publicApi.
Un exemple de middleware
Section intitulée « Un exemple de middleware »import express from 'express';import { VimineServer, VimineError } from '@vimine/sdk/server';
const vimineServer = new VimineServer({ clientId: process.env.VIMINE_CLIENT_ID, clientSecret: process.env.VIMINE_SECRET });const app = express();
app.get('/cards/:id/status', async (req, res) => { try { const { status, verdict, valid_until } = await vimineServer.memberships.status(req.params.id); res.json({ status, verdict, valid_until }); } catch (err) { if (err instanceof VimineError && err.code === 'not_found') return res.status(404).end(); throw err; }});