npm package: @invoicenavigator/sdk
Description: Official TypeScript SDK for Invoice Navigator — EU e-invoicing compliance API. Validate, remediate, and certify invoices against EN 16931, Peppol BIS 3.0, XRechnung, and ZUGFeRD.
Author: Invoice Navigator
Latest version: 0.1.1

# @invoicenavigator/sdk

Official TypeScript/JavaScript SDK for [Invoice Navigator](https://www.invoicenavigator.eu) — the compliance engine for EU e-invoicing pipelines.

Validate, **auto-remediate**, and certify invoices against EN 16931, Peppol BIS 3.0, XRechnung, ZUGFeRD/Factur-X, and country-specific CIUS rules.

## Install

```bash
npm install @invoicenavigator/sdk
```

## Quick Start

```typescript
import { InvoiceNavigator } from '@invoicenavigator/sdk'

const client = new InvoiceNavigator({ apiKey: 'sk_live_...' })

// 1. Validate
const result = await client.validate({ xml: invoiceXml })

if (result.isValid) {
  console.log('Already compliant')
} else {
  // 2. Fix — auto-remediate every fixable error
  const fix = await client.fix({
    xml: invoiceXml,
    error_codes: result.errors.map(e => e.code),
  })

  console.log(`Fixed ${fix.stats.totalFixesApplied} issues`)
  console.log(`Compliant: ${fix.is_compliant}`)

  // 3. Use the fixed XML downstream
  if (fix.is_compliant) {
    sendToPeppol(fix.fixed_xml)
  }
}
```

## What It Does

| Method | Description |
|--------|-------------|
| **Validation** | |
| `validate(options)` | Validate against EN 16931 + Peppol/XRechnung/ZUGFeRD rules |
| `validateBatch(invoices)` | Batch validate up to 100 invoices |
| **Remediation** | |
| `fix(options)` | Auto-remediate structural compliance errors |
| `fixWithInput(options)` | Resolve errors that need user-provided values |
| `validateAndFix(options)` | Validate + auto-remediate in a single call |
| `categorize(options)` | Preview which errors are auto-fixable, need input, or blocked |
| `fixerUsage()` | Check remediation quota and usage stats |
| `fixFlow(id)` | Track status of a multi-step remediation flow |
| **Evidence** | |
| `evidencePack(options)` | Generate signed compliance evidence (PDF or JSON) |
| `verify(id)` | Verify an evidence pack's cryptographic signature |
| **Conversion** | |
| `convert(options)` | Convert between UBL and CII formats |
| **Intelligence** | |
| `countries()` | List supported countries and their mandate status |
| `country(code)` | Get country-specific compliance details |
| `rules(country)` | Get country-specific validation rules |
| `deadlines(options)` | Get upcoming compliance deadlines |
| `requirements(options)` | Get requirements for a seller/buyer trade lane |
| `complianceScore(options)` | Calculate compliance readiness score |
| `changes(options)` | Get regulatory changes since a date |
| `errors(options)` | List all validation error definitions |
| `error(ruleId)` | Get details for a specific error code |
| `searchFacts(options)` | Search compliance facts across countries |
| `facts(country)` | Get all facts for a country |

## Test Mode

Use `sk_test_` keys for development. Same engine, same rules — no quota consumed.

```typescript
const client = new InvoiceNavigator({
  apiKey: 'sk_test_...'   // 100 requests/hour, no charge
})
```

## Remediation

Invoice Navigator doesn't just find errors — it fixes them.

### Validate + Fix (one call)

The fastest path. Validates and auto-remediates in a single request.

```typescript
const result = await client.validateAndFix({
  xml: invoiceXml,
  generate_evidence_pack: true,
})

if (result.fixedValid) {
  console.log(`Fixed ${result.fixesApplied} issues — now compliant`)
  // result.fixedXml is the remediated XML
  // result.evidencePackUrl has the signed proof
}
```

### Fix specific errors

When you already have validation results and want granular control:

```typescript
const validation = await client.validate({ xml: invoiceXml })

if (!validation.isValid) {
  const fix = await client.fix({
    xml: invoiceXml,
    error_codes: validation.errors.map(e => e.code),
  })

  console.log(`Applied: ${fix.stats.totalFixesApplied}`)
  console.log(`Remaining: ${fix.remaining_errors.length}`)
  console.log(`Engine: ${fix.engine}`)
  // fix.flow_id tracks this remediation session
}
```

### Input-required workflow

Some errors can't be auto-fixed — they need values only the user knows (a missing VAT number, a wrong bank account). This is what makes Invoice Navigator different from every other validator: instead of just listing errors, we tell you exactly which fields to collect and apply them surgically.

```typescript
// 1. Categorize errors to see what's fixable
const cat = await client.categorize({
  error_codes: validation.errors.map(e => e.code),
})

console.log(`Auto-fixable: ${cat.stats.auto}`)    // e.g. 5
console.log(`Needs input:  ${cat.stats.input}`)    // e.g. 2
console.log(`Blocked:      ${cat.stats.blocked}`)   // e.g. 0

// 2. Auto-fix the safe ones first
const fix = await client.fix({
  xml: invoiceXml,
  error_codes: validation.errors.map(e => e.code),
})

// 3. Prompt the user for input-required fields, then apply
if (!fix.is_compliant) {
  const result = await client.fixWithInput({
    xml: fix.fixed_xml,
    flow_id: fix.flow_id,
    values: {
      'BT-48': 'DE123456789',    // buyer VAT number
      'BT-49': 'VAT',            // buyer tax registration scheme
    },
    skipped: ['BR-CO-26'],       // accept this error as-is
  })

  console.log(`Compliant: ${result.is_compliant}`)
}
```

### Track a remediation flow

Monitor multi-step remediation progress:

```typescript
const flow = await client.fixFlow(fix.flow_id)

console.log(`Status: ${flow.status}`)
console.log(`Auto-fixed: ${flow.auto_fixes_applied}`)
console.log(`User inputs: ${flow.user_inputs_provided}`)
console.log(`Final compliant: ${flow.final_compliant}`)
```

### Usage tracking

Monitor remediation quota consumption:

```typescript
const usage = await client.fixerUsage()

console.log(`Flows: ${usage.usage.flows_used}/${usage.usage.flows_limit}`)
console.log(`Resets: ${usage.resets_at}`)
```

## Validation

```typescript
const result = await client.validate({
  xml: '<Invoice>...</Invoice>',
  fileName: 'invoice-001.xml',   // optional
  webhookUrl: 'https://...',     // optional — receive async notification
})

result.validationRef   // "val_abc123" — reference for evidence packs
result.isValid         // boolean
result.format          // "XRechnung-UBL" | "Factur-X" | ...
result.formatVersion   // "3.0.1"
result.errors          // ValidationError[]
result.warnings        // ValidationWarning[]
result.metadata        // extracted invoice metadata
```

### Batch Validation

Validate multiple invoices in one request. Requires Pro tier or higher.

```typescript
const batch = await client.validateBatch([
  { xml: invoice1Xml, id: 'inv-001' },
  { xml: invoice2Xml, id: 'inv-002' },
])

console.log(`${batch.validCount}/${batch.totalCount} valid`)
```

## Evidence Packs

Generate cryptographically signed compliance evidence.

```typescript
// PDF format
const pdf = await client.evidencePack({
  validationRef: 'val_abc123',
  format: 'pdf',
  companyName: 'ACME GmbH',
})

import { writeFileSync } from 'fs'
writeFileSync('evidence.pdf', Buffer.from(pdf.pdf))

// JSON format
const json = await client.evidencePack({
  validationRef: 'val_abc123',
  format: 'json',
})
console.log(`Verify at: ${json.verifyUrl}`)

// Verify an Evidence Pack (public endpoint, no auth required)
const verification = await client.verify('EP-ABC123-DEF456')
console.log(`Verified: ${verification.verified}`)
```

## Format Conversion

Convert between UBL and CII invoice formats. Requires Pro tier or higher.

```typescript
const result = await client.convert({
  source: Buffer.from(xml).toString('base64'),
  sourceFormat: 'auto',
  targetFormat: 'xrechnung-ubl',
})

const convertedXml = Buffer.from(result.result, 'base64').toString()
```

Supported formats: `ubl-2.1`, `xrechnung-ubl`, `xrechnung-cii`, `peppol-bis`, `factur-x-minimum`, `factur-x-basic`, `factur-x-extended`, `cii`.

## Regulatory Intelligence

```typescript
// Countries and mandate status
const countries = await client.countries()
const germany = await client.country('DE')

// Upcoming deadlines
const deadlines = await client.deadlines({ country: 'DE', months: 6 })

// Trade lane requirements
const reqs = await client.requirements({ from: 'DE', to: 'FR', type: 'b2b' })

// Regulatory changes since a date
const changes = await client.changes({ since: '2025-01-01', countries: ['DE', 'FR'] })

// Compliance score
const score = await client.complianceScore({
  businessCountry: 'DE',
  customerCountries: ['FR', 'BE', 'NL'],
})
```

## Error Handling

```typescript
import { InvoiceNavigator, InvoiceNavigatorError } from '@invoicenavigator/sdk'

try {
  const result = await client.validate({ xml })
} catch (error) {
  if (error instanceof InvoiceNavigatorError) {
    console.log(error.code)       // 'RATE_LIMIT_EXCEEDED'
    console.log(error.statusCode)  // 429
    console.log(error.message)     // 'Hourly rate limit exceeded'
  }
}
```

| Code | Status | Meaning |
|------|--------|---------|
| `VALIDATION_ERROR` | 400 | Invalid request parameters |
| `UNAUTHORIZED` | 401 | Missing or invalid API key |
| `FORBIDDEN` | 403 | Insufficient tier for this endpoint |
| `RATE_LIMIT_EXCEEDED` | 429 | Rate limit hit |
| `TIMEOUT` | 408 | Request exceeded configured timeout |
| `NETWORK_ERROR` | 0 | Network failure |

## Rate Limits

Available after each request via `client.rateLimit`:

```typescript
await client.validate({ xml })
console.log(client.rateLimit)
// { limit: 100, remaining: 97, reset: 1709312400 }
```

## Webhooks

Verify and parse webhook payloads:

```typescript
import {
  verifyWebhookSignature,
  parseWebhookPayload,
  isValidationCompletedEvent,
} from '@invoicenavigator/sdk'

const isValid = await verifyWebhookSignature(rawBody, signature, webhookSecret)
const payload = parseWebhookPayload(body)

if (isValidationCompletedEvent(payload)) {
  console.log('Validation completed:', payload.data.validationRef)
}
```

## Configuration

```typescript
const client = new InvoiceNavigator({
  apiKey: 'sk_live_...',                          // required
  baseUrl: 'https://api.invoicenavigator.eu',     // optional, default shown
  timeout: 30000,                                  // optional, ms
  fetch: customFetchFn,                            // optional, for older runtimes
})
```

## Supported Standards

- EN 16931 (European e-invoicing standard)
- Peppol BIS Billing 3.0
- XRechnung 3.0 (Germany)
- ZUGFeRD 2.3 / Factur-X (Germany/France)
- Country CIUS: DE, FR, IT, NL, BE, AT, and more

## Requirements

- Node.js 18+ (uses native `fetch` and `crypto.subtle`)
- Works in modern browsers, Deno, Bun, and Cloudflare Workers

## Links

- [API Documentation](https://www.invoicenavigator.eu/developers)
- [Sandbox & Test Mode](https://www.invoicenavigator.eu/developers/sandbox)
- [Quickstart Guide](https://www.invoicenavigator.eu/developers/quickstart)

## License

MIT