{"openapi":"3.1.0","info":{"title":"firmendata Public API","description":"Programmatic access to German, Swiss and Austrian company data: register profile, filed\nfinancial statements, company events, and current cap tables.\n\n## Authentication\n\nBearer token in the `Authorization` header. Create and manage your\ntokens in [API Key Settings](https://firmendata.com/de/developer/api-keys).\n\n## Identifying your integration\n\nOptionally send `X-FirmenData-Client: <name>/<version>` (lower-case name of letters, digits, `.`, `_`, `-`, up to 32 characters; version up to 32 characters, e.g. `X-FirmenData-Client: acme-crm/2.1.0`) so we can tell integrations apart when you contact support. Our SDKs and the n8n node send it automatically. The header is informational only: it never changes pricing, rate limits or responses, and an invalid value is ignored.\n\n## Data freshness\n\nEvery company endpoint exposes a `freshness` object so you can see, at\na glance, how stale the response is and which fetch mode produced it:\n\n```jsonc\n\"freshness\": {\n  \"object\": \"freshness\",\n  \"last_checked_at\": \"2026-04-30T12:14:08Z\",\n  \"realtime_fetching_status\": \"realtime_fetching_disabled\"\n}\n```\n\n`last_checked_at` is the UTC timestamp of the last successful refresh\nof the underlying data slice from the German registries. Compare it\nagainst your own staleness tolerance to decide which of the three\nfetch modes below fits the call. `null` means the slice has never been\nsuccessfully fetched for this company.\n\nThere are three ways to consume the data, each with a different\nfreshness guarantee:\n\n1. **Cached read (default).** Returns the most recent data we already\n   have on file for the company. Cheapest and fastest. The data may\n   be stale — the `freshness.last_checked_at` field tells you exactly\n   how stale.\n\n2. **Realtime fetch (`fetch_realtime=true`).** Refreshes the\n   underlying slice from the German registries inline before\n   responding. Costs more credits and adds upstream latency\n   (typically several seconds, sometimes longer). For company endpoints,\n   this only affects German (DE) companies; Swiss (CH) and Austrian (AT)\n   companies ignore the flag and incur no realtime surcharge. On upstream\n   failure, the response falls back to the most recent cached data\n   for the company; `freshness.realtime_fetching_status` reports the\n   outcome (`success`, `platform_unavailable`,\n   `documents_temporarily_unavailable`, `file_unavailable`,\n   `company_unavailable`, or `realtime_fetching_disabled`). When we\n   have no record of the company at all, the endpoint returns 404\n   the same as without `fetch_realtime`.\n\n   On `/companies/autocomplete` and `/companies/search` the flag means\n   *discovery* rather than refresh: the keyword is searched against the\n   German registers, so companies we do not have yet can appear in the\n   same response with their identity and registered seat. Their full\n   profile may become available shortly after at no extra cost.\n\n3. **Subscriptions (German companies only).** The only mode that *guarantees* you eventually\n   see fresh data: failed data checks are retried on the\n   configured cadence. Updates arrive by webhook or through the events API\n   when something changes. Manage subscriptions via `/subscriptions`.\n\n## Pagination\n\nList endpoints (`/companies/search`, `/lists/{list_id}`, `/subscriptions`,\n`/subscriptions/{id}/events`) use opaque cursor pagination and return the\nsame `pagination` object. Pass the `pagination.next_cursor` value from a\nresponse back unchanged as the `cursor` query parameter to fetch the next\npage. Cursors are signed: one that was edited, or issued by a different\nendpoint, is rejected with `422`. A search cursor also remembers the\nfilters of the request that issued it, so the next page needs only\n`cursor`; repeating the same filters is fine, changing them is a `422`.\nSearch and list cursors are not\nguaranteed to survive a deploy. Feed cursors under `/v1/feeds` persist\nacross deploys and restarts: keep `next_cursor` even after an empty page.\nFeed positions expire after seven days; restart with `since` if expired.\n\n## Rate limits\n\nEvery bearer token is capped at:\n\n- **5 requests per second** (burst protection)\n- **100 requests per minute** (sustained)\n\nBoth windows are enforced via a sliding-window counter, so limits degrade\ngracefully across window boundaries. Every response — success or error —\nincludes headers so clients can self-pace:\n\n- `RateLimit-Limit` — numeric limit of the tighter window currently applying\n- `RateLimit-Remaining` — calls left in that window (never negative)\n- `RateLimit-Reset` — seconds until the window resets\n- `RateLimit-Warning` — present only when fewer than 10% of the window\n  remains; a hint to slow down before hitting 429\n\nWhen a limit is exceeded the server returns `429 Too Many Requests` with\na `Retry-After` header (seconds) and an RFC 7807 body. Rejected requests\ndo not consume the limit or any credits — they are free to retry once\nthe reset period elapses.\n\n## Errors\n\nAll non-2xx responses follow [RFC 7807 `application/problem+json`](https://datatracker.ietf.org/doc/html/rfc7807).\nThe body always carries `type`, `title`, `status`, `detail`, `instance` and\n`request_id` (the same value as the `X-Request-Id` response header); 422\nresponses add `errors: [{param, message}]`, one entry per offending\nparameter.\n\nInput is validated strictly, so a mistake fails loudly instead of returning\nunfiltered data: an unknown query parameter, a value outside a parameter's\nvocabulary, and an inverted range (`revenue_min` above `revenue_max`,\n`founded_from` after `founded_to`) are all `422`. Enum values stay\ncase-insensitive and accept the documented alternative spellings.\n\n## Stability\n\nObject types carry an `object` discriminator (e.g. `\"object\": \"company\"`).\nNullable fields are always present (never omitted) and list fields default\nto `[]` so client codegen output is stable across releases.\n\n## Subscriptions\n\nStay current without polling on a fixed schedule: subscribe a single\ncompany to one data slice and firmendata detects changes for you on the\ncadence you choose, under `/subscriptions`. Pick one of three delivery\nmodes via `notification_type`:\n\n* **Webhook** (`notification_type: \"webhook\"`) — firmendata POSTs a\n  signed JSON body to your `webhook_url` on each change. Every request is\n  HMAC-SHA256 signed; verify `X-Firmendata-Signature` against the\n  `webhook_secret` returned at creation. Requires `webhook_url`.\n\n* **Email** (`notification_type: \"email\"`) — a bilingual notification to\n  `recipient_email` (with the register document attached as a PDF for\n  `doc_*` subscriptions). Requires `recipient_email`.\n\n* **Poll-only / async** (`notification_type: null` — the **default**) —\n  no outbound delivery is performed. Each detected\n  change becomes a `subscription_event`, and you retrieve the payload\n  by polling `GET /subscriptions/{id}/events` with the subscription\n  (job) id returned on create. Omit both `webhook_url` and\n  `recipient_email`. Ideal when you can't expose an inbound webhook\n  endpoint and would rather pull changes on your own schedule.\n\n`mode` selects `recurring` (deliver on every change) or `one_time`\n(poll until the first successful delivery, then stop); `cadence` controls\nhow often the change check runs.\n\n## Pricing\n\nEvery successful 2xx call deducts credits from your account; 4xx and 5xx\nresponses are free — no credits are spent on failed requests. A 2xx that\ncarries no data is free too: a cap table or UBO report whose\n`coverage.status` says there is nothing on file, or a financials response\nfor a company without any financial data. Every response states what it\ncost in the `X-Credits-Charged` header (`0` when nothing was charged).\n\nPer-endpoint credit costs, subscription pricing, plan allowances, and\nrate-limit tiers are listed on the [pricing page](https://firmendata.com/en/plans)\n— the single source of truth, so this spec links there instead of\nduplicating numbers that can drift.","contact":{"name":"firmendata Support","email":"info@firmendata.com"},"license":{"name":"Commercial","url":"https://firmendata.com/en/terms-and-conditions"},"version":"1.3.0"},"servers":[{"url":"https://api.firmendata.com","description":"FirmenData API"}],"paths":{"/v1/companies/autocomplete":{"get":{"tags":["Search"],"summary":"Autocomplete suggestions","description":"Companies whose name starts with `q`, from a single character, so a search box can suggest from the first keystroke. Exact core-name matches (ignoring legal-form suffixes) come first, then biggest revenue. From three characters, companies whose name contains `q` as a whole word also rank by revenue. Use `country` to restrict suggestions to a company register. Each hit carries just enough context — company name and register reference — to pick the right result out of a dropdown. Not meant for programmatic search — use `/companies/search` for that.\n\n**Free without an API key.** This is the only v1 endpoint you can call unauthenticated. Keyless access is rate limited — modestly, and by address — and is intended for trying the API out, for a search box, or for low-volume use. Send an `Authorization: Bearer <key>` header for substantially higher limits; the call still costs 0 credits either way. Respect `Retry-After` on a `429`.\n\nSet `fetch_realtime=true` (with `q` of at least 3 characters) to also search the German company registers live, so companies we do not have yet — including ones registered only days ago — appear in the same response. **`fetch_realtime` requires an API key** and is billed; keyless requests that set it are rejected with `401`.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"autocompleteCompanies","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"maxLength":100,"description":"Start of a company name, at least 1 character after trimming (3 with `fetch_realtime`).","examples":["s","sap","deutsche bank"],"title":"Q"},"description":"Start of a company name, at least 1 character after trimming (3 with `fetch_realtime`)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":25,"minimum":1,"description":"Maximum number of suggestions to return. Hard upper bound is 25.","default":10,"title":"Limit"},"description":"Maximum number of suggestions to return. Hard upper bound is 25."},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string","enum":["DE","CH","AT"]},{"type":"null"}],"description":"Restrict all suggestions to the company register: DE, CH or AT. Case-insensitive; omitted searches all countries.","title":"Country"},"description":"Restrict all suggestions to the company register: DE, CH or AT. Case-insensitive; omitted searches all countries."},{"name":"fetch_realtime","in":"query","required":false,"schema":{"type":"boolean","description":"When `true`, search the German company registers live for the keyword and include any companies not yet known to firmendata, so newly founded companies appear in the suggestions of this same response. Adds upstream latency (typically a few seconds) and a higher credit cost. Refresh failures never fail the request — `freshness.realtime_fetching_status` reports the outcome and the local suggestions are returned regardless.","default":false,"title":"Fetch Realtime"},"description":"When `true`, search the German company registers live for the keyword and include any companies not yet known to firmendata, so newly founded companies appear in the suggestions of this same response. Adds upstream latency (typically a few seconds) and a higher credit cost. Refresh failures never fail the request — `freshness.realtime_fetching_status` reports the outcome and the local suggestions are returned regardless."}],"responses":{"200":{"description":"Suggestion hits, exact core-name matches first, then biggest revenue.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutocompleteResponse"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"security":[],"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/autocomplete?q=sap\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/autocomplete?q=sap\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/autocomplete?q=sap\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/companies/search":{"get":{"tags":["Search"],"summary":"Advanced search","description":"Full-text + filter search over German, Swiss and Austrian commercial registers. Cursor-paginated,\nup to 50 hits per page. `total_approx` caps at 10,000 — tighten filters for an\nexact count.\n\nEach hit carries identity and registered seat, the register reference (court,\ntype, number), headline financials in EUR, the company's website, and the CPV\ncodes of any EU tenders it won.\n\nFilter values are case-insensitive, several filters accept multiple values, and\nthe financial figures need one caveat before you compute ratios with them — see\nthe **Search** section above for all three. Unknown parameters, unknown filter\nvalues and inverted ranges (`*_min` above `*_max`, `founded_from` after\n`founded_to`) are rejected with `422` instead of being ignored.\n\nSetting `fetch_realtime=true` additionally searches the German registers live\nfor `q` (or `company_name`, one of which is then required) and appends any\ncompanies not yet known to firmendata to the first page, carrying identity and\nseat only. First page only — omit `cursor`.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"searchCompanies","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":3,"maxLength":200},{"type":"null"}],"description":"Unified keyword, tried as an eu_id, then a company-name prefix, then a person name — falling through whenever a phase returns nothing. Overrides `company_name`, `eu_id` and `person_name` when supplied alongside them.","examples":["DEF1103R.HRB279792B","bayerische motoren werke","schulze"],"title":"Q"},"description":"Unified keyword, tried as an eu_id, then a company-name prefix, then a person name — falling through whenever a phase returns nothing. Overrides `company_name`, `eu_id` and `person_name` when supplied alongside them."},{"name":"company_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":3,"maxLength":200},{"type":"null"}],"description":"Company name prefix, ignoring case, accents, quotes and invisible characters — `Müller \"Süd\" GmbH` and `Müller Süd GmbH` match the same company. The legal-form suffix is kept, so `Bosch GmbH` narrows against `Bosch`.","examples":["bayerische motoren werke"],"title":"Company Name"},"description":"Company name prefix, ignoring case, accents, quotes and invisible characters — `Müller \"Süd\" GmbH` and `Müller Süd GmbH` match the same company. The legal-form suffix is kept, so `Bosch GmbH` narrows against `Bosch`."},{"name":"eu_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"description":"Exact eu_id lookup (no prefix expansion).","examples":["DEF1103R.HRB279792B"],"title":"Eu Id"},"description":"Exact eu_id lookup (no prefix expansion)."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Maximum number of hits to return per page. Hard upper bound is 50.","default":50,"title":"Limit"},"description":"Maximum number of hits to return per page. Hard upper bound is 50."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":4096},{"type":"null"}],"description":"Opaque pagination cursor. Pass the `pagination.next_cursor` (or `previous_cursor`) from a previous response unchanged; a cursor that was not issued by this endpoint is rejected with `422`. The cursor remembers the filters of the request that issued it: send it alone (with `limit` if you like), or with the same filters — a cursor sent with different filters is rejected with `422`.","title":"Cursor"},"description":"Opaque pagination cursor. Pass the `pagination.next_cursor` (or `previous_cursor`) from a previous response unchanged; a cursor that was not issued by this endpoint is rejected with `422`. The cursor remembers the filters of the request that issued it: send it alone (with `limit` if you like), or with the same filters — a cursor sent with different filters is rejected with `422`."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/Sort"},{"type":"null"}],"description":"Field to order results by. Defaults to keyword-match relevance when `q` is given, otherwise `revenue` descending. Companies missing the value always sort last, whichever direction is chosen. `total_assets` ranks far more companies than `revenue` does — see the filter notes on those two.","title":"Sort"},"description":"Field to order results by. Defaults to keyword-match relevance when `q` is given, otherwise `revenue` descending. Companies missing the value always sort last, whichever direction is chosen. `total_assets` ranks far more companies than `revenue` does — see the filter notes on those two."},{"name":"sort_direction","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SortDirection"},{"type":"null"}],"description":"Defaults to `desc`, except `asc` for `sort=name`.","title":"Sort Direction"},"description":"Defaults to `desc`, except `asc` for `sort=name`."},{"name":"register_number","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Exact Registernummer, digits only (`12345` for HRB 12345). Register numbers repeat across courts and types — combine with `register_court` / `register_type` to identify one company.","examples":[12345],"title":"Register Number"},"description":"Exact Registernummer, digits only (`12345` for HRB 12345). Register numbers repeat across courts and types — combine with `register_court` / `register_type` to identify one company."},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/Country"},{"type":"null"}],"description":"Country of the company register. Single-valued.","title":"Country"},"description":"Country of the company register. Single-valued."},{"name":"canton","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Canton"}},{"type":"null"}],"description":"Swiss address canton codes. Multi-valued; OR-merged with `bundesland`.","title":"Canton"},"description":"Swiss address canton codes. Multi-valued; OR-merged with `bundesland`."},{"name":"register_type","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/RegisterType"},{"type":"null"}],"description":"Register type. Single-valued.","title":"Register Type"},"description":"Register type. Single-valued."},{"name":"register_court","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/RegisterCourt"},{"type":"null"}],"description":"Registering court (Registergericht), by its canonical Handelsregister name. An `Amtsgericht ` prefix is accepted and ignored. Single-valued. Ten listed courts were consolidated away years ago and hold no companies — they stay valid inputs so existing calls keep working.","examples":["München"],"title":"Register Court"},"description":"Registering court (Registergericht), by its canonical Handelsregister name. An `Amtsgericht ` prefix is accepted and ignored. Single-valued. Ten listed courts were consolidated away years ago and hold no companies — they stay valid inputs so existing calls keep working."},{"name":"city","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Registered seat city, matched exactly but umlaut-insensitively. Compare with `registered_seat` on each hit; `address.city` is the business address and can differ. Multi-valued, and OR-merged with `bundesland` into one location filter.","examples":[["München","Hamburg"]],"title":"City"},"description":"Registered seat city, matched exactly but umlaut-insensitively. Compare with `registered_seat` on each hit; `address.city` is the business address and can differ. Multi-valued, and OR-merged with `bundesland` into one location filter."},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Bundesland"}},{"type":"null"}],"description":"German or Austrian federal state. Multi-valued; also accepts postal codes (`BY`, `NRW`) and English names (`Bavaria`).","examples":[["Bayern","Baden-Württemberg"]],"title":"Bundesland"},"description":"German or Austrian federal state. Multi-valued; also accepts postal codes (`BY`, `NRW`) and English names (`Bavaria`)."},{"name":"founded_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Earliest founding date (inclusive, `YYYY-MM-DD`).","title":"Founded From"},"description":"Earliest founding date (inclusive, `YYYY-MM-DD`)."},{"name":"founded_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Latest founding date (inclusive, `YYYY-MM-DD`).","title":"Founded To"},"description":"Latest founding date (inclusive, `YYYY-MM-DD`)."},{"name":"revenue_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum latest reported revenue in EUR, inclusive. Most German companies file abridged accounts with no profit-and-loss statement, so revenue is the scarcest financial figure — prefer `total_assets_min` to filter on size.","title":"Revenue Min"},"description":"Minimum latest reported revenue in EUR, inclusive. Most German companies file abridged accounts with no profit-and-loss statement, so revenue is the scarcest financial figure — prefer `total_assets_min` to filter on size."},{"name":"revenue_max","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum latest reported revenue in EUR, inclusive.","title":"Revenue Max"},"description":"Maximum latest reported revenue in EUR, inclusive."},{"name":"profit_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum latest reported profit in EUR, inclusive.","title":"Profit Min"},"description":"Minimum latest reported profit in EUR, inclusive."},{"name":"profit_max","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum latest reported profit in EUR, inclusive.","title":"Profit Max"},"description":"Maximum latest reported profit in EUR, inclusive."},{"name":"total_assets_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Minimum balance-sheet total (Bilanzsumme) in EUR, inclusive. Every filing company publishes a balance sheet, so this is the widest-reaching size filter.","title":"Total Assets Min"},"description":"Minimum balance-sheet total (Bilanzsumme) in EUR, inclusive. Every filing company publishes a balance sheet, so this is the widest-reaching size filter."},{"name":"total_assets_max","in":"query","required":false,"schema":{"anyOf":[{"type":"number"},{"type":"null"}],"description":"Maximum balance-sheet total (Bilanzsumme) in EUR, inclusive.","title":"Total Assets Max"},"description":"Maximum balance-sheet total (Bilanzsumme) in EUR, inclusive."},{"name":"employee_count_min","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Minimum reported employee count, inclusive. Reporting headcount is optional for most German legal forms, so this is the narrowest of the size filters — expect small result sets.","title":"Employee Count Min"},"description":"Minimum reported employee count, inclusive. Reporting headcount is optional for most German legal forms, so this is the narrowest of the size filters — expect small result sets."},{"name":"employee_count_max","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"description":"Maximum reported employee count, inclusive.","title":"Employee Count Max"},"description":"Maximum reported employee count, inclusive."},{"name":"wz_2025_code","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"WZ 2025 industry code (German *Klassifikation der Wirtschaftszweige 2025*, compatible with NACE Rev. 2.1), at any level of the hierarchy: `K` (section), `62` (division), `62.1` (group), `62.10` (class) or `62.10.3` (subclass). Matches the company's primary code and all its parent levels. Multi-valued, OR-merged with `industry_slug`.\n\n**Codes are WZ 2025, not WZ 2008** — the two are not interchangeable and a WZ 2008 code usually matches nothing. Classes were renumbered (`62.01` became `62.10`) and the section letters were reassigned, so WZ 2008's `K` (finance) is now `L`, and `K` is IT and telecoms.","examples":[["62.10","62.20"]],"title":"Wz 2025 Code"},"description":"WZ 2025 industry code (German *Klassifikation der Wirtschaftszweige 2025*, compatible with NACE Rev. 2.1), at any level of the hierarchy: `K` (section), `62` (division), `62.1` (group), `62.10` (class) or `62.10.3` (subclass). Matches the company's primary code and all its parent levels. Multi-valued, OR-merged with `industry_slug`.\n\n**Codes are WZ 2025, not WZ 2008** — the two are not interchangeable and a WZ 2008 code usually matches nothing. Classes were renumbered (`62.01` became `62.10`) and the section letters were reassigned, so WZ 2008's `K` (finance) is now `L`, and `K` is IT and telecoms."},{"name":"industry_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/IndustrySlug"}},{"type":"null"}],"description":"High-level firmendata industry category. Expands server-side to WZ 2025 divisions. Multi-valued, OR-merged with `wz_2025_code`.","examples":[["technology"]],"title":"Industry Slug"},"description":"High-level firmendata industry category. Expands server-side to WZ 2025 divisions. Multi-valued, OR-merged with `wz_2025_code`."},{"name":"rechtsform","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Rechtsform"}},{"type":"null"}],"description":"German, Swiss or Austrian legal form. Multi-valued. Common abbreviations and the long forms are accepted too (`eK`, `UG (haftungsbeschränkt)`, `GmbH & Co KG`).","examples":[["GmbH","AG"]],"title":"Rechtsform"},"description":"German, Swiss or Austrian legal form. Multi-valued. Common abbreviations and the long forms are accepted too (`eK`, `UG (haftungsbeschränkt)`, `GmbH & Co KG`)."},{"name":"person_name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Name of an associated person — current or historical board member, shareholder or partner. Combines with the other filters, which narrow the companies that person is linked to.","examples":["schulze"],"title":"Person Name"},"description":"Name of an associated person — current or historical board member, shareholder or partner. Combines with the other filters, which narrow the companies that person is linked to."},{"name":"cpv_code","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"CPV (Common Procurement Vocabulary) prefix from the EU tenders a company won — `45` matches all construction contracts.","examples":["45"],"title":"Cpv Code"},"description":"CPV (Common Procurement Vocabulary) prefix from the EU tenders a company won — `45` matches all construction contracts."},{"name":"avg_birth_year_min","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2100,"minimum":1900},{"type":"null"}],"description":"Minimum average birth year across the company's associated persons.","title":"Avg Birth Year Min"},"description":"Minimum average birth year across the company's associated persons."},{"name":"avg_birth_year_max","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2100,"minimum":1900},{"type":"null"}],"description":"Maximum average birth year across the company's associated persons.","title":"Avg Birth Year Max"},"description":"Maximum average birth year across the company's associated persons."},{"name":"legal_status","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/LegalStatus"}},{"type":"null"}],"description":"Company lifecycle status according to the commercial register and insolvency notices, including Swiss Official Gazette of Commerce (SHAB) bankruptcy and composition notices. Multi-valued.\n\n- `active` — no insolvency or dissolution on record\n- `insolvent` — proceedings open or preliminary measures in force\n- `in_liquidation` — dissolved, with a Liquidator in office\n- `dissolved` — dissolved with no Liquidator, or a proceeding since lifted\n- `deleted` — removed from the register; outranks the others\n\nThe five are disjoint and exhaustive, so selecting every value is the same as selecting none.","examples":[["insolvent","in_liquidation"]],"title":"Legal Status"},"description":"Company lifecycle status according to the commercial register and insolvency notices, including Swiss Official Gazette of Commerce (SHAB) bankruptcy and composition notices. Multi-valued.\n\n- `active` — no insolvency or dissolution on record\n- `insolvent` — proceedings open or preliminary measures in force\n- `in_liquidation` — dissolved, with a Liquidator in office\n- `dissolved` — dissolved with no Liquidator, or a proceeding since lifted\n- `deleted` — removed from the register; outranks the others\n\nThe five are disjoint and exhaustive, so selecting every value is the same as selecting none."},{"name":"company_size","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/CompanySize"}},{"type":"null"}],"description":"Statutory size class under § 267 / § 267a HGB. Multi-valued.\n\n- `kleinst` — Kleinstkapitalgesellschaft (§ 267a)\n- `klein` — kleine Kapitalgesellschaft (§ 267 Abs. 1)\n- `mittelgross` — mittelgroße Kapitalgesellschaft (§ 267 Abs. 2)\n\nRead from the filing's form or a declaration in its notes (Anhang): a company that omits its profit-and-loss statement (§ 326 Abs. 1) or collapses it into a Rohergebnis (§ 276) is claiming a relief only a company of that size may claim. Publishing *more* than required is permitted at every size and asserts nothing, so a full P&L alone establishes no class — for those the reported `revenue` is the answer. The values are therefore not exhaustive, and selecting all is a real filter meaning \"the filing form implies a size class\", not a no-op the way selecting every `legal_status` is. `gross` is not offered because no relief can assert largeness: the company that claims nothing is exactly the large one.\n\nBecause the § 267 test is \"does not exceed at least two of three\" (balance-sheet total, revenue, employees), a class on its own does not bound revenue — it does so only where a second criterion is already over its limit. This filter is a size filter, not a revenue filter.","examples":[["klein","kleinst"]],"title":"Company Size"},"description":"Statutory size class under § 267 / § 267a HGB. Multi-valued.\n\n- `kleinst` — Kleinstkapitalgesellschaft (§ 267a)\n- `klein` — kleine Kapitalgesellschaft (§ 267 Abs. 1)\n- `mittelgross` — mittelgroße Kapitalgesellschaft (§ 267 Abs. 2)\n\nRead from the filing's form or a declaration in its notes (Anhang): a company that omits its profit-and-loss statement (§ 326 Abs. 1) or collapses it into a Rohergebnis (§ 276) is claiming a relief only a company of that size may claim. Publishing *more* than required is permitted at every size and asserts nothing, so a full P&L alone establishes no class — for those the reported `revenue` is the answer. The values are therefore not exhaustive, and selecting all is a real filter meaning \"the filing form implies a size class\", not a no-op the way selecting every `legal_status` is. `gross` is not offered because no relief can assert largeness: the company that claims nothing is exactly the large one.\n\nBecause the § 267 test is \"does not exceed at least two of three\" (balance-sheet total, revenue, employees), a class on its own does not bound revenue — it does so only where a second criterion is already over its limit. This filter is a size filter, not a revenue filter."},{"name":"membership","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Membership"}},{"type":"null"}],"description":"Companies listed in at least one of these external registries. Multi-valued.\n\n- `Steuerberaterkammer` — BStBK directory\n- `Wirtschaftsprueferkammer` — WPK directory\n- `bbh` — Bundesverband der Bilanzbuchhalter\n- `BaFin` — supervised institutes\n- `LEI` — holds an active Legal Entity Identifier","examples":[["BaFin","LEI"]],"title":"Membership"},"description":"Companies listed in at least one of these external registries. Multi-valued.\n\n- `Steuerberaterkammer` — BStBK directory\n- `Wirtschaftsprueferkammer` — WPK directory\n- `bbh` — Bundesverband der Bilanzbuchhalter\n- `BaFin` — supervised institutes\n- `LEI` — holds an active Legal Entity Identifier"},{"name":"lei_code","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":20,"maxLength":20,"pattern":"^[A-Za-z0-9]{20}$"},{"type":"null"}],"description":"Exact LEI (ISO 17442), matched against the company's active LEI record. Case-insensitive.","examples":["529900T8BM49AURSDO55"],"title":"Lei Code"},"description":"Exact LEI (ISO 17442), matched against the company's active LEI record. Case-insensitive."},{"name":"ust_idnr","in":"query","required":false,"schema":{"anyOf":[{"type":"string","minLength":3,"maxLength":32},{"type":"null"}],"description":"Exact VAT identification number. German USt-IdNr and Austrian UIDs (ATU…) are accepted. Case-insensitive.","examples":["DE123456789"],"title":"Ust Idnr"},"description":"Exact VAT identification number. German USt-IdNr and Austrian UIDs (ATU…) are accepted. Case-insensitive."},{"name":"has_website","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Restrict to companies with (`true`) or without (`false`) a known website.","title":"Has Website"},"description":"Restrict to companies with (`true`) or without (`false`) a known website."},{"name":"has_email","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Restrict to companies with (`true`) or without (`false`) a known email.","title":"Has Email"},"description":"Restrict to companies with (`true`) or without (`false`) a known email."},{"name":"fetch_realtime","in":"query","required":false,"schema":{"type":"boolean","description":"Also search the German registers live for `q` / `company_name` (one is required with this flag) and append any companies not yet known to us, carrying identity and seat only. First page only. Adds a few seconds of latency and costs more credits; refresh failures never fail the request — check `freshness.realtime_fetching_status`.","default":false,"title":"Fetch Realtime"},"description":"Also search the German registers live for `q` / `company_name` (one is required with this flag) and append any companies not yet known to us, carrying identity and seat only. First page only. Adds a few seconds of latency and costs more credits; refresh failures never fail the request — check `freshness.realtime_fetching_status`."},{"name":"tender_role","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TenderRole"}},{"type":"null"}],"description":"Companies appearing in EU public-procurement notices (TED), in the selected role. Multi-valued.\n\n- `winner` — was awarded a public contract\n- `buyer` — published a notice as the contracting authority\n\nThe roles overlap and are *not* exhaustive — most of the register appears in neither — so unlike `legal_status`, selecting both is a real filter meaning \"appears in TED at all\". Coverage starts with notices published 2025-01-02. `buyer` is intrinsically small: most contracting authorities have no Handelsregister entry to match against.","examples":[["winner"]],"title":"Tender Role"},"description":"Companies appearing in EU public-procurement notices (TED), in the selected role. Multi-valued.\n\n- `winner` — was awarded a public contract\n- `buyer` — published a notice as the contracting authority\n\nThe roles overlap and are *not* exhaustive — most of the register appears in neither — so unlike `legal_status`, selecting both is a real filter meaning \"appears in TED at all\". Coverage starts with notices published 2025-01-02. `buyer` is intrinsically small: most contracting authorities have no Handelsregister entry to match against."},{"name":"family_managed","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Restrict to companies where two or more members of one family hold an ownership or governing role (`true`), or where the people on record are unrelated (`false`).\n\nDerived from the register: shared surnames among owners and officers, a founder's surname carried in the company name, family wording in the name (`Gebr.`, `& Söhne`), a generation gap between two relatives, or a shared address. Companies whose register entry shows only one person and whose name says nothing are reported as neither — they are excluded from both `true` and `false` rather than assumed unrelated. Spouses who took different surnames are not visible to this filter, so it under-reports rather than over-claims.","examples":[true],"title":"Family Managed"},"description":"Restrict to companies where two or more members of one family hold an ownership or governing role (`true`), or where the people on record are unrelated (`false`).\n\nDerived from the register: shared surnames among owners and officers, a founder's surname carried in the company name, family wording in the name (`Gebr.`, `& Söhne`), a generation gap between two relatives, or a shared address. Companies whose register entry shows only one person and whose name says nothing are reported as neither — they are excluded from both `true` and `false` rather than assumed unrelated. Spouses who took different surnames are not visible to this filter, so it under-reports rather than over-claims."},{"name":"founder_led","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Restrict to companies where a person holding an ownership or governing role at first registration is still in office (`true`), or where the founding officers have all been replaced (`false`).\n\nRequires the chronological register extract, so companies whose register history is unavailable are excluded from both values. Companies whose extract begins with a transfer from another register court are also excluded: their first entry records the move, not the founding.","examples":[true],"title":"Founder Led"},"description":"Restrict to companies where a person holding an ownership or governing role at first registration is still in office (`true`), or where the founding officers have all been replaced (`false`).\n\nRequires the chronological register extract, so companies whose register history is unavailable are excluded from both values. Companies whose extract begins with a transfer from another register court are also excluded: their first entry records the move, not the founding."},{"name":"succession_risk","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Restrict to founder-led companies whose oldest serving founder has reached 65 (`true`), or has not (`false`). Companies that are not founder-led, and founders with no birth date on record, are excluded from both values.","examples":[true],"title":"Succession Risk"},"description":"Restrict to founder-led companies whose oldest serving founder has reached 65 (`true`), or has not (`false`). Companies that are not founder-led, and founders with no birth date on record, are excluded from both values."}],"responses":{"200":{"description":"Page of search hits with pagination, echoed filters, and execution time.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/search?company_name=bayerische+motoren+werke&limit=10\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/search?company_name=bayerische+motoren+werke&limit=10\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/search?company_name=bayerische+motoren+werke&limit=10\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/companies/{eu_id}":{"get":{"tags":["Company"],"summary":"Company detail","description":"Everything you need to render a company landing page in a single call.\n\n- **Identity & registration** — names, legal form, register entry, founding dates, registered address\n- **Financial headline** — latest-year revenue, profit, assets, liabilities, equity, employee count\n- **Business & industry** — trade description, products, primary WZ 2025 code with the full category tree\n- **Management** — register entry members (managing directors, authorised signatories, supervisory board)\n- **Ownership (LEI graph)** — direct parent and the first 25 direct subsidiaries via GLEIF, with the total count\n- **Contact & web presence** — primary domain, Impressum URL, primary email, phone and fax numbers, and discovered social profiles\n- **Insolvency** — current status, court, case number, dissolution flag, most recent event date\n- **AI insights** — company summary, outlook, and risk + opportunity keywords in German and English\n- **Documents** — downloadable register documents available for the company (Aktueller Abdruck, Chronologischer Abdruck, Liste der Gesellschafter, Articles of Association — Gesellschaftsvertrag / Satzung / Statut depending on legal form, Anmeldung, Musterprotokoll); fetch a presigned URL via `/companies/{eu_id}/documents/download`; `is_outdated` flags a register extract older than the latest register entry\n\nFor multi-year history, employee time series, relationships, and Bilanz publications, call `/companies/{eu_id}/financials`.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getCompanyDetail","parameters":[{"name":"eu_id","in":"path","required":true,"schema":{"type":"string","minLength":3,"maxLength":64,"description":"firmendata company identifier (also referred to as `eu_id`).","examples":["DEF1103R.HRB279792B"],"title":"Eu Id"},"description":"firmendata company identifier (also referred to as `eu_id`)."},{"name":"fetch_realtime","in":"query","required":false,"schema":{"type":"boolean","description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, refresh the company's register snapshot from the German registries before building the response, so the underlying data is as fresh as possible. Adds upstream latency (typically several seconds). Refresh failures do not fail the request — the most recent available data is returned instead. The chronological register history is refreshed by `/v1/companies/{eu_id}/history` instead — this endpoint does not refresh it.","default":false,"title":"Fetch Realtime"},"description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, refresh the company's register snapshot from the German registries before building the response, so the underlying data is as fresh as possible. Adds upstream latency (typically several seconds). Refresh failures do not fail the request — the most recent available data is returned instead. The chronological register history is refreshed by `/v1/companies/{eu_id}/history` instead — this endpoint does not refresh it."}],"responses":{"200":{"description":"The company's detail profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDetail"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/companies/{eu_id}/financials":{"get":{"tags":["Company"],"summary":"Company financials","description":"Multi-year financial profile for one company.\n\n- **Aggregated summary** — latest-year revenue, profit, total assets, total liabilities and equity, and equity\n- **Multi-year history** — per fiscal year: top-line metrics plus the top-level balance-sheet and P&L positions (see *Two levels of detail* below)\n- **Employee time series** — total, full-time, and part-time headcount per year\n- **Group relationships** — parent company and known subsidiaries sourced from consolidated filings\n- **Filed Bilanzen** — list of Jahresabschluss and Konzernabschluss filings with type and publication date (PDF downloads are not exposed in v1)\n\n### Two levels of detail\n\n**Detailed (default)** — `GET /v1/companies/{eu_id}/financials`\n\nEvery row of the filed statements at every depth in `history.profit_and_loss`, `history.assets` and `history.liabilities_and_equity` — e.g. Löhne und Gehälter under Personalaufwand, or Grundstücke and Technische Anlagen under Sachanlagen — each with its position in the HGB hierarchy (`section` … `subsubsubsection`) and current and prior-year values, plus everything the lean level has. Responses can be large (often 100 KB+ for groups); combine with `years=N` to keep them small.\n\n**Lean** — `GET /v1/companies/{eu_id}/financials?details=false`\n\nThe line-item arrays are left empty. Each entry of `history.metrics` still carries:\n\n- the headline figures: `revenue`, `profit`, `balance_sheet_total` (Summe Aktiva), `liabilities_and_equity_total` (Summe Passiva)\n- `balance_sheet` — the top-level positions of § 266 HGB: Anlagevermögen with Immaterielle Vermögensgegenstände, Sachanlagen and Finanzanlagen; Umlaufvermögen with Vorräte, Forderungen, Wertpapiere and Kassenbestand; Eigenkapital with Gezeichnetes Kapital and Rücklagen; Rückstellungen; Verbindlichkeiten by creditor; Rechnungsabgrenzung and latente Steuern\n- `income_statement` — the key positions of § 275 HGB: Umsatzerlöse, Materialaufwand, Personalaufwand, Abschreibungen, sonstige betriebliche Erträge/Aufwendungen, Beteiligungs- and Zinsergebnis, Steuern, Ergebnis nach Steuern, Jahresüberschuss\n\nA lean response is typically a few kilobytes — enough for screening, dashboards and bulk calls. Both levels cost the same.\n\nPositions are taken as filed, never computed: a position the filing does not show is `null`. Small companies file a shortened balance sheet and usually no P&L, so their `income_statement` is `null`.\n\n`years=N` limits every per-year array — metrics, line items, employee\nseries and filings — to the N most recent fiscal years on record.\n\nA company with no financial data on record at all (no figures, no\nheadcount, no filings, no group relationships) is answered with the empty\nshape and costs no credits.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getCompanyFinancials","parameters":[{"name":"eu_id","in":"path","required":true,"schema":{"type":"string","minLength":3,"maxLength":64,"description":"firmendata company identifier (also referred to as `eu_id`).","examples":["DEF1103R.HRB279792B"],"title":"Eu Id"},"description":"firmendata company identifier (also referred to as `eu_id`)."},{"name":"details","in":"query","required":false,"schema":{"type":"boolean","description":"Detail level. Default `true`: every filed P&L, assets and liabilities-and-equity row at every depth in `history.profit_and_loss`, `history.assets` and `history.liabilities_and_equity`. Pass `details=false` for the lean response: those arrays stay empty, and each year keeps only its top-level positions in `history.metrics[].balance_sheet` / `.income_statement`. Same credit cost.","examples":[false],"default":true,"title":"Details"},"description":"Detail level. Default `true`: every filed P&L, assets and liabilities-and-equity row at every depth in `history.profit_and_loss`, `history.assets` and `history.liabilities_and_equity`. Pass `details=false` for the lean response: those arrays stay empty, and each year keeps only its top-level positions in `history.metrics[].balance_sheet` / `.income_statement`. Same credit cost."},{"name":"include","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"const":"line_items","type":"string"}},{"type":"null"}],"description":"Deprecated: line items are now returned by default. Accepted for compatibility; `include=line_items` forces the detailed response even with `details=false`.","deprecated":true,"title":"Include"},"description":"Deprecated: line items are now returned by default. Accepted for compatibility; `include=line_items` forces the detailed response even with `details=false`.","deprecated":true},{"name":"years","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":1},{"type":"null"}],"description":"Only the N most recent fiscal years in each per-year array (metrics, line items, employee series, filings). Omit for the full history.","examples":[5],"title":"Years"},"description":"Only the N most recent fiscal years in each per-year array (metrics, line items, employee series, filings). Omit for the full history."}],"responses":{"200":{"description":"Aggregated and historic financial data for the company.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyFinancials"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/financials\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/financials\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/financials\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/companies/{eu_id}/shareholders":{"get":{"tags":["Company"],"summary":"Shareholder cap table","description":"Latest aggregated Gesellschafterliste (cap table) for a GmbH or UG.\n\n- **Coverage status** — whether a cap table is `available`, `not_applicable` (the legal form does not file Gesellschafterlisten), or `not_filed` (expected but missing)\n- **Shareholders** — each participant with share count, percentage of capital, and share class\n- **As-of metadata** — filing date of the aggregated list\n- **`fetch_realtime`** — optional. When `true`, retrieve the current shareholder list from the German register before returning.\n  Adds upstream latency (typically several seconds). Refresh failures are surfaced via `freshness.realtime_fetching_status`; the response still\n  falls back to the most recent available cap table when a refresh fails.\n\nHistorical snapshots and cross-filing diffs are reserved for a later release.\n\nA response without a cap table (`coverage.status` other than `available`)\ncosts no credits.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getCompanyShareholders","parameters":[{"name":"eu_id","in":"path","required":true,"schema":{"type":"string","minLength":3,"maxLength":64,"description":"firmendata company identifier (also referred to as `eu_id`).","examples":["DEF1103R.HRB279792B"],"title":"Eu Id"},"description":"firmendata company identifier (also referred to as `eu_id`)."},{"name":"fetch_realtime","in":"query","required":false,"schema":{"type":"boolean","description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, retrieve the current shareholder list from the German register before responding. Adds latency (typically several seconds). Refresh failures are surfaced via `freshness.realtime_fetching_status` rather than failing the request.","default":false,"title":"Fetch Realtime"},"description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, retrieve the current shareholder list from the German register before responding. Adds latency (typically several seconds). Refresh failures are surfaced via `freshness.realtime_fetching_status` rather than failing the request."}],"responses":{"200":{"description":"Current cap table with coverage status.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareholdersReport"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/shareholders\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/shareholders\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/shareholders\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/companies/{eu_id}/ubo":{"get":{"tags":["Company"],"summary":"Ultimate beneficial owner (UBO) report","description":"Walk the company's ownership chain and identify the natural persons\nwho ultimately benefit from it.\n\nFor every German GmbH/UG encountered in the chain, the latest filed\nGesellschafterliste is read; recursion stops at natural persons,\nforeign organisations, or any organisation without a German\nGesellschafterliste obligation. Each branch carries its direct share\npercentage. Beneficial-owner attribution follows the German\n\"all-or-nothing\" rule: each link in the chain is independently checked\nagainst the 25 % control threshold (covering both >50 % majority\ncontrol and >25 % Sperrminorität under the BVA's post-TraFinG\nreading of §3 Abs. 2 Nr. 3 GwG). The share attributed to a UBO is\nthe share at the final hop into the root — the actual capital stake\nthe UBO ultimately controls, not the multiplicative product.\n\n- **Graph** — every node and directed `source → target` edge\n  traversed during the walk. Use it to render an ownership tree or to\n  audit which branches stop short.\n- **Beneficial owners** — natural persons attributed more than 25 %\n  of the root via direct holdings, controlled chains, or the sum of\n  both, sorted descending. Empty when no person crosses the threshold\n  (e.g. ownership diluted across many parties or the chain ends in\n  unresolved organisations). Fictional UBO under §3 Abs. 2 S. 5 GwG\n  is not surfaced.\n- **Potential beneficial owners** — unresolved organisations whose\n  summed effective share at the root crosses 25 % under the same\n  all-or-nothing rule. The natural person(s) controlling each entity\n  are candidate UBOs that we couldn't trace ourselves. Same-entity\n  dedup across multiple chain positions is by `(name, registered_\n  seat, country_code)`, so an org appearing twice with 15 % + 15 %\n  surfaces as one entry at 30 %.\n- **Coverage** — `coverage.status` distinguishes four states:\n  `available` (chain fully resolved, OR remaining unresolved\n  branches sum to ≤25 % effective share and cannot hide a UBO);\n  `partial` (an unresolved branch could hide a beneficial owner —\n  read `potential_beneficial_owners` and `coverage.reason`);\n  `not_filed` (no cap table on file); `not_applicable` (legal form\n  has no Gesellschafterliste obligation).\n- **Completeness** — `has_unresolved_branches` flags any non-root\n  unresolved node in the graph; whether that compromises the answer\n  is encoded in `coverage.status` (`partial` if so, otherwise\n  `available` with `coverage.reason` explaining why the unresolved\n  branches are immaterial).\n- **`fetch_realtime`** — optional. When `true`, refetch the latest\n  Liste der Gesellschafter for every German GmbH/UG in the chain\n  before building the graph. Adds noticeable latency (several seconds\n  per company in the chain). Failures are surfaced via\n  `freshness.realtime_fetching_status`; the graph still falls back to the most\n  recent available cap tables when a refresh fails.\n\n**Edge cases worth knowing:**\n\n- **Control passes through 100 %, not the chain product.** A holds\n  60 % of H, H holds 30 % of root → A is a UBO with\n  `effective_share_percent = 30`, not `18`. Each link is checked\n  independently against the 25 % threshold.\n- **Sperrminorität counts as control.** A 26 % blocking minority at\n  any intermediate level continues the chain; the 50 % majority bar\n  only matters as the higher of the two ways to qualify.\n- **Sub-threshold links break the chain.** A holds 15 % of H, H\n  holds 30 % of root → A is **not** attributed root ownership; H\n  isn't controlled by A.\n- **Direct positions aggregate even below 25 %.** A person holding\n  15 % + 15 % directly in the root is a UBO at 30 %.\n- **Multiple controlled branches sum.** A controls X and Y; X holds\n  30 %, Y holds 40 % of root → A's `effective_share_percent = 70`\n  (each branch is independently a control link, and the root-edge\n  shares add up).\n\nDesigned for KYC workflows where the freshest possible chain matters.\n\nA response with `coverage.status` `not_filed` or `not_applicable` carries no\nownership data and costs no credits.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getCompanyUbo","parameters":[{"name":"eu_id","in":"path","required":true,"schema":{"type":"string","minLength":3,"maxLength":64,"description":"firmendata company identifier (also referred to as `eu_id`).","examples":["DEF1103R.HRB279792B"],"title":"Eu Id"},"description":"firmendata company identifier (also referred to as `eu_id`)."},{"name":"fetch_realtime","in":"query","required":false,"schema":{"type":"boolean","description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, refetch the latest Liste der Gesellschafter for every German GmbH/UG visited in the ownership chain before building the graph. Adds noticeable latency. Failures are surfaced via `freshness.realtime_fetching_status` rather than failing the request.","default":false,"title":"Fetch Realtime"},"description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, refetch the latest Liste der Gesellschafter for every German GmbH/UG visited in the ownership chain before building the graph. Adds noticeable latency. Failures are surfaced via `freshness.realtime_fetching_status` rather than failing the request."}],"responses":{"200":{"description":"UBO graph plus beneficial-owner roll-up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UboReport"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/ubo\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/ubo\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/ubo\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/companies/{eu_id}/history":{"get":{"tags":["Company"],"summary":"Chronological register history","description":"Aggregated chronological register-entry history for a company.\n\nFor each kind of change — company name (`names`), seat (`seats`), share\ncapital (`share_capital`), officers (`board_changes`), business purpose,\nlegal form and articles — the endpoint returns the full timeline of\nentries that affected it, oldest first. `current_board` is who holds office\nnow, taking appointments, departures and corrections into account.\nDates are ISO 8601; people use the same `person` object as the company\ndetail.\n\n- **`fetch_realtime`** — optional. When `true`, refresh the\n  underlying register history from the German registries before\n  responding. Adds upstream latency (typically several seconds).\n  Failures are surfaced via `freshness.realtime_fetching_status`; the response\n  still falls back to the most recent available data when a refresh\n  fails.\n\n`coverage.status` is `not_available` when no chronological extract exists\nfor the company — the Swiss commercial register publishes none, Austrian\nhistory is not available yet, and some German entries have not been\nretrieved yet. Such responses are not charged;\nSwiss companies still receive their legal-status timeline from the Swiss Official Gazette of Commerce (SHAB).\nA 404 means the company itself is unknown.\nThe same data backs the `history` webhook subscription type, so the\nshape returned here is exactly the shape downstream consumers fetch\nwhen responding to a `history.updated` webhook.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getCompanyHistory","parameters":[{"name":"eu_id","in":"path","required":true,"schema":{"type":"string","minLength":3,"maxLength":64,"description":"firmendata company identifier (also referred to as `eu_id`).","examples":["DEF1103R.HRB279792B"],"title":"Eu Id"},"description":"firmendata company identifier (also referred to as `eu_id`)."},{"name":"fetch_realtime","in":"query","required":false,"schema":{"type":"boolean","description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, refresh the chronological register history from the German registries before responding. Adds upstream latency (typically several seconds). Refresh failures are surfaced via `freshness.realtime_fetching_status` rather than failing the request.","default":false,"title":"Fetch Realtime"},"description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, refresh the chronological register history from the German registries before responding. Adds upstream latency (typically several seconds). Refresh failures are surfaced via `freshness.realtime_fetching_status` rather than failing the request."}],"responses":{"200":{"description":"Chronological register history grouped by category.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyHistory"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/history\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/history\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/history\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/companies/{eu_id}/documents/download":{"get":{"tags":["Documents"],"summary":"Download a register document","description":"Resolve one register document for the company and return a\nshort-lived presigned download URL alongside its metadata.\n\n- **`file_type`** — required. One of:\n\n  | `file_type` | German term | Coverage |\n  |---|---|---|\n  | `register_extract_current` | Aktueller Abdruck | Every Handelsregister-registered company. |\n  | `register_extract_chronological` | Chronologischer Abdruck | Every Handelsregister-registered company. |\n  | `shareholder_list` | Liste der Gesellschafter | GmbH and UG (haftungsbeschränkt) only. Companies founded via the simplified procedure (§2 Abs. 1a GmbHG) file no separate Liste — request `model_protocol` instead to download their founding deed. **For parsed cap-table data** (which already auto-falls-back to the Musterprotokoll), call `/companies/{eu_id}/shareholders` rather than this endpoint. |\n  | `articles_of_association` | Gesellschaftsvertrag / Satzung / Statut (the German name varies by legal form: Gesellschaftsvertrag for GmbH/KG/OHG/GbR, Satzung for AG/eG/Verein, Statut for some specific forms) | Most companies — but not those founded via the simplified procedure, which use a Musterprotokoll (`model_protocol`) in place of a constitutional document. |\n  | `company_registration` | Anmeldung | Any newly-registered company. |\n  | `model_protocol` | Musterprotokoll | **Only** companies founded with the simplified procedure under §2 Abs. 1a GmbHG. Legally substitutes for both the constitutional document (Gesellschaftsvertrag / Satzung / Statut) and the Liste der Gesellschafter for those companies — it names the founders and their share allocations directly. |\n\n  Wire values mirror the corresponding `subscription_type` values on\n  `POST /v1/subscriptions`, so a webhook event_type like\n  `articles_of_association.updated` can be passed straight through here\n  to download the file that triggered it.\n- **`file_id`** — optional. When omitted, falls back to the latest published\n  file of the requested type.\n- **`document_id`** — optional catalog identifier (`doc_<int>`) from\n  `GET /v1/companies/{eu_id}/documents`. Downloads that specific document version,\n  including older versions, fetching it on demand when no stored copy exists.\n  `file_type` must match. Cannot be combined with `file_id` or\n  `fetch_realtime=true`. Register extracts have no catalog identifier;\n  request them by `file_type`.\n- **`fetch_realtime`** — optional. When `true`, fetch the requested\n  `file_type` from the German registries before resolving the file, so the\n  presigned URL points at the freshest version. Adds upstream latency\n  (typically several seconds). Failures are surfaced via\n  `freshness.realtime_fetching_status`; the response still falls back to the most\n  recent available file when realtime fetching fails.\n\nReturns `404` when no matching document is available — the `detail`\nfield distinguishes whether the document is unknown to the German\nregistries, whether the company is no longer present in the registries,\nor whether the registries were unreachable. A `404` costs no credits. The\n`download_url` is valid for 1 day; refetch this endpoint to obtain a new\nURL when it expires.\n\n`is_outdated` flags a register extract older than the company's latest\nregister entry; request it with `fetch_realtime=true` for a current copy.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"downloadCompanyDocument","parameters":[{"name":"eu_id","in":"path","required":true,"schema":{"type":"string","minLength":3,"maxLength":64,"description":"firmendata company identifier (also referred to as `eu_id`).","examples":["DEF1103R.HRB279792B"],"title":"Eu Id"},"description":"firmendata company identifier (also referred to as `eu_id`)."},{"name":"file_type","in":"query","required":true,"schema":{"enum":["register_extract_current","register_extract_chronological","shareholder_list","articles_of_association","company_registration","model_protocol"],"type":"string","description":"Document type to download.","title":"File Type"},"description":"Document type to download."},{"name":"file_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Specific document id (as returned in the company detail `documents[]` block). Defaults to the latest published file of `file_type` when omitted.","examples":["file_12345"],"title":"File Id"},"description":"Specific document id (as returned in the company detail `documents[]` block). Defaults to the latest published file of `file_type` when omitted."},{"name":"document_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^doc_[0-9]+$"},{"type":"null"}],"description":"Specific document version from the live document list. Cannot be combined with `file_id` or `fetch_realtime=true`.","title":"Document Id"},"description":"Specific document version from the live document list. Cannot be combined with `file_id` or `fetch_realtime=true`."},{"name":"fetch_realtime","in":"query","required":false,"schema":{"type":"boolean","description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, fetch the requested `file_type` from the German registries before resolving the file, so the presigned URL points at the freshest version. Adds upstream latency (typically several seconds). Failures are surfaced via `freshness.realtime_fetching_status` rather than failing the request.","default":false,"title":"Fetch Realtime"},"description":"Only affects German (DE) companies; ignored for Swiss (CH) and Austrian (AT) companies, with no realtime surcharge. When `true`, fetch the requested `file_type` from the German registries before resolving the file, so the presigned URL points at the freshest version. Adds upstream latency (typically several seconds). Failures are surfaced via `freshness.realtime_fetching_status` rather than failing the request."}],"responses":{"200":{"description":"Document metadata plus a 1-day presigned download URL.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDocumentDownload"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/documents/download\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/documents/download\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/documents/download\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/companies/{eu_id}/documents":{"get":{"tags":["Documents"],"summary":"List a company's register documents (live)","description":"Check the German registries live and list register documents,\nincluding older document versions. This typically takes several seconds.\n\nPass a document's `document_id` and its `type` as `file_type` to\n`GET /v1/companies/{eu_id}/documents/download` to download that version.\n`register_extract_current` and `register_extract_chronological` are generated\non request and have no `document_id`; download them by `file_type`.\n`stored` indicates that a copy is already available for immediate download.\n\nWhen the registries are unreachable or the company is no longer listed,\nthe response serves the stored catalog with the outcome in `freshness`.\nUnreachable-registry, unavailable-company and empty answers are not billed.\nSwiss and Austrian companies return an empty list with `coverage.status=not_applicable`.\nThis endpoint always checks live and accepts no `fetch_realtime` parameter.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"listCompanyDocuments","parameters":[{"name":"eu_id","in":"path","required":true,"schema":{"type":"string","minLength":3,"maxLength":64,"description":"firmendata company identifier.","title":"Eu Id"},"description":"firmendata company identifier."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDocumentList"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/documents\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/documents\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/companies/DEF1103R.HRB279792B/documents\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/subscriptions":{"post":{"tags":["Subscriptions"],"summary":"Create subscription","description":"Create a webhook, email, or async (poll-only) subscription for a single\nGerman (DE) company. Subscriptions are currently available for German\ncompanies only.\n\n## Async (poll-only) subscriptions\n\nPass `\"notification_type\": null` (and omit both `webhook_url` and\n`recipient_email`) to create a poll-only subscription. firmendata\nperforms the same change detection as for webhook/email, but instead of\ncalling out to your infrastructure on each change it records the\nrendered payload as a `subscription_event`. Retrieve change events\nafterwards via `GET /v1/subscriptions/{subscription_id}/events`,\nwhere `subscription_id` is the value returned in this response (the\n\"job id\" the response carries). `webhook_secret` is `null` for async\nsubscriptions — there is no outbound HTTP to sign.\n\n## Webhook signature verification\n\nfirmendata signs **every** outgoing webhook request with HMAC-SHA256\nso receivers can verify the request actually came from firmendata.\nVerify on every incoming POST:\n\n* `X-Firmendata-Signature: sha256=<hex>` — HMAC-SHA256 of\n  `f\"{X-Firmendata-Timestamp}.{raw_body}\"` keyed by the\n  `webhook_secret` returned in this response. Use a constant-time\n  comparison.\n* `X-Firmendata-Timestamp: <unix-seconds>` — reject values older than\n  5 minutes to defeat replay attacks.\n* `X-Firmendata-Delivery-Id: <uuid>` — idempotency key; safe to dedupe\n  on. firmendata may re-POST the same delivery id after a transient\n  receiver error.\n* `X-Firmendata-Event-Type: <subscription_type>.updated` — e.g.\n  `details.updated`, `doc_articles_of_association.updated`.\n\nThe response carries a one-time **`webhook_secret`**. Store it now —\nit is **not** recoverable later. To rotate, delete the subscription\nand re-create it.\n\n## Defaults\n\n* `mode` → `recurring` — see `mode` for the `one_time` alternative.\n* `notification_type` → `null` (async, poll-only) — see `notification_type` for the `webhook` / `email` alternatives.\n* `cadence` → `daily`.\n* `language` → `en` (affects email rendering only).\n\n## Email-mode rendering\n\nWhen `notification_type=email`, the recipient's inbox shows:\n\n* **Body table** with the company name, company id (`eu_id`),\n  notification type, publish date, and — for `doc_*` subscriptions —\n  the document type and file id. No authenticated `/v1/...` API URLs\n  are rendered (email recipients carry no bearer token); a single\n  public **\"View company on FirmenData\"** button links to\n  `https://firmendata.com/{language}/company/{eu_id}`.\n* **PDF attachment** (only for `doc_*` subscriptions) — the actual\n  register document (Articles of Association / Anmeldung /\n  Musterprotokoll / Liste der Gesellschafter) attached as a\n  `application/pdf` MIME part. Recipients can save / forward / parse\n  the file straight from their inbox.\n\nParsed-data subscriptions (`details`, `history`, `shareholders`,\n`ubo`) deliver the body table only — the structured JSON itself\nremains accessible via the v1 API for authenticated clients, and\nthe email recipient gets a human summary.\n\n## Cadence semantics\n\n`cadence` controls how often you wish to receive notifications. A\nnotification is only delivered when there is an actual change since\nthe previous successful delivery — no update means no notification.\n`immediately` delivers an update as soon as it is detected, with a\nservice-level objective of within 1 hour of publication.\n`daily` / `weekly` / `monthly` batch the check at the named cadence.\n\nFor `recurring` subscriptions, the **first** delivery is a snapshot\nof the current state; after that, deliveries only fire on actual\nupdates.\n\nFor `one_time` subscriptions, `cadence` is the retry spacing while\nwe wait for the data to become available; the subscription stops on\nthe first successful delivery.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"createSubscription","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCreateRequest"},"examples":{"emailOneTime":{"summary":"Email, one-time delivery","value":{"eu_id":"DEF1103R.HRB279792B","subscription_type":"details","mode":"one_time","notification_type":"email","recipient_email":"alerts@example.com"}}}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCreated"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"409":{"description":"The request conflicts with the current resource state (e.g. duplicate subscription).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/conflict","title":"Conflict.","status":409,"detail":"A subscription for this company, type, and notification channel already exists.","message":"A subscription for this company, type, and notification channel already exists.","instance":"/v1/subscriptions","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X POST \"https://api.firmendata.com/v1/subscriptions\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.post(\n    \"https://api.firmendata.com/v1/subscriptions\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/subscriptions\", {\n  method: \"POST\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]},"get":{"tags":["Subscriptions"],"summary":"List subscriptions","description":"Returns the subscriptions owned by the calling user, newest first, one page at a time. Pass `pagination.next_cursor` back as `cursor` for the next page.\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"listSubscriptions","parameters":[{"name":"eu_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to subscriptions for one company.","title":"Eu Id"},"description":"Filter to subscriptions for one company."},{"name":"subscription_type","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubscriptionType"},{"type":"null"}],"description":"Filter by subscription type.","title":"Subscription Type"},"description":"Filter by subscription type."},{"name":"mode","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SubscriptionMode"},{"type":"null"}],"description":"Filter by `recurring` or `one_time`.","title":"Mode"},"description":"Filter by `recurring` or `one_time`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Subscriptions per page.","default":100,"title":"Limit"},"description":"Subscriptions per page."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"description":"Opaque pagination cursor from `pagination.next_cursor`.","title":"Cursor"},"description":"Opaque pagination cursor from `pagination.next_cursor`."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Rows to skip. Prefer `cursor`; the two cannot be combined.","default":0,"title":"Offset"},"description":"Rows to skip. Prefer `cursor`; the two cannot be combined."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionList"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/subscriptions\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/subscriptions\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/subscriptions\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/subscriptions/events/{event_id}":{"get":{"tags":["Subscriptions"],"summary":"Get event","description":"Returns the full event including the JSON body firmendata POSTed and the `request_signature` / `request_timestamp` needed to re-verify the HMAC offline.\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getEvent","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionEvent"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/subscriptions/events/{event_id}\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/subscriptions/events/{event_id}\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/subscriptions/events/{event_id}\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/subscriptions/events/{event_id}/resend":{"post":{"tags":["Subscriptions"],"summary":"Resend event","description":"Re-sends a previously delivered webhook event to the subscription's current `webhook_url`. The body is cloned from the stored event verbatim; only `event_id` and `delivered_at` are refreshed so the receiver sees a distinct delivery it can dedupe on. Creates a new event — the original is left untouched.\n\nOnly valid for webhook subscriptions whose original event has a stored `request_body`. Email events, async (poll-only) events, and older events without recorded request bodies return 422 — there's nothing to re-POST.\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"resendEvent","parameters":[{"name":"event_id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"title":"Event Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionEventResendResponse"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X POST \"https://api.firmendata.com/v1/subscriptions/events/{event_id}/resend\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.post(\n    \"https://api.firmendata.com/v1/subscriptions/events/{event_id}/resend\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/subscriptions/events/{event_id}/resend\", {\n  method: \"POST\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/subscriptions/{subscription_id}/events":{"get":{"tags":["Subscriptions"],"summary":"List events","description":"Returns delivery attempts for `subscription_id`, newest first. Each event includes the exact JSON body firmendata POSTed plus the signing material, so customers can render a Stripe-style history view and re-verify signatures offline.\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"listEvents","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"title":"Subscription Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Events per page.","default":50,"title":"Limit"},"description":"Events per page."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":256},{"type":"null"}],"description":"Opaque pagination cursor from `pagination.next_cursor`.","title":"Cursor"},"description":"Opaque pagination cursor from `pagination.next_cursor`."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Rows to skip. Prefer `cursor`; the two cannot be combined.","default":0,"title":"Offset"},"description":"Rows to skip. Prefer `cursor`; the two cannot be combined."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionEventList"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/subscriptions/{subscription_id}/events\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/subscriptions/{subscription_id}/events\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/subscriptions/{subscription_id}/events\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/subscriptions/{subscription_id}":{"get":{"tags":["Subscriptions"],"summary":"Get subscription","description":"Returns the subscription plus the most recent delivery attempt embedded in `last_delivery`. Use this endpoint to poll the status of a `one_time` subscription while you wait for the data to become available.\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getSubscription","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"title":"Subscription Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/subscriptions/{subscription_id}\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/subscriptions/{subscription_id}\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/subscriptions/{subscription_id}\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]},"delete":{"tags":["Subscriptions"],"summary":"Delete subscription","description":"Permanently deletes the subscription and its delivery history. Returns `204 No Content` on success and `404` when the subscription does not exist or belongs to another user.\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"deleteSubscription","parameters":[{"name":"subscription_id","in":"path","required":true,"schema":{"type":"string","minLength":1,"maxLength":64,"title":"Subscription Id"}}],"responses":{"204":{"description":"Successful Response","headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X DELETE \"https://api.firmendata.com/v1/subscriptions/{subscription_id}\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.delete(\n    \"https://api.firmendata.com/v1/subscriptions/{subscription_id}\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/subscriptions/{subscription_id}\", {\n  method: \"DELETE\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/subscriptions/test":{"post":{"tags":["Subscriptions"],"summary":"Test delivery","description":"Send one **real** sample notification — webhook **or** email — using\nthe same rendering, signing, and delivery path as production. **No\nsubscription is created**, nothing is stored and no data is fetched.\nSafe and cheap to call repeatedly from your CI / integration tests.\n\nPick the transport via `notification_type`:\n\n* **`webhook`** — POSTs a signed JSON body to `webhook_url`. The\n  request is always signed with the documented public test secret\n  `firmendata_test_secret_do_not_use_in_production`. The HMAC recipe\n  is identical to production, so any verification code that matches\n  with this constant will also match a real per-subscription secret.\n  Hard-code it in your unit tests; never reuse it for real\n  subscriptions.\n* **`email`** — composes the bilingual change-notification email\n  (subject + HTML body) and sends it to `recipient_email`. Subject\n  is prefixed with `[TEST]`; the body carries an explicit \"this is a\n  test\" banner so a human reading the inbox can't mistake it for a\n  live update. For `doc_*` subscription types the response also\n  attaches a tiny on-the-fly **sample PDF** so the customer's\n  attachment handling (parse Content-Type, save to disk,\n  forward to S3, …) can be exercised end to end. In production the\n  attachment is the real register PDF.\n\nNo retries — this is a fail-fast probe. The receiver's status, error\ndetail, and the exact bytes / headers / subject / body firmendata\nsent are all returned, so you can diff them against your verification\nroutine offline if your endpoint isn't yet live.\n\n`subscription_type` controls the payload shape, summary copy, and —\nfor `doc_*` types — the embedded download URL / file metadata block,\nidentical to what a real notification carries. `eu_id` is embedded in\nthe payload but does **not** need to be known to firmendata.\n\n## Webhook payload faithfulness\n\nTop-level `publish_date` and `links` are present on every delivery.\nThe per-type `data` block matches a production change delivery for\nthe same `subscription_type`:\n\n* Parsed-data types (`details`, `history`, `shareholders`, `ubo`)\n  deliver the **same response shape as the corresponding\n  `GET /v1/companies/{eu_id}[/...]` endpoint**. When the\n  `eu_id` you pass is known to firmendata the test endpoint embeds the\n  real current data; when it does not, `data` is a sparse placeholder\n  containing only `{eu_id}` — the field set is what varies, the schema\n  does not.\n* `doc_*` types deliver `{url, expires_at, file_id, file_type,\n  fetched_at}` directly under `data`. In test mode the `url` points at\n  the v1 documents endpoint (clearly identifiable as a test artifact);\n  in production it is a 7-day presigned URL to the real document.\n\nThe only top-level difference between test and production is an extra\n`_meta: {\"test\": true}` key — receivers that ignore unknown top-level\nkeys (recommended) need no test branch at all. The `subscription_id`\nis a freshly-minted UUID, not a real id; treat it as opaque.\n\n## Integration-test scenarios\n\nWebhook only — pick via `delivery_scenario`:\n\n* `success` (default) — single signed POST. Receiver should return 2xx.\n* `retry_delivery` — two POSTs back-to-back with byte-identical body,\n  signature, timestamp, and `X-Firmendata-Delivery-Id`. Mirrors how\n  production retries look after a 5xx so you can verify your\n  idempotent dedupe.\n* `bad_signature` — single POST signed with a wrong secret. Your\n  endpoint SHOULD reject with 4xx; that is the test passing.\n* `stale_timestamp` — single POST whose `X-Firmendata-Timestamp` is\n  10 minutes in the past. Your endpoint SHOULD reject with 4xx; that\n  is the test passing.\n\nPer-attempt detail (status, signature, timestamp, response excerpt)\nis returned in `attempts[]` regardless of scenario.\n\n## Sample receiver\n\nA minimal listener that verifies the signature and prints the body —\ndrop into your test harness, point your `webhook_url` at it, and call\nthis endpoint to drive it.\n\n### Python (Flask)\n\n```python\n# pip install flask\nimport hashlib\nimport hmac\nimport json\nfrom flask import Flask, abort, request\n\nWEBHOOK_SECRET = \"firmendata_test_secret_do_not_use_in_production\"\nMAX_TIMESTAMP_SKEW_SECONDS = 5 * 60\n\napp = Flask(__name__)\n\n\n@app.post(\"/firmendata/webhook\")\ndef receive_webhook():\n    raw = request.get_data()\n    sig = request.headers.get(\"X-Firmendata-Signature\", \"\")\n    ts = request.headers.get(\"X-Firmendata-Timestamp\", \"\")\n\n    expected = \"sha256=\" + hmac.new(\n        WEBHOOK_SECRET.encode(),\n        f\"{ts}.\".encode() + raw,\n        hashlib.sha256,\n    ).hexdigest()\n    if not hmac.compare_digest(sig, expected):\n        abort(401)\n\n    # Replay protection — reject anything older than 5 minutes.\n    import time\n    if abs(int(time.time()) - int(ts or 0)) > MAX_TIMESTAMP_SKEW_SECONDS:\n        abort(401)\n\n    payload = json.loads(raw)\n    print(\n        f\"[{payload['event_type']}] eu_id={payload['eu_id']} \"\n        f\"delivery_id={request.headers['X-Firmendata-Delivery-Id']}\"\n    )\n    print(json.dumps(payload, indent=2))\n    return (\"\", 200)\n\n\nif __name__ == \"__main__\":\n    app.run(port=8080)\n```\n\n### Node.js (Express)\n\n```js\n// npm install express\nimport crypto from \"node:crypto\";\nimport express from \"express\";\n\nconst WEBHOOK_SECRET = \"firmendata_test_secret_do_not_use_in_production\";\nconst MAX_TIMESTAMP_SKEW_SECONDS = 5 * 60;\n\nconst app = express();\n\napp.post(\n  \"/firmendata/webhook\",\n  express.raw({ type: \"application/json\" }),\n  (req, res) => {\n    const sig = req.header(\"X-Firmendata-Signature\") ?? \"\";\n    const ts = req.header(\"X-Firmendata-Timestamp\") ?? \"\";\n\n    const expected =\n      \"sha256=\" +\n      crypto\n        .createHmac(\"sha256\", WEBHOOK_SECRET)\n        .update(`${ts}.${req.body.toString()}`)\n        .digest(\"hex\");\n    const sigBuf = Buffer.from(sig);\n    const expBuf = Buffer.from(expected);\n    if (\n      sigBuf.length !== expBuf.length ||\n      !crypto.timingSafeEqual(sigBuf, expBuf)\n    ) {\n      return res.status(401).end();\n    }\n\n    if (Math.abs(Math.floor(Date.now() / 1000) - Number(ts || 0)) >\n        MAX_TIMESTAMP_SKEW_SECONDS) {\n      return res.status(401).end();\n    }\n\n    const payload = JSON.parse(req.body.toString());\n    console.log(\n      `[${payload.event_type}] eu_id=${payload.eu_id} ` +\n        `delivery_id=${req.header(\"X-Firmendata-Delivery-Id\")}`\n    );\n    console.log(JSON.stringify(payload, null, 2));\n    res.status(200).end();\n  }\n);\n\napp.listen(8080);\n```\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"testDelivery","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionTestRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionTestResponse"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1.0}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0.0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0.0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X POST \"https://api.firmendata.com/v1/subscriptions/test\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.post(\n    \"https://api.firmendata.com/v1/subscriptions/test\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/subscriptions/test\", {\n  method: \"POST\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/lists":{"get":{"tags":["Lists"],"summary":"Your company lists","description":"Every company list the authenticated caller owns, newest first.\n\nReturns each list's id, name, company count and whether change alerts are\nenabled — enough to pick one and fetch its companies with\n`GET /v1/lists/{list_id}`. Lists are created and edited in the web app.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getLists","responses":{"200":{"description":"The caller's lists.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListsResponse"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1.0}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0.0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0.0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/lists\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/lists\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/lists\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/lists/{list_id}":{"get":{"tags":["Lists"],"summary":"Companies on a list","description":"One page of companies from one of the caller's lists.\n\n- **Rows** match `GET /v1/companies/search` hits exactly, so both surfaces\n  deserialize into the same type\n- **`sort`** orders the whole list before the page is cut, so paging never\n  reshuffles rows. Omit it for the order companies were added in\n- **Pagination** is the standard opaque cursor; `pagination.total_approx` is\n  the list's exact size\n\nA list id that does not exist, or belongs to someone else, returns `404` —\nthe two are deliberately indistinguishable.\n\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"getList","parameters":[{"name":"list_id","in":"path","required":true,"schema":{"type":"integer","minimum":1,"description":"Identifier of one of your lists, from `GET /v1/lists`.","examples":[42],"title":"List Id"},"description":"Identifier of one of your lists, from `GET /v1/lists`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Companies per page.","default":100,"title":"Limit"},"description":"Companies per page."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque pagination cursor. Pass the `pagination.next_cursor` from a previous response to fetch the next page.","title":"Cursor"},"description":"Opaque pagination cursor. Pass the `pagination.next_cursor` from a previous response to fetch the next page."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/Sort"},{"type":"null"}],"description":"Order the list by a company attribute instead of by when companies were added. Same vocabulary as `/companies/search`.","title":"Sort"},"description":"Order the list by a company attribute instead of by when companies were added. Same vocabulary as `/companies/search`."},{"name":"sort_direction","in":"query","required":false,"schema":{"$ref":"#/components/schemas/SortDirection","description":"Sort direction; applies only with `sort`.","default":"desc"},"description":"Sort direction; applies only with `sort`."}],"responses":{"200":{"description":"One page of the list's companies.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListDetailResponse"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"404":{"description":"The requested resource does not exist.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/not-found","title":"Resource not found.","status":404,"detail":"No company with id DEF1103R.HRB999999B.","message":"No company with id DEF1103R.HRB999999B.","instance":"/v1/companies/DEF1103R.HRB999999B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/lists/{list_id}\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/lists/{list_id}\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/lists/{list_id}\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/feeds/new-companies":{"get":{"tags":["Feeds"],"summary":"Poll new companies (Beta)","description":"**Beta.** Poll company events in discovery order. On the first\ncall, `since` defaults to the last day; it must be within the last seven days.\nPass `next_cursor` back unchanged, including after an empty page. Cursors\npersist across deploys and restarts. A discovery position older than seven\ndays expires; restart with a recent `since`.\nEvents become available after a short delay. `has_more=true` means continue\npaging immediately; otherwise poll again later. The same event may appear\nmore than once: clients must deduplicate on `id`. Only company information is returned. A page with events costs one\ncredit; an empty page costs zero credits. An API key is required. Swiss events cover newly registered companies announced in the Swiss Official Gazette of Commerce (SHAB).\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"pollNewCompanies","parameters":[{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Persistent discovery cursor from the previous response's next_cursor.","title":"Cursor"},"description":"Persistent discovery cursor from the previous response's next_cursor."},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Initial discovery timestamp; ignored when cursor is supplied.","title":"Since"},"description":"Initial discovery timestamp; ignored when cursor is supplied."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Maximum events returned in this page.","default":50,"title":"Limit"},"description":"Maximum events returned in this page."},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/Country"},{"type":"null"}],"description":"Company country; omit to include all countries.","title":"Country"},"description":"Company country; omit to include all countries."},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Bundesland"}},{"type":"null"}],"description":"Company Bundesland; repeated values are matched with OR.","title":"Bundesland"},"description":"Company Bundesland; repeated values are matched with OR."},{"name":"canton","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Canton"}},{"type":"null"}],"description":"Swiss company canton; repeated values are matched with OR.","title":"Canton"},"description":"Swiss company canton; repeated values are matched with OR."},{"name":"register_court","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/RegisterCourt"}},{"type":"null"}],"description":"German Registergericht or Austrian Firmenbuch court; repeated values are matched with OR. Select Swiss companies with canton, since their register office is cantonal.","title":"Register Court"},"description":"German Registergericht or Austrian Firmenbuch court; repeated values are matched with OR. Select Swiss companies with canton, since their register office is cantonal."},{"name":"industry_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/IndustrySlug"}},{"type":"null"}],"description":"Company industry category; repeated values are matched with OR.","title":"Industry Slug"},"description":"Company industry category; repeated values are matched with OR."},{"name":"rechtsform","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Rechtsform"}},{"type":"null"}],"description":"Company legal form; repeated values are matched with OR and UG is distinguished from GmbH.","title":"Rechtsform"},"description":"Company legal form; repeated values are matched with OR and UG is distinguished from GmbH."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedResponse"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/feeds/new-companies\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/feeds/new-companies\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/feeds/new-companies\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}},"/v1/feeds/insolvencies":{"get":{"tags":["Feeds"],"summary":"Poll insolvency notices (Beta)","description":"**Beta.** Poll company events in discovery order. On the first\ncall, `since` defaults to the last day; it must be within the last seven days.\nPass `next_cursor` back unchanged, including after an empty page. Cursors\npersist across deploys and restarts. A discovery position older than seven\ndays expires; restart with a recent `since`.\nEvents become available after a short delay. `has_more=true` means continue\npaging immediately; otherwise poll again later. The same event may appear\nmore than once: clients must deduplicate on `id`. Only company information is returned. A page with events costs one\ncredit; an empty page costs zero credits. An API key is required. Schuldenruf notices are included only when selected by name.\n\n## Pricing\n\nSee the [pricing page](https://firmendata.com/en/plans) for this endpoint's credit cost.","operationId":"pollInsolvencies","parameters":[{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Persistent discovery cursor from the previous response's next_cursor.","title":"Cursor"},"description":"Persistent discovery cursor from the previous response's next_cursor."},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Initial discovery timestamp; ignored when cursor is supplied.","title":"Since"},"description":"Initial discovery timestamp; ignored when cursor is supplied."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Maximum events returned in this page.","default":50,"title":"Limit"},"description":"Maximum events returned in this page."},{"name":"country","in":"query","required":false,"schema":{"$ref":"#/components/schemas/Country","description":"Notice country; defaults to DE and selects the country's filter vocabulary.","default":"DE"},"description":"Notice country; defaults to DE and selects the country's filter vocabulary."},{"name":"bundesland","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Bundesland"}},{"type":"null"}],"description":"Company Bundesland in the selected country; repeated values are matched with OR.","title":"Bundesland"},"description":"Company Bundesland in the selected country; repeated values are matched with OR."},{"name":"canton","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Canton"}},{"type":"null"}],"description":"Swiss notice canton for country=CH; repeated values are matched with OR.","title":"Canton"},"description":"Swiss notice canton for country=CH; repeated values are matched with OR."},{"name":"register_court","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/RegisterCourt"}},{"type":"null"}],"description":"Company register court, not the insolvency court. German Registergericht or Austrian Firmenbuch court; repeated values are matched with OR. Select Swiss companies with canton, since their register office is cantonal.","title":"Register Court"},"description":"Company register court, not the insolvency court. German Registergericht or Austrian Firmenbuch court; repeated values are matched with OR. Select Swiss companies with canton, since their register office is cantonal."},{"name":"industry_slug","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/IndustrySlug"}},{"type":"null"}],"description":"Company industry category; repeated values are matched with OR.","title":"Industry Slug"},"description":"Company industry category; repeated values are matched with OR."},{"name":"rechtsform","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/Rechtsform"}},{"type":"null"}],"description":"Company legal form; repeated values are matched with OR and UG is distinguished from GmbH.","title":"Rechtsform"},"description":"Company legal form; repeated values are matched with OR and UG is distinguished from GmbH."},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/InsolvencyCategory"}},{"type":"null"}],"description":"Notice category; repeated values are matched with OR and Schuldenruf must be requested by name.","title":"Category"},"description":"Notice category; repeated values are matched with OR and Schuldenruf must be requested by name."},{"name":"revenue_min","in":"query","required":false,"schema":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Inclusive lower bound on the company's latest known revenue in euros.","title":"Revenue Min"},"description":"Inclusive lower bound on the company's latest known revenue in euros."},{"name":"revenue_max","in":"query","required":false,"schema":{"anyOf":[{"type":"number","minimum":0},{"type":"null"}],"description":"Exclusive upper bound on the company's latest known revenue in euros.","title":"Revenue Max"},"description":"Exclusive upper bound on the company's latest known revenue in euros."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedResponse"}}},"headers":{"X-Credits-Charged":{"description":"Credits this call deducted from your balance. `0` for free endpoints and for responses that carry no data.","schema":{"type":"integer","minimum":0}}}},"401":{"description":"Missing, invalid, revoked, or expired bearer token.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/unauthenticated","title":"Authentication required.","status":401,"detail":"A valid `Authorization: Bearer <token>` header is required.","message":"A valid `Authorization: Bearer <token>` header is required.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"402":{"description":"Not enough credits for this call; top up or upgrade your plan","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"examples":{"insufficient_credits":{"value":{"type":"https://api.firmendata.com/problems/insufficient-credits","title":"Insufficient credits.","status":402,"detail":"Not enough credits for this call; top up or upgrade your plan","message":"Not enough credits for this call; top up or upgrade your plan","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}}},"422":{"description":"Request validation failed; see `errors[]` for per-field details.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/validation-error","title":"Request validation failed.","status":422,"detail":"limit: Input should be less than or equal to 50","message":"limit: Input should be less than or equal to 50","instance":"/v1/companies/search","request_id":"req_01HXYZABC123DEF456GHI789J","errors":[{"param":"limit","message":"Input should be less than or equal to 50"}]}}}},"429":{"description":"Rate limit exceeded. Rejected requests do not consume the limit or any credits. Honour `Retry-After` (seconds) before retrying.","headers":{"Retry-After":{"description":"Seconds to wait before the next request will succeed.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Numeric limit of the tighter window currently applying.","schema":{"type":"integer"}},"RateLimit-Remaining":{"description":"Requests left in that window (0 on 429).","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Seconds until the window resets.","schema":{"type":"integer","minimum":0}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/rate-limit-exceeded","title":"Too many requests.","status":429,"detail":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","message":"Rate limit exceeded: more than 5 requests per 1 second. Retry in 1s.","instance":"/v1/companies/autocomplete","request_id":"req_01HXYZABC123DEF456GHI789J"}}}},"500":{"description":"Unexpected server error.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"https://api.firmendata.com/problems/server-error","title":"Internal server error.","status":500,"detail":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","message":"An unexpected error occurred. Please retry later or contact support with the `request_id`.","instance":"/v1/companies/DEF1103R.HRB279792B","request_id":"req_01HXYZABC123DEF456GHI789J"}}}}},"x-codeSamples":[{"lang":"shell","label":"cURL","source":"API_KEY=\"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\ncurl -X GET \"https://api.firmendata.com/v1/feeds/insolvencies\" \\\n  -H \"Authorization: Bearer $API_KEY\""},{"lang":"python","label":"Python (requests)","source":"import requests\n\nAPI_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\n\nresponse = requests.get(\n    \"https://api.firmendata.com/v1/feeds/insolvencies\",\n    headers={\"Authorization\": f\"Bearer {API_KEY}\"},\n    timeout=30,\n)\nresponse.raise_for_status()\ndata = response.json()\nprint(data)"},{"lang":"js","label":"JavaScript (fetch)","source":"const API_KEY = \"firmendata_live_xxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\";\n\nconst response = await fetch(\"https://api.firmendata.com/v1/feeds/insolvencies\", {\n  method: \"GET\",\n  headers: { \"Authorization\": `Bearer ${API_KEY}` },\n});\nif (!response.ok) throw new Error(`HTTP ${response.status}`);\nconst data = await response.json();\nconsole.log(data);"}]}}},"components":{"schemas":{"Address":{"properties":{"object":{"type":"string","const":"address","title":"Object","description":"Discriminator. Always `address`.","default":"address"},"street":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Street","description":"Street name."},"house_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"House Number","description":"House number, including any suffix."},"postal_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Postal Code","description":"Postal code (PLZ)."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City","description":"City or municipality."},"federal_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Federal State","description":"State the address lies in: the Bundesland for a German address, the canton (official name, e.g. `Zug`, `Genève`) for a Swiss one, the Bundesland (e.g. `Salzburg`) for an Austrian one. Read from the address itself, so it can differ from the canton of a Swiss company's register office (`register_canton`). `null` when the address does not determine it."},"country_code":{"type":"string","title":"Country Code","description":"ISO 3166-1 alpha-2 country code of the address: `DE`, `CH` or `AT`.","default":"DE"},"latitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latitude","description":"Latitude in decimal degrees (WGS-84). `null` when geocoding is unavailable."},"longitude":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Longitude","description":"Longitude in decimal degrees (WGS-84). `null` when geocoding is unavailable."},"formatted_display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Formatted Display","description":"Pre-formatted single-line address suitable for display."}},"type":"object","title":"Address","description":"A postal address with optional geocoding."},"AddressEntry":{"properties":{"object":{"type":"string","const":"address_entry","title":"Object","description":"Discriminator. Always `address_entry`.","default":"address_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"address":{"$ref":"#/components/schemas/Address","description":"Business address (Geschäftsanschrift) as of this entry."}},"type":"object","required":["address"],"title":"AddressEntry","description":"A business address recorded by one entry."},"AiInsightsBlock":{"properties":{"object":{"type":"string","const":"ai_insights","title":"Object","description":"Discriminator. Always `ai_insights`.","default":"ai_insights"},"summary":{"anyOf":[{"$ref":"#/components/schemas/LocalizedText"},{"type":"null"}],"description":"One-paragraph company summary, localized."},"outlook":{"anyOf":[{"$ref":"#/components/schemas/LocalizedText"},{"type":"null"}],"description":"Forward-looking outlook, localized. Omitted when based on a fiscal year two or more years older than the latest financial statements."},"based_on_fiscal_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Based On Fiscal Year","description":"Fiscal year of the filing the insights were generated from. The outlook is omitted when this year is two or more years older than `financial_summary.latest_fiscal_year`."},"generated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Generated At","description":"When the insights were generated (UTC)."}},"type":"object","title":"AiInsightsBlock","description":"Company summary and outlook based on one filed annual report."},"ArticlesEntry":{"properties":{"object":{"type":"string","const":"articles_entry","title":"Object","description":"Discriminator. Always `articles_entry`.","default":"articles_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"change":{"type":"string","enum":["created","amended"],"title":"Change","description":"`created`: the original document; `amended`: a later change."},"document_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Type","description":"Document as filed: `Satzung`, `Gesellschaftsvertrag` or `Statut`.","examples":["Gesellschaftsvertrag"]},"document_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Document Date","description":"Date of the document or resolution."}},"type":"object","required":["change"],"title":"ArticlesEntry","description":"Creation or amendment of the articles (Satzung / Gesellschaftsvertrag / Statut)."},"AutocompleteHit":{"properties":{"object":{"type":"string","const":"autocomplete_hit","title":"Object","description":"Discriminator. Always `autocomplete_hit`.","default":"autocomplete_hit"},"eu_id":{"type":"string","title":"Eu Id","description":"firmendata company identifier."},"country_code":{"type":"string","enum":["DE","CH","AT"],"title":"Country Code","description":"Country of the register the company is entered in: `DE` for the German registers (Handelsregister, Genossenschafts-, Partnerschafts-, Vereinsregister), `CH` for the Swiss commercial register, `AT` for the Austrian Firmenbuch."},"legal_name":{"type":"string","title":"Legal Name","description":"Full legal name as filed."},"display_name":{"type":"string","title":"Display Name","description":"The legal name without its legal-form suffix and status markers (`VOLKSWAGEN AKTIENGESELLSCHAFT` → `VOLKSWAGEN`, `Siemens Suisse SA` → `Siemens Suisse`). Identical for the same company on every endpoint."},"registered_seat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Registered Seat","description":"Registered seat as filed (German, may include district).","examples":["München"]},"register_court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Court","description":"Registering court (Registergericht, Firmenbuchgericht) for German and Austrian companies; for Swiss companies, the full name of the canton whose register office keeps the entry (e.g. `Vaud`)."},"register_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Type","description":"Register type code (e.g. `HRB`, `HRA`, `GnR`, `PR`, `VR`, `CH-HR`, `AT-FB`)."},"register_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Register Number","description":"Register entry number (digits only). Combine with `register_type` for a full reference.","examples":[12345]},"register_canton":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Canton","description":"Swiss companies only: two-letter code of the canton whose commercial register keeps the entry (e.g. `VD`). `null` for German and Austrian companies.","examples":["VD"]},"uid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uid","description":"Swiss companies only: the Unternehmens-Identifikationsnummer in its official format. `null` for German and Austrian companies.","examples":["CHE-105.909.036"]}},"type":"object","required":["eu_id","country_code","legal_name","display_name"],"title":"AutocompleteHit","description":"One autocomplete suggestion."},"AutocompleteResponse":{"properties":{"object":{"type":"string","const":"list","title":"Object","description":"Discriminator. Always `list`.","default":"list"},"data":{"items":{"$ref":"#/components/schemas/AutocompleteHit"},"type":"array","title":"Data","description":"Suggestion hits ordered by match relevance."},"pagination":{"$ref":"#/components/schemas/PaginationInfo","description":"Pagination metadata for this page."},"filters_echo":{"additionalProperties":true,"type":"object","title":"Filters Echo","description":"The effective filter values applied to this query, echoed back for client convenience."},"freshness":{"$ref":"#/components/schemas/Freshness","description":"Outcome of the `fetch_realtime` register search for this request. `last_checked_at` is always `null` here — the suggestions span many companies, so no single slice timestamp applies."}},"type":"object","title":"AutocompleteResponse","description":"Response envelope for `GET /v1/companies/autocomplete`."},"BalanceSheetPositions":{"properties":{"object":{"type":"string","const":"balance_sheet_positions","title":"Object","description":"Discriminator. Always `balance_sheet_positions`.","default":"balance_sheet_positions"},"total_assets":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Summe Aktiva — the balance-sheet total from the assets side."},"fixed_assets":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Anlagevermögen."},"intangible_assets":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Immaterielle Vermögensgegenstände (within Anlagevermögen)."},"tangible_assets":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Sachanlagen (within Anlagevermögen)."},"financial_assets":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Finanzanlagen (within Anlagevermögen)."},"current_assets":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Umlaufvermögen."},"inventories":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Vorräte (within Umlaufvermögen)."},"receivables":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Forderungen und sonstige Vermögensgegenstände (within Umlaufvermögen)."},"securities":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Wertpapiere des Umlaufvermögens."},"cash":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Kassenbestand, Bundesbankguthaben, Guthaben bei Kreditinstituten und Schecks."},"prepaid_expenses":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Aktive Rechnungsabgrenzungsposten."},"deferred_tax_assets":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Aktive latente Steuern."},"deficit_not_covered_by_equity":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Nicht durch Eigenkapital gedeckter Fehlbetrag (shown on the assets side when equity is negative)."},"total_liabilities_and_equity":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Summe Passiva — the balance-sheet total from the liabilities-and-equity side."},"equity":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Eigenkapital."},"subscribed_capital":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Gezeichnetes Kapital (within Eigenkapital)."},"capital_reserves":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Kapitalrücklage (within Eigenkapital)."},"revenue_reserves":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Gewinnrücklagen (within Eigenkapital)."},"provisions":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Rückstellungen."},"pension_provisions":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Rückstellungen für Pensionen und ähnliche Verpflichtungen."},"tax_provisions":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Steuerrückstellungen."},"other_provisions":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Sonstige Rückstellungen."},"liabilities":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Verbindlichkeiten."},"liabilities_to_banks":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Verbindlichkeiten gegenüber Kreditinstituten."},"trade_payables":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Verbindlichkeiten aus Lieferungen und Leistungen."},"liabilities_to_affiliates":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Verbindlichkeiten gegenüber verbundenen Unternehmen."},"liabilities_to_shareholders":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Verbindlichkeiten gegenüber Gesellschaftern."},"other_liabilities":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Sonstige Verbindlichkeiten."},"deferred_income":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Passive Rechnungsabgrenzungsposten."},"deferred_tax_liabilities":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Passive latente Steuern."}},"type":"object","title":"BalanceSheetPositions","description":"Top-level balance-sheet positions for one fiscal year (§ 266 HGB).\n\nTaken from the same filing as the year's line items; a position the\nfiling does not show is `null`. Small companies file a shortened balance\nsheet, so the sub-positions are often missing while the totals are there.\nEvery row at every depth is in `history.assets` / `liabilities_and_equity`."},"BeneficialOwner":{"properties":{"object":{"type":"string","const":"beneficial_owner","title":"Object","description":"Discriminator. Always `beneficial_owner`.","default":"beneficial_owner"},"node_id":{"type":"string","title":"Node Id","description":"`UboNode.id` of the beneficial owner — always points at a `person` node."},"person":{"$ref":"#/components/schemas/Person","description":"Natural-person details."},"effective_share_percent":{"type":"number","title":"Effective Share Percent","description":"Capital share of the root attributable to this person. For direct holdings, the sum of their direct positions. For indirect holdings, the share at the final hop into the root (the company directly held by the root that this person ultimately controls); when reached via several distinct branches, the sum of those branches' root-edge shares. **Not** a multiplicative product — German UBO law treats every controlling link as 100 % pass-through. Always strictly greater than 25."}},"type":"object","required":["node_id","person","effective_share_percent"],"title":"BeneficialOwner","description":"A natural person who qualifies as a beneficial owner of the\nroot under §3 GwG (German \"all-or-nothing\" attribution: each link\nin the ownership chain is checked independently against the 25 %\nthreshold; Sperrminorität above 25 % counts as control under the\nBVA's post-TraFinG reading of §3 Abs. 2 Nr. 3 GwG)."},"BilanzAttachment":{"properties":{"object":{"type":"string","const":"bilanz_attachment","title":"Object","description":"Discriminator. Always `bilanz_attachment`.","default":"bilanz_attachment"},"file_id":{"type":"string","title":"File Id","description":"firmendata file identifier."},"file_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Type","description":"Attachment kind (`annual_report_pdf`, `consolidated_report_pdf`, `combined_report_pdf`)."},"file_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Name","description":"Original file name as published."},"file_size_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"File Size Bytes","description":"File size in bytes, when known."},"public_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Public Name","description":"Display name of the file."},"fetched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Fetched At","description":"When firmendata last fetched the file."}},"type":"object","required":["file_id"],"title":"BilanzAttachment","description":"Reference to the filed Bilanz PDF."},"BoardChange":{"properties":{"object":{"type":"string","const":"board_change","title":"Object","description":"Discriminator. Always `board_change`.","default":"board_change"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"change":{"type":"string","enum":["appointed","departed","updated"],"title":"Change","description":"`updated`: the entry corrected the member's data (Geändert, nun)."},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","description":"Role as filed.","examples":["Geschäftsführer"]},"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"Natural person, when applicable."},"organization":{"anyOf":[{"$ref":"#/components/schemas/OrganizationRef"},{"type":"null"}],"description":"Organisation, when applicable."},"representation":{"anyOf":[{"$ref":"#/components/schemas/BoardRepresentation"},{"type":"null"}],"description":"Representation power, when the entry states it."}},"type":"object","required":["change"],"title":"BoardChange","description":"One appointment, departure or correction of an officer or limited partner."},"BoardMember":{"properties":{"object":{"type":"string","const":"board_member","title":"Object","description":"Discriminator. Always `board_member`.","default":"board_member"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","description":"Role as filed.","examples":["Vorstand"]},"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"Natural person, when applicable."},"organization":{"anyOf":[{"$ref":"#/components/schemas/OrganizationRef"},{"type":"null"}],"description":"Organisation holding the role, when applicable."},"appointed_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Appointed Date","description":"Date of the entry that first records this member in the role. For a company whose extract starts with a transfer this is the transfer date, not necessarily the appointment."},"representation":{"anyOf":[{"$ref":"#/components/schemas/BoardRepresentation"},{"type":"null"}],"description":"Representation power, when the entry states it."}},"type":"object","title":"BoardMember","description":"A company officer currently in office."},"BoardRepresentation":{"properties":{"object":{"type":"string","const":"board_representation","title":"Object","description":"Discriminator. Always `board_representation`.","default":"board_representation"},"sole":{"type":"boolean","title":"Sole","description":"Authorised to represent the company alone.","default":false},"joint":{"type":"boolean","title":"Joint","description":"Represents jointly with another officer or Prokurist.","default":false},"joint_with":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Joint With","description":"Who the joint representation is with, when the entry names it."},"exempt_from_self_dealing_ban":{"type":"boolean","title":"Exempt From Self Dealing Ban","description":"Released from the restrictions of § 181 BGB.","default":false},"excluded":{"type":"boolean","title":"Excluded","description":"Excluded from representation.","default":false}},"type":"object","title":"BoardRepresentation","description":"How a board member may represent the company, as filed."},"BranchEntry":{"properties":{"object":{"type":"string","const":"branch_entry","title":"Object","description":"Discriminator. Always `branch_entry`.","default":"branch_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"branches":{"items":{"$ref":"#/components/schemas/HistoryBranch"},"type":"array","title":"Branches","description":"Branches (Zweigniederlassungen) as listed by this entry."}},"type":"object","title":"BranchEntry","description":"The branch offices listed by one entry."},"Bundesland":{"type":"string","enum":["Baden-Württemberg","Bayern","Berlin","Brandenburg","Bremen","Hamburg","Hessen","Mecklenburg-Vorpommern","Niedersachsen","Nordrhein-Westfalen","Rheinland-Pfalz","Saarland","Sachsen","Sachsen-Anhalt","Schleswig-Holstein","Thüringen","Burgenland","Kärnten","Niederösterreich","Oberösterreich","Salzburg","Steiermark","Tirol","Vorarlberg","Wien"],"title":"Bundesland","description":"The 16 German and the 9 Austrian Länder (no name is shared)."},"BusinessBlock":{"properties":{"object":{"type":"string","const":"company_business","title":"Object","description":"Discriminator. Always `company_business`.","default":"company_business"},"products":{"items":{"type":"string"},"type":"array","title":"Products","description":"Products and services described in filings."},"business_branches":{"items":{"$ref":"#/components/schemas/BusinessBranch"},"type":"array","title":"Business Branches","description":"Reported business segments and their revenue split."},"risk_keywords":{"items":{"type":"string"},"type":"array","title":"Risk Keywords","description":"Risk indicators mentioned in management reports."},"opportunity_keywords":{"items":{"type":"string"},"type":"array","title":"Opportunity Keywords","description":"Opportunity indicators mentioned in management reports."}},"type":"object","title":"BusinessBlock","description":"Company products, business segments and keywords."},"BusinessBranch":{"properties":{"object":{"type":"string","const":"business_branch","title":"Object","description":"Discriminator. Always `business_branch`.","default":"business_branch"},"name":{"type":"string","title":"Name","description":"Branch or segment name."},"revenue":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Revenue","description":"Revenue attributed to this branch in `revenue_unit`."},"revenue_unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revenue Unit","description":"Unit/scale label for `revenue`."},"percentage_of_total":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Percentage Of Total","description":"Branch share of total revenue (0–100)."},"parent_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Name","description":"Parent branch name, when nested."}},"type":"object","required":["name"],"title":"BusinessBranch","description":"One business branch / segment with optional revenue split."},"Canton":{"type":"string","enum":["AG","AI","AR","BE","BL","BS","FR","GE","GL","GR","JU","LU","NE","NW","OW","SG","SH","SO","SZ","TG","TI","UR","VD","VS","ZG","ZH"],"title":"Canton"},"CapitalEntry":{"properties":{"object":{"type":"string","const":"capital_entry","title":"Object","description":"Discriminator. Always `capital_entry`.","default":"capital_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"amount":{"$ref":"#/components/schemas/Money","description":"Share capital (Stamm-/Grundkapital) after this entry."},"change":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Difference to the previous capital entry. `null` for the first."},"change_type":{"type":"string","enum":["initial","cash_increase","contribution_in_kind","from_authorized_capital","from_conditional_capital","decrease","unchanged"],"title":"Change Type","description":"How the capital changed, as the entry describes it."}},"type":"object","required":["amount","change_type"],"title":"CapitalEntry","description":"A share-capital figure recorded by one entry."},"ClassificationCode":{"properties":{"object":{"type":"string","const":"classification_code","title":"Object","description":"Discriminator. Always `classification_code`.","default":"classification_code"},"code":{"type":"string","title":"Code","description":"Code in the stated classification version."},"title_de":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title De","description":"Official German title, when available."},"title_en":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title En","description":"Official English title, when available."}},"type":"object","required":["code"],"title":"ClassificationCode"},"ClassificationRepresentation":{"properties":{"object":{"type":"string","const":"classification_representation","title":"Object","description":"Discriminator. Always `classification_representation`.","default":"classification_representation"},"scheme":{"type":"string","enum":["nace_rev_2_1","wz_2008","nace_rev_2","isic_rev_4"],"title":"Scheme","description":"Classification version: NACE Rev. 2.1 is the revised EU classification; WZ 2008 is Germany's previous classification; NACE Rev. 2 is the previous EU classification; ISIC Rev. 4 is the United Nations' International Standard Industrial Classification."},"codes":{"items":{"$ref":"#/components/schemas/ClassificationCode"},"type":"array","title":"Codes","description":"Corresponding codes using the official Destatis (WZ 2008 ↔ WZ 2025) and Eurostat (NACE Rev. 2 ↔ Rev. 2.1) correspondence tables and Eurostat's NACE Rev. 2 ↔ ISIC Rev. 4 table."},"partial":{"type":"boolean","title":"Partial","description":"The code corresponds to several codes in this version, so the list is a set of candidates."}},"type":"object","required":["scheme","partial"],"title":"ClassificationRepresentation"},"CompanyDetail":{"properties":{"object":{"type":"string","const":"company","title":"Object","description":"Discriminator. Always `company`.","default":"company"},"eu_id":{"type":"string","title":"Eu Id","description":"firmendata company identifier."},"country_code":{"type":"string","enum":["DE","CH","AT"],"title":"Country Code","description":"Country of the register the company is entered in: `DE` for the German registers (Handelsregister, Genossenschafts-, Partnerschafts-, Vereinsregister), `CH` for the Swiss commercial register, `AT` for the Austrian Firmenbuch."},"ust_id_nr":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ust Id Nr","description":"VAT identification number (Umsatzsteuer-Identifikationsnummer)."},"wirtschafts_id_nr":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Wirtschafts Id Nr","description":"Wirtschafts-Identifikationsnummer (W-IdNr.) for the main establishment, derived from `ust_id_nr` by appending `-00001` (e.g. `DE123456789-00001`). `null` when no USt-IdNr is known."},"freshness":{"$ref":"#/components/schemas/Freshness","description":"How current the register snapshot in this response is. `last_checked_at` is the timestamp at which the company's register profile was last successfully fetched; `realtime_fetching_status` reports the outcome of the realtime attempt for this request. The chronological register history has its own freshness object served by `/v1/companies/{eu_id}/history`."},"display_name":{"type":"string","title":"Display Name","description":"The legal name without its legal-form suffix and status markers (`VOLKSWAGEN AKTIENGESELLSCHAFT` → `VOLKSWAGEN`, `Siemens Suisse SA` → `Siemens Suisse`). Identical for the same company on every endpoint."},"legal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Name","description":"Full legal name as filed."},"legal_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Form","description":"Legal-form short name (Rechtsform), e.g. `GmbH`, `AG`, `KG`. Swiss legal forms carry a `(CH)` suffix, e.g. `AG (CH)`.","examples":["GmbH"]},"elf_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Elf Code","description":"ISO 20275 Entity Legal Form (ELF) code, when mapped.","examples":["6QQB"]},"legal_status":{"type":"string","enum":["active","in_liquidation","insolvent","dissolved","deleted"],"title":"Legal Status","description":"Company lifecycle status according to the commercial register and insolvency notices, including Swiss Official Gazette of Commerce (SHAB) bankruptcy and composition notices.\n\n`deleted` — company has been removed from the German registries.\n`insolvent` — insolvency proceedings are open or preliminary measures are in force.\n`in_liquidation` — the company is dissolved (Auflösung, whether by shareholder resolution or as a consequence of insolvency) and a Liquidator is in office.\n`dissolved` — dissolved with no Liquidator in office, or an insolvency proceeding that has been lifted (Aufhebung des Verfahrens).\n`active` — default for everything else.","default":"active"},"founding_document_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Founding Document Date","description":"Date of the founding document (Gründungsdokument), as filed in the register."},"first_register_entry_at":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"First Register Entry At","description":"Date of the company's first observable register entry. A date of 1 January usually means the register states only the year."},"latest_register_entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Latest Register Entry Date","description":"Date of the most recent register entry observed for this company (XJustiz `letzteEintragung`). `null` when no register entry has yet been observed for this company."},"register_court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Court","description":"Registering court (Registergericht, Firmenbuchgericht) for German and Austrian companies; for Swiss companies, the full name of the canton whose register office keeps the entry (e.g. `Vaud`)."},"register_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Type","description":"Register type code (e.g. `HRB`, `HRA`, `GnR`, `PR`, `VR`, `CH-HR`, `AT-FB`)."},"register_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Register Number","description":"Register entry number (digits only). Combine with `register_type` for a full reference.","examples":[12345]},"register_canton":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Canton","description":"Swiss companies only: two-letter code of the canton whose commercial register keeps the entry (e.g. `VD`). `null` for German and Austrian companies.","examples":["VD"]},"uid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uid","description":"Swiss companies only: the Unternehmens-Identifikationsnummer in its official format. `null` for German and Austrian companies.","examples":["CHE-105.909.036"]},"is_branch":{"type":"boolean","title":"Is Branch","description":"`true` when this register entry is a branch office (Zweigniederlassung, succursale) of a company registered elsewhere, not a company of its own — a foreign company's German branch, or a Swiss branch office, which has its own UID.","default":false},"registered_seat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Registered Seat","description":"Registered seat as filed (German, may include district)."},"address":{"anyOf":[{"$ref":"#/components/schemas/Address"},{"type":"null"}],"description":"Registered seat address."},"share_capital":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Currently registered share capital (Stammkapital / Grundkapital), from the structured register extract or, where that carries none, the latest capital entry in the chronological one. `null` when the register states none — partnerships have no share capital."},"business_purpose":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Business Purpose","description":"Company purpose (Gegenstand des Unternehmens, German as filed)."},"eu_sme_declaration":{"anyOf":[{"$ref":"#/components/schemas/EuSmeDeclaration"},{"type":"null"}],"description":"The company's own most recent declaration under the EU SME definition (Commission Recommendation 2003/361/EC). Null means no declaration known."},"industry_categorization":{"$ref":"#/components/schemas/IndustryBlock","description":"Industry classification (NACE codes)."},"business_info":{"anyOf":[{"$ref":"#/components/schemas/BusinessBlock"},{"type":"null"}],"description":"Business profile (products, segments, keywords). `null` when no products, segments, or keywords are available."},"financial_summary":{"anyOf":[{"$ref":"#/components/schemas/FinancialSummaryBlock"},{"type":"null"}],"description":"Headline figures for the latest reported fiscal year. `null` when no financial filings are available. For the full multi-year history, call `GET /v1/companies/{eu_id}/financials`."},"insolvency":{"anyOf":[{"$ref":"#/components/schemas/InsolvencyBlock"},{"type":"null"}],"description":"Insolvency, Auflösung and Liquidation snapshot. `null` when the company has no such event on record and is not dissolved."},"founder_profile":{"anyOf":[{"$ref":"#/components/schemas/FounderProfileBlock"},{"type":"null"}],"description":"Founder, family-involvement and succession assessment derived from the register's board history. `null` when the company could not be assessed at all."},"contact":{"$ref":"#/components/schemas/ContactBlock","description":"Contact and web presence (domain, logo, social profiles)."},"management":{"items":{"$ref":"#/components/schemas/Member"},"type":"array","title":"Management","description":"Management members from the register entry (managing directors, authorised signatories, supervisory board). Excludes non-management roles like Rechtsträger and Registergericht."},"lei_graph":{"anyOf":[{"$ref":"#/components/schemas/LeiGraphBlock"},{"type":"null"}],"description":"LEI-based ownership graph — parent and direct children when the company has an LEI. `null` when the company has no LEI and no LEI-graph relations are available."},"ai_insights":{"anyOf":[{"$ref":"#/components/schemas/AiInsightsBlock"},{"type":"null"}],"description":"Company summary and outlook, localized. `null` when no company insights are available for this company."},"documents":{"items":{"$ref":"#/components/schemas/CompanyDocument"},"type":"array","title":"Documents","description":"Downloadable register documents available for this company (Aktueller Abdruck, Chronologischer Abdruck, Liste der Gesellschafter, Articles of Association — Gesellschaftsvertrag / Satzung / Statut depending on legal form, Anmeldung, Musterprotokoll). Use `GET /companies/{eu_id}/documents/download` to obtain a presigned URL for any entry."}},"type":"object","required":["eu_id","country_code","freshness","display_name","industry_categorization","contact"],"title":"CompanyDetail","description":"Hero detail profile returned by `GET /v1/companies/{eu_id}`.\n\nEvery block is populated on every response — no `expand[]` opt-in.\nHeavy historic data (financial history, employee history, parent/\nsubsidiary relationships) lives on the separate\n`GET /v1/companies/{eu_id}/financials` endpoint."},"CompanyDocument":{"properties":{"object":{"type":"string","const":"company_document","title":"Object","description":"Discriminator. Always `company_document`.","default":"company_document"},"file_id":{"type":"string","title":"File Id","description":"Stable file identifier. Pass to `/documents/download` to obtain a presigned URL."},"type":{"type":"string","enum":["register_extract_current","register_extract_chronological","shareholder_list","articles_of_association","company_registration","model_protocol"],"title":"Type","description":"Kind of register document."},"type_label_de":{"type":"string","title":"Type Label De","description":"German type name (e.g. `Aktueller Abdruck`, `Chronologischer Abdruck`, `Liste der Gesellschafter`, `Gesellschaftsvertrag` / `Satzung` / `Statut` (the term varies by legal form), `Anmeldung`, `Musterprotokoll`)."},"type_label_en":{"type":"string","title":"Type Label En","description":"English type name (e.g. `Current Register Extract`, `Chronological Register Extract`, `Shareholder List`, `Articles of Association`, `Company Registration`, `Model Protocol`)."},"file_name_de":{"type":"string","title":"File Name De","description":"German display name composed as `\"<type label> vom <date>\"` (e.g. `Liste der Gesellschafter vom 2026-02-17`)."},"file_name_en":{"type":"string","title":"File Name En","description":"English display name composed as `\"<type label> from <date>\"` (e.g. `Shareholder List from 2026-02-17`)."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"When firmendata last fetched this document."},"published_at":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Published At","description":"Publication date as filed in the register. The `register_extract_current` and `register_extract_chronological` document types are not stamped with a publication date by the registry — for those, this falls back to the date portion of `updated_at`."},"is_outdated":{"type":"boolean","title":"Is Outdated","description":"`true` for a register extract (`register_extract_current` / `register_extract_chronological`) older than the company's latest register entry — the extract predates a change the register has since recorded. Pass `fetch_realtime=true` to `/documents/download` for a fresh one. Always `false` for the other document types.","default":false}},"type":"object","required":["file_id","type","type_label_de","type_label_en","file_name_de","file_name_en","updated_at"],"title":"CompanyDocument","description":"One downloadable register document available for the company."},"CompanyDocumentDownload":{"properties":{"object":{"type":"string","const":"company_document_download","title":"Object","description":"Discriminator. Always `company_document_download`.","default":"company_document_download"},"file_id":{"type":"string","title":"File Id","description":"Stable file identifier. Pass to `/documents/download` to obtain a presigned URL."},"type":{"type":"string","enum":["register_extract_current","register_extract_chronological","shareholder_list","articles_of_association","company_registration","model_protocol"],"title":"Type","description":"Kind of register document."},"type_label_de":{"type":"string","title":"Type Label De","description":"German type name (e.g. `Aktueller Abdruck`, `Chronologischer Abdruck`, `Liste der Gesellschafter`, `Gesellschaftsvertrag` / `Satzung` / `Statut` (the term varies by legal form), `Anmeldung`, `Musterprotokoll`)."},"type_label_en":{"type":"string","title":"Type Label En","description":"English type name (e.g. `Current Register Extract`, `Chronological Register Extract`, `Shareholder List`, `Articles of Association`, `Company Registration`, `Model Protocol`)."},"file_name_de":{"type":"string","title":"File Name De","description":"German display name composed as `\"<type label> vom <date>\"` (e.g. `Liste der Gesellschafter vom 2026-02-17`)."},"file_name_en":{"type":"string","title":"File Name En","description":"English display name composed as `\"<type label> from <date>\"` (e.g. `Shareholder List from 2026-02-17`)."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"When firmendata last fetched this document."},"published_at":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Published At","description":"Publication date as filed in the register. The `register_extract_current` and `register_extract_chronological` document types are not stamped with a publication date by the registry — for those, this falls back to the date portion of `updated_at`."},"is_outdated":{"type":"boolean","title":"Is Outdated","description":"`true` for a register extract (`register_extract_current` / `register_extract_chronological`) older than the company's latest register entry — the extract predates a change the register has since recorded. Pass `fetch_realtime=true` to `/documents/download` for a fresh one. Always `false` for the other document types.","default":false},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id","description":"Catalog identifier echoed for the requested document version."},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"The document's label as the registry lists it. Its language depends on which register portal answered (German or English); use `type_label_de` / `type_label_en` for a stable name."},"freshness":{"$ref":"#/components/schemas/Freshness","description":"How current the served file is. `last_checked_at` mirrors the parent `updated_at` (the moment firmendata last fetched this document); `realtime_fetching_status` reports the outcome of the realtime attempt for this request — `download_url` still points at the most recent file on record regardless of that outcome."},"download_url":{"type":"string","title":"Download Url","description":"Presigned download URL. Honours the file's original content type."},"download_url_expires_at":{"type":"string","format":"date-time","title":"Download Url Expires At","description":"UTC timestamp at which `download_url` stops working."}},"type":"object","required":["file_id","type","type_label_de","type_label_en","file_name_de","file_name_en","updated_at","freshness","download_url","download_url_expires_at"],"title":"CompanyDocumentDownload","description":"Document metadata plus a short-lived presigned download URL."},"CompanyDocumentList":{"properties":{"object":{"type":"string","const":"company_document_list","title":"Object","description":"Discriminator. Always `company_document_list`.","default":"company_document_list"},"eu_id":{"type":"string","title":"Eu Id","description":"firmendata company identifier."},"country_code":{"type":"string","enum":["DE","CH","AT"],"title":"Country Code","description":"Country of the register the company is entered in: `DE` for the German registers (Handelsregister, Genossenschafts-, Partnerschafts-, Vereinsregister), `CH` for the Swiss commercial register, `AT` for the Austrian Firmenbuch."},"coverage":{"$ref":"#/components/schemas/DocumentsCoverage","description":"Whether register document downloads apply to this company."},"freshness":{"$ref":"#/components/schemas/Freshness","description":"Outcome of this request's document availability check. `last_checked_at` is the successful check time, or null on failure. Failed checks return the last available document list without billing."},"data":{"items":{"$ref":"#/components/schemas/CompanyDocumentListItem"},"type":"array","title":"Data","description":"Register extracts first, then other register documents grouped by type, newest dated versions first and undated versions last. Includes older document versions. Empty when no documents are available or downloads do not apply."}},"type":"object","required":["eu_id","country_code","coverage","freshness","data"],"title":"CompanyDocumentList"},"CompanyDocumentListItem":{"properties":{"object":{"type":"string","const":"company_document_listing","title":"Object","description":"Discriminator. Always `company_document_listing`.","default":"company_document_listing"},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id","description":"Catalog identifier accepted by `/documents/download`; null for register extracts, which are downloaded by `file_type`."},"type":{"type":"string","enum":["register_extract_current","register_extract_chronological","shareholder_list","articles_of_association","company_registration","model_protocol"],"title":"Type","description":"Kind of register document."},"type_label_de":{"type":"string","title":"Type Label De","description":"German document type name, such as `Aktueller Abdruck` or `Liste der Gesellschafter`."},"type_label_en":{"type":"string","title":"Type Label En","description":"English document type name, such as `Current Register Extract` or `Shareholder List`."},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label","description":"The document's label as the registry lists it. Its language depends on which register portal answered (German or English); use `type_label_de` / `type_label_en` for a stable name and `document_date` for the date."},"document_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Document Date","description":"Document date stated in the registry label, when known; null for register extracts."},"published_at":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Published At","description":"Publication date recorded in the catalog, when known; null for register extracts."},"is_latest":{"type":"boolean","title":"Is Latest","description":"`true` for the first, newest listed version of its type. Always `true` for register extracts."},"stored":{"type":"boolean","title":"Stored","description":"`true` when firmendata holds a copy that can be downloaded immediately."},"file_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"File Id","description":"Identifier of the stored copy (`file_<id>`); null when no copy is held."},"fetched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Fetched At","description":"When firmendata last fetched the stored copy; null when no copy is held."},"is_outdated":{"type":"boolean","title":"Is Outdated","description":"`true` for a stored register extract older than the company's latest register entry. Request `/documents/download` with `fetch_realtime=true` for a current extract. Always `false` for other register documents.","default":false}},"type":"object","required":["type","type_label_de","type_label_en","is_latest","stored"],"title":"CompanyDocumentListItem"},"CompanyFinancials":{"properties":{"object":{"type":"string","const":"company_financials","title":"Object","description":"Discriminator. Always `company_financials`.","default":"company_financials"},"eu_id":{"type":"string","title":"Eu Id","description":"firmendata company identifier."},"freshness":{"$ref":"#/components/schemas/Freshness","description":"How current the financial filings in this response are. `last_checked_at` is the timestamp at which the company's filings were last successfully refreshed; `realtime_fetching_status` reports the outcome of the realtime attempt for this request."},"summary":{"anyOf":[{"$ref":"#/components/schemas/FinancialSummaryBlock"},{"type":"null"}],"description":"Headline figures for the latest reported fiscal year. `null` when no financial filings are on record."},"history":{"$ref":"#/components/schemas/FinancialHistoryBlock","description":"Multi-year history: annual top-line metrics with the top-level positions, plus the structured profit-and-loss, assets, and liabilities-and-equity rows from the filings (left empty with `details=false`)."},"employee_history":{"$ref":"#/components/schemas/EmployeeHistoryBlock","description":"Per-year employee headcount (total / full-time / part-time) sourced from annual Jahresabschluss filings."},"financial_publications":{"items":{"$ref":"#/components/schemas/FinancialPublication"},"type":"array","title":"Financial Publications","description":"Filed annual financial statements (Bilanz files) available for this company: Jahresabschluss, Konzernabschluss, or combined. Sorted by `published_at` descending. Attachments reference the filed PDF — downloads are not exposed in v1."},"relationships":{"anyOf":[{"$ref":"#/components/schemas/RelationshipsBlock"},{"type":"null"}],"description":"Parent and subsidiary companies. Populated from consolidated financial filings; absent when the company is not part of a reported group."}},"type":"object","required":["eu_id","freshness","history","employee_history"],"title":"CompanyFinancials","description":"Full historic + aggregated financial profile for one company.\n\nReturned by `GET /v1/companies/{eu_id}/financials`. Heavier than the\nhero detail endpoint — expect multi-year P&L, balance-sheet line\nitems, employee time series, and parent/subsidiary references."},"CompanyHistory":{"properties":{"object":{"type":"string","const":"company_history","title":"Object","description":"Discriminator. Always `company_history`.","default":"company_history"},"eu_id":{"type":"string","title":"Eu Id","description":"firmendata company identifier."},"coverage":{"$ref":"#/components/schemas/HistoryCoverage"},"freshness":{"$ref":"#/components/schemas/Freshness","description":"How current the chronological register history is. `last_checked_at` is when the company's chronological extract was last fetched; `realtime_fetching_status` reports the outcome of the realtime attempt for this request."},"legal_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Status","description":"Current legal status derived from the timeline (`active`, `dissolved`, `in_liquidation`, `insolvent`). `null` when the German register history is not available. Swiss companies still receive their legal status from the Swiss Official Gazette of Commerce (SHAB) bankruptcy and Nachlass notices.","examples":["active"]},"legal_status_events":{"items":{"$ref":"#/components/schemas/LegalStatusEvent"},"type":"array","title":"Legal Status Events","description":"Insolvency, Auflösung and Liquidation events, newest first, merged and deduplicated across the source registries. Swiss companies still receive their legal-status timeline from the Swiss Official Gazette of Commerce (SHAB) bankruptcy and Nachlass notices when register history is not available. Empty for a company that has never been in insolvency or liquidation."},"first_entry":{"anyOf":[{"$ref":"#/components/schemas/FirstRegisterEntry"},{"type":"null"}],"description":"The earliest entry of the extract, and whether it is the founding."},"current_board":{"items":{"$ref":"#/components/schemas/BoardMember"},"type":"array","title":"Current Board","description":"Officers in office now, from replaying every appointment, departure and correction in `board_changes`."},"board_changes":{"items":{"$ref":"#/components/schemas/BoardChange"},"type":"array","title":"Board Changes","description":"Every appointment, departure and correction of an officer (Geschäftsführer, Vorstand, Liquidator, persönlich haftender Gesellschafter) or limited partner."},"limited_partners":{"items":{"$ref":"#/components/schemas/LimitedPartner"},"type":"array","title":"Limited Partners","description":"Current limited partners (Kommanditisten). Only KG-shaped legal forms have them."},"names":{"items":{"$ref":"#/components/schemas/NameEntry"},"type":"array","title":"Names","description":"Company names over time."},"seats":{"items":{"$ref":"#/components/schemas/SeatEntry"},"type":"array","title":"Seats","description":"Registered seats over time."},"business_addresses":{"items":{"$ref":"#/components/schemas/AddressEntry"},"type":"array","title":"Business Addresses","description":"Business addresses over time."},"share_capital":{"items":{"$ref":"#/components/schemas/CapitalEntry"},"type":"array","title":"Share Capital","description":"Share capital over time."},"business_purposes":{"items":{"$ref":"#/components/schemas/PurposeEntry"},"type":"array","title":"Business Purposes","description":"Business purposes over time."},"branches":{"items":{"$ref":"#/components/schemas/BranchEntry"},"type":"array","title":"Branches","description":"Branch offices, as listed by each entry that names them."},"legal_forms":{"items":{"$ref":"#/components/schemas/LegalFormEntry"},"type":"array","title":"Legal Forms","description":"Legal-form changes over time."},"articles_of_association":{"items":{"$ref":"#/components/schemas/ArticlesEntry"},"type":"array","title":"Articles Of Association","description":"Creation and amendments of the constitutional document — Satzung, Gesellschaftsvertrag or Statut depending on legal form."}},"type":"object","required":["eu_id","coverage","freshness"],"title":"CompanyHistory","description":"Chronological register history for a company.\n\nEverything recorded against a company in the chronological register\nextract (Chronologischer Abdruck), grouped by what changed. Timelines are\noldest first; dates are ISO 8601 and people use the same `person` shape\nas the company detail."},"CompanyListDetailResponse":{"properties":{"object":{"type":"string","const":"list","title":"Object","description":"Discriminator. Always `list`.","default":"list"},"data":{"items":{"$ref":"#/components/schemas/SearchHit"},"type":"array","title":"Data","description":"One page of the list's companies. Same row shape as `/companies/search`, so both surfaces deserialize into one type."},"pagination":{"$ref":"#/components/schemas/PaginationInfo","description":"Pagination metadata for this page."},"filters_echo":{"additionalProperties":true,"type":"object","title":"Filters Echo","description":"The effective filter values applied to this query, echoed back for client convenience."},"list_id":{"type":"integer","title":"List Id","description":"Identifier of the list."},"name":{"type":"string","title":"Name","description":"List name as set in the app."}},"type":"object","required":["list_id","name"],"title":"CompanyListDetailResponse","description":"Response envelope for `GET /v1/lists/{list_id}`."},"CompanyListSummary":{"properties":{"object":{"type":"string","const":"company_list","title":"Object","description":"Discriminator. Always `company_list`.","default":"company_list"},"list_id":{"type":"integer","title":"List Id","description":"Identifier to pass to `GET /v1/lists/{list_id}`."},"name":{"type":"string","title":"Name","description":"List name as set in the app."},"company_count":{"type":"integer","title":"Company Count","description":"How many companies are on the list.","default":0},"is_shared":{"type":"boolean","title":"Is Shared","description":"`true` when a public share link is currently active.","default":false},"alerts_enabled":{"type":"boolean","title":"Alerts Enabled","description":"`true` when change alerts are switched on for this list.","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When the list was created."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"When the list was last changed."}},"type":"object","required":["list_id","name","created_at","updated_at"],"title":"CompanyListSummary","description":"One of the caller's company lists, without its companies."},"CompanyListsResponse":{"properties":{"object":{"type":"string","const":"list","title":"Object","description":"Discriminator. Always `list`.","default":"list"},"data":{"items":{"$ref":"#/components/schemas/CompanyListSummary"},"type":"array","title":"Data","description":"The caller's lists, newest first."},"pagination":{"$ref":"#/components/schemas/PaginationInfo","description":"Pagination metadata for this page."},"filters_echo":{"additionalProperties":true,"type":"object","title":"Filters Echo","description":"The effective filter values applied to this query, echoed back for client convenience."}},"type":"object","title":"CompanyListsResponse","description":"Response envelope for `GET /v1/lists`."},"CompanySize":{"type":"string","enum":["kleinst","klein","mittelgross"],"title":"CompanySize","description":"Statutory size class under § 267 / § 267a HGB, read from the filing.\n\nA class is assigned only where the company claimed a size-dependent\nrelief, which is an assertion of being at most that size. Publishing more\nthan required is permitted at every size and asserts nothing, so a full\nprofit-and-loss statement alone establishes no class — for those the\nreported revenue is the answer. Micro companies may declare their class\nin the notes (Anhang). The values are therefore not exhaustive,\nand selecting all is a real filter rather than a no-op."},"ContactBlock":{"properties":{"object":{"type":"string","const":"company_contact","title":"Object","description":"Discriminator. Always `company_contact`.","default":"company_contact"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website","description":"Primary web domain."},"impressum_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Impressum Url","description":"URL of the company's Impressum page."},"primary_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Email","description":"Primary business contact email address."},"phones":{"items":{"$ref":"#/components/schemas/Phone"},"type":"array","title":"Phones","description":"Company phone and fax numbers."},"social_profiles":{"items":{"$ref":"#/components/schemas/SocialProfile"},"type":"array","title":"Social Profiles","description":"Discovered social-media profiles."},"websites":{"items":{"$ref":"#/components/schemas/WebsiteEntry"},"type":"array","title":"Websites","description":"All known websites of the company, primary first."}},"type":"object","title":"ContactBlock","description":"Contact/web-presence block. Populated only when `expand=contact`."},"Country":{"type":"string","enum":["DE","CH","AT"],"title":"Country"},"DocumentsCoverage":{"properties":{"object":{"type":"string","const":"documents_coverage","title":"Object","description":"Discriminator. Always `documents_coverage`.","default":"documents_coverage"},"status":{"type":"string","enum":["available","not_applicable"],"title":"Status","description":"`available` for companies in the German registers; `not_applicable` for the Swiss commercial register, which publishes no document downloads, and for the Austrian Firmenbuch. An available catalog may be empty."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Explanation when document downloads do not apply to this company."}},"type":"object","required":["status"],"title":"DocumentsCoverage"},"EmployeeHistoryBlock":{"properties":{"object":{"type":"string","const":"employee_history","title":"Object","description":"Discriminator. Always `employee_history`.","default":"employee_history"},"series":{"items":{"$ref":"#/components/schemas/EmployeeYear"},"type":"array","title":"Series","description":"Headcount per year, sorted ascending by year."}},"type":"object","title":"EmployeeHistoryBlock","description":"Multi-year employee history."},"EmployeeYear":{"properties":{"object":{"type":"string","const":"employee_year","title":"Object","description":"Discriminator. Always `employee_year`.","default":"employee_year"},"year":{"type":"integer","title":"Year","description":"Reporting year."},"total":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total","description":"Total employee count for the year."},"full_time":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Full Time","description":"Full-time employee count, when reported."},"part_time":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Part Time","description":"Part-time employee count, when reported."}},"type":"object","required":["year"],"title":"EmployeeYear","description":"Employee headcount for one year."},"EuSmeDeclaration":{"properties":{"object":{"type":"string","const":"eu_sme_declaration","title":"Object","description":"Discriminator. Always `eu_sme_declaration`.","default":"eu_sme_declaration"},"is_sme":{"type":"boolean","title":"Is Sme","description":"The company's own most recent declaration under the EU SME definition (Commission Recommendation 2003/361/EC)."},"declared_on":{"type":"string","format":"date","title":"Declared On","description":"Date of that declaration."}},"type":"object","required":["is_sme","declared_on"],"title":"EuSmeDeclaration"},"FeedCompany":{"properties":{"eu_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Eu Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"legal_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Form"},"rechtsform_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rechtsform Code"},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City"},"country":{"type":"string","enum":["DE","CH","AT"],"title":"Country"},"register_court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Court"},"register_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Type"},"register_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Id"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"nace_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nace Code"}},"type":"object","required":["country"],"title":"FeedCompany"},"FeedEvent":{"properties":{"object":{"type":"string","const":"feed_event","title":"Object","default":"feed_event"},"id":{"type":"string","title":"Id"},"type":{"type":"string","enum":["company.founded","company.insolvency_notice"],"title":"Type"},"discovered_at":{"type":"string","format":"date-time","title":"Discovered At"},"occurred_on":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Occurred On"},"company":{"$ref":"#/components/schemas/FeedCompany"},"insolvency":{"anyOf":[{"$ref":"#/components/schemas/FeedInsolvency"},{"type":"null"}]},"links":{"$ref":"#/components/schemas/FeedLinks"}},"type":"object","required":["id","type","discovered_at","company","links"],"title":"FeedEvent","description":"A company event. The same event may appear more than once; deduplicate on `id`."},"FeedInsolvency":{"properties":{"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Court"},"publish_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Publish Date"},"publication_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Publication Ref"}},"type":"object","title":"FeedInsolvency"},"FeedLinks":{"properties":{"company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company"}},"type":"object","title":"FeedLinks"},"FeedResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/FeedEvent"},"type":"array","title":"Data"},"next_cursor":{"type":"string","title":"Next Cursor","description":"Always present. Persist and pass back even after an empty page."},"has_more":{"type":"boolean","title":"Has More","description":"Continue immediately when true; otherwise poll again later."}},"type":"object","required":["next_cursor","has_more"],"title":"FeedResponse"},"FinancialHistoryBlock":{"properties":{"object":{"type":"string","const":"financial_history","title":"Object","description":"Discriminator. Always `financial_history`.","default":"financial_history"},"metrics":{"items":{"$ref":"#/components/schemas/FinancialMetric"},"type":"array","title":"Metrics","description":"Annual top-line metrics, one entry per fiscal year."},"profit_and_loss":{"items":{"$ref":"#/components/schemas/FinancialRow"},"type":"array","title":"Profit And Loss","description":"Every filed profit-and-loss row at every depth, with its HGB hierarchy. Empty with `details=false`; the top-level positions are always in `metrics[].income_statement`."},"assets":{"items":{"$ref":"#/components/schemas/FinancialRow"},"type":"array","title":"Assets","description":"Every filed assets-side (Aktiva) row at every depth, with its HGB hierarchy. Empty with `details=false`; the top-level positions are always in `metrics[].balance_sheet`."},"liabilities_and_equity":{"items":{"$ref":"#/components/schemas/FinancialRow"},"type":"array","title":"Liabilities And Equity","description":"Every filed liabilities-and-equity (Passiva) row at every depth, with its HGB hierarchy. Empty with `details=false`; the top-level positions are always in `metrics[].balance_sheet`."}},"type":"object","title":"FinancialHistoryBlock","description":"Multi-year financial history.\n\n`metrics` is always populated, with each year's top-level\n`balance_sheet` and `income_statement` positions. The three line-item\narrays hold every filed row at every depth; they are empty when the\nrequest passes `details=false`."},"FinancialMetric":{"properties":{"object":{"type":"string","const":"financial_metric","title":"Object","description":"Discriminator. Always `financial_metric`.","default":"financial_metric"},"year":{"type":"integer","title":"Year","description":"Fiscal year."},"revenue":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Annual revenue (Umsatzerlöse) for this year. Null when the company did not publish it — see `size_class`, which says what the omission itself discloses."},"gross_profit":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Rohergebnis (§ 276 HGB) — the collapsed top line a small or medium-sized company may publish *instead of* revenue and cost of materials. Where this is set and `revenue` is null, this is the only top-line figure on file. It is not revenue and must not be compared with it: it is already net of input costs."},"other_operating_income":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Other operating income — `sonstige betriebliche Erträge` plus interest and commission income. Reported separately from `revenue`, which counts only Umsatzerlöse."},"profit":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Annual profit (Jahresüberschuss / Jahresfehlbetrag) for this year."},"balance_sheet_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Balance-sheet total (Bilanzsumme), i.e. Summe Aktiva."},"liabilities_and_equity_total":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Total liabilities and equity (Summe Passiva)."},"balance_sheet":{"anyOf":[{"$ref":"#/components/schemas/BalanceSheetPositions"},{"type":"null"}],"description":"Top-level balance-sheet positions (Anlagevermögen, Sachanlagen, Umlaufvermögen, Eigenkapital, Rückstellungen, Verbindlichkeiten, …). `null` when no balance sheet is available for this year."},"income_statement":{"anyOf":[{"$ref":"#/components/schemas/IncomeStatementPositions"},{"type":"null"}],"description":"Key profit-and-loss positions (Materialaufwand, Personalaufwand, Abschreibungen, Steuern, …). `null` when the company filed no profit-and-loss statement for this year."},"size_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Size Class","description":"Statutory size class for this fiscal year — `kleinst`, `klein`, `mittelgross` or `gross` (§ 267 / § 267a HGB).\n\nDerived from the reliefs the filing claims, so it is an exact statement about the company's own filing, not an estimate. **Null never means large.** It means the filing asserts no size — typically because a full profit-and-loss statement was published, in which case `revenue` carries the answer directly.","examples":["klein"]},"size_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Size Basis","description":"Why `size_class` was assigned, as a stable code:\n\n- `no_guv` — no profit-and-loss statement published (§ 326 Abs. 1)\n- `rohergebnis` — P&L collapsed to a Rohergebnis (§ 276)\n- `declared` — the filing states its own class\n- `filed_221_ugb` — an Austrian filing states its § 221 UGB class\n- `ceiling_balance_sheet` / `ceiling_employees` — a second § 267 criterion is over its limit, which tightened the class","examples":["no_guv"]},"revenue_ceiling":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Highest revenue this company can have had in this fiscal year without losing the size class it filed under — a hard upper bound, not an estimate.\n\nUsually null, and that is the normal case rather than missing data: § 267 asks whether a company exceeds **at least two of three** criteria, so a size class alone permits any revenue. The bound only exists where a second criterion (balance-sheet total or employees) is already over its limit, which forces revenue under its own. Where it is null, no revenue bound follows from the class and none should be inferred.","examples":[{"amount":12000000.0,"currency":"EUR"}]},"ceiling_basis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ceiling Basis","description":"Which second criterion forces `revenue_ceiling` — `ceiling_balance_sheet` or `ceiling_employees`. Null whenever `revenue_ceiling` is null.","examples":["ceiling_balance_sheet"]}},"type":"object","required":["year"],"title":"FinancialMetric","description":"Top-line annual financial metrics for one fiscal year."},"FinancialPublication":{"properties":{"object":{"type":"string","const":"financial_publication","title":"Object","description":"Discriminator. Always `financial_publication`.","default":"financial_publication"},"id":{"type":"string","title":"Id","description":"Stable identifier for this filing."},"type":{"type":"string","enum":["financial_statement_annual","financial_statement_consolidated","financial_statement_combined"],"title":"Type","description":"Kind of financial statement filed."},"fiscal_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fiscal Year","description":"Fiscal year the statement covers."},"title":{"type":"string","title":"Title","description":"Filing title as published in the Unternehmensregister (German as filed)."},"published_at":{"type":"string","format":"date","title":"Published At","description":"Date the filing was made public."},"attachment":{"anyOf":[{"$ref":"#/components/schemas/BilanzAttachment"},{"type":"null"}],"description":"Reference to the PDF filing, when available."}},"type":"object","required":["id","type","title","published_at"],"title":"FinancialPublication","description":"One filed financial statement (Jahresabschluss / Konzernabschluss)."},"FinancialRow":{"properties":{"object":{"type":"string","const":"financial_row","title":"Object","description":"Discriminator. Always `financial_row`.","default":"financial_row"},"year":{"type":"integer","title":"Year","description":"Fiscal year of the statement this row belongs to."},"report_type":{"type":"string","title":"Report Type","description":"Report type (e.g. `Jahresabschluss`, `Konzernabschluss`)."},"section":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section","description":"Top-level section heading."},"subsection":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subsection","description":"Second-level heading."},"subsubsection":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subsubsection","description":"Third-level heading."},"subsubsubsection":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subsubsubsection","description":"Fourth-level heading."},"title":{"type":"string","title":"Title","description":"Line-item title as filed."},"current_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Current Value","description":"Value for the current fiscal year, in EUR."},"previous_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Previous Value","description":"Value for the prior comparison year, in EUR."}},"type":"object","required":["year","report_type","title"],"title":"FinancialRow","description":"One row from a structured financial statement (P&L or balance sheet)."},"FinancialSummaryBlock":{"properties":{"object":{"type":"string","const":"financial_summary","title":"Object","description":"Discriminator. Always `financial_summary`.","default":"financial_summary"},"latest_fiscal_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latest Fiscal Year","description":"Fiscal year of the latest reported figures."},"latest_revenue":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Revenue (Umsatzerlöse) from the most recent fiscal year that reports one — see `latest_revenue_year`. Small and medium-sized companies file no profit-and-loss statement, so this is often `null`."},"latest_revenue_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latest Revenue Year","description":"Fiscal year `latest_revenue` is for."},"latest_profit":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Annual profit (Jahresüberschuss / Bilanzgewinn) from the most recent fiscal year that reports one — see `latest_profit_year`."},"latest_profit_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latest Profit Year","description":"Fiscal year `latest_profit` is for."},"latest_total_assets":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Total assets reported for `latest_fiscal_year`."},"latest_total_liabilities_and_equity":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Total liabilities and equity reported for `latest_fiscal_year`."},"latest_equity":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Equity (Eigenkapital) reported for `latest_fiscal_year`. Only on the financials endpoint; `null` when that year's balance sheet does not show it."},"latest_employee_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latest Employee Count","description":"Employee count from the most recent year that reports one — see `latest_employee_count_year`."},"latest_employee_count_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latest Employee Count Year","description":"Year `latest_employee_count` is for."}},"type":"object","title":"FinancialSummaryBlock","description":"Headline financial figures for the latest reported fiscal year."},"FirstRegisterEntry":{"properties":{"object":{"type":"string","const":"first_register_entry","title":"Object","description":"Discriminator. Always `first_register_entry`.","default":"first_register_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"first_registered_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"First Registered Date","description":"Date the company was first entered in a German register (Tag der ersten Eintragung). Earlier than `entry_date` when the extract starts after a court transfer or a digitisation.","examples":["1961-04-27"]},"origin":{"type":"string","enum":["founding","transfer","conversion","charter_predates"],"title":"Origin","description":"What the first entry records. `founding`: the company's registration. `transfer`: a move from another register court or a digitisation — earlier entries exist elsewhere. `conversion`: the company arose from an Umwandlung (Formwechsel, Verschmelzung, Spaltung). `charter_predates`: the entry cites an articles of association or contract more than a year older than itself. Only `founding` supports the `founder_profile` verdicts; for the others they are `null`.","default":"founding"},"founding_document_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Founding Document Type","description":"Constitutional document as filed: `Satzung`, `Gesellschaftsvertrag` or `Statut`.","examples":["Satzung"]},"founding_document_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Founding Document Date","description":"Date of that document.","examples":["1960-07-06"]}},"type":"object","title":"FirstRegisterEntry","description":"The earliest entry of the chronological extract, and what it records."},"FounderProfileBlock":{"properties":{"object":{"type":"string","const":"founder_profile","title":"Object","description":"Discriminator. Always `founder_profile`.","default":"founder_profile"},"founder_led":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Founder Led","description":"Whether someone holding a role at first registration is still in office. `null` when the chronological extract is missing or its first entry is not the founding — a transfer from another register court, an Umwandlung (Formwechsel, Verschmelzung, Spaltung), or an entry citing a far older charter. `founders` is then empty too: the officers on that day are not founders."},"founder_led_confidence":{"anyOf":[{"type":"string","enum":["confirmed","likely"]},{"type":"null"}],"title":"Founder Led Confidence","description":"`likely` when the company was renamed shortly after registration, the signature of a shelf company (Vorratsgesellschaft) whose first officer is the provider's nominee rather than a founder."},"founder_led_since":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Founder Led Since","description":"Start of the longest-serving founder's tenure."},"family_managed":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Family Managed","description":"Whether two or more members of one family hold an ownership or governing role. `null` when the register shows only one person and the company name carries no family signal — there is then nothing to compare against, which is not the same as unrelated."},"family_confidence":{"anyOf":[{"type":"string","enum":["confirmed","likely"]},{"type":"null"}],"title":"Family Confidence","description":"`confirmed` rests on two identified people; `likely` on the name alone."},"family_signals":{"items":{"type":"string"},"type":"array","title":"Family Signals","description":"Which signals fired: `shared_surname`, `eponymous` (a person's surname is in the company name), `lexical` (`Gebr.`, `& Söhne`), `multigenerational` (relatives a generation apart), `shared_address`.","examples":[["shared_surname","eponymous"]]},"family_surname":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Family Surname","description":"Normalised surname the family signal rests on."},"succession_risk":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Succession Risk","description":"Whether the oldest serving founder has reached 65. `null` when the company is not founder-led, or no founder birth date is on record."},"oldest_founder_birth_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Oldest Founder Birth Year","description":"Birth year of the oldest founder still serving."},"founder_count":{"type":"integer","title":"Founder Count","description":"How many natural persons were identified at first registration.","default":0},"founders":{"items":{"$ref":"#/components/schemas/FounderRecordItem"},"type":"array","title":"Founders","description":"The identified founders."},"evidence_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Evidence Source","description":"Register information supporting this assessment."},"as_of":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"As Of","description":"Date of the register snapshot this rests on. A director who resigned after this date is not yet reflected."}},"type":"object","title":"FounderProfileBlock","description":"Founder, family-involvement and succession assessment.\n\nEvery field is **derived** from the register's board history rather\nthan read off a filing, so each verdict ships with the evidence that\nproduced it. The three verdicts are deliberately nullable and `null`\nnever means \"no\": it means the register does not support an answer."},"FounderRecordItem":{"properties":{"object":{"type":"string","const":"founder","title":"Object","description":"Discriminator. Always `founder`.","default":"founder"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name","description":"Given name as filed."},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name","description":"Family name as filed."},"birth_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Birth Year","description":"Year of birth, when the register records a birth date."},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","description":"Role held at first registration (e.g. `Geschäftsführer`, `Kommanditist`).","examples":["Geschäftsführer"]},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the first register entry.","examples":["2006-09-20"]},"still_serving":{"type":"boolean","title":"Still Serving","description":"Whether this person is still in office.","default":false},"share_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Share Percent","description":"Capital share held at founding, in percent. Only limited partners (Kommanditisten) record this in the register; for every other legal form the founding cap table is not public register data and this is `null`."}},"type":"object","title":"FounderRecordItem","description":"One person identified as holding a role at first registration."},"Freshness":{"properties":{"object":{"type":"string","const":"freshness","title":"Object","description":"Discriminator. Always `freshness`.","default":"freshness"},"last_checked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Checked At","description":"Timestamp (UTC) of the last successful refresh of the underlying data slice from the German registries. Compare against your own staleness tolerance to decide whether to re-issue the call with `fetch_realtime=true`. `null` when the slice has never been successfully fetched for this company.","examples":["2026-04-30T12:14:08Z"]},"realtime_fetching_status":{"type":"string","enum":["success","platform_unavailable","documents_temporarily_unavailable","file_unavailable","company_unavailable","realtime_fetching_disabled"],"title":"Realtime Fetching Status","description":"Outcome of the realtime fetch attempt for this request (`fetch_realtime=true`). `realtime_fetching_disabled` when the parameter was not set; `success` when fresh data was merged into the response; otherwise the response falls back to the cached read and this field reports why."}},"type":"object","required":["realtime_fetching_status"],"title":"Freshness","description":"How current the data in this response is.\n\nSee the `Data Freshness` section of the API overview for the\nthree modes (cached read, realtime fetch, subscriptions) and how\n`last_checked_at` is computed per endpoint."},"HistoryBranch":{"properties":{"object":{"type":"string","const":"branch","title":"Object","description":"Discriminator. Always `branch`.","default":"branch"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Branch name as filed."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City","description":"Branch seat."},"address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Address","description":"Branch address as filed."},"register_court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Court","description":"Court registering the branch, if filed."},"register_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Type","description":"Register type of the branch entry."},"register_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Number","description":"Register number of the branch entry."}},"type":"object","title":"HistoryBranch","description":"One branch office (Zweigniederlassung) as listed by an entry."},"HistoryCoverage":{"properties":{"object":{"type":"string","const":"history_coverage","title":"Object","description":"Discriminator. Always `history_coverage`.","default":"history_coverage"},"status":{"type":"string","enum":["available","not_available"],"title":"Status","description":"`available`: the chronological register history is available and the timelines below are populated. `not_available`: no extract exists for this company — the Swiss commercial register publishes none, Austrian history is not available yet, and for a German company none has been retrieved yet (`fetch_realtime=true` retrieves it). The register timelines are then empty and the call is not charged. Swiss companies still receive their legal-status timeline from the Swiss Official Gazette of Commerce (SHAB)."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Customer-safe explanation when `status` is `not_available`."}},"type":"object","required":["status"],"title":"HistoryCoverage","description":"Whether a chronological register history exists for this company."},"IncomeStatementPositions":{"properties":{"object":{"type":"string","const":"income_statement_positions","title":"Object","description":"Discriminator. Always `income_statement_positions`.","default":"income_statement_positions"},"revenue":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Umsatzerlöse, as filed in this year's profit-and-loss statement."},"cost_of_materials":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Materialaufwand. Expenses are negative, as filed."},"personnel_expenses":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Personalaufwand. Negative, as filed."},"depreciation_and_amortization":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Abschreibungen auf immaterielle Vermögensgegenstände des Anlagevermögens und Sachanlagen. Negative, as filed."},"other_operating_income":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Sonstige betriebliche Erträge."},"other_operating_expenses":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Sonstige betriebliche Aufwendungen. Negative, as filed."},"operating_result":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Betriebsergebnis, when the filing states it (most HGB filings do not)."},"income_from_investments":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Erträge aus Beteiligungen."},"interest_income":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Sonstige Zinsen und ähnliche Erträge."},"interest_expenses":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Zinsen und ähnliche Aufwendungen. Negative, as filed."},"income_taxes":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Steuern vom Einkommen und vom Ertrag. Negative, as filed; positive for a refund."},"result_after_taxes":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Ergebnis nach Steuern."},"other_taxes":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Sonstige Steuern. Negative, as filed."},"net_income":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Jahresüberschuss / Jahresfehlbetrag as filed in the profit-and-loss statement."}},"type":"object","title":"IncomeStatementPositions","description":"Key profit-and-loss positions for one fiscal year (§ 275 HGB).\n\nValues are signed as filed: income positive, expenses negative. Most\nsmall and medium-sized companies file no profit-and-loss statement, in\nwhich case this block is `null`. Every row is in\n`history.profit_and_loss`."},"IndustryBlock":{"properties":{"object":{"type":"string","const":"company_industry","title":"Object","description":"Discriminator. Always `company_industry`.","default":"company_industry"},"primary_wz_2025_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Wz 2025 Code","description":"Primary (highest-confidence) WZ 2025 code. Dotted-hierarchy format, e.g. `62.01.9`."},"wz_2025_codes":{"items":{"$ref":"#/components/schemas/Wz2025Score"},"type":"array","title":"Wz 2025 Codes","description":"Ranked WZ 2025 candidates with confidence scores."}},"type":"object","title":"IndustryBlock","description":"Industry block: ranked WZ 2025 classifications."},"IndustrySlug":{"type":"string","enum":["automotive","chemicals","construction","consulting","education","energy","financial_services","food","healthcare","holdings","hospitality","insurance","legal","logistics","manufacturing","media","mining","other_services","public_sector","technology","telecom","trade"],"title":"IndustrySlug"},"InsolvencyBlock":{"properties":{"object":{"type":"string","const":"insolvency_status","title":"Object","description":"Discriminator. Always `insolvency_status`.","default":"insolvency_status"},"has_insolvency":{"type":"boolean","title":"Has Insolvency","description":"`true` when an insolvency *proceeding* is on record. A company dissolved by shareholder resolution reports `false` here while still reporting `current_status` of `in_liquidation`.","default":false},"current_status":{"type":"string","enum":["active","preliminary","in_insolvency","rejected","terminated","in_liquidation","dissolved"],"title":"Current Status","description":"Current stage of the proceeding. `preliminary` — vorläufige Insolvenzverwaltung / Sicherungsmaßnahmen / provisorische Nachlassstundung. `in_insolvency` — Verfahren eröffnet / Konkurseröffnung / definitive Nachlassstundung. `rejected` — Abweisung mangels Masse / Einstellung mangels Aktiven. `terminated` — Verfahren aufgehoben / Schluss des Konkursverfahrens / Nachlassvertrag mit Vermögensabtretung. `in_liquidation` / `dissolved` — no insolvency proceeding, the company was dissolved under corporate law. `active` — no proceeding.","default":"active"},"court_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Court Name","description":"Name of the insolvency court, when proceedings are open; bankruptcy office or court for Swiss companies."},"case_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Case Number","description":"Insolvency case number (Aktenzeichen). Swiss companies have no case number."},"is_dissolved":{"type":"boolean","title":"Is Dissolved","description":"`true` when the company is dissolved (aufgelöst).","default":false},"has_liquidator":{"type":"boolean","title":"Has Liquidator","description":"`true` when a Liquidator or Abwickler is in office.","default":false},"self_administration":{"type":"boolean","title":"Self Administration","description":"`true` when the proceeding is in self-administration (Eigenverwaltung).","default":false},"most_recent_event_at":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Most Recent Event At","description":"Date of the most recent insolvency event on record."}},"type":"object","title":"InsolvencyBlock","description":"Insolvency / Auflösung / Liquidation snapshot.\n\nPresent whenever any legal-status event is on record — a voluntary\nliquidation reports `has_insolvency=false` with a `current_status`\nof `in_liquidation`."},"InsolvencyCategory":{"type":"string","enum":["Abweisungen mangels Masse","Aufhebung der Nachlassstundung","Bestätigung des Nachlassvertrages","Definitive Nachlassstundung","Einstellung mangels Aktiven","Eröffnungen","Konkurseröffnung","Konkursverfahren eröffnet","Nachlassvertrag mit Vermögensabtretung","Nichteröffnung mangels Vermögens","Provisorische Nachlassstundung","Sanierungsverfahren eröffnet","Schluss des Konkursverfahrens","Schuldenruf","Sicherungsmaßnahmen","Widerruf des Konkurses"],"title":"InsolvencyCategory"},"LegalFormEntry":{"properties":{"object":{"type":"string","const":"legal_form_entry","title":"Object","description":"Discriminator. Always `legal_form_entry`.","default":"legal_form_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"legal_form":{"type":"string","title":"Legal Form","description":"Legal form as filed.","examples":["Aktiengesellschaft"]},"previous_legal_form":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Legal Form","description":"Legal form before this entry. `null` for the first."}},"type":"object","required":["legal_form"],"title":"LegalFormEntry","description":"A change of legal form."},"LegalStatus":{"type":"string","enum":["active","in_liquidation","insolvent","dissolved","deleted"],"title":"LegalStatus","description":"Company lifecycle buckets for the search filter.\n\nDisjoint and exhaustive — every company is in exactly one,\nand `deleted` outranks the rest (a deleted company that was also in\nliquidation counts as deleted, matching the company detail page)."},"LegalStatusEvent":{"properties":{"object":{"type":"string","const":"legal_status_event","title":"Object","description":"Discriminator. Always `legal_status_event`.","default":"legal_status_event"},"category":{"type":"string","title":"Category","description":"Event type, in the shared German vocabulary: `Sicherungsmaßnahmen`, `Eröffnungen`, `Abweisungen mangels Masse`, `Aufhebung Sicherungsmaßnahmen`, `Aufhebung des Verfahrens`, `Auflösung durch Gesellschafterbeschluss`, `Auflösung mit Fortführung`, `Auflösung`. Swiss Official Gazette of Commerce (SHAB) notices for Swiss companies: `Konkurseröffnung`, `Einstellung mangels Aktiven`, `Schluss des Konkursverfahrens`, `Widerruf des Konkurses`, `Provisorische Nachlassstundung`, `Definitive Nachlassstundung`, `Aufhebung der Nachlassstundung`, `Bestätigung des Nachlassvertrages`, `Nachlassvertrag mit Vermögensabtretung`.","examples":["Auflösung durch Gesellschafterbeschluss"]},"sources":{"items":{"type":"string","enum":["si","cd","portal","shab","firmenbuch"]},"type":"array","title":"Sources","description":"Register or official publication venue recording this event: the commercial register, Insolvenzbekanntmachungen, the Swiss Official Gazette of Commerce (SHAB), or the Austrian Firmenbuch."},"event_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Event Date","description":"Register entry date, portal publication date, or the Swiss Official Gazette of Commerce (SHAB) publication date for `shab`. `null` when the source records no date."},"decision_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Decision Date","description":"Date of the court order or shareholder resolution (Beschluss)."},"effective_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Effective Date","description":"When a dissolution takes effect, if later than the decision."},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running register entry number (laufende Nummer)."},"court_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Court Name","description":"Court named in the entry; bankruptcy office or court for Swiss companies."},"case_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Case Number","description":"Insolvency case number (Aktenzeichen), when the entry states one. Swiss companies have no case number."},"legal_basis":{"items":{"type":"string"},"type":"array","title":"Legal Basis","description":"Statutory citations found in the entry text.","examples":[["§ 60 Abs. 1 GmbHG"]]},"dissolved":{"type":"boolean","title":"Dissolved","description":"`true` when this event dissolves the company.","default":false},"self_administration":{"type":"boolean","title":"Self Administration","description":"`true` for Eigenverwaltung (§ 270 InsO).","default":false},"ex_officio":{"type":"boolean","title":"Ex Officio","description":"`true` when entered von Amts wegen.","default":false}},"type":"object","required":["category"],"title":"LegalStatusEvent","description":"One insolvency / Auflösung / Liquidation event.\n\nDeduplicated across the four sources, so a single event carries every\nregistry that recorded it in `sources`."},"LeiGraphBlock":{"properties":{"object":{"type":"string","const":"lei_graph","title":"Object","description":"Discriminator. Always `lei_graph`.","default":"lei_graph"},"lei_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lei Code","description":"The company's own LEI code, when assigned."},"direct_parent":{"anyOf":[{"$ref":"#/components/schemas/LeiRelative"},{"type":"null"}],"description":"Direct parent in the LEI graph, when reported."},"direct_children":{"items":{"$ref":"#/components/schemas/LeiRelative"},"type":"array","title":"Direct Children","description":"Direct children in the LEI graph, ordered by legal name. At most 25 — `direct_children_total` says how many there are."},"direct_children_total":{"type":"integer","title":"Direct Children Total","description":"Number of direct children in the LEI graph, including any beyond the 25 listed in `direct_children`.","default":0}},"type":"object","title":"LeiGraphBlock","description":"LEI-based ownership graph: the direct parent and direct children."},"LeiRelative":{"properties":{"object":{"type":"string","const":"lei_relative","title":"Object","description":"Discriminator. Always `lei_relative`.","default":"lei_relative"},"lei_code":{"type":"string","title":"Lei Code","description":"Legal Entity Identifier (ISO 17442)."},"eu_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Eu Id","description":"firmendata company identifier when the entity is known to firmendata."},"legal_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Legal Name","description":"Full legal name from the LEI record."},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name","description":"Best human-readable name to use in UIs."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City","description":"Headquarters city from the LEI record."},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"ISO 3166-1 alpha-2 country code."},"relationship":{"type":"string","title":"Relationship","description":"Relationship type (e.g. `direct_parent`, `direct_child`)."},"register_court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Court","description":"Name of the registering court (Registergericht)."},"register_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Type","description":"Register type code (e.g. `HRB`, `HRA`, `GnR`, `PR`, `VR`)."},"register_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Register Number","description":"Register entry number (digits only). Combine with `register_type` for a full reference.","examples":[12345]}},"type":"object","required":["lei_code","relationship"],"title":"LeiRelative","description":"A node in the LEI-derived ownership graph."},"LimitedPartner":{"properties":{"object":{"type":"string","const":"limited_partner","title":"Object","description":"Discriminator. Always `limited_partner`.","default":"limited_partner"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"Natural person, when applicable."},"organization":{"anyOf":[{"$ref":"#/components/schemas/OrganizationRef"},{"type":"null"}],"description":"Organisation, when applicable."},"contribution":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Registered liability contribution (Hafteinlage)."},"share_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Share Percent","description":"Share of all registered contributions, in percent."}},"type":"object","title":"LimitedPartner","description":"A current limited partner (Kommanditist) and the contribution filed.\n\n`entry_date` / `entry_number` refer to the partner's most recent change."},"LocalizedText":{"properties":{"object":{"type":"string","const":"localized_text","title":"Object","description":"Discriminator. Always `localized_text`.","default":"localized_text"},"de":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"De","description":"German rendering of the text, if available."},"en":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"En","description":"English rendering of the text, if available."},"translation_source":{"anyOf":[{"type":"string","enum":["original","human","machine","passthrough"]},{"type":"null"}],"title":"Translation Source","description":"Provenance of the English rendering. `original`: the value as filed; `human`: human translation; `machine`: machine translation; `passthrough`: identical to the source language. `null` when there is no English rendering (`en` is `null`).","default":"original"}},"type":"object","title":"LocalizedText","description":"A piece of text rendered in German and/or English."},"Member":{"properties":{"object":{"type":"string","const":"member","title":"Object","description":"Discriminator. Always `member`.","default":"member"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","description":"Role label as filed."},"role_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Code","description":"Stable machine-readable role code."},"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"Natural person, when applicable."},"organization":{"anyOf":[{"$ref":"#/components/schemas/OrganizationRef"},{"type":"null"}],"description":"Organisation, when applicable."}},"type":"object","title":"Member","description":"A management or representative member of the company as filed in the register."},"Membership":{"type":"string","enum":["Steuerberaterkammer","Wirtschaftsprueferkammer","bbh","BaFin","LEI"],"title":"Membership","description":"External-registry memberships used as a company filter.\n\nSelecting multiple values matches companies with any of the selected\nmemberships."},"Money":{"properties":{"object":{"type":"string","const":"money","title":"Object","description":"Discriminator. Always `money`.","default":"money"},"amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Amount","description":"Numeric amount in `currency` units. `null` when not reported.","examples":[1250000.0]},"currency":{"type":"string","title":"Currency","description":"ISO 4217 currency code. Defaults to EUR.","default":"EUR"}},"type":"object","title":"Money","description":"A monetary amount in the given currency."},"NameEntry":{"properties":{"object":{"type":"string","const":"name_entry","title":"Object","description":"Discriminator. Always `name_entry`.","default":"name_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"name":{"type":"string","title":"Name","description":"Company name (Firma) as registered by this entry."}},"type":"object","required":["name"],"title":"NameEntry","description":"A company name (Firma) registered by one entry."},"NotificationCadence":{"type":"string","enum":["immediately","daily","weekly","monthly"],"title":"NotificationCadence","description":"How often you wish to receive notifications.\n\nA notification is only delivered when there is an actual update\nsince the previous successful delivery — no update means no\nnotification. For `one_time` subscriptions, this is the retry\nspacing while we wait for the data to become available.\n\n`immediately` delivers an update as soon as it is detected —\nservice-level objective: within 1 hour of publication.\n`daily` / `weekly` / `monthly` batch the check at the named\ncadence and notify only on actual changes."},"NotificationLanguage":{"type":"string","enum":["en","de"],"title":"NotificationLanguage","description":"Display language for human-targeted notifications (currently\njust email subject + body). Webhook payloads carry both languages\nin a bilingual `summary` block regardless of this setting."},"NotificationType":{"type":"string","enum":["webhook","email"],"title":"NotificationType","description":"Transport for the notification.\n\n* `webhook`: HTTP POST a signed JSON payload to `webhook_url`.\n* `email`:   Send a bilingual email to `recipient_email`.\n\nWith `notification_type = null`, no outbound notification is sent.\nRetrieve changes through the events API using the subscription/job id\nreturned when the subscription is created."},"OrganizationRef":{"properties":{"object":{"type":"string","const":"organization_ref","title":"Object","description":"Discriminator. Always `organization_ref`.","default":"organization_ref"},"eu_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Eu Id","description":"firmendata company identifier when the organisation is known to firmendata, otherwise `null`."},"legal_name":{"type":"string","title":"Legal Name","description":"Full legal name as filed."},"display_name":{"type":"string","title":"Display Name","description":"Best human-readable name to use in UIs."},"registered_seat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Registered Seat","description":"Registered seat city, when known."},"register_court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Court","description":"Name of the registering court (Registergericht)."},"register_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Type","description":"Register type code (e.g. `HRB`, `HRA`, `GnR`, `PR`, `VR`)."},"register_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Register Number","description":"Register entry number (digits only). Combine with `register_type` for a full reference.","examples":[12345]},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"ISO 3166-1 alpha-2 country code of the organisation, when known."},"lei_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lei Code","description":"Legal Entity Identifier (ISO 17442), when assigned."}},"type":"object","required":["legal_name","display_name"],"title":"OrganizationRef","description":"Reference to another organisation (parent, subsidiary, shareholder org)."},"PaginationInfo":{"properties":{"object":{"type":"string","const":"pagination","title":"Object","description":"Discriminator. Always `pagination`.","default":"pagination"},"has_more":{"type":"boolean","title":"Has More","description":"`true` when more pages are available after this one.","default":false},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Opaque cursor to fetch the next page. `null` on the last page."},"previous_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Cursor","description":"Opaque cursor to fetch the previous page. `null` on the first page."},"total_approx":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Approx","description":"Approximate total result count. Capped at 10,000 for `/companies/search`; exact for the lists endpoints; `null` for the subscription listings, which do not count."},"total_is_capped":{"type":"boolean","title":"Total Is Capped","description":"`true` when `total_approx` was clamped to the cap. Narrow your query for an exact count.","default":false}},"type":"object","title":"PaginationInfo","description":"Cursor-pagination metadata included in every list response."},"Person":{"properties":{"object":{"type":"string","const":"person","title":"Object","description":"Discriminator. Always `person`.","default":"person"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"Honorific or academic title (e.g. `Dr.`)."},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name","description":"Given name."},"middle_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Middle Name","description":"Middle name(s), if filed."},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name","description":"Family name."},"full_name":{"type":"string","title":"Full Name","description":"Pre-composed display name."},"date_of_birth":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Date Of Birth","description":"Date of birth, when reported by the register. May be a full date or a year-only date (`YYYY-01-01`) when only the year was filed."},"age":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Age","description":"Approximate current age in years, derived from `date_of_birth`."},"city":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"City","description":"City of residence as filed."}},"type":"object","required":["full_name"],"title":"Person","description":"A natural person referenced by the company (board member, shareholder, etc.)."},"Phone":{"properties":{"object":{"type":"string","const":"phone","title":"Object","description":"Discriminator. Always `phone`.","default":"phone"},"number":{"type":"string","title":"Number","description":"Phone or fax number in E.164 format."},"kind":{"type":"string","enum":["phone","fax"],"title":"Kind","description":"Whether the number is a phone or fax."},"display":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display","description":"Number formatted for display."}},"type":"object","required":["number","kind"],"title":"Phone","description":"A company phone or fax number."},"PotentialBeneficialOwner":{"properties":{"object":{"type":"string","const":"potential_beneficial_owner","title":"Object","description":"Discriminator. Always `potential_beneficial_owner`.","default":"potential_beneficial_owner"},"organization":{"$ref":"#/components/schemas/OrganizationRef","description":"The unresolved organisation node — same shape as `UboNode.organization`, including any partial registry metadata we have."},"unresolved_reason":{"type":"string","enum":["foreign_org","unlisted_org","cap_table_not_filed","max_depth_reached"],"title":"Unresolved Reason","description":"Why we couldn't continue the chain past this entity — matches the `UboNode.unresolved_reason` of the same node in `graph`."},"effective_share_percent":{"type":"number","title":"Effective Share Percent","description":"Effective share at the root summed across every chain position where this organisation appears. Computed under the same all-or-nothing rule as `BeneficialOwner.effective_share_percent` (root-edge share for each >25 % control chain reaching the entity, plus direct holdings)."},"chain_positions":{"type":"integer","title":"Chain Positions","description":"Number of distinct root-edges through which this organisation accumulated its effective share. >1 means the same name+city+country appeared as the apex of multiple controlled branches."}},"type":"object","required":["organization","unresolved_reason","effective_share_percent","chain_positions"],"title":"PotentialBeneficialOwner","description":"An unresolved organisation whose effective share at the root crosses\nthe §3 GwG 25 % threshold. The natural person(s) controlling this\nentity could be ultimate beneficial owners — we just couldn't follow\nthe chain past it (foreign country, no German Gesellschafterliste,\nor depth cap)."},"PurposeEntry":{"properties":{"object":{"type":"string","const":"purpose_entry","title":"Object","description":"Discriminator. Always `purpose_entry`.","default":"purpose_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"purpose":{"type":"string","title":"Purpose","description":"Business purpose (Unternehmensgegenstand) as of this entry."}},"type":"object","required":["purpose"],"title":"PurposeEntry","description":"A business purpose recorded by one entry."},"Rechtsform":{"type":"string","enum":["GmbH","KG","e.K.","eGbR","UG","GmbH & Co. KG","OHG","PartG","e.V.","AG","eG","ausländische Rechtsform (HRB)","gGmbH","UG & Co. KG","ausländische Rechtsform","SE","sonstige juristische Person","EWIV","KGaA","Ltd. & Co. KG","sonstige juristische Person (HRA)","GmbH & Co. OHG","VVaG","SE & Co. KG","ausländische Rechtsform (HRA)","AG & Co. KG","ausländische Rechtsform (PR)","SCE","ausländische Rechtsform (GnR)","Stiftung & Co. KG","eG & Co. KG","Einzelunternehmen (CH)","Kollektivgesellschaft (CH)","Kommanditgesellschaft (CH)","Kommanditaktiengesellschaft (CH)","AG (CH)","GmbH (CH)","Genossenschaft (CH)","Verein (CH)","Stiftung (CH)","Zweigniederlassung ausl. Ges. (CH)","Besondere Rechtsform (CH)","KmGK (CH)","SICAV (CH)","SICAF (CH)","Institut des öffentlichen Rechts (CH)","Nichtkaufmännische Prokura (CH)","Gemeinderschaft (CH)","Zweigniederlassung (CH)","GmbH (AT)","AG (AT)","FlexCo (AT)","KG (AT)","OG (AT)","e.U. (AT)","Genossenschaft (AT)","Privatstiftung (AT)","Sparkasse (AT)","VVaG (AT)","SE (AT)","EWIV (AT)","Sonstiger Rechtsträger (AT)","OHG (AT, alt)","KEG (AT, alt)","OEG (AT, alt)","Einzelkaufmann (AT, alt)"],"title":"Rechtsform"},"RegisterCourt":{"type":"string","enum":["Aachen","Ahaus","Amberg","Ansbach","Arnsberg","Aschaffenburg","Augsburg","Aurich","Bad Hersfeld","Bad Homburg v.d.H.","Bad Kreuznach","Bad Oeynhausen","Bamberg","Bayreuth","Berlin (Charlottenburg)","Bielefeld","Bocholt","Bochum","Bonn","Borken","Braunschweig","Bremen","Bremerhaven","Chemnitz","Coburg","Coesfeld","Cottbus","Darmstadt","Deggendorf","Dortmund","Dresden","Duisburg","Dülmen","Düren","Düsseldorf","Eschwege","Essen","Flensburg","Frankfurt am Main","Frankfurt/Oder","Freiburg","Friedberg","Fritzlar","Fulda","Fürth","Gelsenkirchen","Gießen","Gronau","Göttingen","Gütersloh","Hagen","Hamburg","Hamm","Hanau","Handelsgericht Wien","Hannover","Hildesheim","Hof","Homburg","Ingolstadt","Iserlohn","Jena","Kaiserslautern","Kassel","Kempten (Allgäu)","Kerpen","Kiel","Kleve","Koblenz","Korbach","Krefeld","Köln","Königstein","Landau","Landesgericht Eisenstadt","Landesgericht Feldkirch","Landesgericht Innsbruck","Landesgericht Klagenfurt","Landesgericht Korneuburg","Landesgericht Krems an der Donau","Landesgericht Leoben","Landesgericht Linz","Landesgericht Ried im Innkreis","Landesgericht Salzburg","Landesgericht St. Pölten","Landesgericht Steyr","Landesgericht Wels","Landesgericht Wiener Neustadt","Landesgericht für Zivilrechtssachen Graz","Landshut","Langenfeld","Lebach","Leipzig","Lemgo","Limburg","Ludwigshafen a.Rhein (Ludwigshafen)","Lübeck","Lüdinghausen","Lüneburg","Mainz","Mannheim","Marburg","Memmingen","Merzig","Montabaur","Mönchengladbach","München","Münster","Neubrandenburg","Neunkirchen","Neuruppin","Neuss","Nürnberg","Offenbach am Main","Oldenburg (Oldenburg)","Osnabrück","Ottweiler","Paderborn","Passau","Pinneberg","Potsdam","Recklinghausen","Regensburg","Rostock","Saarbrücken","Saarlouis","Schleiden","Schweinfurt","Schwerin","Siegburg","Siegen","St. Ingbert (St Ingbert)","St. Wendel (St Wendel)","Stadthagen","Steinfurt","Stendal","Stralsund","Straubing","Stuttgart","Tostedt","Traunstein","Ulm","Völklingen","Walsrode","Weiden i. d. OPf.","Wetzlar","Wiesbaden","Wittlich","Wuppertal","Würzburg","Zweibrücken"],"title":"RegisterCourt"},"RegisterType":{"type":"string","enum":["HRA","HRB","GnR","PR","VR","GsR","CH-HR","AT-FB"],"title":"RegisterType"},"RelatedCompany":{"properties":{"object":{"type":"string","const":"related_company","title":"Object","description":"Discriminator. Always `related_company`.","default":"related_company"},"eu_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Eu Id","description":"firmendata company identifier when available, otherwise `null`."},"legal_name":{"type":"string","title":"Legal Name","description":"Full legal name as filed."},"display_name":{"type":"string","title":"Display Name","description":"Best human-readable name to use in UIs."},"registered_seat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Registered Seat","description":"Registered seat city."},"register_court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Court","description":"Name of the registering court (Registergericht)."},"register_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Type","description":"Register type code (e.g. `HRB`, `HRA`, `GnR`, `PR`, `VR`)."},"register_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Register Number","description":"Register entry number (digits only). Combine with `register_type` for a full reference.","examples":[12345]},"reporting_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reporting Year","description":"Fiscal year the relationship was reported in."},"bilanz_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bilanz Type","description":"Type of the financial statement the relationship was sourced from."}},"type":"object","required":["legal_name","display_name"],"title":"RelatedCompany","description":"Reference to a related company (parent or subsidiary)."},"RelationshipsBlock":{"properties":{"object":{"type":"string","const":"company_relationships","title":"Object","description":"Discriminator. Always `company_relationships`.","default":"company_relationships"},"parent_company":{"anyOf":[{"$ref":"#/components/schemas/RelatedCompany"},{"type":"null"}],"description":"Reported parent company, when known."},"subsidiaries":{"items":{"$ref":"#/components/schemas/RelatedCompany"},"type":"array","title":"Subsidiaries","description":"Reported subsidiaries, ordered by name. At most 25 — `subsidiaries_total` says how many there are."},"subsidiaries_total":{"type":"integer","title":"Subsidiaries Total","description":"Number of reported subsidiaries, including any beyond the 25 listed in `subsidiaries`.","default":0}},"type":"object","title":"RelationshipsBlock","description":"Parent + subsidiaries reported in consolidated financial filings."},"SearchHit":{"properties":{"object":{"type":"string","const":"search_hit","title":"Object","description":"Discriminator. Always `search_hit`.","default":"search_hit"},"eu_id":{"type":"string","title":"Eu Id","description":"firmendata company identifier."},"country_code":{"type":"string","enum":["DE","CH","AT"],"title":"Country Code","description":"Country of the register the company is entered in: `DE` for the German registers (Handelsregister, Genossenschafts-, Partnerschafts-, Vereinsregister), `CH` for the Swiss commercial register, `AT` for the Austrian Firmenbuch."},"legal_name":{"type":"string","title":"Legal Name","description":"Full legal name as filed."},"display_name":{"type":"string","title":"Display Name","description":"The legal name without its legal-form suffix and status markers (`VOLKSWAGEN AKTIENGESELLSCHAFT` → `VOLKSWAGEN`, `Siemens Suisse SA` → `Siemens Suisse`). Identical for the same company on every endpoint."},"registered_seat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Registered Seat","description":"Registered seat as filed (German, may include district)."},"register_court":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Court","description":"Registering court (Registergericht, Firmenbuchgericht) for German and Austrian companies; for Swiss companies, the full name of the canton whose register office keeps the entry (e.g. `Vaud`)."},"register_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Type","description":"Register type code (e.g. `HRB`, `HRA`, `GnR`, `PR`, `VR`, `CH-HR`, `AT-FB`)."},"register_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Register Number","description":"Register entry number (digits only). Combine with `register_type` for a full reference.","examples":[12345]},"register_canton":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Register Canton","description":"Swiss companies only: two-letter code of the canton whose commercial register keeps the entry (e.g. `VD`). `null` for German and Austrian companies.","examples":["VD"]},"uid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Uid","description":"Swiss companies only: the Unternehmens-Identifikationsnummer in its official format. `null` for German and Austrian companies.","examples":["CHE-105.909.036"]},"is_branch":{"type":"boolean","title":"Is Branch","description":"`true` when this register entry is a branch office (Zweigniederlassung, succursale) of a company registered elsewhere, not a company of its own. Same rule as `CompanyDetail.is_branch`.","default":false},"address":{"anyOf":[{"$ref":"#/components/schemas/Address"},{"type":"null"}],"description":"Registered seat address."},"legal_status":{"type":"string","enum":["active","in_liquidation","insolvent","dissolved","deleted"],"title":"Legal Status","description":"Company lifecycle status according to the commercial register and insolvency notices, including Swiss Official Gazette of Commerce (SHAB) bankruptcy and composition notices. Same vocabulary as `CompanyDetail.legal_status` and the `legal_status` search filter.","default":"active"},"founded_at":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Founded At","description":"Founding date, when reported. A date of 1 January usually means the register states only the year."},"employee_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Employee Count","description":"Most recently reported employee count."},"employee_count_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Employee Count Year","description":"Fiscal year (`YYYY`) that `employee_count` is for."},"revenue":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Revenue","description":"Most recently reported annual revenue in EUR (Umsatzerlöse). The fiscal year it is for is `revenue_year`. Null when the company has never disclosed one — which is the common case, not an edge case: small and medium-sized filers publish abridged accounts with no profit-and-loss statement. Use `total_assets` for a size measure with far broader coverage."},"revenue_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Revenue Year","description":"Fiscal year (`YYYY`) that `revenue` is for. May differ from `profit_year`, `total_assets_year` and `financial_year` — each figure is resolved to the most recent filing that actually carries it, so do not assume two of them share a year when computing ratios."},"profit":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Profit","description":"Most recently reported annual profit in EUR (Jahresüberschuss / Bilanzgewinn). The fiscal year it is for is `profit_year`, which is **not** guaranteed to equal `revenue_year`."},"profit_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Profit Year","description":"Fiscal year (`YYYY`) that `profit` is for."},"total_assets":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Assets","description":"Balance-sheet total (Bilanzsumme) in EUR, from the most recent filing that reports one. Every filing company publishes a balance sheet — abridged accounts omit the profit-and-loss statement but not this — which makes it the most widely available measure of company size."},"total_assets_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Assets Year","description":"Fiscal year (`YYYY`) that `total_assets` is for."},"financial_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Financial Year","description":"The company's latest filing year (`YYYY`) — the most recent year for which *any* financial statement is on file. This is a filing-activity indicator, **not** the year of the figures above; for those use `revenue_year`, `profit_year` and `total_assets_year`. Typically 1–3 years behind the current calendar year due to German Handelsregister publication lag. Null when no financials have been filed."},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website","description":"Primary web domain associated with the company."},"cpv_award_codes":{"items":{"type":"string"},"type":"array","title":"Cpv Award Codes","description":"CPV (Common Procurement Vocabulary) codes from public-procurement awards."}},"type":"object","required":["eu_id","country_code","legal_name","display_name"],"title":"SearchHit","description":"One search result."},"SearchResponse":{"properties":{"object":{"type":"string","const":"list","title":"Object","description":"Discriminator. Always `list`.","default":"list"},"data":{"items":{"$ref":"#/components/schemas/SearchHit"},"type":"array","title":"Data","description":"Search hits for this page."},"pagination":{"$ref":"#/components/schemas/PaginationInfo","description":"Pagination metadata for this page."},"filters_echo":{"additionalProperties":true,"type":"object","title":"Filters Echo","description":"The effective filter values applied to this query, echoed back for client convenience."},"execution_time_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Execution Time Ms","description":"Server-side query execution time in whole milliseconds."},"freshness":{"$ref":"#/components/schemas/Freshness","description":"Outcome of the `fetch_realtime` register discovery for this request. `last_checked_at` is always `null` here — the hits span many companies, so no single slice timestamp applies."}},"type":"object","title":"SearchResponse","description":"Response envelope for `GET /v1/companies/search`."},"SeatEntry":{"properties":{"object":{"type":"string","const":"seat_entry","title":"Object","description":"Discriminator. Always `seat_entry`.","default":"seat_entry"},"entry_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Entry Date","description":"Date of the register entry. `null` when the entry carries no date.","examples":["2021-07-15"]},"entry_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Entry Number","description":"Running number of the register entry (laufende Nummer der Eintragung).","examples":[124]},"seat":{"type":"string","title":"Seat","description":"Registered seat (Sitz) as of this entry."}},"type":"object","required":["seat"],"title":"SeatEntry","description":"A registered seat (Sitz) recorded by one entry."},"Shareholder":{"properties":{"object":{"type":"string","const":"shareholder","title":"Object","description":"Discriminator. Always `shareholder`.","default":"shareholder"},"party_type":{"type":"string","enum":["natural_person","organization"],"title":"Party Type","description":"Type of shareholder. Determines whether `person` or `organization` is populated."},"display_name":{"type":"string","title":"Display Name","description":"Best human-readable name to use in UIs."},"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"Natural-person details (when `party_type` is `natural_person`)."},"organization":{"anyOf":[{"$ref":"#/components/schemas/OrganizationRef"},{"type":"null"}],"description":"Organisation details (when `party_type` is `organization`)."},"share_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Share Percent","description":"Aggregated share percentage in [0, 100]."},"shares_nominal":{"anyOf":[{"$ref":"#/components/schemas/Money"},{"type":"null"}],"description":"Nominal value of the shares held."},"total_shares":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total Shares","description":"Total number of shares held."}},"type":"object","required":["party_type","display_name"],"title":"Shareholder","description":"One shareholder entry in the cap table."},"ShareholdersCoverage":{"properties":{"object":{"type":"string","const":"shareholders_coverage","title":"Object","description":"Discriminator. Always `shareholders_coverage`.","default":"shareholders_coverage"},"status":{"type":"string","enum":["available","not_applicable","not_filed","token_limit_reached"],"title":"Status","description":"Coverage status. `available`: cap table available and returned; `not_applicable`: legal form does not file a Gesellschafterliste, or the company is Austrian (no shareholder data yet); `not_filed`: filing expected but not yet received; `token_limit_reached`: filing too large to process.","default":"not_filed"}},"type":"object","title":"ShareholdersCoverage","description":"Coverage signal for the shareholders endpoint."},"ShareholdersReport":{"properties":{"object":{"type":"string","const":"shareholders_report","title":"Object","description":"Discriminator. Always `shareholders_report`.","default":"shareholders_report"},"eu_id":{"type":"string","title":"Eu Id","description":"firmendata company identifier."},"coverage":{"$ref":"#/components/schemas/ShareholdersCoverage","description":"Coverage status for this company."},"freshness":{"$ref":"#/components/schemas/Freshness","description":"How current the cap-table snapshot in this response is. `last_checked_at` is the timestamp at which the underlying Liste der Gesellschafter (or Musterprotokoll fallback) was last successfully retrieved for this company; `null` when `coverage.status != \"available\"`. `realtime_fetching_status` reports the outcome of the realtime attempt for this request."},"as_of_snapshot":{"anyOf":[{"$ref":"#/components/schemas/ShareholdersSnapshot"},{"type":"null"}],"description":"Latest cap-table snapshot. `null` unless `coverage.status == \"available\"`."}},"type":"object","required":["eu_id","coverage","freshness"],"title":"ShareholdersReport","description":"Current shareholders and their shares in the company."},"ShareholdersSnapshot":{"properties":{"object":{"type":"string","const":"shareholders_snapshot","title":"Object","description":"Discriminator. Always `shareholders_snapshot`.","default":"shareholders_snapshot"},"shareholders":{"items":{"$ref":"#/components/schemas/Shareholder"},"type":"array","title":"Shareholders","description":"Shareholders in this snapshot."}},"type":"object","title":"ShareholdersSnapshot","description":"A point-in-time cap table snapshot."},"SocialProfile":{"properties":{"object":{"type":"string","const":"social_profile","title":"Object","description":"Discriminator. Always `social_profile`.","default":"social_profile"},"platform":{"type":"string","title":"Platform","description":"Platform identifier (e.g. `linkedin`, `instagram`)."},"url":{"type":"string","title":"Url","description":"Canonical profile URL."}},"type":"object","required":["platform","url"],"title":"SocialProfile","description":"A link to one of the company's social-media profiles."},"Sort":{"type":"string","enum":["name","revenue","profit","total_assets","employee_count"],"title":"Sort","description":"How to order search results.\n\nCompanies missing the value always sort last, whichever direction is\nchosen. `total_assets` ranks the most companies of the size measures:\nevery filing company publishes a balance sheet, where only a minority\npublish a full profit-and-loss statement."},"SortDirection":{"type":"string","enum":["asc","desc"],"title":"SortDirection"},"Subscription":{"properties":{"object":{"type":"string","const":"subscription","title":"Object","description":"Discriminator. Always `subscription`.","default":"subscription"},"id":{"type":"string","title":"Id","description":"UUID of the subscription."},"eu_id":{"type":"string","title":"Eu Id","description":"Company the subscription is scoped to."},"subscription_type":{"$ref":"#/components/schemas/SubscriptionType","description":"Slice of company data this subscription tracks. See the `SubscriptionType` schema for the per-value coverage table — in particular: `shareholders` auto-falls-back to Musterprotokoll for simplified-procedure GmbHs, while `articles_of_association` does not (pick `model_protocol` instead for those companies)."},"mode":{"$ref":"#/components/schemas/SubscriptionMode","description":"`recurring` keeps delivering forever at the configured `cadence`. `one_time` keeps polling at the configured `cadence` until the first successful delivery, then stops. The subscription remains available as a record — `DELETE` it when you're done."},"notification_type":{"anyOf":[{"$ref":"#/components/schemas/NotificationType"},{"type":"null"}],"description":"Delivery transport — `webhook`, `email`, or `null` for async (poll-only) subscriptions, where no outbound delivery is performed and the customer consumes change events via the events API."},"cadence":{"anyOf":[{"$ref":"#/components/schemas/NotificationCadence"},{"type":"null"}],"description":"How often you wish to receive notifications. A delivery is only made when the underlying data has actually changed since `latest_succeeded_publish_date` — no change means no notification. `immediately` delivers an update as soon as it is detected, with a service-level objective of within 1 hour of publication. `daily` / `weekly` / `monthly` batch the check at the named cadence. `null` only for legacy subscriptions without a named cadence; use `cadence_seconds` instead."},"cadence_seconds":{"type":"integer","title":"Cadence Seconds","description":"Canonical numeric form of `cadence`."},"subscription_end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Subscription End Date","description":"Optional terminal date. After this calendar day the subscription stops checking for updates; the configuration stays in place until you `DELETE` it."},"language":{"$ref":"#/components/schemas/NotificationLanguage","description":"Display language for human-targeted notifications. Webhook payloads carry both languages in `summary` regardless of this setting; only email subject + body are rendered in this language.","default":"en"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url","description":"Webhook receiver URL. Populated only when `notification_type=webhook`. https only."},"recipient_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Email","description":"Email recipient. Populated only when `notification_type=email`."},"last_attempted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Attempted At","description":"UTC timestamp of the most recent delivery attempt."},"latest_succeeded_publish_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Latest Succeeded Publish Date","description":"Publish date of the document last successfully delivered. The next webhook is sent only when a strictly newer publish date appears."},"last_event":{"anyOf":[{"$ref":"#/components/schemas/SubscriptionEventStatus"},{"type":"null"}],"description":"Detail of the most recent delivery attempt. `null` until the first attempt has been made."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"UTC timestamp of subscription creation."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"UTC timestamp of last subscription update."}},"type":"object","required":["id","eu_id","subscription_type","mode","notification_type","cadence","cadence_seconds","created_at","updated_at"],"title":"Subscription","description":"A webhook or email subscription, with the most recent delivery\nattempt embedded.\n\nThe signing secret is **never** returned here; only\n`SubscriptionCreated` carries it, and only once."},"SubscriptionCreateRequest":{"properties":{"eu_id":{"type":"string","maxLength":64,"minLength":3,"title":"Eu Id","description":"firmendata company identifier to subscribe against.","examples":["DEF1103R.HRB279792B"]},"subscription_type":{"$ref":"#/components/schemas/SubscriptionType","description":"Which slice of company data to track. See the `SubscriptionType` schema for the per-value coverage table — `shareholders` works for every GmbH/UG (it auto-falls-back to Musterprotokoll when no Liste is filed), while `doc_articles_of_association` does not — pick `doc_model_protocol` for the founding deed of simplified-procedure companies."},"mode":{"$ref":"#/components/schemas/SubscriptionMode","description":"Delivery behaviour. **Default: `recurring`.**\n\n- `recurring` — the **first** delivery is a snapshot of the current state. After that, you only get a notification when there is an actual update.\n- `one_time` — keep polling at the configured `cadence` *until* the first successful delivery, then stop. Useful when:\n  - the document you're waiting for is not yet available on Handelsregister (e.g. a Gesellschafterliste not yet filed, a Bilanz not yet published in Bundesanzeiger),\n  - or Handelsregister is currently failing to serve the file due to a technical issue on their end (transient 5xx, anti-bot blocks) and you want firmendata to keep retrying on your behalf without you having to call the API on a schedule.\n  The subscription stays in place after the first successful delivery as a record — `DELETE` it when you're done.","default":"recurring"},"notification_type":{"anyOf":[{"$ref":"#/components/schemas/NotificationType"},{"type":"null"}],"description":"Delivery transport. **Default: `null`** — async (poll-only).\n\n- `null` — no outbound delivery; each change is available as a `subscription_event` and the customer retrieves the rendered payload by polling `GET /v1/subscriptions/{id}/events` using the subscription/job id this request returns. Must omit both `webhook_url` and `recipient_email`.\n- `webhook` — POST a signed JSON body to `webhook_url`. Requires `webhook_url`; rejects `recipient_email`.\n- `email` — send a bilingual notification email to `recipient_email`. Requires `recipient_email`; rejects `webhook_url`."},"cadence":{"$ref":"#/components/schemas/NotificationCadence","description":"How often you wish to receive notifications. **Default: `daily`.** A notification is dispatched only when there is an actual change since the previous successful delivery — no update means no notification. `immediately` delivers an update as soon as it is detected, with a service-level objective of within 1 hour of publication. `daily` / `weekly` / `monthly` batch the check at the named cadence. For `one_time` subscriptions this is the retry spacing while we wait for the data to become available.","default":"daily"},"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url","description":"https-only URL that will receive webhook calls. Required when `notification_type=webhook`; must be omitted for `notification_type=email`.","examples":["https://example.com/firmendata/webhook"]},"recipient_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Email","description":"Email address to deliver notifications to. Required when `notification_type=email`; must be omitted for `notification_type=webhook`.","examples":["alerts@example.com"]},"language":{"$ref":"#/components/schemas/NotificationLanguage","description":"Display language for human-targeted notifications. **Default: `en`.** Currently affects only email subject + body — webhook payloads carry both languages in the bilingual `summary` block regardless of this setting.","default":"en"},"subscription_end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Subscription End Date","description":"Optional terminal date. After this calendar day the subscription stops checking for updates. **Default: `null`** — open-ended subscription."}},"type":"object","required":["eu_id","subscription_type"],"title":"SubscriptionCreateRequest"},"SubscriptionCreated":{"properties":{"object":{"type":"string","const":"subscription_created","title":"Object","description":"Discriminator. Always `subscription_created`.","default":"subscription_created"},"id":{"type":"string","title":"Id","description":"UUID of the subscription."},"eu_id":{"type":"string","title":"Eu Id","description":"Company the subscription is scoped to."},"subscription_type":{"$ref":"#/components/schemas/SubscriptionType","description":"Slice of company data this subscription tracks. See the `SubscriptionType` schema for the per-value coverage table — in particular: `shareholders` auto-falls-back to Musterprotokoll for simplified-procedure GmbHs, while `articles_of_association` does not (pick `model_protocol` instead for those companies)."},"mode":{"$ref":"#/components/schemas/SubscriptionMode","description":"`recurring` keeps delivering forever at the configured `cadence`. `one_time` keeps polling at the configured `cadence` until the first successful delivery, then stops. The subscription remains available as a record — `DELETE` it when you're done."},"notification_type":{"anyOf":[{"$ref":"#/components/schemas/NotificationType"},{"type":"null"}],"description":"Delivery transport — `webhook`, `email`, or `null` for async (poll-only) subscriptions, where no outbound delivery is performed and the customer consumes change events via the events API."},"cadence":{"anyOf":[{"$ref":"#/components/schemas/NotificationCadence"},{"type":"null"}],"description":"How often you wish to receive notifications. A delivery is only made when the underlying data has actually changed since `latest_succeeded_publish_date` — no change means no notification. `immediately` delivers an update as soon as it is detected, with a service-level objective of within 1 hour of publication. `daily` / `weekly` / `monthly` batch the check at the named cadence. `null` only for legacy subscriptions without a named cadence; use `cadence_seconds` instead."},"cadence_seconds":{"type":"integer","title":"Cadence Seconds","description":"Canonical numeric form of `cadence`."},"subscription_end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Subscription End Date","description":"Optional terminal date. After this calendar day the subscription stops checking for updates; the configuration stays in place until you `DELETE` it."},"language":{"$ref":"#/components/schemas/NotificationLanguage","description":"Display language for human-targeted notifications. Webhook payloads carry both languages in `summary` regardless of this setting; only email subject + body are rendered in this language.","default":"en"},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url","description":"Webhook receiver URL. Populated only when `notification_type=webhook`. https only."},"recipient_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Email","description":"Email recipient. Populated only when `notification_type=email`."},"last_attempted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Attempted At","description":"UTC timestamp of the most recent delivery attempt."},"latest_succeeded_publish_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Latest Succeeded Publish Date","description":"Publish date of the document last successfully delivered. The next webhook is sent only when a strictly newer publish date appears."},"last_event":{"anyOf":[{"$ref":"#/components/schemas/SubscriptionEventStatus"},{"type":"null"}],"description":"Detail of the most recent delivery attempt. `null` until the first attempt has been made."},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"UTC timestamp of subscription creation."},"updated_at":{"type":"string","format":"date-time","title":"Updated At","description":"UTC timestamp of last subscription update."},"webhook_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Secret","description":"HMAC-SHA256 signing secret. Populated only for `notification_type=webhook` subscriptions. Store it somewhere safe — firmendata cannot re-display it. Use it to verify the `X-Firmendata-Signature` header on every incoming webhook (the signed string is `f\"{X-Firmendata-Timestamp}.{raw_request_body}\"`). Always `null` for `notification_type=email`."}},"type":"object","required":["id","eu_id","subscription_type","mode","notification_type","cadence","cadence_seconds","created_at","updated_at"],"title":"SubscriptionCreated","description":"Newly created subscription. Includes the subscription details and,\nfor webhook subscriptions, additionally\ncarries the plaintext signing secret — only available here, never\nreturned by any other endpoint. For email subscriptions\n`webhook_secret` is `null` (signatures don't apply to email)."},"SubscriptionEvent":{"properties":{"object":{"type":"string","const":"subscription_event","title":"Object","description":"Discriminator. Always `subscription_event`.","default":"subscription_event"},"event_id":{"type":"string","title":"Event Id","description":"UUID echoed in the `X-Firmendata-Delivery-Id` header of the outgoing webhook. Use it to correlate this status with the request your endpoint received."},"started_at":{"type":"string","format":"date-time","title":"Started At","description":"UTC timestamp the attempt began."},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At","description":"UTC timestamp the attempt finished, or `null` while still in progress."},"outcome":{"type":"string","title":"Outcome","description":"What happened on this attempt. One of: `change_delivered`, `no_change_silent`, `webhook_delivery_failed`, `scrape_failed_company_not_found`, `scrape_failed_file_not_found`, `scrape_failed_documents_temporarily_unavailable`, `scrape_failed_platform_error`, `scrape_failed_parser_error`, `scrape_failed_unknown`, `skipped_unsupported`, `skipped_ended`."},"change_detected":{"type":"boolean","title":"Change Detected","description":"True iff the latest check produced a publish date strictly newer than the previously delivered one."},"publish_date_seen":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Publish Date Seen","description":"Publish date observed in the latest check (max register entry date or file publication date)."},"publish_date_previous":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Publish Date Previous","description":"The previous `latest_succeeded_publish_date`, for diffing."},"scrape_error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data check error message","description":"Explanation of a failed data check, or `null` for successful or non-failure events. Failed checks are retried on the configured `cadence`. For `scrape_failed_company_not_found`, the company must reappear in the register before data can be retrieved."},"delivery_attempted":{"type":"boolean","title":"Delivery Attempted","description":"False when no notification was sent (e.g. silent no-change, unsupported, ended)."},"delivery_attempts":{"type":"integer","title":"Delivery Attempts","description":"Number of in-run delivery attempts for this event. Webhook: 0–3 (retried on 5xx / transport errors). Email: 0–1 (send failures wait for the next cadence)."},"delivery_http_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Delivery Http Status","description":"Webhook only: HTTP status of the last in-run attempt, or `null` on transport-level failure. Always `null` for email and for async (poll-only) events."},"delivery_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Error","description":"Short error string from a failing delivery attempt."},"delivery_duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Delivery Duration Ms","description":"Wall-clock time of the last delivery attempt in milliseconds."},"notification_type":{"anyOf":[{"$ref":"#/components/schemas/NotificationType"},{"type":"null"}],"description":"Transport this event was delivered over — `webhook`, `email`, or `null` for async (poll-only) subscriptions. Inherited from the parent subscription, which is immutable, so every event for a given subscription carries the same value. For email and async events the `request_url` / `request_signature` / `request_timestamp` / `delivery_http_status` fields are always `null`. For async events `request_body` is populated (the customer consumes the change payload through the events API); for email it is null."},"request_body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Request Body","description":"The exact JSON body firmendata POSTed to your endpoint. `null` for email events and older events without a recorded request body. Re-verify the signature with: `hmac_sha256(secret, f'{request_timestamp}.{json.dumps(request_body, separators=(\",\",\":\"))}')`."},"request_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Url","description":"The webhook URL firmendata used for this attempt. May differ from the subscription's current `webhook_url` if the URL was changed via PATCH after the event."},"request_signature":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Signature","description":"The `X-Firmendata-Signature` header firmendata sent. Format: `sha256=<hex>`."},"request_timestamp":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Timestamp","description":"The `X-Firmendata-Timestamp` header (unix-seconds) firmendata sent."},"delivery_response_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Response Excerpt","description":"First ~512 chars of your endpoint's response body, captured for debugging. Webhook only."}},"type":"object","required":["event_id","started_at","outcome","change_detected","delivery_attempted","delivery_attempts","notification_type"],"title":"SubscriptionEvent","description":"Full event record with the exact bytes firmendata sent on the\nwire. Returned by the historical event endpoints — heavier than\n`SubscriptionEventStatus`, the shorter status block embedded in\nsubscription detail responses.\n\nFor email events and older events without recorded request details,\nevery `request_*` field is `null`."},"SubscriptionEventList":{"properties":{"object":{"type":"string","const":"list","title":"Object","description":"Discriminator. Always `list`.","default":"list"},"data":{"items":{"$ref":"#/components/schemas/SubscriptionEvent"},"type":"array","title":"Data","description":"Events for the subscription, newest first."},"pagination":{"$ref":"#/components/schemas/PaginationInfo","description":"Pagination metadata for this page."}},"type":"object","title":"SubscriptionEventList"},"SubscriptionEventResendResponse":{"properties":{"object":{"type":"string","const":"subscription_event_resend","title":"Object","description":"Discriminator. Always `subscription_event_resend`.","default":"subscription_event_resend"},"event":{"$ref":"#/components/schemas/SubscriptionEvent","description":"The new event recording this resend. Has its own fresh `event_id`. The receiver sees that same id in the body and in the `X-Firmendata-Delivery-Id` header."},"succeeded":{"type":"boolean","title":"Succeeded","description":"True iff the receiver returned a 2xx response."},"http_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Http Status","description":"HTTP status of the last in-run attempt, or `null` on transport failure."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Short error string when the resend did not succeed."},"duration_ms":{"type":"integer","title":"Duration Ms","description":"Wall-clock time of the resend in milliseconds."}},"type":"object","required":["event","succeeded","duration_ms"],"title":"SubscriptionEventResendResponse","description":"Result of resending a subscription event."},"SubscriptionEventStatus":{"properties":{"object":{"type":"string","const":"subscription_event_status","title":"Object","description":"Discriminator. Always `subscription_event_status`.","default":"subscription_event_status"},"event_id":{"type":"string","title":"Event Id","description":"UUID echoed in the `X-Firmendata-Delivery-Id` header of the outgoing webhook. Use it to correlate this status with the request your endpoint received."},"started_at":{"type":"string","format":"date-time","title":"Started At","description":"UTC timestamp the attempt began."},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At","description":"UTC timestamp the attempt finished, or `null` while still in progress."},"outcome":{"type":"string","title":"Outcome","description":"What happened on this attempt. One of: `change_delivered`, `no_change_silent`, `webhook_delivery_failed`, `scrape_failed_company_not_found`, `scrape_failed_file_not_found`, `scrape_failed_documents_temporarily_unavailable`, `scrape_failed_platform_error`, `scrape_failed_parser_error`, `scrape_failed_unknown`, `skipped_unsupported`, `skipped_ended`."},"change_detected":{"type":"boolean","title":"Change Detected","description":"True iff the latest check produced a publish date strictly newer than the previously delivered one."},"publish_date_seen":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Publish Date Seen","description":"Publish date observed in the latest check (max register entry date or file publication date)."},"publish_date_previous":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Publish Date Previous","description":"The previous `latest_succeeded_publish_date`, for diffing."},"scrape_error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Data check error message","description":"Explanation of a failed data check, or `null` for successful or non-failure events. Failed checks are retried on the configured `cadence`. For `scrape_failed_company_not_found`, the company must reappear in the register before data can be retrieved."},"delivery_attempted":{"type":"boolean","title":"Delivery Attempted","description":"False when no notification was sent (e.g. silent no-change, unsupported, ended)."},"delivery_attempts":{"type":"integer","title":"Delivery Attempts","description":"Number of in-run delivery attempts for this event. Webhook: 0–3 (retried on 5xx / transport errors). Email: 0–1 (send failures wait for the next cadence)."},"delivery_http_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Delivery Http Status","description":"Webhook only: HTTP status of the last in-run attempt, or `null` on transport-level failure. Always `null` for email and for async (poll-only) events."},"delivery_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Error","description":"Short error string from a failing delivery attempt."},"delivery_duration_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Delivery Duration Ms","description":"Wall-clock time of the last delivery attempt in milliseconds."}},"type":"object","required":["event_id","started_at","outcome","change_detected","delivery_attempted","delivery_attempts"],"title":"SubscriptionEventStatus","description":"Status block describing the most recent delivery attempt for a\nsubscription. Embedded in subscription detail responses."},"SubscriptionList":{"properties":{"object":{"type":"string","const":"list","title":"Object","description":"Discriminator. Always `list`.","default":"list"},"data":{"items":{"$ref":"#/components/schemas/Subscription"},"type":"array","title":"Data","description":"Subscriptions owned by the calling user, newest first."},"pagination":{"$ref":"#/components/schemas/PaginationInfo","description":"Pagination metadata for this page."}},"type":"object","title":"SubscriptionList"},"SubscriptionMode":{"type":"string","enum":["recurring","one_time"],"title":"SubscriptionMode","description":"Recurring delivery vs single-shot poll-until-success (one_time)."},"SubscriptionTestRequest":{"properties":{"notification_type":{"$ref":"#/components/schemas/NotificationType","description":"Transport to test — `webhook` or `email`. Async (poll-only) subscriptions have no outbound transport to exercise; pick `webhook` or `email` here."},"subscription_type":{"$ref":"#/components/schemas/SubscriptionType","description":"Subscription type to mimic. Determines the bilingual summary, the webhook `event_type` header (e.g. `articles_of_association.updated`), the email subject + body, and the `data.links` block. See the `SubscriptionType` schema for the per-value coverage table."},"eu_id":{"type":"string","maxLength":64,"minLength":3,"title":"Eu Id","description":"Company identifier embedded in the test payload. Does not need to be known to firmendata — only used to compose the example links.","examples":["DEF1103R.HRB279792B"]},"scenario":{"type":"string","const":"change","title":"Scenario","description":"Kind of notification to send. Today only `change` is supported (the only event firmendata currently delivers). Additional scenarios may be added later.","default":"change"},"delivery_scenario":{"$ref":"#/components/schemas/WebhookTestDeliveryScenario","description":"How to deliver the test notification. Defaults to `success` (single signed POST). Use `retry_delivery` to exercise your idempotent dedupe, `bad_signature` to exercise your HMAC-rejection path, or `stale_timestamp` to exercise your replay-window rejection. Webhook-only — ignored when `notification_type=email`.","default":"success"},"webhook_url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Webhook Url","description":"https-only URL the test event will be POSTed to. Required for `notification_type=webhook`.","examples":["https://example.com/firmendata/webhook"]},"recipient_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Email","description":"Email address that will receive the test message. Required for `notification_type=email`.","examples":["alerts@example.com"]},"language":{"$ref":"#/components/schemas/NotificationLanguage","description":"Display language for the test email. Ignored for `notification_type=webhook`.","default":"en"}},"type":"object","required":["notification_type","subscription_type","eu_id"],"title":"SubscriptionTestRequest","description":"Inputs for `POST /v1/subscriptions/test`.\n\nSame discriminator rules as the create payload: webhook\nsubscriptions need `webhook_url`, email subscriptions need\n`recipient_email`. Sending the wrong combination returns `422`."},"SubscriptionTestResponse":{"properties":{"object":{"type":"string","const":"subscription_test_result","title":"Object","description":"Discriminator. Always `subscription_test_result`.","default":"subscription_test_result"},"notification_type":{"$ref":"#/components/schemas/NotificationType","description":"Transport that was tested."},"webhook_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url","description":"URL the test was POSTed to. `null` for email tests."},"webhook_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Secret","description":"HMAC-SHA256 signing secret used for the webhook test. Always the same documented public constant `firmendata_test_secret_do_not_use_in_production`, so you can hard-code it. `null` for email tests."},"sent_event_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sent Event Id","description":"Value sent in `X-Firmendata-Delivery-Id`. `null` for email tests."},"sent_event_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sent Event Type","description":"Value sent in `X-Firmendata-Event-Type`. `null` for email tests."},"sent_signature_header":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sent Signature Header","description":"Full `X-Firmendata-Signature` header value. `null` for email tests."},"sent_timestamp_header":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sent Timestamp Header","description":"Full `X-Firmendata-Timestamp` header value. `null` for email tests."},"sent_body":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Sent Body","description":"Exact JSON body sent to the webhook. `null` for email tests."},"recipient_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Email","description":"Address the test email was sent to. `null` for webhook tests."},"sent_subject":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sent Subject","description":"Subject line of the test email. `null` for webhook tests."},"sent_body_html":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sent Body Html","description":"Full HTML body of the test email. `null` for webhook tests."},"receiver_succeeded":{"type":"boolean","title":"Receiver Succeeded","description":"Webhook: the receiver returned a 2xx status. Email: the email provider accepted the message."},"receiver_http_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Receiver Http Status","description":"Webhook only: HTTP status the receiver returned. `null` for email tests or transport-level failure."},"receiver_response_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Receiver Response Excerpt","description":"Webhook only: first ~512 chars of the receiver's response body."},"receiver_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Receiver Error","description":"Short error string when the test failed."},"duration_ms":{"type":"integer","title":"Duration Ms","description":"Wall-clock milliseconds for the entire test — sum across attempts when `delivery_scenario=retry_delivery`."},"delivery_scenario":{"anyOf":[{"$ref":"#/components/schemas/WebhookTestDeliveryScenario"},{"type":"null"}],"description":"Echo of the `delivery_scenario` requested. `null` for email tests."},"attempts":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookTestAttempt"},"type":"array"},{"type":"null"}],"title":"Attempts","description":"Per-attempt detail. One element for `success`, `bad_signature`, and `stale_timestamp`; two for `retry_delivery` (sharing the same signature, timestamp, body, and `X-Firmendata-Delivery-Id`). `null` for email tests."}},"type":"object","required":["notification_type","receiver_succeeded","duration_ms"],"title":"SubscriptionTestResponse","description":"Outputs for `POST /v1/subscriptions/test`.\n\nTransport-shaped: the webhook fields populate when the request was\na webhook test, the email fields populate when it was an email\ntest. The common `receiver_*` block describes the outcome\nregardless of transport."},"SubscriptionType":{"type":"string","enum":["details","history","shareholders","ubo","doc_articles_of_association","doc_company_registration","doc_model_protocol","doc_shareholder_list"],"title":"SubscriptionType","description":"Slice of company data a subscription tracks. Two flavours:\n\n- **Parsed-data** types — `details`, `history`, `shareholders`, `ubo`. The webhook body's `data` block carries a publish-date timestamp and `links` to the v1 endpoints that serve the parsed JSON.\n- **Document** types — every `doc_*` value. The webhook body's `data.download.url` is a 7-day presigned URL to the PDF, so the customer can fetch the file directly without a follow-up API call. After expiry, `GET /v1/companies/{eu_id}/documents/download` mints a fresh URL.\n\n**Coverage is not uniform across types.** German company law lets the smallest GmbH / UG (haftungsbeschränkt) replace the Articles of Association (Gesellschaftsvertrag / Satzung / Statut — the name varies by legal form) and the Liste der Gesellschafter with a single **Musterprotokoll** (model protocol) at founding. firmendata handles this asymmetrically by intent:\n\n- `shareholders` **auto-falls-back** to the Musterprotokoll when no Liste der Gesellschafter is filed — pick this for cap-table tracking regardless of legal form.\n- `doc_articles_of_association` does **not** fall back — pick `doc_model_protocol` when you need the founding deed of a simplified-procedure company.\n- `doc_shareholder_list` does **not** fall back — pick `doc_model_protocol` for Musterprotokoll-only companies, or `shareholders` for parsed cap-table data that works for any GmbH/UG.\n- `doc_*` subscriptions only fire for companies that actually filed the matching document; mismatches return `scrape_failed_file_not_found` until the document appears (use `mode=one_time` if you're waiting for a one-off filing).\n\n| Value | What it tracks |\n|---|---|\n| `details` | Current company snapshot — identity, registered address, current board, share capital, and lifecycle status. The webhook body's `data.links.company_detail` resolves to `GET /v1/companies/{eu_id}` for the full parsed JSON. Available for every Handelsregister-registered company. |\n| `history` | Chronological register history — every recorded change to company name (firma), seat (Sitz), capital, board, business purpose, etc. The webhook body's `data.links.company_history` resolves to `GET /v1/companies/{eu_id}/history` for the full parsed timeline. Available for every Handelsregister-registered company. |\n| `shareholders` | Cap table — primarily from the **Liste der Gesellschafter** (list of shareholders), filed by GmbH and UG (haftungsbeschränkt). **Auto-fallback to Musterprotokoll:** companies founded via the simplified procedure under §2 Abs. 1a GmbHG do not file a separate Liste — their **Musterprotokoll** (model protocol) names the founders and their share allocations directly. firmendata handles this transparently: when no Liste has been filed, the `shareholders` subscription derives the cap table from the Musterprotokoll instead. So `shareholders` is the right subscription for cap-table updates regardless of which document the company filed. The webhook body links to `GET /v1/companies/{eu_id}/shareholders` for the parsed cap table. |\n| `ubo` | Beneficial owners (**wirtschaftlich Berechtigte**) — natural persons who ultimately own or control the company, derived by walking the Gesellschafter graph. Each dispatch refreshes the cap-table document for **every** German GmbH/UG in the ownership chain (root and parents), not just the root, and fires when **any** chain member's Liste der Gesellschafter (or Musterprotokoll fallback) gets a newer publish date. The webhook body carries the full UBO report (graph, `beneficial_owners`, `potential_beneficial_owners`, `coverage` with `reason`) plus a per-node `chain` breakdown (`eu_id`, `depth`, refresh `status`, latest `publish_date`).  `coverage.status=\"partial\"` means one or more unresolved branches carry effective share above 25 % at the root and could hide a UBO — `potential_beneficial_owners` lists those entities (foreign holdings, unlisted parents, depth-capped branches) with their summed effective share so KYC consumers can decide whether to escalate. `coverage.status=\"available\"` with `has_unresolved_branches=true` means unresolved branches exist but are immaterial (combined share below the threshold or isolated by sub-threshold control links).  Transient per-node failures (e.g. `documents_temporarily_unavailable`, `platform_unavailable`) delay notification until the next successful check; the next cadence retries. Other per-node outcomes (e.g. `file_unavailable`, `skipped_not_applicable` for non-GmbH chain members) are surfaced in the chain breakdown but do **not** block delivery — the rest of the chain still ships. |\n| `doc_articles_of_association` | **Articles of association** document — Germany's constitutional company document, called **Gesellschaftsvertrag** (GmbH, KG, OHG, GbR), **Satzung** (AG, KGaA, eG, Verein), or **Statut** (some specific forms) depending on legal form. Each is the constitutional document for its legal form.  Webhook body's `data.download.url` is a 7-day presigned URL to the PDF — the customer can fetch the file directly without a follow-up API call. After the URL expires, `GET /v1/companies/{eu_id}/documents/download?file_type=articles_of_association` mints a fresh one.  **Not all companies have one.** Companies founded via the simplified procedure under §2 Abs. 1a GmbHG file a **Musterprotokoll** in its place — subscribe to `doc_model_protocol` for those. |\n| `doc_company_registration` | **Initial company registration filing (Anmeldung zur Eintragung)** — the notarial document submitted to register the company. Webhook body carries a 7-day presigned download URL (`data.download.url`). Available for any newly-registered company; fires when a new Anmeldung is filed. |\n| `doc_model_protocol` | **Model protocol document (Musterprotokoll)** — the simplified notarial founding deed for small GmbH and UG (haftungsbeschränkt) companies under §2 Abs. 1a GmbHG. Legally substitutes for **both** the Articles of Association and the Liste der Gesellschafter for these companies. The Musterprotokoll itself names the founders, their share allocations, and the basic company terms in a single document.  Webhook body carries a 7-day presigned download URL (`data.download.url`). Only companies founded via the simplified procedure have one; for everyone else this subscription reports `scrape_failed_file_not_found`. For **cap-table changes** — regardless of which document was filed — subscribe to `shareholders` instead (it auto-falls-back to the Musterprotokoll when no Liste has been filed). |\n| `doc_shareholder_list` | **Liste der Gesellschafter** document — the standalone shareholder-list filing. Webhook body carries a 7-day presigned download URL (`data.download.url`).  Distinct from the parsed `shareholders` subscription: this tracks the **document itself** with no Musterprotokoll fallback, so a Musterprotokoll-only GmbH (founded under §2 Abs. 1a GmbHG) reports `scrape_failed_file_not_found` until they file a real Liste. For parsed cap-table updates that work for any GmbH/UG, subscribe to `shareholders` instead. |","x-enum-descriptions":["Current company snapshot — identity, registered address, current board, share capital, and lifecycle status. The webhook body's `data.links.company_detail` resolves to `GET /v1/companies/{eu_id}` for the full parsed JSON. Available for every Handelsregister-registered company.","Chronological register history — every recorded change to company name (firma), seat (Sitz), capital, board, business purpose, etc. The webhook body's `data.links.company_history` resolves to `GET /v1/companies/{eu_id}/history` for the full parsed timeline. Available for every Handelsregister-registered company.","Cap table — primarily from the **Liste der Gesellschafter** (list of shareholders), filed by GmbH and UG (haftungsbeschränkt). **Auto-fallback to Musterprotokoll:** companies founded via the simplified procedure under §2 Abs. 1a GmbHG do not file a separate Liste — their **Musterprotokoll** (model protocol) names the founders and their share allocations directly. firmendata handles this transparently: when no Liste has been filed, the `shareholders` subscription derives the cap table from the Musterprotokoll instead. So `shareholders` is the right subscription for cap-table updates regardless of which document the company filed. The webhook body links to `GET /v1/companies/{eu_id}/shareholders` for the parsed cap table.","Beneficial owners (**wirtschaftlich Berechtigte**) — natural persons who ultimately own or control the company, derived by walking the Gesellschafter graph. Each dispatch refreshes the cap-table document for **every** German GmbH/UG in the ownership chain (root and parents), not just the root, and fires when **any** chain member's Liste der Gesellschafter (or Musterprotokoll fallback) gets a newer publish date. The webhook body carries the full UBO report (graph, `beneficial_owners`, `potential_beneficial_owners`, `coverage` with `reason`) plus a per-node `chain` breakdown (`eu_id`, `depth`, refresh `status`, latest `publish_date`).\n\n`coverage.status=\"partial\"` means one or more unresolved branches carry effective share above 25 % at the root and could hide a UBO — `potential_beneficial_owners` lists those entities (foreign holdings, unlisted parents, depth-capped branches) with their summed effective share so KYC consumers can decide whether to escalate. `coverage.status=\"available\"` with `has_unresolved_branches=true` means unresolved branches exist but are immaterial (combined share below the threshold or isolated by sub-threshold control links).\n\nTransient per-node failures (e.g. `documents_temporarily_unavailable`, `platform_unavailable`) delay notification until the next successful check; the next cadence retries. Other per-node outcomes (e.g. `file_unavailable`, `skipped_not_applicable` for non-GmbH chain members) are surfaced in the chain breakdown but do **not** block delivery — the rest of the chain still ships.","**Articles of association** document — Germany's constitutional company document, called **Gesellschaftsvertrag** (GmbH, KG, OHG, GbR), **Satzung** (AG, KGaA, eG, Verein), or **Statut** (some specific forms) depending on legal form. Each is the constitutional document for its legal form.\n\nWebhook body's `data.download.url` is a 7-day presigned URL to the PDF — the customer can fetch the file directly without a follow-up API call. After the URL expires, `GET /v1/companies/{eu_id}/documents/download?file_type=articles_of_association` mints a fresh one.\n\n**Not all companies have one.** Companies founded via the simplified procedure under §2 Abs. 1a GmbHG file a **Musterprotokoll** in its place — subscribe to `doc_model_protocol` for those.","**Initial company registration filing (Anmeldung zur Eintragung)** — the notarial document submitted to register the company. Webhook body carries a 7-day presigned download URL (`data.download.url`). Available for any newly-registered company; fires when a new Anmeldung is filed.","**Model protocol document (Musterprotokoll)** — the simplified notarial founding deed for small GmbH and UG (haftungsbeschränkt) companies under §2 Abs. 1a GmbHG. Legally substitutes for **both** the Articles of Association and the Liste der Gesellschafter for these companies. The Musterprotokoll itself names the founders, their share allocations, and the basic company terms in a single document.\n\nWebhook body carries a 7-day presigned download URL (`data.download.url`). Only companies founded via the simplified procedure have one; for everyone else this subscription reports `scrape_failed_file_not_found`. For **cap-table changes** — regardless of which document was filed — subscribe to `shareholders` instead (it auto-falls-back to the Musterprotokoll when no Liste has been filed).","**Liste der Gesellschafter** document — the standalone shareholder-list filing. Webhook body carries a 7-day presigned download URL (`data.download.url`).\n\nDistinct from the parsed `shareholders` subscription: this tracks the **document itself** with no Musterprotokoll fallback, so a Musterprotokoll-only GmbH (founded under §2 Abs. 1a GmbHG) reports `scrape_failed_file_not_found` until they file a real Liste. For parsed cap-table updates that work for any GmbH/UG, subscribe to `shareholders` instead."],"x-enumDescriptions":["Current company snapshot — identity, registered address, current board, share capital, and lifecycle status. The webhook body's `data.links.company_detail` resolves to `GET /v1/companies/{eu_id}` for the full parsed JSON. Available for every Handelsregister-registered company.","Chronological register history — every recorded change to company name (firma), seat (Sitz), capital, board, business purpose, etc. The webhook body's `data.links.company_history` resolves to `GET /v1/companies/{eu_id}/history` for the full parsed timeline. Available for every Handelsregister-registered company.","Cap table — primarily from the **Liste der Gesellschafter** (list of shareholders), filed by GmbH and UG (haftungsbeschränkt). **Auto-fallback to Musterprotokoll:** companies founded via the simplified procedure under §2 Abs. 1a GmbHG do not file a separate Liste — their **Musterprotokoll** (model protocol) names the founders and their share allocations directly. firmendata handles this transparently: when no Liste has been filed, the `shareholders` subscription derives the cap table from the Musterprotokoll instead. So `shareholders` is the right subscription for cap-table updates regardless of which document the company filed. The webhook body links to `GET /v1/companies/{eu_id}/shareholders` for the parsed cap table.","Beneficial owners (**wirtschaftlich Berechtigte**) — natural persons who ultimately own or control the company, derived by walking the Gesellschafter graph. Each dispatch refreshes the cap-table document for **every** German GmbH/UG in the ownership chain (root and parents), not just the root, and fires when **any** chain member's Liste der Gesellschafter (or Musterprotokoll fallback) gets a newer publish date. The webhook body carries the full UBO report (graph, `beneficial_owners`, `potential_beneficial_owners`, `coverage` with `reason`) plus a per-node `chain` breakdown (`eu_id`, `depth`, refresh `status`, latest `publish_date`).\n\n`coverage.status=\"partial\"` means one or more unresolved branches carry effective share above 25 % at the root and could hide a UBO — `potential_beneficial_owners` lists those entities (foreign holdings, unlisted parents, depth-capped branches) with their summed effective share so KYC consumers can decide whether to escalate. `coverage.status=\"available\"` with `has_unresolved_branches=true` means unresolved branches exist but are immaterial (combined share below the threshold or isolated by sub-threshold control links).\n\nTransient per-node failures (e.g. `documents_temporarily_unavailable`, `platform_unavailable`) delay notification until the next successful check; the next cadence retries. Other per-node outcomes (e.g. `file_unavailable`, `skipped_not_applicable` for non-GmbH chain members) are surfaced in the chain breakdown but do **not** block delivery — the rest of the chain still ships.","**Articles of association** document — Germany's constitutional company document, called **Gesellschaftsvertrag** (GmbH, KG, OHG, GbR), **Satzung** (AG, KGaA, eG, Verein), or **Statut** (some specific forms) depending on legal form. Each is the constitutional document for its legal form.\n\nWebhook body's `data.download.url` is a 7-day presigned URL to the PDF — the customer can fetch the file directly without a follow-up API call. After the URL expires, `GET /v1/companies/{eu_id}/documents/download?file_type=articles_of_association` mints a fresh one.\n\n**Not all companies have one.** Companies founded via the simplified procedure under §2 Abs. 1a GmbHG file a **Musterprotokoll** in its place — subscribe to `doc_model_protocol` for those.","**Initial company registration filing (Anmeldung zur Eintragung)** — the notarial document submitted to register the company. Webhook body carries a 7-day presigned download URL (`data.download.url`). Available for any newly-registered company; fires when a new Anmeldung is filed.","**Model protocol document (Musterprotokoll)** — the simplified notarial founding deed for small GmbH and UG (haftungsbeschränkt) companies under §2 Abs. 1a GmbHG. Legally substitutes for **both** the Articles of Association and the Liste der Gesellschafter for these companies. The Musterprotokoll itself names the founders, their share allocations, and the basic company terms in a single document.\n\nWebhook body carries a 7-day presigned download URL (`data.download.url`). Only companies founded via the simplified procedure have one; for everyone else this subscription reports `scrape_failed_file_not_found`. For **cap-table changes** — regardless of which document was filed — subscribe to `shareholders` instead (it auto-falls-back to the Musterprotokoll when no Liste has been filed).","**Liste der Gesellschafter** document — the standalone shareholder-list filing. Webhook body carries a 7-day presigned download URL (`data.download.url`).\n\nDistinct from the parsed `shareholders` subscription: this tracks the **document itself** with no Musterprotokoll fallback, so a Musterprotokoll-only GmbH (founded under §2 Abs. 1a GmbHG) reports `scrape_failed_file_not_found` until they file a real Liste. For parsed cap-table updates that work for any GmbH/UG, subscribe to `shareholders` instead."]},"TenderRole":{"type":"string","enum":["winner","buyer"],"title":"TenderRole","description":"Which side of an EU public-procurement notice a company was on.\n\nA company can be a buyer, a winner, both, or neither. Selecting both\nvalues matches companies that appear in TED in either role."},"UboCoverage":{"properties":{"object":{"type":"string","const":"ubo_coverage","title":"Object","description":"Discriminator. Always `ubo_coverage`.","default":"ubo_coverage"},"status":{"type":"string","enum":["available","partial","not_applicable","not_filed"],"title":"Status","description":"Coverage status. `available`: chain fully resolved to natural persons, OR remaining unresolved branches sum to ≤25 % effective share and cannot hide a beneficial owner; `partial`: at least one unresolved branch could hide a beneficial owner — either a single unresolved org carries >25 % effective share at the root, or several sum to >25 %; `not_applicable`: legal form does not file a Gesellschafterliste, or the company is Austrian (no shareholder data yet); `not_filed`: filing expected but not yet received.","default":"not_filed"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"Customer-safe one-sentence explanation of the coverage state when it's not the trivial `available`-with-nothing-to-explain case. For `partial`, names the top unresolved branches and their combined effective share so KYC consumers can decide whether to escalate. `null` only for the trivial `available` case."}},"type":"object","title":"UboCoverage","description":"Coverage signal for the UBO endpoint."},"UboEdge":{"properties":{"object":{"type":"string","const":"ubo_edge","title":"Object","description":"Discriminator. Always `ubo_edge`.","default":"ubo_edge"},"source_id":{"type":"string","title":"Source Id","description":"`UboNode.id` of the shareholder (the owner)."},"target_id":{"type":"string","title":"Target Id","description":"`UboNode.id` of the company being owned."},"share_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Share Percent","description":"Direct share percentage in [0, 100] from source to target, or `null` when the underlying filing didn't report a percentage."}},"type":"object","required":["source_id","target_id"],"title":"UboEdge","description":"A direct-ownership edge: `source` holds `share_percent` of `target`."},"UboGraph":{"properties":{"object":{"type":"string","const":"ubo_graph","title":"Object","description":"Discriminator. Always `ubo_graph`.","default":"ubo_graph"},"root_id":{"type":"string","title":"Root Id","description":"`UboNode.id` of the root company."},"nodes":{"items":{"$ref":"#/components/schemas/UboNode"},"type":"array","title":"Nodes","description":"All nodes in the graph (root included)."},"edges":{"items":{"$ref":"#/components/schemas/UboEdge"},"type":"array","title":"Edges","description":"Directed `source → target` ownership edges."}},"type":"object","required":["root_id"],"title":"UboGraph","description":"The full ownership graph rooted at the requested company."},"UboNode":{"properties":{"object":{"type":"string","const":"ubo_node","title":"Object","description":"Discriminator. Always `ubo_node`.","default":"ubo_node"},"id":{"type":"string","title":"Id","description":"Stable identifier for this node within the response. Use it to match the `source_id` / `target_id` references on edges."},"node_type":{"type":"string","enum":["company","person","organization_unresolved"],"title":"Node Type","description":"`company`: a German GmbH/UG whose cap table was traversed; `person`: a natural person leaf; `organization_unresolved`: an organisation that could not be followed further (foreign entity, unknown to firmendata, or no Gesellschafterliste obligation) — the chain stops here."},"is_root":{"type":"boolean","title":"Is Root","description":"`true` for the company the report was requested for.","default":false},"is_unresolved":{"type":"boolean","title":"Is Unresolved","description":"`true` when the chain could not be walked further past this node. Beneficial-owner attribution stops here, so any UBOs above this node are missing from `beneficial_owners`. Pair with `unresolved_reason` to decide whether to retry, raise the depth cap, or accept the gap.","default":false},"unresolved_reason":{"anyOf":[{"type":"string","enum":["foreign_org","unlisted_org","cap_table_not_filed","max_depth_reached"]},{"type":"null"}],"title":"Unresolved Reason","description":"Why the chain terminated at this node. `null` when `is_unresolved=false`. `foreign_org`: cap-table row referenced an organisation registered outside Germany (`country_code` set and not `DE`); foreign chains are not followed. `unlisted_org`: cap-table row referenced a German organisation we couldn't match to a known `eu_id`. `cap_table_not_filed`: company is known but no Gesellschafterliste has been filed yet. `max_depth_reached`: recursion hit the depth cap; the chain may continue further upstream."},"eu_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Eu Id","description":"firmendata company identifier when `node_type=company`, otherwise `null`."},"person":{"anyOf":[{"$ref":"#/components/schemas/Person"},{"type":"null"}],"description":"Natural-person details when `node_type=person`."},"organization":{"anyOf":[{"$ref":"#/components/schemas/OrganizationRef"},{"type":"null"}],"description":"Organisation details. Populated for `company` and `organization_unresolved` nodes."}},"type":"object","required":["id","node_type"],"title":"UboNode","description":"One vertex in the UBO ownership graph."},"UboReport":{"properties":{"object":{"type":"string","const":"ubo_report","title":"Object","description":"Discriminator. Always `ubo_report`.","default":"ubo_report"},"eu_id":{"type":"string","title":"Eu Id","description":"firmendata company identifier of the root."},"coverage":{"$ref":"#/components/schemas/UboCoverage","description":"Coverage status for this company."},"freshness":{"$ref":"#/components/schemas/Freshness","description":"How current the ownership chain is. `last_checked_at` is the **oldest** (`MIN`) of the per-hop shareholder-file fetch timestamps across every company in the resolved chain — the graph is only as fresh as its weakest link. `realtime_fetching_status` reports the outcome of the realtime attempt across the whole chain for this request."},"graph":{"$ref":"#/components/schemas/UboGraph","description":"Full ownership graph rooted at `eu_id`. Empty for `coverage.status` of `not_filed` or `not_applicable`."},"has_unresolved_branches":{"type":"boolean","title":"Has Unresolved Branches","description":"`true` when at least one non-root node in `graph` has `is_unresolved=true`. Indicates one or more branches terminated short of natural persons (foreign holding, missing Gesellschafterliste, depth cap). Whether this compromises the answer depends on the unresolved branches' effective share — read `coverage.status` for the materiality verdict (`partial` = it could hide a UBO; `available` with `has_unresolved_branches=true` = unresolved share is below threshold and immaterial).","default":false},"beneficial_owners":{"items":{"$ref":"#/components/schemas/BeneficialOwner"},"type":"array","title":"Beneficial Owners","description":"Natural persons holding more than 25 % of the root, ordered by effective share descending. Empty when no person crosses the threshold or when coverage is `not_filed`/`not_applicable`. When `coverage.status == \"partial\"`, each listed person's `effective_share_percent` is a **lower bound** — they could also own shares hidden behind unresolved branches."},"potential_beneficial_owners":{"items":{"$ref":"#/components/schemas/PotentialBeneficialOwner"},"type":"array","title":"Potential Beneficial Owners","description":"Unresolved organisations whose summed effective share at the root crosses 25 %. The natural person(s) controlling each entity are candidate UBOs — we just couldn't trace past the entity ourselves. Sorted by effective share descending. Always empty when `coverage.status` is `available` (no organisation crossed the threshold) or `not_filed`/`not_applicable`. Same-organisation dedup across multiple chain positions is by `(name, registered_seat, country_code)`."}},"type":"object","required":["eu_id","coverage","freshness","graph"],"title":"UboReport","description":"Ultimate beneficial owners and their ownership relationships."},"WebhookTestAttempt":{"properties":{"object":{"type":"string","const":"webhook_test_attempt","title":"Object","description":"Discriminator. Always `webhook_test_attempt`.","default":"webhook_test_attempt"},"attempt":{"type":"integer","title":"Attempt","description":"1-indexed attempt number within this test run."},"succeeded":{"type":"boolean","title":"Succeeded","description":"True iff the receiver returned a 2xx status."},"http_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Http Status","description":"HTTP status returned by the receiver, or `null` on transport failure."},"response_excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Response Excerpt","description":"First ~512 chars of the receiver's response body."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Short error string when the attempt did not succeed."},"duration_ms":{"type":"integer","title":"Duration Ms","description":"Wall-clock milliseconds for this attempt."},"sent_signature_header":{"type":"string","title":"Sent Signature Header","description":"`X-Firmendata-Signature` header value sent on this attempt."},"sent_timestamp_header":{"type":"string","title":"Sent Timestamp Header","description":"`X-Firmendata-Timestamp` header value sent on this attempt."}},"type":"object","required":["attempt","succeeded","duration_ms","sent_signature_header","sent_timestamp_header"],"title":"WebhookTestAttempt","description":"One outbound POST inside a webhook test run.\n\nFor `delivery_scenario=success` / `bad_signature` /\n`stale_timestamp` the response carries a single attempt; for\n`retry_delivery` it carries two with byte-identical headers and\nbody so the customer can see exactly what duplicate delivery looks\nlike on the wire."},"WebhookTestDeliveryScenario":{"type":"string","enum":["success","retry_delivery","bad_signature","stale_timestamp"],"title":"WebhookTestDeliveryScenario","description":"Transport-level behaviour the test endpoint should exhibit.\n\nIndependent of :attr:`SubscriptionTestRequest.scenario`, which picks\nthe *kind* of notification (today only `change`). This field\npicks how that notification is *delivered* so receivers can\nintegration-test their HMAC, replay-window, and idempotent-dedupe\npaths against firmendata's real wire format."},"WebsiteEntry":{"properties":{"object":{"type":"string","const":"company_website","title":"Object","description":"Discriminator. Always `company_website`.","default":"company_website"},"domain":{"type":"string","title":"Domain","description":"Registrable domain."},"impressum_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Impressum Url","description":"URL of the site's Impressum page."},"is_primary":{"type":"boolean","title":"Is Primary","description":"Whether this is the company's primary website.","default":false},"verification":{"type":"string","title":"Verification","description":"Evidence associating the website with the company: `register` (register reference in the Impressum), `lei` (LEI record), `linkedin_domain` (the website stated on the company's LinkedIn page), `name_unique` (unique company name), or `unverified`.","default":"unverified"}},"type":"object","required":["domain"],"title":"WebsiteEntry","description":"One of a company's websites. Companies can operate several domains."},"Wz2025Score":{"properties":{"object":{"type":"string","const":"wz_2025_score","title":"Object","description":"Discriminator. Always `wz_2025_score`.","default":"wz_2025_score"},"code":{"type":"string","title":"Code","description":"WZ 2025 code (German *Klassifikation der Wirtschaftszweige 2025*, compatible with NACE Rev. 2.1). Dotted-hierarchy format, e.g. `62.01.9`.","examples":["62.01.9"]},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Human-readable description of the WZ 2025 code."},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score","description":"Confidence score for this code, from 0 (none) to 1 (certain), rounded to three decimals. Meaningful for ranking a company's candidate codes against each other; not calibrated as a probability.","examples":[0.157]},"section":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section","description":"WZ 2025 section letter (e.g. `J` for Information and communication)."},"source_classification":{"anyOf":[{"type":"string","enum":["wz_2008","nace_rev_2","nace_rev_2_1","oenace_2025"]},{"type":"null"}],"title":"Source Classification","description":"Classification version the code was originally recorded in, when different from canonical WZ 2025: WZ 2008, NACE Rev. 2, NACE Rev. 2.1 or ÖNACE 2025, Austria's official national version of NACE Rev. 2.1, for Austrian companies."},"source_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Code","description":"The code as originally recorded in that version."},"source_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Title","description":"Official English title of the originally recorded code, falling back to German when unavailable."},"other_classifications":{"items":{"$ref":"#/components/schemas/ClassificationRepresentation"},"type":"array","title":"Other Classifications","description":"Other classification versions in NACE Rev. 2.1, WZ 2008, NACE Rev. 2, ISIC Rev. 4 order. Conversions start from the originally recorded code when available, otherwise the canonical WZ 2025 code."}},"type":"object","required":["code"],"title":"Wz2025Score","description":"A WZ 2025 classification candidate with a confidence score."},"Problem":{"type":"object","title":"Problem","description":"RFC 7807 problem details object.","required":["type","title","status","message","request_id"],"properties":{"type":{"type":"string","format":"uri","description":"URI identifying the problem type.","example":"https://api.firmendata.com/problems/validation-error"},"title":{"type":"string","description":"Short, human-readable summary of the problem.","example":"Request validation failed."},"status":{"type":"integer","description":"HTTP status code.","example":422},"detail":{"type":"string","description":"Human-readable explanation specific to this occurrence.","nullable":true},"message":{"type":"string","description":"Same as `detail`; provided for HTTP clients that read a `message` field."},"instance":{"type":"string","description":"URI reference identifying the specific occurrence (typically the request path).","nullable":true},"request_id":{"type":"string","description":"Same value as the `X-Request-Id` response header: the one you sent, or a server-generated id. Quote it when contacting support."},"errors":{"type":"array","description":"Parameter-level validation failures (only on 422 responses).","items":{"type":"object","required":["param","message"],"properties":{"param":{"type":"string","description":"Name of the offending parameter (dotted for a nested body field)."},"message":{"type":"string","description":"What is wrong with it."}}},"nullable":true}}}},"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"firmendata API key","description":"Bearer token in the `Authorization` header. Create and manage your tokens in [API Key Settings](https://firmendata.com/de/developer/api-keys)."}}},"tags":[{"name":"Feeds","description":"Beta company event streams, polled with persistent discovery cursors."},{"name":"Search","description":"Find companies by free-text query and firmographic filters. Use `autocomplete` for fast suggestions and `search` for programmatic, filterable lookups.\n\n### Filter values\n\nEnum values are **case-insensitive** and tolerate the umlaut spellings German text arrives in, so `gmbh`, `muenchen` and `Baden-Wurttemberg` all resolve. Common abbreviations and alternative names work too (`NRW`, `Bavaria`, `Charlottenburg`, `Amtsgericht München`). A value that could mean two different things is rejected rather than guessed at — `Frankfurt` names two courts, so spell out `Frankfurt am Main` or `Frankfurt/Oder`. Unknown values and unknown parameter names are rejected with `422` too, never silently ignored.\n\n### Repeating a filter\n\nFilters that accept several values (`city`, `bundesland`, `canton`, `rechtsform`, `wz_2025_code`, `industry_slug`, `legal_status`, `membership`, `tender_role`) OR-merge their values and accept any of the three encodings HTTP clients produce:\n\n```\n?rechtsform=GmbH&rechtsform=AG     repeated key\n?rechtsform=GmbH,AG                comma-separated\n?rechtsform[]=GmbH&rechtsform[]=AG bracket / indexed\n```\n\nDifferent filters are AND-merged. `city`, `bundesland` and `canton` are the one exception: they form a single location filter, so a company matches when it is in any selected city **or** any selected federal state or canton.\n\n### Reading the financials\n\nEach figure is resolved to the most recent filing that actually carries it, so they can come from *different* fiscal years — `revenue_year`, `profit_year`, `total_assets_year` and `employee_count_year` say which. Don't assume two of them share a year when computing a ratio. `financial_year` is a separate thing: the latest year the company filed anything at all.\n\nCoverage differs sharply between the metrics, and it is not a data-quality gap — it follows German filing law. Small and medium-sized companies file abridged accounts under §§ 266, 276 HGB: a balance sheet, but no profit-and-loss statement, and no headcount. So the balance-sheet total is available for far more companies than revenue or employees are. **If you are filtering on company size, use `total_assets_min` / `total_assets_max` — the revenue bounds reach only the minority that publish a full P&L.**"},{"name":"Company","description":"Company profile endpoints. `detail` returns the full hero profile with contact, people, LEI graph, and company insights; `financials` returns multi-year financials, employee history, and parent/subsidiary references; `shareholders` returns the latest cap table; `ubo` walks the ownership chain to the natural-person beneficial owners; `history` returns the chronological register-entry timeline."},{"name":"Documents","description":"Downloadable register documents available for the company: Aktueller Abdruck, Chronologischer Abdruck, Liste der Gesellschafter, Articles of Association (Gesellschaftsvertrag / Satzung / Statut — the name varies by legal form), Anmeldung (initial company registration), and Musterprotokoll (model protocol — the simplified founding deed for small GmbH/UG that replaces both the constitutional document and the Liste der Gesellschafter)."},{"name":"Subscriptions","description":"Webhook and email subscriptions for company-data updates. firmendata checks the underlying source on the cadence you choose (`immediately` / `daily` / `weekly` / `monthly`) and only delivers a notification when there is an actual update — no update means no call.\n\nTwo kinds of `subscription_type`:\n\n- **Parsed-data** types (`details`, `history`, `shareholders`, `ubo`) — the webhook body carries the publish-date and links to the v1 endpoints that serve parsed JSON.\n- **Document** types (every `doc_*` value) — the webhook body carries a 7-day presigned download URL for the PDF, so the customer can grab the file directly with no follow-up API call.\n\nCoverage is **not uniform** across legal forms: small GmbHs founded under the simplified procedure (§2 Abs. 1a GmbHG) replace the Articles of Association (Gesellschaftsvertrag / Satzung / Statut — the name varies by legal form) and the Liste der Gesellschafter with a single **Musterprotokoll** (model protocol). `shareholders` handles this transparently (auto-falls-back to the Musterprotokoll); the `doc_*` subscriptions do not — pick `doc_model_protocol` when you need the founding deed of a simplified-procedure company. The `SubscriptionType` schema documents the full per-value coverage table.\n\nEvery delivery (webhook or email) is recorded in the events history (`GET /v1/subscriptions/{id}/events`) — for webhooks the exact JSON body POSTed is persisted and can be replayed via `POST /v1/subscriptions/events/{event_id}/resend`."}],"security":[{"BearerAuth":[]}]}