Skip to content

TypeScript SDK

Official TypeScript/JavaScript SDK for thelawin.dev.

Requires Node.js 18+ or modern browser

Installation

Beta-Phase

Während der Beta sind die SDKs über GitHub verfügbar. npm-Veröffentlichung folgt mit dem stabilen Release.

bash
# Via GitHub
npm install github:steviee/thelawin-clients#path:typescript

# Oder in package.json
"dependencies": {
  "@thelawin/sdk": "github:steviee/thelawin-clients#path:typescript"
}

Quick Start

typescript
import { ThelawinClient } from '@thelawin/sdk'

const client = new ThelawinClient('env_sandbox_xxx')

const result = await client.invoice()
  .number('2026-001')
  .date('2026-01-15')
  .seller({ name: 'Acme GmbH', vatId: 'DE123456789', city: 'Berlin', country: 'DE' })
  .buyer({ name: 'Customer AG', city: 'München', country: 'DE' })
  .addItem({ description: 'Consulting Services', quantity: 8, unit: 'HUR', unitPrice: 150, vatRate: 19 })
  .template('minimal')
  .generate()

if (result.success) {
  await result.savePdf('./invoice.pdf')
  console.log(`Generated: ${result.filename}`)
} else {
  result.errors.forEach(e => console.error(`${e.path}: ${e.message}`))
}

Client Options

typescript
const client = new ThelawinClient('env_sandbox_xxx', {
  baseUrl: 'https://api.thelawin.dev',  // optional
  timeout: 30000                         // optional, ms
})

Builder API

Invoice Details

typescript
client.invoice()
  .number('2026-001')           // Required
  .date('2026-01-15')           // Required, string or Date
  .dueDate('2026-02-15')        // Optional
  .currency('EUR')              // Default: 'EUR'

Parties

typescript
.seller({
  name: 'Acme GmbH',           // Required
  vatId: 'DE123456789',        // Required
  street: 'Hauptstraße 1',
  city: 'Berlin',              // Required
  postalCode: '10115',
  country: 'DE'                // Required
})
.buyer({
  name: 'Customer AG',         // Required
  vatId: 'DE987654321',
  city: 'München',             // Required
  country: 'DE'                // Required
})

Line Items

typescript
.addItem({
  description: 'Consulting',   // Required
  quantity: 8,                 // Required
  unit: 'HUR',                 // Required
  unitPrice: 150.00,           // Required
  vatRate: 19.0                // Required
})
// Add multiple items
.addItem({ description: 'Support', quantity: 2, unit: 'HUR', unitPrice: 100, vatRate: 19 })

Customization

typescript
.template('minimal')           // 'minimal' | 'classic' | 'compact'
.locale('de')                  // 'en' | 'de' | 'fr' | 'es' | 'it'
.accentColor('#8b5cf6')
.footerText('Thank you!')
typescript
// Node.js: from file (auto Base64)
.logoFile('./logo.png')
.logoFile('./logo.png', 30)    // with width in mm

// Browser: from URL
await builder.logoFromUrl('/logo.png')

// Both: from Base64
.logoBase64('iVBORw0KGgo...', 30)

Result Handling

typescript
const result = await builder.generate()

if (result.success) {
  // Success
  console.log(result.filename)      // 'invoice-2026-001.pdf'
  console.log(result.validation)    // { status: 'valid', profile: 'EN16931' }

  // Save (Node.js)
  await result.savePdf('./invoice.pdf')

  // Get bytes
  const bytes = result.toBytes()

  // Get data URL (browser)
  const dataUrl = result.toDataUrl()

  // Download (browser)
  result.downloadPdf()
  result.openInNewTab()
} else {
  // Failure
  result.errors.forEach(error => {
    console.error(`${error.path}: ${error.message}`)
  })
}

Error Handling

typescript
import { ThelawinApiError, ThelawinNetworkError, ThelawinQuotaExceededError } from '@thelawin/sdk'

try {
  const result = await client.invoice().generate()
} catch (error) {
  if (error instanceof ThelawinQuotaExceededError) {
    console.log('Quota exceeded, upgrade your plan')
  } else if (error instanceof ThelawinNetworkError) {
    console.log('Network error, retry later')
  } else if (error instanceof ThelawinApiError) {
    console.log(`API error: ${error.message}`)
  }
}

TypeScript Types

typescript
import type {
  InvoiceResult,
  InvoiceSuccess,
  InvoiceFailure,
  ValidationError,
  Party,
  LineItem
} from '@thelawin/sdk'

Browser Usage

typescript
// ESM import
import { ThelawinClient } from '@thelawin/sdk'

// UMD (script tag)
const { ThelawinClient } = window.Thelawin

Source Code

github.com/steviee/thelawin-clients/tree/main/typescript

ZUGFeRD 2.3 & Factur-X 1.0 compliant