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!')Logo
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