LIVE · CATENA D'AUDIT · UE
SISTEMA · 99,99% UPTIME
v 1.0 ↗ FATTO IN UE

@nexbasira/node

SDK TypeScript lato server. Copre ogni risorsa dell'API pubblica con richieste e risposte tipizzate, helper per la paginazione a cursore e un verificatore di firma dei webhook che gira in tempo costante.

Installazione

npm install @nexbasira/node

Richiede Node 18+. Supportati sia ESM che CommonJS.

Inizializzazione

import { NexBasira } from "@nexbasira/node";

const nb = new NexBasira({
  apiKey: process.env.NB_PUBLIC_KEY!,    // nb_pub_*
  apiSecret: process.env.NB_SECRET_KEY!, // nb_sec_*
  // baseURL: "https://app.nexbasira.com/api/v1/public", // default
  // timeout: 30_000,                                          // default
});

Risorse

Ogni risorsa dell'API pubblica ha un client tipizzato sull'istanza cvp:

nb.sessions       // create / list / retrieve / end / invite
nb.evidence       // list / retrieve / signed download URL
nb.whiteboards    // list per session
nb.webhooks       // register / rotate-secret / test-fire / constructEvent
nb.branding       // read-only
nb.org            // read-only

Pattern comuni

Crea + invita

const session = await nb.sessions.create({
  notes: "Vehicle damage claim CL-2026-0042",
  scheduled_for: "2026-05-23T10:00:00Z",
  locale: "fr",
});

const invite = await nb.sessions.invite(session.id, {
  recipient_email: "alex@policyholder.com",
  send_email: true,
});

console.log(invite.url); // shown ONCE

Paginazione con async-iterator

Gli endpoint di listing restituiscono un async iterator che pagina in modo trasparente. Basta con il "ricordati di passare cursor dalla risposta precedente":

for await (const session of nb.sessions.list({ limit: 50 })) {
  console.log(session.id, session.status);
}

// Or a single page if you want pagination control:
const page = await nb.sessions.listPage({ limit: 25 });
// page.data, page.has_more, page.next_cursor

POST idempotente

Passa un idempotencyKey per rendere una scrittura sicura in caso di retry:

const session = await nb.sessions.create(
  { notes: "..." },
  { idempotencyKey: crypto.randomUUID() },
);

Il backend memorizza in cache la risposta per (key, credential) per 24 ore. Un POST ripetuto con la stessa chiave restituisce la risposta originale senza ricreare la risorsa.

Verificare un webhook

import express from "express";
import { NexBasira, InvalidSignatureError } from "@nexbasira/node";

const app = express();
const nb = new NexBasira({ apiKey: "...", apiSecret: "..." });

// IMPORTANT: use express.raw() — constructEvent needs the untouched
// bytes the signature was computed over.
app.post("/nb-webhook", express.raw({ type: "application/json" }), (req, res) => {
  try {
    const event = nb.webhooks.constructEvent(
      req.body,
      req.header("NB-Signature")!,
      process.env.NB_WEBHOOK_SECRET!,
    );
    // event.type is type-narrowed; event.data is the resource shape
    switch (event.type) {
      case "session.completed":
        return onCompleted(event.data, res);
      case "audit.anchored":
        return onAnchored(event.data, res);
    }
    res.status(204).end();
  } catch (err) {
    if (err instanceof InvalidSignatureError) {
      return res.status(401).send("bad signature");
    }
    throw err;
  }
});

Errori tipizzati

L'SDK lancia una piccola gerarchia di errori tipizzati così puoi gestire deliberatamente ogni classe:

ClasseQuando
AuthenticationError401 — credenziali errate o chiave mancante
PermissionError403 — la credenziale non ha lo scope
NotFoundError404 — la risorsa non esiste o non è nella tua org
RateLimitError429 — throttle raggiunto. Ha retryAfterMs
InvalidSignatureErrorSolo da constructEvent() — firma errata / mancante / scaduta
NexBasiraErrorClasse base — intercetta questa per "qualsiasi errore dell'SDK"
try {
  await nb.sessions.create({ ... });
} catch (err) {
  if (err instanceof RateLimitError) {
    await sleep(err.retryAfterMs);
    return retry();
  }
  if (err instanceof NexBasiraError) {
    log.warn({ status: err.status, code: err.code }, "cvp error");
  }
  throw err;
}

Tipi OpenAPI

L'SDK include tipi di richiesta e risposta generati con openapi-typescript sotto @nexbasira/node/types. Importali direttamente se vuoi handler fortemente tipizzati a monte della chiamata all'SDK:

import type { Session, Evidence, WebhookEvent } from "@nexbasira/node/types";

function onSessionCompleted(session: Session) {
  // ...
}

Prossimi passi