e-bon
e-bon.ro
TypeScript SDK

SDK overview

What the @e-bon/sdk TypeScript client is, how to install it, instantiate it with an API key or JWT, and the ten resource accessors it exposes.

SDK overview

@e-bon/sdk is the official TypeScript client for the e-bon REST API. It is the same library used internally by the e-bon Portal and is the recommended way to talk to api.e-bon.ro/docs from any TypeScript or modern JavaScript runtime (Node 22+, Deno, Bun, modern browsers). Real-time updates live in the standalone @e-bon/realtime package.

What the SDK gives you on top of raw fetch:

  • A typed EBonClient with one accessor per resource (devices, commands, receipts, …).
  • Automatic auth header handling — pass an API key or a JWT once and forget about it.
  • A real EBonApiError exception with status, code, details and retryAfter so you can branch on the error envelope without parsing JSON yourself.
  • A FiscalError exception for fiscal command failures, with a precomputed retryable flag.

The SDK is REST-only. For real-time updates (receipts, command results, device status, alerts), use the standalone @e-bon/realtime package instead — the two share @e-bon/types but have no other coupling.

The SDK is a thin, faithful mapping over the documented HTTP API. Everything it does is also possible with curl — see the API overview for the wire-level reference.

Install

pnpm add @e-bon/sdk

The package is also installable with npm install @e-bon/sdk or yarn add @e-bon/sdk. It has a single runtime dependency (@e-bon/types) and ships with TypeScript declarations.

The SDK uses native fetch. On Node it requires Node 22 or newer. There is no polyfill bundled — if you need to run on older Node, install a global fetch polyfill before importing the SDK.

Instantiate the client

EBonClient is the single entry point. It takes an EBonClientOptions object with one of two auth modes — never both at once.

With an API key (POS partners, server integrations)

import { EBonClient } from '@e-bon/sdk';

const client = new EBonClient({
  baseUrl: 'https://api.e-bon.ro',
  apiKey: 'ebon_live_<orgId>_<32-hex>',
});

The SDK sends the key as X-API-Key on every request. This is the mode you want for any unattended backend.

With a JWT (portal sessions, the mobile app)

import { EBonClient } from '@e-bon/sdk';

const client = new EBonClient({
  baseUrl: 'https://api.e-bon.ro',
  token: 'eyJ...',
});

The SDK sends the token as Authorization: Bearer <token>. After a refresh, push the new access token into the same client without re-creating it:

client.setToken('eyJ...new-access-token');

Configure other options

OptionTypeDefaultMeaning
baseUrlstring—Required. The API base URL (https://api.e-bon.ro in production).
apiKeystring—API key. Mutually exclusive with token.
tokenstring—JWT access token. Mutually exclusive with apiKey.
timeoutnumber30000Per-request timeout in milliseconds. Aborts via AbortController.

If you pass neither apiKey nor token, every request will fail with 401 UNAUTHORIZED. If baseUrl is missing the constructor throws synchronously.

Access resources

EBonClient exposes ten typed resource accessors. Each one wraps a slice of /api/v1/* and returns plain TypeScript objects backed by the types in @e-bon/types.

AccessorWrapsPurpose
client.devices/api/v1/devices/*Device CRUD, status, commands, receipts, alerts, header/footer, VAT, operator. → reference
client.commands/api/v1/commands/*Submit fiscal commands, list, poll a single command, cancel a pending one. → reference
client.receipts/api/v1/receipts/*Store and retrieve receipts. → reference
client.reports/api/v1/devices/{deviceId}/reports/*Live device reports — MF/EJ reads, X/Z/periodic prints, ANAF archive export. → reference
client.billing/api/v1/billing/*Stripe subscriptions, invoices and the customer-portal redirect. → reference
client.org/api/v1/org/*Organization profile, locations, notification settings. → reference
client.apiKeys/api/v1/org/api-keys/*Programmatic API-key management (Owners and Admins only). → reference
client.controllers/api/v1/controllers/*Connected E-BON controllers (mobile-app instances). → reference
client.users/api/v1/users/*Authenticated user profile, settings, password change. → reference
client.webhooks/api/v1/org/webhooks/*Webhook subscription management and delivery history. → reference

Every accessor is constructed once when you instantiate EBonClient; they are stable references you can safely store on a long-lived object.

Handle errors

Every HTTP call routes through the same handler and surfaces errors as one of two concrete classes:

  • EBonApiError — wraps any non-2xx HTTP response. Carries status, code (matches the HTTP error catalogue), message, details and, on 429, retryAfter (seconds).
  • FiscalError — surfaced when a fiscal command fails on the printer. Carries code (ErrorCode enum), message, retryable, commandId and deviceId.

The retryable flag on FiscalError is precomputed from the RETRYABLE_ERRORS set in @e-bon/types, so you can branch directly:

import { FiscalError, isRetryable } from '@e-bon/sdk';

try {
  await client.commands.send({ deviceId, type: 'print_receipt', payload });
} catch (err) {
  if (err instanceof FiscalError && err.retryable) {
    // Safe to re-send with the same Idempotency-Key
  } else {
    throw err;
  }
}

The full catalogue of error codes, the retry pattern and the EBonApiError shape live on the Errors page.

Subscribe to real-time events

Real-time delivery lives in the standalone @e-bon/realtime package — receipts being printed, command results, device-status changes and derived alerts all flow over its WebSocket channel. Install it alongside the SDK and reuse the same credentials:

import { RealtimeClient } from '@e-bon/realtime';

const realtime = new RealtimeClient('https://api.e-bon.ro', {
  apiKey: process.env.EBON_API_KEY!,
});

realtime.on('receipt.created', (data) => console.log('receipt', data.receiptId));
realtime.on('command.failed', (data) => console.error('failed', data.fiscalError));
realtime.close();

The full event catalogue, payload types and reconnect semantics are documented under Realtime › Events.

Where to next

  • Getting started — install, get an API key, instantiate the client and issue your first receipt.
  • Realtime overview — the standalone WebSocket client for live updates.
  • Errors — FiscalError, EBonApiError and the recommended retry pattern.
  • API overview — the wire-level REST reference the SDK is built on.
  • Receipts, Commands, Devices — per-resource HTTP references with request and response schemas.