Nordlet

Docs / Guides

Getting started

API keys, first calls, the full invoicing cycle, SDKs and webhooks.

Nordlet is an API-first accounting platform for the EU/EEA market, launching with full Lithuanian compliance. Everything the product does — invoicing, general ledger, bank reconciliation, i.SAF — is available over one JSON API.

1. Get an API key

Every request is authenticated with a Bearer API key scoped to one company:

Authorization: Bearer nl_...

For local development, bootstrap a company and key:

pnpm --filter @nordlet/db bootstrap:dev     # empty company
pnpm --filter @nordlet/api seed:demo        # company with demo data

Interactive API reference (OpenAPI spec at /openapi.json; a local instance serves the same reference at http://localhost:3001/docs).

Postman

Prefer Postman? Import the ready-made collection — every endpoint, grouped by module, with bearer auth pre-wired: Nordlet Postman collection. After importing, set the collection's bearerToken variable to your API key and every request is authenticated.

Sandbox companies

For integration testing, create a company with isSandbox: true (POST /v1/account/companies/create, or tick the sandbox checkbox during onboarding in the app). A sandbox company behaves exactly like a real one — same modules, same API, so you can push realistic transaction volume through it — but it is visibly badged as test data and deleting it purges everything immediately instead of after the 10-day retention window. Run any number of sandbox companies alongside your real one under the same account; the flag is immutable after creation, so real books can never be silently reclassified as test data.

2. First calls

Every operation is POST /v1/{module}/{resource}/{action} with a JSON body. Create a customer:

curl -X POST https://api.nordlet.com/v1/partners/create \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: partner-create-001" \
  -d '{"name": "UAB Klientas", "code": "301111222", "vatCode": "LT100001112223"}'

Issue an invoice (amounts are decimal strings, never floats):

curl -X POST https://api.nordlet.com/v1/sales/invoices/create \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{
    "partnerId": "<partner id>",
    "lines": [{"description": "Konsultacijos", "quantity": 4, "unitPriceExclVat": "75.0000", "vatClassifierCode": "PVM1"}]
  }'

curl -X POST https://api.nordlet.com/v1/sales/invoices/issue \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"id": "<invoice id>", "issueDate": "2026-07-09"}'

Issuing allocates a gapless number (SF-1), checks the accounting period is open, and posts the balanced journal entry (D 2410 receivable / C 5001 revenue / C 4492 VAT) in the same transaction.

3. The full cycle

Step Call
Register a supplier bill purchases/invoices/createpurchases/invoices/register
Import a bank statement bank/statements/import (camt.053 XML) or bank/transactions/import (JSON)
Get match suggestions bank/transactions/suggest-matches
Reconcile a payment bank/transactions/match — posts the payment and updates paymentStatus
Pay suppliers bank/payments/export — pain.001 SEPA file for your bank
Monthly VAT registers declarations/lt/isaf/generate — i.SAF 1.2 XML for VMI
VAT return figures declarations/lt/fr0600/compute — FR0600 fields reconciled against the registers
Ship goods with a waybill transport/waybills/createissue, then declarations/lt/ivaz/generate — i.VAZ XML for VMI

4. TypeScript SDK

import { createNordletClient, idempotent } from '@nordlet/sdk'

const client = createNordletClient({
  baseUrl: 'https://api.nordlet.com',
  apiKey: process.env.NORDLET_API_KEY!,
})

const { data, error } = await client.POST('/v1/sales/invoices/create', {
  body: {
    partnerId,
    lines: [{ description: 'Konsultacijos', quantity: 4, unitPriceExclVat: '75.0000' }],
  },
  ...idempotent(`order-${orderId}`),
})

The SDK is generated from the live OpenAPI spec (pnpm --filter @nordlet/sdk generate), so every request and response is fully typed.

5. Webhooks

Subscribe to events instead of polling:

curl -X POST https://api.nordlet.com/v1/webhooks/subscriptions/create \
  -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/hooks/hyperion", "events": ["sale_invoice.issued", "sale_invoice.paid"]}'

Deliveries carry an HMAC signature (x-nordlet-signature: sha256=<hex> of the raw body with your subscription secret) and are retried with exponential backoff.

Current events: sale_invoice.issued, sale_invoice.paid, purchase_invoice.registered, purchase_invoice.paid.

See API conventions for list queries, error envelopes, idempotency semantics, and rate limits.