npm SDK
SDKs

Node.js SDK

The official Node.js SDK for accessing German company registry data through the Handelsregister.ai API.

Node.js 22.13+ • AGPL-3.0

Installation and authentication

npm install handelsregister

export HANDELSREGISTER_API_KEY=your-api-key

The SDK sends credentials only as x-api-key or Authorization: Bearer … headers, never in URLs. API keys are the default; Bearer tokens provide fine-grained, expiring access and take precedence when both are available. Add gateway headers with extraHeaders or HANDELSREGISTER_EXTRA_HEADERS; SDK-managed authentication and User-Agent headers cannot be replaced.

const { Handelsregister, Company } = require('handelsregister');

const client = new Handelsregister({
  apiKey: process.env.HANDELSREGISTER_API_KEY,
  timeout: 60_000,
  cacheEnabled: true,
  rateLimit: 1,
});

// Bearer tokens take precedence over API keys.
const tokenClient = new Handelsregister({
  bearerToken: process.env.HANDELSREGISTER_BEARER_TOKEN,
});

Signals

Signals provide cursor-paginated commercial-register changes. Catalog requests are free; successful list pages and detail requests cost 20 credits. Pages contain 20 entries.

const { SignalTopic } = require('handelsregister');

const filters = {
  topics: [SignalTopic.CAPITAL_CHANGES, SignalTopic.TRANSFORMATIONS],
  organizationIds: ['organization-id-one', 'organization-id-two'],
  fromDate: '2026-07-01',
  toDate: '2026-07-30',
};

const page = await client.listSignals(filters);
const catalog = await client.getSignalCatalog();
const detail = await client.getSignal(page.signals[0].event.id);

for await (const signal of client.iterateSignals({
  topics: [SignalTopic.NEW_REGISTRATIONS], maxResults: 50,
})) {
  console.log(signal.event.id, signal.organization?.entity_id);
}

Preserve filters and pass pagination.next_cursor unchanged for manual pagination. Multiple organization IDs use OR semantics. The seven topics are NEW_REGISTRATIONS, MASTER_DATA_CHANGES, CLOSURES, ROLE_HOLDER_CHANGES, CAPITAL_CHANGES, INSOLVENCIES (Pro/Max), and TRANSFORMATIONS (Max). HTTP 403 PLAN_REQUIRED becomes SubscriptionRequiredError and costs zero credits.

Account and usage

Account requests are free. An API key or account:read Bearer token can read the profile, credits, usage, subscription, and masked API keys. Date ranges are limited to 366 days; transaction pages use opaque cursors. Creating or revoking API keys requires a dashboard-created Bearer token with account:keys; full key values are returned only once.

const account = await client.getAccount();
const credits = await client.getAccountCredits();
const subscription = await client.getAccountSubscription();
const keys = await client.listApiKeys();

for await (const transaction of client.iterateAccountUsageTransactions({
  perPage: 100,
})) {
  console.log(transaction.endpoint, transaction.credits);
}

Monitoring and webhooks

Monitoring watches organizations and pushes normalized Signals to HTTPS endpoints. Reads and management requests are free; an activated monitor starts with the current 10-credit cycle floor. Check getMonitoringPricing() before creating or resuming a monitor. Monitor lifecycle operations require account:read plus monitoring:manage; webhook endpoint lifecycle requires account:read plus account:keys.

const admin = new Handelsregister({ bearerToken: process.env.ADMIN_TOKEN });
const createdEndpoint = await admin.createWebhookEndpoint({
  name: 'Production receiver',
  url: 'https://hooks.example.com/handelsregister',
  headers: { 'x-tenant': 'customer-42' },
});
const endpointId = createdEndpoint.endpoint.id;
const signingSecret = createdEndpoint.signing_secret; // returned only once

await admin.verifyWebhookEndpoint(endpointId);
await admin.testWebhookEndpoint(endpointId);

const monitor = (await client.createMonitor({
  entityId: 'organization-entity-id',
  pollIntervalDays: 7,
  endpointIds: [endpointId],
  label: 'Important customer',
})).monitor;

await client.pauseMonitor(monitor.id);
await client.resumeMonitor(monitor.id);
await client.archiveMonitor(monitor.id);

Store the one-time signing secret immediately. Monitoring mutations receive an automatically generated Idempotency-Key, reused across safe retries; provide idempotencyKey for durable retries across restarts and inspect client.lastIdempotencyStatus. HTTP 409 ambiguity is never retried. Verify raw bytes with constructEvent() before parsing JSON, answer verification challenges with verificationResponseHeaders(), and deduplicate at-least-once deliveries by event ID.

Tokens, enrichment, and CLI

Bearer-token management supports creating, listing, revoking one token, and revoking all tokens deliberately. Batch enrichment supports CSV, JSON, and XLSX snapshots. The bundled CLI covers lookups, filters-only search, documents, enrichment, monitoring, webhook endpoints, deliveries, and events.

const { token } = await client.createToken({
  tokenName: 'ci-pipeline',
  abilities: ['*'],
  expiresAt: '2027-01-01 00:00:00',
});
const { tokens } = await client.listTokens();
await client.revokeToken(tokens[0].id);

await client.enrich({
  filePath: 'companies.csv',
  inputType: 'csv',
  queryProperties: { company_name: 'name', city: 'location' },
  snapshotDir: './snapshots',
  params: { features: ['financial_kpi', 'related_persons'] },
});
handelsregister fetch "KONUX GmbH München" --feature financial_kpi
handelsregister search --filters '{"legal_form_code":"GmbH"}' --limit 30
handelsregister document "KONUX GmbH" --type SI --output konux.xml
handelsregister enrich companies.csv --feature related_persons
handelsregister monitors pricing --interval 7
handelsregister webhooks events

TypeScript, features, and errors

The package is written in TypeScript and ships full type definitions. Available features include related_persons, financial_kpi, balance_sheet_accounts, profit_and_loss_account, publications, annual_financial_statements, annual_financial_statements__html, insolvency_publications, shareholders, ubos, shareholdings, mergers_and_acquisitions, news, and website_content. Current responses use nested contact_data, representation_scheme, and feature structures; publications is returned as history.

import { Handelsregister, CompanyData, Feature } from 'handelsregister';

const features: Feature[] = ['financial_kpi', 'related_persons'];
const data: CompanyData = await client.fetchOrganization({
  q: 'company name',
  features,
});

Errors expose response, statusCode, responseHeaders, and errorCode. Use the specific error classes for authentication, credits, subscriptions, idempotency conflicts, service availability, not found, timeouts, rate limits, and validation. Legacy base error classes remain compatible with instanceof checks. Never commit API keys, Bearer tokens, or webhook signing secrets.

For the complete API surface and runnable examples, see the Handelsregister Node.js SDK repository.