@brivio-ro/sdk
Official TypeScript/JavaScript SDK for the Brivio public
API — invoicing, contacts, articles, payments, e-Factura and the TrustFlow
eIDAS trust services (signatures, seals, validation, timestamps).
Install
npm install @brivio-ro/sdk
pnpm add @brivio-ro/sdk
Inside the Brivio monorepo the workspace package is named @brivio/sdk; the
published npm name is @brivio-ro/sdk (also mirrored unscoped as brivio-sdk).
Quick start
import { BrivioClient } from "@brivio-ro/sdk";
const brivio = new BrivioClient({ apiKey: "brivio_sk_live_…" });
const me = await brivio.me.get();
const { data: contacts } = await brivio.contacts.list({ search: "srl" });
const contact = await brivio.contacts.create({
name: "ACME SRL",
vat_number: "RO12345678",
});
const article = await brivio.articles.create({
name: "Consultanță",
price: 100,
vat_rate: 21,
});
const invoice = await brivio.invoices.create({
contact_id: contact.id,
series: "FAC",
issue_date: "2026-11-03",
due_date: "2026-11-17",
items: [
{ description: "Consultanță", quantity: 1, unit_price: 100, vat_rate: 21 },
],
});
await brivio.invoices.submitToEFactura(invoice.id);
const status = await brivio.invoices.efacturaStatus(invoice.id);
Available resources: me, contacts, articles, locations, modules,
invoices (CRUD + submitToEFactura), documents (CRUD), projects
(list/create), quotes (list/get), timeEntries (list/get), expenses
(list/create), contracts (list/create), payments
(charge), catalog (list), subscriptions (manage), webhooks
(CRUD + rotateSecret + deliveries), apiKeys (list/create/revoke),
trust (sign/validate/timestamp/providers).
Webhooks
Every list endpoint returns a { data, meta } page. For large datasets use the
built-in async iterator — it fetches subsequent pages automatically:
for await (const contact of brivio.paginate<Contact>("/contacts", {
search: "srl",
})) {
console.log(contact.name);
}
Resilience
Transient failures (429, 502-504, network errors) are retried automatically
(default: 2 retries, exponential backoff + jitter, honors Retry-After).
Each request has a 30-second timeout. Both are configurable:
const brivio = new BrivioClient({
apiKey: "brivio_sk_live_…",
maxRetries: 3,
timeoutMs: 10_000,
});
Webhooks
const hook = await brivio.webhooks.create({
url: "https://app.example/hooks/brivio",
events: ["invoice.paid", "contact.created"],
});
import { verifyWebhookSignature } from "@brivio-ro/sdk";
const ok = verifyWebhookSignature(
rawBody,
{
id: req.headers["webhook-id"],
timestamp: req.headers["webhook-timestamp"],
signature: req.headers["webhook-signature"],
},
hook.secret,
);
AI assistant
Talk to the Brivio assistant on behalf of the person behind the key (scopes
assistant:read / assistant:write; thread and proposal ids are integers):
const thread = await brivio.assistant.threads.create({ title: "Încasări" });
const run = await brivio.assistant.runs.create(thread.id, {
message: "Ce facturi am neîncasate?",
locale: "ro",
});
for await (const ev of brivio.assistant.runs.stream(thread.id, {
message: "Și pe luna trecută?",
})) {
if (ev.type === "text") process.stdout.write(ev.delta);
if (ev.type === "done") console.log(ev.run.status);
if (ev.type === "error") console.error(ev.code, ev.message);
}
const pending = await brivio.assistant.proposals.list();
await brivio.assistant.proposals.reject(pending[0].id);
Approvals never happen over the API. A run that wants to change data comes
back pending_approval; each of run.pending_approvals carries an
approve_url that opens the Approval Feed in the Brivio app, where a member
approves it. The SDK can only list and reject proposals. Run text is
AI-generated and unreviewed (ai_generated: true).
API surfaces
Two backends serve the API, both behind the same key:
- Gateway (
https://api.brivio.ro/v1, default) — core data resources:
me, contacts, articles, invoices, documents, projects,
expenses, contracts, locations, modules, webhooks.
- App (
https://app.brivio.ro/api/v1) — Stripe/KMS-bound resources that
must run in the app: payments, catalog, subscriptions.
Point those resources at the app surface by constructing a second client:
const billing = new BrivioClient({
apiKey: "brivio_sk_live_…",
baseUrl: "https://app.brivio.ro/api/v1",
});
await billing.payments.charge({
amount: 1000,
currency: "RON",
order_id: "o1",
});
Authentication
Mint an API key in Developers → API keys:
brivio_sk_live_… # production
brivio_sk_test_… # sandbox
Migrating from a competitor?
For PHP, the brivio/sdk Composer
package ships drop-in shims for FGO, SmartBill, Oblio and Facturis. See the
migration guides.
Types
The SDK ships full TypeScript types generated from the OpenAPI spec
(trustflow-openapi.json). Bring your own fetch (Node 18+, edge, browsers).
License
MIT