Skip to main content

firmendata-python

Official Python client for the firmendata API — data on 2.4 million German companies from the Unternehmensregister and Handelsregister: register profiles, parsed annual financial statements, shareholder cap tables, UBO chains, insolvency notices and public-tender links.

PyPI Python License: MIT

pip install firmendata

Try it without signing up

Company-name autocomplete is free and needs no API key:

from firmendata import FirmenData

for hit in FirmenData().autocomplete("siemens")["data"]:
    print(hit["eu_id"], hit["display_name"])

Keyless calls are rate limited, modestly and by address — enough to try the API, back a search box, or run low-volume queries. Add a key for substantially higher limits plus every other endpoint. On a 429, honour Retry-After; the client already does this for you.

With an API key

Create one at firmendata.com — the free plan includes 100 credits.

from firmendata import FirmenData

fd = FirmenData(api_key="firmendata_live_...")

# Advanced search — filters combine with AND, lists with OR
results = fd.search(
    city=["Berlin", "Hamburg"],
    revenue_min=1_000_000,
    legal_status=["insolvent"],
    limit=25,
)

for hit in results["data"]:
    print(hit["display_name"], hit["address"]["city"])

# Paginate
if results["pagination"]["has_more"]:
    next_page = fd.search(cursor=results["pagination"]["next_cursor"])
eu_id = "DEB1103R_HRB123456"

fd.get_company(eu_id)        # full profile
fd.get_financials(eu_id)     # multi-year statements, parsed into figures
fd.get_shareholders(eu_id)   # cap table from the Gesellschafterliste
fd.get_ubo(eu_id)            # beneficial owners through ownership chains
fd.get_history(eu_id)        # chronological register history

Async

Same methods, same semantics:

import asyncio
from firmendata import AsyncFirmenData

async def main():
    async with AsyncFirmenData(api_key="firmendata_live_...") as fd:
        company = await fd.get_company("DEB1103R_HRB123456")
        print(company["display_name"])

asyncio.run(main())

Errors

Every failure is a typed exception carrying the API's RFC 7807 problem detail, including a request_id you can quote to support.

from firmendata import FirmenData, InsufficientCreditsError, RateLimitError

try:
    fd.get_ubo(eu_id)
except InsufficientCreditsError:
    ...                      # top up or upgrade
except RateLimitError as e:
    ...                      # e.retry_after is the server's own hint
Exception Status Meaning
AuthenticationError 401 Missing/invalid key, or a keyless call used a paid feature
TokenExpiredError 401 Key expired
InsufficientCreditsError 402 Balance too low for this call
NotFoundError 404 No such company, subscription or event
ConflictError 409 Conflicts with existing state
ValidationError 422 Bad parameters — see .errors for the fields
RateLimitError 429 Retry budget exhausted — see .retry_after
ServerError 5xx Retried automatically for idempotent calls
APIConnectionError / APITimeoutError No response at all

Retries

Automatic and deliberately conservative:

  • 429 is always retried, on any method — the server rejects rate-limited calls before the handler runs, so nothing happened and nothing was billed. The server's Retry-After is used verbatim.
  • 5xx and connection failures are retried only for idempotent methods. A create_subscription that times out may already have been applied; replaying it would create a second one.
  • Backoff is exponential with full jitter, so clients that trip the same limit together don't all return at the same instant.

Tune with FirmenData(max_retries=...); 0 disables it.

Types

Responses are plain dictionaries described by generated TypedDicts, so editors complete every field and mypy checks them — with no pydantic dependency to collide with your own. The only runtime requirement is httpx.

Both src/firmendata/types.py and src/firmendata/params.py are generated from contracts/openapi.v1.json, a vendored copy of the published spec:

python scripts/generate_types.py

CI regenerates them and fails if the result differs from what is committed, so the SDK cannot silently drift from the API it targets.

Development

pip install -e '.[dev]'
pytest              # no network, no credentials
mypy && ruff check

Links

License

MIT — see LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

firmendata-0.1.1.tar.gz (82.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

firmendata-0.1.1-py3-none-any.whl (25.8 kB view details)

Uploaded Python 3

File details

Details for the file firmendata-0.1.1.tar.gz.

File metadata

  • Download URL: firmendata-0.1.1.tar.gz
  • Upload date:
  • Size: 82.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for firmendata-0.1.1.tar.gz
Algorithm Hash digest
SHA256 35715170824800c5f3f166890db332188720c8babcb3f4afa8722acb804e8e64
MD5 e286123d16dab329f1bbe7d27a35dfc4
BLAKE2b-256 ee0beb9459da89a3c16ecdba1ee66bb307f9628663dc8e7f9dc6e2faf1c29609

See more details on using hashes here.

Provenance

The following attestation bundles were made for firmendata-0.1.1.tar.gz:

Publisher: publish.yml on FirmenData/firmendata-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file firmendata-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: firmendata-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 25.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for firmendata-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9a377719c989bfdbb4f3e710cc3274f8eb240525340263ed12b7815a4541a13a
MD5 9078745c3701ce025f66138d0716f992
BLAKE2b-256 c8cb49a0876e484c470bde4f0efea5c89969d6a9e9b94387a6fbc4eb09351ae1

See more details on using hashes here.

Provenance

The following attestation bundles were made for firmendata-0.1.1-py3-none-any.whl:

Publisher: publish.yml on FirmenData/firmendata-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.2.0

2 files

This release

0.1.1 This release

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page