API Dokumentation
Alt du behøver for at integrere danske virksomhedsdata i din applikation.
Kom i gang
Du kan integrere FirmaAPI i din applikation på under 5 minutter. Tre simple trin:
Tilføj API-nøgle
Send din API-nøgle som Bearer token i Authorization headeren.
Kald API'et
Foretag dit første kald og modtag virksomhedsdata som JSON.
curl https://firmaapi.dk/api/v1/company/24256790 \
-H "Authorization: Bearer cvr_live_din_api_nøgle"Autentifikation
Alle API-kald kræver en gyldig API-nøgle. Du kan sende nøglen på to måder:
Authorization: Bearer cvr_live_abc123def456...X-API-Key: cvr_live_abc123def456...Om API-nøgler
- ●Nøgler starter med
cvr_live_prefix og er 49 tegn lange - ●Du kan oprette flere nøgler fra dit dashboard
- ●Nøgler kan deaktiveres og genaktiveres uden at slette dem
- ●Hold dine nøgler hemmelige – del dem aldrig i offentlig kode
Sikkerhed: Kald aldrig API'et direkte fra klient-side kode (browser/app). Brug altid en server-side proxy, så din API-nøgle forbliver hemmelig.
Base URL
Alle API-kald foretages mod følgende base URL:
https://firmaapi.dk/api/v1/Miljøer
https://firmaapi.dk/api/v1/Alle data og infrastruktur er hosted i EU. GDPR-compliant.
Sandbox / test-nøgler
Test din integration uden at bruge betalte API-kald. Tag din live-nøgle og erstat cvr_live_ med cvr_test_:
# Din live-nøgle:
cvr_live_abc123def456...
# Din test-nøgle (samme nøgle, andet prefix):
cvr_test_abc123def456...curl https://firmaapi.dk/api/v1/company/24256790 \
-H "Authorization: Bearer cvr_test_abc123def456..."Hvad gør test-nøgler?
- ●Returnerer syntetisk data med alle enterprise-felter (ejere, regnskab, historik, GPS m.m.)
- ●Ingen rate limits, ingen kvote-forbrugt — perfekt til integrationstest
- ●Response inkluderer
X-Sandbox: trueogX-Billing-Counted: falseheaders - ●Alle endpoints understøttes: company, search, batch, person, regnskab, webhooks
CVR-opslag
Hent komplet virksomhedsdata via et 8-cifret CVR-nummer. For de fleste integrationer er dette det primære endpoint, og include= bruges kun til ekstra, tunge datablokke.
/api/v1/company/{cvr}| Parameter | Type | Beskrivelse |
|---|---|---|
cvr* | string | 8-cifret CVR-nummer (i URL path) |
curl https://firmaapi.dk/api/v1/company/24256790 \
-H "Authorization: Bearer cvr_live_..."curl "https://firmaapi.dk/api/v1/company/24256790?include=history,finance,production_units,relations" \
-H "Authorization: Bearer cvr_live_..."{
"cvr": "24256790",
"name": "Novo Nordisk A/S",
"address": "Novo Allé 1",
"zipcode": "2880",
"city": "Bagsværd",
"status": "Aktiv",
"company_type": "Aktieselskab",
"industry_code": "212000",
"industry_text": "Fremstilling af farmaceutiske præparater",
"founded": "1989-01-01",
"employees": "1000+",
"phone": "44448888",
"email": null,
"website": "https://www.novonordisk.com",
"ad_protected": false,
"secondary_industries": [
{ "code": "721100", "text": "Forskning og udvikling inden for bioteknologi" }
],
"capital": 500000000,
"capital_currency": "DKK",
"signing_rule": "Selskabet tegnes af bestyrelsens formand...",
"production_unit_count": 12,
"relations": {
"parents": [
{ "cvr": "24257630", "name": "Novo Holdings A/S", "ownership_share": 75, "voting_share": 75, "relation_type": "parent", "inferred": true }
],
"subsidiaries": [
{ "cvr": "12345678", "name": "Eksempel Datter A/S", "ownership_share": 100, "voting_share": 100, "relation_type": "subsidiary", "inferred": true }
]
},
"owners": [
{ "name": "Novo Holdings A/S", "title": "Reel ejer" },
{ "name": "Lars Fruergaard Jørgensen", "title": "Direktør, Bestyrelsesmedlem" }
],
"meta": {
"cached_at": "2025-01-15T12:00:00Z",
"source": "FirmaAPI"
}
}Bemærk: owners feltet er kun inkluderet for Basis plan eller højere. Gratis-brugere vil ikke se dette felt i response.
Tip: Response inkluderer en X-Data-Age header med alderen på cached data i sekunder.
Anbefaling: Start med /api/v1/company/{cvr}. Company-responsen indeholder allerede alle plan-tilgængelige virksomhedsfelter. Brug kun include= til ekstra blokke som historik, regnskaber og produktionsenheder.
Anbefalede include-blokke
Disse blokke hentes kun når du eksplicit beder om dem med include=. Det holder standardresponsen hurtig og slank.
| Include | Indhold | Plan |
|---|---|---|
| history | Historik Henter historiske ændringer for navn, adresse, status, branche, ansatte og binavne (Standard+). | Basis+ |
| finance | Regnskaber Henter regnskabsdata som ekstra blok, inkl. nøgletal (Standard+), årsændringer og udvidede felter (Professionel+). | Standard+ |
| production_units | Produktionsenheder Henter P-enheder som separat blok, så company-responsen kan holdes slank. | Standard+ |
| relations | Koncernrelationer Henter direkte moder-/datterselskabsrelationer som en ekstra blok. | Professionel+ |
| events | Hændelser Henter virksomhedens livscyklus, fusioner/spaltninger og en afledt hændelsestidslinje. | Standard+ |
Felter der følger automatisk med
Disse datablokke returneres automatisk på company-endpointet, når planen giver adgang. Du behøver ikke include= for dem.
| Data | Felter | Plan |
|---|---|---|
Ejere og ledelse Følger automatisk med på company-endpointet for Basis og højere. | owners | Basis+ |
Revisor-information Følger automatisk med på company-endpointet for Professionel og Enterprise. | auditors | Professionel+ |
Ejerskabshistorik Følger automatisk med på company-endpointet for Professionel og Enterprise. | ownership_history | Professionel+ |
GPS-koordinater Latitude og longitude følger automatisk med på company-endpointet. | latitudelongitude | Professionel+ |
Udvidede kontaktoplysninger Alle e-mailadresser, alle telefonnumre og fax følger automatisk med. | all_emailsall_phonesfax | Professionel+ |
Udvidede virksomhedsattributter Audit form, regnskabsårsstart, kapital og tegningsregel følger automatisk med. | audit_formfiscal_year_startcapitalcapital_currencysigning_rule | Professionel+ |
Historik over sekundære brancher Sekundær branchehistorik følger automatisk med på company-endpointet. | secondary_industry_history | Professionel+ |
ERST-attributter (alle planer) Formål, binavne, regnskabsårsslut, regnskabsklasse og årlig beskæftigelse følger automatisk med. | purposesecondary_namesfiscal_year_endaccounting_classannual_employees | Basis+ |
ERST-attributter (Standard+) Arbejdsgiver-/momsregistrering, import/eksport-status, punktafgifter og første regnskabsperiode. | employer_registration_datevat_registration_dateimport_registeredexport_registeredexcise_registrationsfirst_fiscal_period_end | Standard+ |
Navnesøgning
Søg efter virksomheder via navn. Understøtter fuzzy matching og delvis søgning.
/api/v1/company/search?q={query}| Parameter | Type | Beskrivelse |
|---|---|---|
q* | string | Søgeterm, minimum 2 tegn |
status | string | Filtrer på status, f.eks. "Aktiv". Kommasepareret for flere. |
limit | integer | Antal resultater (1-50, default 10) |
curl "https://firmaapi.dk/api/v1/company/search?q=novo+nordisk&status=Aktiv&limit=5" \
-H "Authorization: Bearer cvr_live_..."{
"results": [
{
"cvr": "24256790",
"name": "Novo Nordisk A/S",
"address": "Novo Allé 1",
"zipcode": "2880",
"city": "Bagsværd",
"status": "Aktiv",
"company_type": "Aktieselskab",
"industry_text": "Fremstilling af farmaceutiske præparater",
...,
"meta": {
"cached_at": "2025-01-15T12:00:00Z",
"source": "FirmaAPI"
}
}
],
"total": 12
}Bemærk: owners feltet er kun inkluderet for Basis plan eller højere. Gratis-brugere vil ikke se dette felt i response.
Batch-opslag
Slå op til 100–500 virksomheder op i en enkelt request (afhængigt af plan). Kræver Basis eller højere. Perfekt til databerigelse, CRM-integration og massevalidering.
/api/v1/company/batchRequest body (JSON)
| Parameter | Type | Beskrivelse |
|---|---|---|
cvr_numbers* | string[] | Array af CVR-numre (max afhænger af plan: Basis 100, Standard 200, Professionel 500) |
curl -X POST https://firmaapi.dk/api/v1/company/batch \
-H "Authorization: Bearer cvr_live_..." \
-H "Content-Type: application/json" \
-d '{"cvr_numbers": ["24256790", "54562519", "25313763"]}'{
"results": [
{ "cvr": "24256790", "name": "Novo Nordisk A/S", ..., "meta": { "cached_at": "...", "source": "FirmaAPI" } },
{ "cvr": "54562519", "name": "LEGO A/S", ..., "meta": { "cached_at": "...", "source": "FirmaAPI" } },
{ "cvr": "25313763", "name": "Nets Denmark A/S", ..., "meta": { "cached_at": "...", "source": "FirmaAPI" } }
],
"errors": [],
"total": 3,
"quota_used": 3
}Bemærk: owners feltet er kun inkluderet for Basis plan eller højere. Gratis-brugere vil ikke se dette felt i response.
Tip: Hvert CVR-nummer i et batch-kald tæller som ét opslag mod din månedlige kvote. Feltet quota_used i response viser det samlede antal opslag brugt.
Ejere & ledelse
Ejer- og ledelsesdata følger direkte med på /api/v1/company/{cvr} for Basis og højere. Du behøver ikke et separat endpoint for at hente disse data.
Plan-adgang: Gratis = ingen adgang. Basis, Standard, Professionel og Enterprise = ejere og ledelse på company-endpointet.
curl https://firmaapi.dk/api/v1/company/24256790 -H "Authorization: Bearer cvr_live_..."{
"cvr": "24256790",
"name": "Novo Nordisk A/S",
"owners": [
{
"name": "Novo Holdings A/S",
"title": "Reel ejer",
"ownership_share": 28.1,
"voting_share": 76.5,
"joined_date": "1999-01-01",
"left_date": null,
"participant_cvr": "24257630",
"participant_enhedsnummer": null,
"person_id": null
},
{
"name": "Lars Fruergaard Jørgensen",
"title": "Direktør, Bestyrelsesmedlem",
"ownership_share": null,
"voting_share": null,
"joined_date": "2017-01-01",
"left_date": null,
"participant_cvr": null,
"participant_enhedsnummer": "4000724313",
"person_id": "123e4567-e89b-12d3-a456-426614174000"
}
],
"ownership_history": [
{
"name": "Historisk Holding A/S",
"title": "Reel ejer",
"joined_date": "2019-01-01",
"left_date": "2021-12-31",
"active": false,
"person_id": null
}
]
}Professionel+: ownership_share, voting_share, joined_date, left_date, participant_cvr, participant_enhedsnummer, person_id og ownership_history returneres kun for Professionel og Enterprise.
Personprofil-link: person_id er en UUID der kan sendes direkte til GET /api/v1/person/{id}. Feltet er null hvis deltageren er en virksomhed (fx et holdingselskab) eller endnu ikke er matchet til en personprofil. Samme felt findes på auditors og ownership_history.
Personprofiler & søgning
Personprofiler
Ejer- og ledelsesdata kan kobles til personprofiler, så du kan følge samme person på tværs af flere virksomheder. Personrelationer er tilgængelige via API og vises også offentligt på /person/{id}/{slug}.
Personprofiler bruges til krydsopslag: find personen én gang, og få hele listen af virksomheder personen deltager i.
Sådan får du fat i et person_id: Kald GET /api/v1/company/{cvr} som Professionel/Enterprise-bruger. Hver post i owners, auditors og ownership_history får et person_id-felt (UUID), som du kan sende direkte videre til /api/v1/person/{id}. Feltet er null, hvis deltageren er et selskab eller endnu ikke er matchet til en profil.
/api/v1/person/{id}| Parameter | Type | Beskrivelse |
|---|---|---|
id* | string (UUID) | Personprofil-UUID fra person_id-feltet på owners/auditors/ownership_history i company-responsen. Dette er ikke CVR-enhedsnummeret. |
curl https://firmaapi.dk/api/v1/person/123e4567-e89b-12d3-a456-426614174000 -H "Authorization: Bearer cvr_live_..."{
"id": "123e4567-e89b-12d3-a456-426614174000",
"canonical_name": "Tommy Ahlers",
"slug": "tommy-ahlers",
"active_company_count": 12,
"historical_company_count": 8,
"total_company_count": 20,
"company_count": 20,
"affiliations": [
{
"cvr": "24256790",
"company_name": "Eksempel A/S",
"company_slug": "eksempel-as-24256790",
"role_title": "Bestyrelsesmedlem",
"joined_date": "2023-01-01",
"left_date": null,
"duration_days": 1234
}
]
}Aktive vs historiske roller: active_company_count tæller virksomheder hvor personen p.t. er registreret med en åben rolle (uden left_date) — brug det hvis du kun vil vise nuværende ledelses- og bestyrelsesposter. historical_company_count dækker tidligere, lukkede roller. For nogle advokater kan dette tal være meget højt pga. skuffeselskabs-mønsteret: en advokat står som initial direktør i et nyoprettet ApS i få dage, indtil selskabet sælges til en klient. Brug duration_days >= 180 på affiliations hvis du kun vil se reelle ledelsesrelationer.
Sådan bruger du persontilknytning i API'et
- Hent virksomhed via
/api/v1/company/{cvr}og brug personlink til videre opslag. - Hent personens samlede virksomhedsnetværk via
/api/v1/person/{id}. - Brug
affiliations[].cvrtil overvågning, scoring, relationstræ og netværksanalyse.
Plan-adgang: Gratis/Basis = ingen adgang. Professionel/Enterprise = adgang.
Personsøgning
Slå personprofiler op uden at starte i en virksomhed. Brug det til KYC-workflows, sales-prospecting og relationsgrafer hvor du kun har et navn — eller et enhedsnummer/CVR fra en anden kilde.
/api/v1/person/search?q={query}| Parameter | Type | Beskrivelse |
|---|---|---|
q* | string | Søgeterm, minimum 2 tegn. Navne normaliseres (unicode, whitespace, lowercase). Et rent numerisk query på 7+ cifre matches også direkte mod enhedsnummer/CVR fra tidligere company-respons. |
limit | integer | Antal resultater (1-50, default 10) |
curl "https://firmaapi.dk/api/v1/person/search?q=lars+sandahl&limit=5" \
-H "Authorization: Bearer cvr_live_..."{
"results": [
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"canonical_name": "Lars Sandahl Sørensen",
"slug": "lars-sandahl-sorensen",
"normalized_name": "lars sandahl sorensen",
"match_strategy": "strong_identity",
"match_confidence": 0.9,
"active_company_count": 5,
"historical_company_count": 2,
"total_company_count": 7,
"company_count": 7,
"match_type": "exact"
}
],
"total": 1
}Match-typer og sortering
strong_key— numerisk query matchede et enhedsnummer eller CVR fra PersonProfileAffiliation. Stærkeste match.exact— normaliseret navn er identisk med profilens kanoniske navn.alias— normaliseret navn matcher et registreret alias.prefix— navn eller alias starter med søgetermen.
Resultater sorteres efter match-type først, derefter efter virksomhedsantal (flest først), og til sidst efter canonical_name alfabetisk for stabil paginering. Hvert hit indeholder både active_company_count (nuværende roller) og historical_company_count (lukkede roller) — feltet company_count er bevaret som bagudkompatibelt alias for total_company_count.
Næste skridt: Send id videre til GET /api/v1/person/{id} for at hente fulde persontilknytninger med virksomhedsnavne, roller og perioder.
Plan-adgang: Gratis/Basis/Standard = ingen adgang. Professionel/Enterprise = adgang.
Regnskabsdata
Regnskabsdata hentes via include=finance på company-endpointet. Det holder standardresponsen hurtig og gør integrationen enklere.
Plan-adgang: Gratis/Basis = ingen adgang. Standard = seneste årsregnskab + PDF-link + nøgletal (ratios) + udvidet P&L/balance (personaleomkostninger, varebeholdninger m.m.). Professionel/Enterprise = alle regnskabsfelter, pengestrømsopgørelse, revisionspåtegning, kvartals-/delårsrapporter, nøgletal + årsændringer (growth).
curl "https://firmaapi.dk/api/v1/company/24256790?include=finance" -H "Authorization: Bearer cvr_live_..."{
"cvr": "24256790",
"has_financials": true,
"financials_pending": false,
"years_included": "5",
"financials": [
{
"year": 2024,
"period_start": "2024-01-01",
"period_end": "2024-12-31",
"report_type": "annual",
"revenue": 290324000000,
"gross_profit": 245891000000,
"profit_before_tax": 112456000000,
"net_profit": 83214000000,
"equity": 156789000000,
"total_assets": 312456000000,
"ebitda": 138200000000,
"cash": 42300000000,
"share_capital": 500000000,
"currency": "DKK",
"report_url": "http://regnskaber.virk.dk/...",
"ratios": {
"profit_margin": 0.2866,
"gross_margin": 0.8469,
"return_on_assets": 0.2663,
"return_on_equity": 0.5308,
"solvency_ratio": 0.5018,
"debt_to_equity": 0.9928
},
"growth": {
"revenue_yoy": 0.2351,
"profit_yoy": 0.1842,
"equity_yoy": 0.1523,
"total_assets_yoy": 0.0891
}
},
{
"year": 2024,
"period_start": "2024-07-01",
"period_end": "2024-09-30",
"report_type": "quarterly",
"revenue": 78500000000,
"currency": "DKK"
}
]
}Nøgletal og årsændringer: Alle værdier i ratios og growth er decimaler — gang med 100 for procent (f.eks. 0.2866 = 28,66%). Felter er null hvis de underliggende regnskabstal mangler eller divisor er 0.
{
"error": {
"code": "PLAN_UPGRADE_REQUIRED",
"include": "finance",
"message": "Regnskabsdata kræver Standard, Professionel eller Enterprise plan.",
"current_plan": "gratis",
"required_plan": "standard"
}
}Historik
Historiske ændringer hentes via include=history på company-endpointet. Her får du navn, adresse, status, branche, ansatte og virksomhedsform samlet i én blok.
Plan-adgang: Gratis = ingen adgang. Basis og højere = historik via include=history.
curl "https://firmaapi.dk/api/v1/company/24256790?include=history" -H "Authorization: Bearer cvr_live_..."{
"cvr": "24256790",
"name": "Novo Nordisk A/S",
"history": {
"names": [
{ "name": "Novo Nordisk A/S", "valid_from": "1999-01-01", "valid_to": null }
],
"addresses": [
{ "address": "Novo Allé 1", "zipcode": "2880", "city": "Bagsværd", "municipality_code": 159, "municipality_name": "Gladsaxe", "valid_from": "2002-10-05", "valid_to": null }
],
"statuses": [
{ "status": "Aktiv", "valid_from": "1989-01-01", "valid_to": null }
],
"industries": [
{ "code": "212000", "text": "Fremstilling af farmaceutiske præparater", "valid_from": "2008-01-01", "valid_to": null }
],
"employees": [
{ "employees": "1000+", "valid_from": "2024-01-01", "valid_to": null }
],
"company_forms": [
{ "form": "Aktieselskab", "valid_from": "1989-01-01", "valid_to": null }
]
}
}{
"error": {
"code": "PLAN_UPGRADE_REQUIRED",
"include": "history",
"message": "Historikdata kræver Basis plan eller højere.",
"current_plan": "gratis",
"required_plan": "basis"
}
}Avanceret søgning
Søg i databasen med multiple filtre. Kombiner navn, by, postnummer, branche, virksomhedsform, status, ansatte, stiftelsesdato og reklamebeskyttelse.
Ydeevne: Advanced search bruger et dedikeret søgeindeks. Endpoint, filtre og response-format er de samme som før, men helt nye company-writes kan være et par minutter om at dukke op i søgningen.
/api/v1/search/advanced| Parameter | Type | Beskrivelse |
|---|---|---|
q | string | Virksomhedsnavn (delvis match). Brug * som wildcard, f.eks. "apple*". Udelad parameteren eller angiv * alene for at returnere alle. |
city | string | By (eksakt match) |
municipality | string | Kommune som kode eller navn, f.eks. "101", "0101" eller "København" (eksakt katalogmatch) |
zipcode | string | Postnummer (eksakt match) |
industry | string | Branchekode (numerisk, prefix-match, f.eks. "43" finder alle under 43xxxx) eller branchetekst (fritekst-match) |
company_type | string | Virksomhedsform, f.eks. "Aktieselskab" (delvis match) |
status | string | Status, f.eks. "Aktiv", "Ophørt" m.fl. |
employees | string | Antal ansatte — brug "5+" (minimum), "2-10" (interval), "42" (præcis), eller CVR-koder som "ANTAL_10_19" (se gyldige værdier nedenfor) |
founded_after | string | Stiftet efter dato (YYYY-MM-DD) |
founded_before | string | Stiftet før dato (YYYY-MM-DD) |
ad_protected | boolean | Reklamebeskyttet (true/false) |
has_financials | boolean | Filtrer på om virksomheden har et kendt regnskabssignal. Kan være true, selv hvis regnskabstallene først hentes hjem ved første finance-opslag. |
revenue_min | integer | Minimum omsætning i seneste regnskabsår |
revenue_max | integer | Maksimum omsætning i seneste regnskabsår |
capital_min | integer | Minimum egenkapital eller selskabskapital i seneste regnskabsår |
capital_max | integer | Maksimum egenkapital eller selskabskapital i seneste regnskabsår |
has_phone | boolean | Filtrer på om virksomheden har mindst ét telefonnummer (primært nummer eller et nummer i all_phones) |
has_email | boolean | Filtrer på om virksomheden har mindst én email (primær email eller en email i all_emails) |
has_website | boolean | Filtrer på om virksomheden har en hjemmeside |
limit | integer | Max resultater (1-100, default 20) |
offset | integer | Pagination offset (default 0) |
include_total | boolean | Sæt true for total antal matches (default false for lavere latency) |
Bemærk: Mindst én søgeparameter skal angives.
curl "https://firmaapi.dk/api/v1/search/advanced?city=København&company_type=Anpartsselskab&status=Aktiv&limit=10" \
-H "Authorization: Bearer cvr_live_..."Kommunefilter: municipality accepterer både kommunenavn og kommunekode. municipality=København, municipality=101 og municipality=0101 matcher samme kommune.
curl "https://firmaapi.dk/api/v1/search/advanced?municipality=København&status=Aktiv&limit=10" \
-H "Authorization: Bearer cvr_live_..."curl "https://firmaapi.dk/api/v1/search/advanced?status=Aktiv&has_phone=true&has_website=true&limit=10" \
-H "Authorization: Bearer cvr_live_..."curl "https://firmaapi.dk/api/v1/search/advanced?status=Aktiv&has_financials=true&revenue_min=1000000&limit=10" \
-H "Authorization: Bearer cvr_live_..."curl "https://firmaapi.dk/api/v1/search/advanced?industry=739&employees=2%2B&ad_protected=true&status=Aktiv" \
-H "Authorization: Bearer cvr_live_..."curl "https://firmaapi.dk/api/v1/search/advanced?city=Aarhus&founded_after=2020-01-01&status=Aktiv" \
-H "Authorization: Bearer cvr_live_..."{
"results": [
{
"cvr": "...",
"name": "...",
...,
"meta": {
"cached_at": "2025-01-15T12:00:00Z",
"source": "FirmaAPI"
}
}
],
"limit": 20,
"offset": 0,
"has_more": true
}{
"results": [ ... ],
"total": 45821,
"limit": 20,
"offset": 0,
"has_more": true
}Bemærk: owners feltet er kun inkluderet for Basis plan eller højere. Gratis-brugere vil ikke se dette felt i response.
Gyldige statusværdier:
Aktiv, Ophørt, Opløst efter konkurs, Opløst efter fusion, Opløst efter spaltning, Opløst efter erklæring, Tvangsopløst, Under konkurs, Under tvangsopløsning, Under rekonstruktion, Slettet
Employees-filter — understøttede formater:
| Format | Eksempel | Betydning |
|---|---|---|
| Minimum | 5+ | 5 eller flere ansatte |
| Interval | 2-10 | Mellem 2 og 10 ansatte |
| Præcis | 42 | Præcis 42 ansatte |
| CVR-kode | ANTAL_10_19 | CVR-interval 10-19 |
CVR-koder: ANTAL_1_1, ANTAL_2_4, ANTAL_5_9, ANTAL_10_19, ANTAL_20_49, ANTAL_50_99, ANTAL_100_199, ANTAL_200_499, ANTAL_500_999, ANTAL_1000_PLUS. INTERVAL-format accepteres også (f.eks. INTERVAL_10_19).
Finansfiltre: revenue_min, revenue_max, capital_min og capital_max måles altid på seneste regnskabsår i søgeindekset.
Hændelser
Hent virksomhedens livscyklus, fusioner, spaltninger og en afledt hændelsestidslinje via include=events på company-endpointet.
Plan-adgang: Gratis/Basis = ingen adgang. Standard+ og højere = fuld adgang. Webhook-events (company.merged, company.demerged) kræver Professionel+.
Eksempel
curl "https://firmaapi.dk/api/v1/company/24256790?include=events" \
-H "X-API-Key: cvr_live_..."{
"lifecycle": [
{ "valid_from": "1923-02-01", "valid_to": null }
],
"mergers": [
{ "type": "merger", "effective_date": "1990-01-01" },
{ "type": "demerger", "effective_date": "2000-11-07" }
],
"events": [
{ "type": "founded", "occurred_at": "1923-02-01", "description": "Virksomheden stiftet" },
{ "type": "merged", "occurred_at": "1990-01-01", "description": "Fusion registreret" },
{ "type": "demerged", "occurred_at": "2000-11-07", "description": "Spaltning registreret" }
]
}| Parameter | Type | Beskrivelse |
|---|---|---|
lifecycle[] | array | Livsperioder (valid_from, valid_to). Flere perioder = virksomheden har været ophørt og genoptaget. |
mergers[] | array | Fusioner (type=merger) og spaltninger (type=demerger) med dato for registrering. |
events[] | array | Afledt tidslinje: founded, dissolved, reopened, merged, demerged med dato og beskrivelse. |
Produktionsenheder
Hent virksomhedens P-enheder via include=production_units på company-endpointet. Brug kun det separate P-nummer-endpoint, når du allerede kender den konkrete enhed.
Plan-adgang: Gratis/Basis = ingen adgang. Standard = P-enheder. Professionel/Enterprise = udvidede P-enhedsfelter.
curl "https://firmaapi.dk/api/v1/company/24256790?include=production_units" -H "Authorization: Bearer cvr_live_..."{
"cvr": "24256790",
"name": "Novo Nordisk A/S",
"production_unit_count": 3,
"production_units": [
{
"p_number": "1234567890",
"name": "Novo Nordisk - Bagsværd",
"address": "Novo Allé 1",
"zipcode": "2880",
"city": "Bagsværd",
"industry_code": "212000",
"industry_text": "Fremstilling af farmaceutiske præparater",
"employees": "1000+"
}
]
}{
"error": {
"code": "PLAN_UPGRADE_REQUIRED",
"include": "production_units",
"message": "Produktionsenheder kræver Standard plan eller højere.",
"current_plan": "gratis",
"required_plan": "standard"
}
}Enkelt P-enhed opslag
/api/v1/production-unit/{p_number}| Parameter | Type | Beskrivelse |
|---|---|---|
p_number* | string | 10-cifret P-nummer (i URL path) |
{
"p_number": "1234567890",
"cvr": "24256790",
"name": "Novo Nordisk - Bagsværd",
"address": "Novo Allé 1",
"zipcode": "2880",
"city": "Bagsværd",
"industry_code": "212000",
"industry_text": "Fremstilling af farmaceutiske præparater",
"employees": "42",
"meta": { ... }
}Referencekataloger
Industrikatalog
Brug /api/v1/industries til kundesync, når du vil spejle hele branchetræet i dit CRM, ERP eller lead-system uden først at lave tunge virksomhed-opslag.
Endpointet returnerer hele hierarkiet, ikke kun de laveste koder. Hver post er en node i træet med både parent_code og child_count, så du kan synkronisere hele strukturens relationer.
Labels på ikke-leaf noder er afledte opsummeringer af de underliggende brancher i snapshotet. De skal derfor læses som sync-labels og ikke som officielle DB07-overskrifter.
Snapshot freshness: meta.refreshed_at fortæller, hvornår snapshot blev opdateret. Snapshotet refreshes periodisk, så tællinger vil ofte være omkring et døgn gamle. Brug derfor altid tidsstemplet som den faktiske friskhedsindikator.
curl "https://firmaapi.dk/api/v1/industries" -H "Authorization: Bearer cvr_live_..."{
"items": [
{
"code": "43",
"display_code": "43",
"label": "Forberedende byggepladsarbejder, Nedrivning, Testboring og prøvetagning m.fl.",
"level": "division",
"parent_code": null,
"company_count": 1234,
"primary_company_count": 1020,
"secondary_company_count": 214,
"child_count": 1
},
{
"code": "431",
"display_code": "43.1",
"label": "Forberedende byggepladsarbejder, Nedrivning, Testboring og prøvetagning m.fl.",
"level": "group",
"parent_code": "43",
"company_count": 420,
"primary_company_count": 390,
"secondary_company_count": 30,
"child_count": 3
}
],
"meta": {
"total": 123,
"refreshed_at": "2026-03-28T10:00:00.000Z"
}
}Kommunekatalog
Brug /api/v1/municipalities til customer sync / reference use, når du vil spejle de kommunekoder og navne, som FirmaAPI eksponerer, i dit eget system uden tunge company-opslag først.
Kataloget er et lille statisk reference-sæt. Hent det én gang, gem mappingen mellem numeric_code og municipality_code lokalt, og brug derefter kommunenavnet som displayværdi i dit CRM, ERP eller lead-system.
Company-payloads inkluderer også municipality_name ved siden af municipality_code som et convenience-felt, så du kan vise adresser uden ekstra opslag.
Bemærk: Kommunekataloget er ikke et snapshot-lag med freshness claims eller cron-opdateringer. Det er en kanonisk reference-liste over de kommunekoder og navne, FirmaAPI eksponerer.
curl "https://firmaapi.dk/api/v1/municipalities" -H "Authorization: Bearer cvr_live_..."{
"items": [
{ "code": "0101", "numeric_code": 101, "name": "København" },
{ "code": "0147", "numeric_code": 147, "name": "Frederiksberg" }
],
"meta": {
"total": 99
}
}Teknisk reference
Response-format
Alle responses returneres som JSON med UTF-8 encoding. Succesfulde kald returnerer data direkte, mens fejl returnerer et standardiseret fejlobjekt.
Virksomhedsobjekt
Felter i et standard virksomhedsresponse:
| Felt | Type | Beskrivelse |
|---|---|---|
| cvr | string | 8-cifret CVR-nummer |
| name | string | Officielt virksomhedsnavn |
| address | string | Vejnavn og husnummer |
| zipcode | string | Postnummer |
| city | string | By |
| municipality_code | integer|null | Kommunekode til brug med kommunekataloget |
| municipality_name | string|null | Kommunenavn som convenience field |
| status | string | Aktiv, Ophørt, Under konkurs m.fl. |
| company_type | string|null | Virksomhedsform (ApS, A/S, IVS m.fl.) |
| industry_code | string|null | 6-cifret branchekode |
| industry_text | string|null | Branchebeskrivelse |
| founded | string|null | Stiftelsesdato (YYYY-MM-DD) |
| employees | string|null | Antal ansatte – eksakt tal som string eller normaliseret interval som 10-19 / 1000+ |
| phone | string|null | Telefonnummer |
| string|null | ||
| website | string|null | Hjemmeside |
| ad_protected | boolean | Om virksomheden er reklamebeskyttet |
| secondary_industries | array | Sekundære brancher med code og text |
| capital | number|null | Selskabskapital (i mindste valutaenhed) |
| capital_currency | string|null | Valuta for kapital (typisk DKK) |
| signing_rule | string|null | Tegningsregel |
| production_unit_count | number | Antal produktionsenheder |
| purpose | string|null | Virksomhedens formål |
| secondary_names | string[] | Aktive binavne |
| fiscal_year_end | string|null | Regnskabsårsslut (MM-DD) |
| accounting_class | string|null | Regnskabsklasse (A/B/C/D) |
| annual_employees | string|null | Årlig beskæftigelse (FTE-interval) |
| owners | array | Aktive ejere og ledelse med navn og rolle (title). Kun Basis plan eller højere. |
Ekstra felter Standard+
Disse felter er kun tilgængelige med Standard plan eller højere:
| Felt | Type | Beskrivelse |
|---|---|---|
| employer_registration_date | string|null | Første arbejdsgiverregistrering (YYYY-MM-DD) |
| vat_registration_date | string|null | Første momsregistrering (YYYY-MM-DD) |
| import_registered | boolean | Aktiv importregistrering |
| export_registered | boolean | Aktiv eksportregistrering |
| excise_registrations | string[] | Aktive punktafgiftsregistreringer |
| first_fiscal_period_end | string|null | Første regnskabsperiode slutdato |
Ekstra felter Professionel+
Disse felter er kun tilgængelige med Professionel plan eller højere:
| Felt | Type | Beskrivelse |
|---|---|---|
| latitude | number|null | Breddegrad (WGS84) |
| longitude | number|null | Længdegrad (WGS84) |
| auditors | array | Revisorer med name, title, participant_cvr og joined_date |
| all_emails | string[] | Alle email-adresser |
| all_phones | string[] | Alle telefonnumre |
| fax | string|null | Faxnummer |
| audit_form | string|null | Revisionsform |
| fiscal_year_start | string|null | Regnskabsår start (f.eks. "01-01") |
| secondary_industry_history | array | Historik over bibrancher inkl. inaktive |
Reklamebeskyttelse
Virksomheder kan være reklamebeskyttede i CVR. Når ad_protected er true, returneres kontaktoplysninger (email, telefon, website) kun i autentificerede API-kald. Du må ikke bruge disse oplysninger til direkte markedsføring, herunder uopfordrede henvendelser via email, telefon, SMS eller fysisk post. Det er dit ansvar at overholde reklamebeskyttelsen.
Meta-objekt
Alle responses inkluderer et meta objekt med information om data-kilden:
"meta": {
"cached_at": "2025-01-15T12:00:00.000Z",
"source": "FirmaAPI"
}Paginering
Endpoints der returnerer lister understøtter paginering med limit og offset parametre.
Sådan paginerer du
curl "https://firmaapi.dk/api/v1/search/advanced?city=Aarhus&limit=20&offset=0" \
-H "Authorization: Bearer cvr_live_..."curl "https://firmaapi.dk/api/v1/search/advanced?city=Aarhus&limit=20&offset=20" \
-H "Authorization: Bearer cvr_live_..."Brug has_more feltet i response til at afgøre om der er flere sider. Hvis du også skal vise samlet antal, tilføj include_total=true. Hver side tæller som ét opslag.
Rate limits
API'et har rate limits per sekund og månedlige kvoter afhængig af din plan.
| Plan | Requests/sek | Opslag/måned |
|---|---|---|
| Gratis | 2 | 1.000 |
| Basis | 5 | 50.000 |
| Standard | 10 | 150.000 |
| Professionel | 20 | 500.000 |
| Enterprise | Individuelt | Efter aftale |
Rate limit headers
Alle responses inkluderer rate limit headers, så du kan håndtere limits proaktivt:
X-RateLimit-Limit: 2 # Max requests per sekund for din plan
X-RateLimit-Remaining: 1 # Resterende requests i dette sekund
X-RateLimit-Reset: 1710000 # Unix timestamp for næste resetNår du rammer grænsen
Hvis du overskrider din rate limit, returnerer API'et HTTP 429 Too Many Requests med en Retry-After header der angiver hvor mange sekunder du skal vente.
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Slow down.",
"retry_after": 1
}
}Best practices
- ✓Spred dine requests jævnt ud – undgå at sende mange på én gang i bursts
- ✓Brug
X-RateLimit-Remainingheaderen til at bremse inden du rammer grænsen - ✓Ved
429– vent det antal sekunderRetry-Afterheaderen angiver - ✓Implementer exponential backoff: fordobl ventetiden ved gentagne
429-svar - ✓Brug batch-endpointet (
/api/v1/company/batch) i stedet for mange enkelte opslag
Eksempel med retry-logik (JavaScript):
async function fetchCompany(cvr, apiKey, retries = 3) {
for (let i = 0; i < retries; i++) {
const res = await fetch(`https://firmaapi.dk/api/v1/company/${cvr}`, {
headers: { Authorization: `Bearer ${apiKey}` },
});
if (res.ok) return res.json();
if (res.status === 429) {
const wait = parseInt(res.headers.get("Retry-After") || "1");
await new Promise((r) => setTimeout(r, wait * 1000 * (i + 1)));
continue;
}
throw new Error(`API error: ${res.status}`);
}
throw new Error("Max retries exceeded");
}Fejlhåndtering
Alle fejl returneres med en standardiseret JSON-struktur og passende HTTP statuskode.
{
"error": {
"code": "ERROR_CODE",
"message": "Menneskelæselig beskrivelse af fejlen"
}
}| HTTP | Kode | Beskrivelse | Løsning |
|---|---|---|---|
| 400 | INVALID_CVR | Ugyldigt CVR-format | Sørg for at CVR er præcis 8 cifre |
| 400 | INVALID_P_NUMBER | Ugyldigt P-nummer format | P-nummer skal være præcis 10 cifre |
| 400 | INVALID_QUERY | Ugyldig eller manglende søgeparameter | Angiv 'q' med min. 2 tegn (søgning) eller mindst én filter (avanceret søgning) |
| 401 | MISSING_API_KEY | Ingen API-nøgle angivet | Tilføj Authorization: Bearer header |
| 401 | INVALID_API_KEY | Ugyldig eller deaktiveret nøgle | Tjek at nøglen er korrekt og aktiv |
| 403 | FORBIDDEN | Adgang nægtet | Din IP eller konto er blokeret – kontakt support |
| 403 | PLAN_UPGRADE_REQUIRED | Funktionen kræver en højere plan | Opgrader din plan – se fejlens 'required_plan' felt |
| 403 | PLAN_NOT_SUPPORTED | Endpoint kræver højere plan | Se endpoint-dokumentationen for plan-krav |
| 404 | NOT_FOUND | Virksomhed ikke fundet | Tjek at CVR-nummeret eksisterer |
| 429 | RATE_LIMIT_EXCEEDED | For mange requests per sekund | Vent og prøv igen (se Retry-After) |
| 429 | MONTHLY_LIMIT_EXCEEDED | Månedlig kvote opbrugt | Opgrader din plan eller vent til næste måned. Response inkluderer 'used' og 'limit' felter. |
| 500 | SERVER_ERROR | Intern serverfejl | Prøv igen om lidt eller kontakt support |
| 400 | INVALID_REQUEST | Ugyldigt request format | Tjek at request body er gyldig JSON |
| 400 | TOO_MANY | For mange CVR-numre i batch-opslag | Reducer antallet – max afhænger af plan (Basis 100, Standard 200, Professionel 500) |
| 400 | INVALID_URL | Ugyldig webhook URL | URL skal bruge HTTPS og må ikke pege på localhost eller private IP'er |
| 403 | PLAN_NOT_ALLOWED | Webhooks er ikke tilgængelige på din plan | Opgrader til Standard eller højere for webhook-adgang |
| 403 | EVENT_NOT_ALLOWED | Hændelsestype ikke tilgængelig på din plan | Opgrader til Professionel for alle hændelsestyper |
| 403 | FILTERS_NOT_ALLOWED | Webhook-filtre kræver Professionel plan | Opgrader til Professionel for filter-support |
| 502 | ERST_ERROR | Fejl ved opslag hos datakilden | Prøv igen om lidt |
| 503 | MAINTENANCE | API er under vedligeholdelse | Prøv igen senere |
AI-integration (MCP)
Brug danske virksomhedsdata direkte i AI-assistenter som Claude Desktop, Claude Code, Cursor og andre MCP-kompatible klienter. Vores MCP-server giver din AI mulighed for at slå virksomheder op, søge og analysere regnskaber.
1. Installer pakken
Kør med din foretrukne package manager:
npm install -g firmaapi-mcp-server # npm
bun add -g firmaapi-mcp-server # bun
pnpm add -g firmaapi-mcp-server # pnpm2. Konfigurer din AI-klient
Claude Desktop
Tilføj til din claude_desktop_config.json:
{
"mcpServers": {
"firmaapi": {
"command": "firmaapi-mcp-server",
"env": {
"FIRMAAPI_KEY": "cvr_live_din_nøgle_her"
}
}
}
}Claude Code
claude mcp add firmaapi -e FIRMAAPI_KEY=cvr_live_... -- firmaapi-mcp-serverCursor
Tilføj til .cursor/mcp.json i dit projekt:
{
"mcpServers": {
"firmaapi": {
"command": "firmaapi-mcp-server",
"env": {
"FIRMAAPI_KEY": "cvr_live_din_nøgle_her"
}
}
}
}3. Brug det
Bed bare din AI om at slå virksomheder op:
"Slå Novo Nordisk op og vis seneste regnskab"
"Find alle IT-virksomheder i Aarhus med over 50 ansatte"
"Hvem ejer CVR 34824770?"
"Søg efter Lars Larsen og vis hans virksomhedstilknytninger"
Tilgængelige MCP-tools (9 stk.)
| Parameter | Type | Beskrivelse |
|---|---|---|
firmaapi_lookup_company | tool | Slå virksomhed op via CVR-nummer med valgfrie ekstrablokke (finance, history, events, production_units, relations). |
firmaapi_search_companies | tool | Søg virksomheder på navn eller nøgleord. |
firmaapi_advanced_search | tool | Avanceret søgning med filtre: by, branche, omsætning, ansatte, status m.m. |
firmaapi_batch_lookup | tool | Batch-opslag af flere CVR-numre på én gang (maks 100). Kræver Basis+. |
firmaapi_get_person | tool | Hent personprofil med alle virksomhedstilknytninger via UUID (Professionel+). |
firmaapi_search_persons | tool | Søg personprofiler på navn (Professionel+). |
firmaapi_production_unit | tool | Slå produktionsenhed op via P-nummer (Standard+). |
firmaapi_industries | tool | Hent branchekoder (DB07) med hierarki og antal virksomheder. |
firmaapi_municipalities | tool | Hent kommuneliste med koder til avanceret søgning. |
Pakken på npm: npmjs.com/package/firmaapi-mcp-server — MCP-serveren bruger din eksisterende API-nøgle og tæller mod din plans kvote.
Webhooks
Modtag automatisk besked når virksomhedsdata ændrer sig. Webhooks sender HTTP POST requests til dit endpoint med signerede payloads.
Tilgængelig fra Standard-planen. Se priser for detaljer.
Webhook-mønstre: enkelt-match og batch
Webhooks er event-drevne. Du kan bruge samme endpoint til både enkelt-match og batch-flow afhængigt af din egen routinglogik.
- Enkelt-match: filtrér i din modtager på
data.company.cvrog send videre til en dedikeret job-kø for det enkelte CVR. - Batch: saml events i vinduer (fx 1-5 min), dedupliker på CVR og kør batch-opslag mod
/api/v1/company/batch.
curl -X POST https://firmaapi.dk/api/v1/company/batch -H "Authorization: Bearer cvr_live_..." -H "Content-Type: application/json" -d '{"cvr_numbers": ["24256790", "19625095", "10940834"]}'Event-typer
| Event | Beskrivelse | Plan |
|---|---|---|
| company.status.changed | Virksomhedens status er ændret | Standard+ |
| company.bankruptcy | Konkurs eller tvangsopløsning | Standard+ |
| company.created | Ny virksomhed registreret | Professionel |
| company.name.changed | Navneændring | Professionel |
| company.address.changed | Adresseændring | Professionel |
| company.participant.changed | Ejere/ledelse ændret | Professionel |
| company.financials.published | Nyt årsregnskab offentliggjort | Professionel |
| company.industry.changed | Branchekode ændret | Professionel |
| company.type.changed | Virksomhedsform ændret | Professionel |
| company.capital.changed | Selskabskapital ændret | Professionel |
Opret webhook
/api/v1/webhookscurl -X POST https://firmaapi.dk/api/v1/webhooks \
-H "Authorization: Bearer din_api_nøgle" \
-H "Content-Type: application/json" \
-d '{
"url": "https://din-server.dk/webhook",
"event_types": ["company.status.changed", "company.bankruptcy"],
"description": "Status-overvågning"
}'Webhook-secret returneres kun ved oprettelse. Gem det sikkert – det bruges til at verificere signaturer.
Payload-format
{
"id": "evt_abc123",
"type": "company.status.changed",
"created_at": "2026-03-15T10:30:00.000Z",
"data": {
"company": {
"cvr": "12345678",
"name": "Firma A/S",
"status": "Under konkurs",
...
},
"changes": {
"status": { "old": "Aktiv", "new": "Under konkurs" }
}
}
}Signaturverifikation
Alle webhook-requests signeres med HMAC-SHA256. Verificér signaturen for at sikre at requesten kommer fra FirmaAPI.
Headers: X-FirmaAPI-Signature, X-FirmaAPI-Timestamp, X-FirmaAPI-Event, X-FirmaAPI-Delivery
const crypto = require("crypto");
function verifySignature(secret, timestamp, body, signature) {
const payload = timestamp + "." + body;
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// I din webhook handler:
app.post("/webhook", (req, res) => {
const sig = req.headers["x-firmaapi-signature"];
const ts = req.headers["x-firmaapi-timestamp"];
const body = JSON.stringify(req.body);
if (!verifySignature(WEBHOOK_SECRET, ts, body, sig)) {
return res.status(401).send("Invalid signature");
}
// Håndtér event
console.log(req.body.type, req.body.data);
res.status(200).send("OK");
});import hmac, hashlib
def verify_signature(secret, timestamp, body, signature):
payload = f"{timestamp}.{body}"
expected = hmac.new(
secret.encode(), payload.encode(), hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
# I din webhook handler (Flask):
@app.route("/webhook", methods=["POST"])
def webhook():
sig = request.headers.get("X-FirmaAPI-Signature")
ts = request.headers.get("X-FirmaAPI-Timestamp")
body = request.get_data(as_text=True)
if not verify_signature(WEBHOOK_SECRET, ts, body, sig):
return "Invalid signature", 401
event = request.get_json()
print(event["type"], event["data"])
return "OK", 200Retry-politik
Hvis dit endpoint returnerer en ikke-2xx status, forsøger vi igen med eksponentiel backoff:
| Forsøg | Ventetid |
|---|---|
| 1. retry | 1 minut |
| 2. retry | 5 minutter |
| 3. retry | 30 minutter |
| 4. retry | 2 timer |
Efter 5 consecutive failures deaktiveres webhooket automatisk. Du kan genaktivere det via API.
Filtre (Professionel)
Med Professionel-planen kan du filtrere events baseret på branchekode og kommunekode:
{
"url": "https://din-server.dk/webhook",
"event_types": ["company.status.changed"],
"filters": {
"industry_codes": ["620100", "620200"],
"municipality_codes": [101, 147]
}
}API-endpoints
| Metode | Endpoint | Beskrivelse |
|---|---|---|
| POST | /api/v1/webhooks | Opret webhook |
| GET | /api/v1/webhooks | List webhooks |
| GET | /api/v1/webhooks/:id | Webhook detaljer |
| PATCH | /api/v1/webhooks/:id | Opdater webhook |
| DELETE | /api/v1/webhooks/:id | Slet webhook |
| GET | /api/v1/webhooks/:id/deliveries | Delivery log |
| POST | /api/v1/webhooks/:id/test | Send test-event |
Kodeeksempler
Komplet eksempler i populære sprog. Kopier og tilpas til dit projekt.
JavaScript / Node.js
// Enkelt CVR-opslag
const response = await fetch("https://firmaapi.dk/api/v1/company/24256790", {
headers: { Authorization: "Bearer cvr_live_din_nøgle" }
});
const company = await response.json();
console.log(company.name); // "Novo Nordisk A/S"
// Søgning
const searchRes = await fetch(
"https://firmaapi.dk/api/v1/company/search?q=novo+nordisk&limit=5",
{ headers: { Authorization: "Bearer cvr_live_din_nøgle" } }
);
const { results } = await searchRes.json();
results.forEach(c => console.log(c.cvr, c.name));
// Batch-opslag
const batchRes = await fetch("https://firmaapi.dk/api/v1/company/batch", {
method: "POST",
headers: {
Authorization: "Bearer cvr_live_din_nøgle",
"Content-Type": "application/json"
},
body: JSON.stringify({ cvr_numbers: ["24256790", "54562519"] })
});
const batch = await batchRes.json();
console.log(batch.results.length, "virksomheder hentet");Python
import requests
API_KEY = "cvr_live_din_nøgle"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# Enkelt CVR-opslag
r = requests.get(
"https://firmaapi.dk/api/v1/company/24256790",
headers=HEADERS
)
company = r.json()
print(company["name"]) # "Novo Nordisk A/S"
# Søgning
r = requests.get(
"https://firmaapi.dk/api/v1/company/search",
params={"q": "novo nordisk", "limit": 5},
headers=HEADERS
)
for c in r.json()["results"]:
print(c["cvr"], c["name"])
# Batch-opslag
r = requests.post(
"https://firmaapi.dk/api/v1/company/batch",
json={"cvr_numbers": ["24256790", "54562519"]},
headers=HEADERS
)
print(f"{r.json()['total']} virksomheder hentet")PHP
<?php
$apiKey = "cvr_live_din_nøgle";
// Enkelt CVR-opslag
$ch = curl_init("https://firmaapi.dk/api/v1/company/24256790");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer $apiKey"],
CURLOPT_RETURNTRANSFER => true,
]);
$company = json_decode(curl_exec($ch), true);
echo $company["name"]; // "Novo Nordisk A/S"
// Batch-opslag
$ch = curl_init("https://firmaapi.dk/api/v1/company/batch");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer $apiKey",
"Content-Type: application/json"
],
CURLOPT_POSTFIELDS => json_encode([
"cvr_numbers" => ["24256790", "54562519"]
]),
CURLOPT_RETURNTRANSFER => true,
]);
$batch = json_decode(curl_exec($ch), true);
echo count($batch["results"]) . " virksomheder hentet";C# / .NET
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Bearer cvr_live_din_nøgle");
// Enkelt CVR-opslag
var response = await client.GetAsync("https://firmaapi.dk/api/v1/company/24256790");
var json = await response.Content.ReadAsStringAsync();
var company = JsonSerializer.Deserialize<JsonElement>(json);
Console.WriteLine(company.GetProperty("name").GetString());
// Batch-opslag
var batchBody = new StringContent(
JsonSerializer.Serialize(new { cvr_numbers = new[] { "24256790", "54562519" } }),
Encoding.UTF8,
"application/json"
);
var batchRes = await client.PostAsync("https://firmaapi.dk/api/v1/company/batch", batchBody);
var batchJson = await batchRes.Content.ReadAsStringAsync();Go
package main
import (
"encoding/json"
"fmt"
"net/http"
"io"
)
func main() {
req, _ := http.NewRequest("GET",
"https://firmaapi.dk/api/v1/company/24256790", nil)
req.Header.Set("Authorization", "Bearer cvr_live_din_nøgle")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var company map[string]interface{}
json.Unmarshal(body, &company)
fmt.Println(company["name"]) // "Novo Nordisk A/S"
}Gratis API-nøgle på 30 sekunder
1.000 opslag/md. Ingen kreditkort.