@velixbiometrics/sdk-core
v0.1.9
Published
Official TypeScript/JavaScript SDK for VELIX Biometrics — facial access control platform
Downloads
1,434
Maintainers
Readme
@velixbiometrics/sdk-core — TypeScript/JavaScript SDK 
Publicado e confirmado funcionando de ponta a ponta contra a API real de staging (onboarding, LGPD, me, events, contexts/Identity Context, internal authorization). npm: https://www.npmjs.com/package/@velixbiometrics/sdk-core
ℹ️ Único gap de cobertura conhecido:
checkin.identify()é exercitado no smoke test (rota alcançável), mas ainda sem um teste que force um resultado de match real (matched: true/falsedeterminístico contra o mesmo rosto). Verdocs/todo/1233-sdk-checkin-smoke-test-hardening.mdno monorepo VELIX antes de depender dele em produção sem validação própria.
Official TypeScript/JavaScript SDK for the VELIX Biometrics platform — facial access control B2B SaaS.
Requirements
- Node.js 20+
- TypeScript 5+ (strict mode)
Installation
npm install @velixbiometrics/sdk-core
# or
yarn add @velixbiometrics/sdk-coreQuick Start
import { VelixClient, CheckinModule } from '@velixbiometrics/sdk-core'
const client = new VelixClient({
apiUrl: process.env.VELIX_API_URL!,
apiKey: process.env.VELIX_API_KEY!,
})
const result = await new CheckinModule(client).identify({ imageBase64: frameBase64 })
console.log(result.match) // true | falseEnvironment Variables
| Variable | Required | Description |
|----------|----------|-------------|
| VELIX_API_URL | Yes | API base URL (https://api.velixbiometrics.com) |
| VELIX_API_KEY | Yes | Tenant API key (vx_live_...) |
| VELIX_TIMEOUT | No | Request timeout in ms (default: 30000) |
Modules
| Module | Methods | Endpoint |
|--------|---------|----------|
| OnboardingModule | enroll() | POST /v1/api/onboarding |
| CheckinModule | identify() | POST /v1/api/checkin/identify |
| LgpdModule | requestDeletion() | POST /v1/api/deletion-request |
| MeModule | get() | GET /v1/api/me/:personId |
| EventsModule | createGuest(), getGuest() | POST/GET /v1/api/events/:id/guests |
| TimeModule | punch(), getEspelho() | não implementado — ver nota abaixo |
| client.contexts | create(), get(), list(), update(), remove(), authorize(), listAuthorizationDecisions(), createLinkRequest() | /v1/contexts/* |
| client.memberships | create(), listByContext(), listByIdentity(), updateStatus(), addRoles(), removeRoles() | /v1/contexts/:id/memberships, /v1/identities/:id/memberships, /v1/memberships/* |
| client.contextRoles | create(), list(), linkPermissions() | /v1/context-roles* |
| client.contextPermissions | create(), list() | /v1/context-permissions |
| client.authorizationTokens | validate() | POST /v1/authorization-tokens/validate |
| client.internalAuthorization | authorize() | POST /v1/internal/contexts/authorize |
Checkin Module
import { CheckinModule } from '@velixbiometrics/sdk-core'
const checkin = new CheckinModule(client)
// Facial identification (base64 JPEG frame)
const result = await checkin.identify({ imageBase64: frameBase64 })
// { match: true, subjectId: 'uuid', liveness: { ok: true }, model: '...', contexts: [...] }
// `contexts` lists the active Identity Context memberships of the matched
// person (e.g. Velix Pay) — no extra call needed to know which programs
// they're in. Use the context's own authorize endpoint for the actual
// authorization decision at transaction time.
if (result.match) {
const inVelixPay = result.contexts.some((c) => c.code === 'payment')
}
// With liveness challenge (token from GET /v1/public/checkin/{tenantSlug}/liveness/challenge)
const result2 = await checkin.identify({
imageBase64: frameBase64,
liveness: { token: challengeToken, samples: [{ action: 'center', imageBase64: frameBase64 }] },
})Onboarding Module
import { OnboardingModule } from '@velixbiometrics/sdk-core'
const onboarding = new OnboardingModule(client)
const result = await onboarding.enroll({
name: 'João Silva',
email: '[email protected]',
documentType: 'CPF',
document: '12345678900',
frames: [frame1, frame2, frame3],
})
// { personId: 'uuid', identityId: 'uuid', enrolled: true, framesProcessed: 3, ... }Me Module
import { MeModule } from '@velixbiometrics/sdk-core'
const me = new MeModule(client)
const person = await me.get('person-uuid')LGPD Module
import { LgpdModule } from '@velixbiometrics/sdk-core'
const lgpd = new LgpdModule(client)
const { protocolNumber } = await lgpd.requestDeletion({ personId: 'uuid' })Events Module (Velix Events — convidados)
import { EventsModule } from '@velixbiometrics/sdk-core'
const events = new EventsModule(client)
const guest = await events.createGuest('event-uuid', {
name: 'João Silva',
email: '[email protected]',
cpf: '12345678900',
})
const fetched = await events.getGuest('event-uuid', guest.id)Time Module
api-velix-time ainda não tem proxy público via api-velix-identity-core (gap de servidor, task #593). TimeModule.punch() e TimeModule.getEspelho() existem apenas para deixar isso explícito — sempre lançam VelixError, nunca simulam sucesso ou retornam dados falsos.
Identity Context
Contexts, roles, permissions, memberships, link-requests (consentimento cross-tenant) e authorization engine. Ver code/lib/lib-velix-contracts/openapi/public-api.yaml, tag Identity Context.
const context = await client.contexts.create({ name: 'Matriz SP', contextType: 'location' })
const decision = await client.contexts.authorize(context.id, {
identityId: 'identity-uuid',
permission: 'access:enter',
})
// { granted: true, token: 'vat_...', ... }
const membership = await client.memberships.create(context.id, {
identityId: 'identity-uuid',
roleIds: ['role-uuid'],
})
// saída de contexto (definitiva, sem carência)
await client.memberships.updateStatus(membership.id, { status: 'revoked' })
// vínculo cross-tenant — fica PENDING até a pessoa consentir via magic link
await client.contexts.createLinkRequest(context.id, { identityId: 'identity-uuid' })
await client.authorizationTokens.validate({ token: 'vat_...' })Internal Authorization (Velix Pay e integrações serviço-a-serviço)
Autorização automática (sem usuário humano logado) contra um contexto do Identity Context,
resolvida por contextCode + personId — diferente de client.contexts.authorize(), que exige
um contextId já conhecido e é autenticado por JWT de usuário. Este módulo usa a mesma apikey de
produto (x-api-key) já configurada no client.
// Fluxo genérico
const decision = await client.internalAuthorization.authorize({
tenantId: 'tenant-uuid',
contextCode: 'payment',
personId: 'person-uuid',
action: 'purchase',
confidence: 0.92,
})
// { authorized: true, reason: '...', contextId: '...', identityId: '...', ... }
// Fluxo de risk score (Velix Pay) — enviar similarityScore muda o formato da resposta
const risk = await client.internalAuthorization.authorize({
tenantId: 'tenant-uuid',
contextCode: 'payment',
personId: 'person-uuid',
action: 'purchase',
similarityScore: 0.87,
})
// { allowed: true } | { allowed: false, risk: 0.4 }Error Handling
import { VelixError, VelixApiError, VelixNetworkError } from '@velixbiometrics/sdk-core'
try {
const result = await checkin.identify({ imageBase64: frame })
} catch (err) {
if (err instanceof VelixApiError) console.error(`HTTP ${err.status}: ${err.message}`)
if (err instanceof VelixNetworkError) console.error('Network error:', err.cause)
if (err instanceof VelixError) console.error(err.message)
}Running Tests
npm test # all tests
npm test -- --coverage # with coverage
npm test -- --watch # watch modeTests use axios mocks — no running service required.
Local Development
npm install
npm run build # compile to dist/
npm run lint # eslint
# Link locally in another project
npm link
# In the consumer project:
npm link @velixbiometrics/sdk-coreGet an API Key
Access the dashboard at velixbiometrics.com → Settings → API Keys → New Key.
