KausateKausate Docs

Getting Started

End-to-end guide for retrieving German company data

This guide walks through a complete German company retrieval workflow—from searching for a company to setting up ongoing monitoring.

Getting an API Key

To use the Kausate API, you'll need an API key. There are two ways to get one:

  • Self-serve signup: Create an account at kausate.com/signup and generate an API key from your dashboard
  • Get in touch: Contact us for enterprise plans or custom requirements

Once you have your API key, include it in all requests using the X-API-Key header.


Data Flow Overview

A typical integration follows this pattern:

StepEndpointUse Case
SearchPOST /v2/companies/search/Find companies by name
PrefillPOST /v2/companies/{id}/prefillFast form prefill (~200ms)
ReportPOST /v2/companies/{id}/reportFull real-time company data
MonitorPOST /v2/monitorsTrack changes over time

Complete Example: German Company Retrieval

Search for a Company

Find the company using live search. This fetches real-time results directly from the official registry.

curl -X POST https://api.kausate.com/v2/companies/search/ \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "companyName": "Bundesanzeiger Verlag",
    "jurisdictionCode": "de"
  }'

Response:

{
  "orderId": "de-live-search-bundesanzeiger-verlag-20250115103000",
  "status": "completed",
  "requestTime": "2025-01-15T10:30:00Z",
  "responseTime": "2025-01-15T10:30:02Z",
  "result": {
    "type": "liveSearch",
    "searchResults": [
      {
        "kausateId": "co_de_7KGHtucR88u2omSx3KhaoH",
        "name": "Bundesanzeiger Verlag GmbH",
        "jurisdictionCode": "de",
        "identifiers": [
          {
            "type": "de_registernumber_weak",
            "value": "HRB 31248",
            "description": "Amtsgericht Köln"
          },
          {
            "type": "de_registernumber_full",
            "value": "R2201_HRB 31248"
          }
        ],
        "addresses": [
          {
            "type": "registered",
            "streetAddress": "Amsterdamer Str. 192",
            "postalCode": "50735",
            "city": "Köln"
          }
        ]
      }
    ]
  }
}

Save the kausateId for subsequent calls.

Quick Data with Prefill

For onboarding flows where speed matters, use the prefill endpoint. It returns indexed data with a real-time fallback, typically in under 200ms.

curl -X POST https://api.kausate.com/v2/companies/co_de_7KGHtucR88u2omSx3KhaoH/prefill \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"customerReference": "onboarding-123"}'

Response:

{
  "orderId": "ord_abc123",
  "status": "completed",
  "requestTime": "2025-01-15T10:30:00Z",
  "responseTime": "2025-01-15T10:30:00.180Z",
  "result": {
    "basicInformation": {
      "legalName": "Bundesanzeiger Verlag GmbH",
      "legalForm": "GmbH",
      "registrationDate": "1998-12-22",
      "addresses": [...],
      "identifiers": [...]
    }
  }
}

Prefill is optimized for speed. For comprehensive data including legal representatives and shareholders, use the report endpoint.

Full Company Report (Real-Time)

For complete company data fetched directly from the Handelsregister, use the report endpoint.

Synchronous mode (sync=true) is not recommended. Government business registries are inherently unreliable—timeouts and temporary unavailability are common. Use the asynchronous approach with webhooks (recommended) or polling using the orderId to receive results reliably.

Asynchronous request (recommended) — returns immediately with orderId:

curl -X POST https://api.kausate.com/v2/companies/co_de_7KGHtucR88u2omSx3KhaoH/report \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"customerReference": "kyc-check-456"}'

The async request returns:

{
  "orderId": "ord_xyz789",
  "customerReference": "kyc-check-456",
  "status": "running"
}

Option A: Set up a webhook (recommended) to receive results automatically:

curl -X POST https://api.kausate.com/v2/webhooks \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Order Results",
    "url": "https://your-server.com/webhooks/kausate",
    "customHeaders": {
      "Authorization": "Bearer your-webhook-secret",
      "X-Team": "compliance"
    }
  }'

Custom headers. customHeaders is an arbitrary map of request headers Kausate attaches to every delivery for this webhook — use it to send an Authorization: Bearer … token your endpoint validates, or any tagging header you route on. Up to 20 headers are allowed; a few reserved names (Content-Type, Host, Content-Length, Transfer-Encoding, Connection, Kausate-Version) are set by Kausate and can't be overridden. Header values are encrypted at rest. Deliveries also come from a fixed set of static source IPs you can allowlist — see Static source IPs in the Monitoring & Webhooks guide.

The response includes a per-endpoint signingSecret. Follow the webhook verification guide to authenticate the raw payload, deduplicate retries, and configure an optional IP allowlist.

Option B: Poll for results:

curl https://api.kausate.com/v2/companies/report/runs/ord_xyz789 \
  -H "X-API-Key: your_api_key"

Completed response:

{
  "orderId": "ord_xyz789",
  "status": "completed",
  "result": {
    "sources": {
      "registrar": "Amtsgericht Köln",
      "retrievalTimestamp": "2025-01-15T10:35:00Z"
    },
    "basicInformation": {
      "legalName": "Bundesanzeiger Verlag GmbH",
      "legalForm": "GmbH",
      "capital": {
        "amount": 1000000,
        "currency": "EUR",
        "type": "share_capital"
      },
      "addresses": [...],
      "identifiers": [...],
      "businessActivities": [...]
    },
    "relationships": {
      "legalRepresentatives": [...],
      "shareholders": [...]
    }
  }
}
Synchronous mode (not recommended)

While a sync=true parameter is available, it is not recommended for production use. Government business registries experience frequent timeouts, rate limiting, and temporary outages. Synchronous requests may fail with HTTP 408 (timeout) errors even when the data would eventually become available.

curl -X POST "https://api.kausate.com/v2/companies/co_de_7KGHtucR88u2omSx3KhaoH/report?sync=true" \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"customerReference": "kyc-check-456"}'

Set Up Monitoring

To track changes to a company over time, create a monitor. When changes are detected, you'll receive a webhook notification.

First, create a webhook:

curl -X POST https://api.kausate.com/v2/webhooks \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Company Changes",
    "url": "https://your-server.com/webhooks/kausate"
  }'

Response:

{
  "id": "wh_def456",
  "name": "Company Changes",
  "url": "https://your-server.com/webhooks/kausate",
  "status": "ACTIVE",
  "createdAt": "2025-01-15T10:40:00Z"
}

Discover the sources you can monitor for this company:

Each company supports a different set of monitoring sources depending on its jurisdiction and the registry capabilities available. Pick from the response when creating the monitor.

curl https://api.kausate.com/v2/monitors/sources?kausateId=co_de_7KGHtucR88u2omSx3KhaoH \
  -H "X-API-Key: your_api_key"

Then, create a monitor:

curl -X POST https://api.kausate.com/v2/monitors \
  -H "X-API-Key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "kausateId": "co_de_7KGHtucR88u2omSx3KhaoH",
    "sources": [
      "company_report",
      "shareholder_graph",
      "de_insolvenzbekanntmachungen.feed"
    ],
    "scheduleCron": "0 8 * * *",
    "webhookUrl": "https://your-server.com/webhooks/kausate"
  }'

Response:

{
  "monitorId": "mon_ghi789",
  "kausateId": "co_de_7KGHtucR88u2omSx3KhaoH",
  "companyName": "Bundesanzeiger Verlag GmbH",
  "sources": [
    "company_report",
    "shareholder_graph",
    "de_insolvenzbekanntmachungen.feed"
  ],
  "categoriesFilter": ["all"],
  "autoDeactivateCategories": ["disappeared"],
  "scheduleCron": "0 8 * * *",
  "webhookUrl": "https://your-server.com/webhooks/kausate",
  "isActive": true,
  "createdAt": "2025-01-15T10:45:00Z"
}

Per-company sources (company_report, shareholder_graph) run on the schedule you set; global feed sources (e.g. de_insolvenzbekanntmachungen.feed) are continuously monitored — the cron field is ignored for those. When a change is detected your webhook URL receives a monitor.change_detected payload tagged with a generic event_code like INSOLVENCY_OPENED or COMPANY_STATUS_CHANGED. See the monitoring guide for the full event taxonomy and filter options.


Choosing the Right Endpoint

NeedEndpointSpeedData Freshness
Form autocomplete/v2/companies/search/autocomplete~50msIndexed
Find companies/v2/companies/search/2-5sReal-time
Prefill forms/v2/companies/{id}/prefill~200msIndexed + fallback
Full company data/v2/companies/{id}/report2-30sReal-time
Ownership structure/v2/companies/{id}/shareholder-graph5-60sReal-time

Handling Errors

Every error response has the same body: a human-readable detail, a stable dotted code to branch on, and a request_id to quote to support.

{
  "detail": "Company not found in Transparenzregister",
  "code": "company.not_found.transparenzregister",
  "request_id": "req_01J8Z5V4Q2X9N7B3C6D1E0F2G4"
}

Branch on code, never on detail — the wording of detail is not part of the contract. Codes are hierarchical and published at full depth, so match a prefix to handle a whole family at once:

if (error.code.startsWith("company.not_found")) {
  showCompanyNotFound();
}

The statuses you can receive:

StatusMeaningRetry?
200Success
400Invalid request (check parameters and body), or a capability that jurisdiction doesn't offerNo
401No API key was suppliedNo, send X-API-Key
403The API key is invalid, or valid but not entitled to this resourceNo
404Company, document or order not found — including "no data available"No
405Wrong HTTP method for that pathNo
408Upstream registry timed out (sync mode only)Yes, or go async
409The resource's state rejects this requestNo
410The referenced state has expiredNo, start a new order
422Well-formed but unprocessable (validation, or data that can't be served)No
429An upstream registry rate-limited us — honour Retry-AfterYes, after Retry-After
500Unexpected failure on our sideYes, with backoff
501Offered for that jurisdiction, but this path isn't implemented (rare)No
502Transient upstream-registry failureYes, shortly
503Upstream registry degraded or unreachableYes, longer backoff

Credit exhaustion is a 403 carrying billing.credit_limit_exceeded. There is no 402. A capability a jurisdiction doesn't offer is a 400 (a 403 while it's coming soon) — see the Errors guide.

For async operations the HTTP response is a 200 and the failure lives in the payload — check the status field, which is one of six values:

  • running — Still processing
  • completed — Result available in result field
  • failed — The order ran and failed
  • canceled — The order was canceled
  • terminated — The order was forcefully stopped
  • timedOut — The order exceeded its time limit

The last four are terminal failures and all carry error (display text) and code (what you branch on), so handle them together rather than switching on failed alone. On this surface code is versioned: it is present from 2026-05-01 onward and absent for a client pinned to 2025-04-01. The sync error body above is not versioned and always carries code.

See the Errors guide for the full code vocabulary and the prefix-matching contract.

Why timeouts happen

Kausate fetches data directly from official government registries (Handelsregister, Companies House, etc.). These external systems are inherently unreliable:

  • Rate limiting — Registries limit requests to prevent abuse
  • Maintenance windows — Government systems have scheduled and unscheduled downtime
  • Slow responses — Some queries take 30+ seconds depending on registry load
  • Temporary outages — Network issues and server errors are common

This is why we recommend asynchronous requests with webhooks (recommended) or polling using the orderId. Our retry logic handles temporary failures automatically, and you'll receive results as soon as they're available.

Last updated on

On this page