For udviklere

Læs din portefølje udefra med en nøgle, du selv udsteder

Ejendomsdrift har et offentligt, versioneret læse-API. Du udsteder selv en nøgle inde i portalen, og den giver adgang til præcis din egen portefølje — boliger, lejemål, frister, sager og listen over dine dokumenter.

Plan

API-adgang er en del af Pro

API-adgang hører til Pro-planen. Er porteføljen bag nøglen ikke på Pro, svarer hvert kald 402 med koden `kraever_pro` og beskeden "API-adgang kræver Pro-planen."

I prøveperioden er API'et åbent. En ny konto har 14 dage med hele produktet uden at vælge en plan, og vælges der plan, følger der 14 dage med. Begge dele giver adgang til API'et på præcis samme vilkår som resten af Pro — en prøve på halve funktioner beviser ingenting.

Nedgraderes planen, sker der intet ved nøglerne. De slettes ikke, de tilbagekaldes ikke, og de virker igen i samme sekund, planen er Pro igen. Det eneste, der ændrer sig, er svaret på kaldet.

Tilbagekaldelse virker altid. Uanset plan, uanset prøvestatus og uanset om abonnementet er ophørt, kan du lukke en nøgle inde i portalen. En lækket nøgle må aldrig kunne holdes i live af en betalingsmur.

Kom i gang

Sådan får du en nøgle

Alt er læsning. Der er ingen endpoints i version 1, der kan rette eller slette noget, og der er ingen vej til selve filerne i dokumentarkivet.

  1. 1. Log ind i portalen

    Nøgler hører til en konto. Har du ikke en, skal du oprette en først — der er ingen anonym adgang til API'et.

  2. 2. Gå til Adgang → API-adgang

    Afsnittet står under de delte adgange, på den samme fane. Klik på "Opret nøgle" og giv den et navn, du kan kende den på.

  3. 3. Kopiér nøglen med det samme

    Nøglen vises én gang. Vi gemmer kun et aftryk af den, så hverken vi eller et databaseudtræk kan finde den frem senere. Mister du den, tilbagekalder du den og laver en ny.

  4. 4. Send den som et Bearer-hoved

    Aldrig i adresselinjen. En nøgle i en URL havner i serverlogs, i browserhistorik og i enhver proxy undervejs — et Authorization-hoved gør ikke.

Første kald
curl -H "Authorization: Bearer edk_din_noegle_her" \
  https://ejendomsdrift.dk/api/v1/mig

Basisadressen er https://ejendomsdrift.dk/api/v1. Versionen står i stien, og alle svar er JSON.

Endpoints

De 7 adresser

Alle er GET, og alle kræver en nøgle. Der er ingen skrive-endpoints i version 1.

Udlejeren bag nøglen

GET /api/v1/mig

Det første kald, en klient bør lave. Den svarer på, hvilken portefølje nøglen giver adgang til — og gør det muligt at fejlsøge en forkert nøgle uden at gætte ud fra tomme lister.

Felter
  • idPorteføljens id. Den samme værdi bag hvert eneste kald med denne nøgle.
  • navnUdlejerens navn, som det står på kontoen.
  • virksomhed_navnVirksomhedens navn, hvis der er sat et. Ellers tom.
  • cvrCVR-nummer, hvis der er sat et. Ellers tom.
  • planAbonnementets plan: "basis" eller "pro". Tom, hvis der ikke er valgt en.
  • plan_navnPlanens navn på dansk, som kunden ser det.
  • abonnement_statusAbonnementets tilstand, som den står på kontoen.
  • oprettet_atHvornår porteføljen blev oprettet.
Eksempelsvar
{
  "data": {
    "id": "9f2c1b7e-4a63-4d5e-9a10-2f7c3b8d6e41",
    "navn": "Mette Holm",
    "virksomhed_navn": "Holm Udlejning ApS",
    "cvr": "12345678",
    "plan": "pro",
    "plan_navn": "Pro",
    "abonnement_status": "aktiv",
    "oprettet_at": "2026-03-14T09:12:44.000Z"
  },
  "next_cursor": null
}
Boliger

GET /api/v1/boliger

Boligerne, sorteret efter hvornår de blev oprettet — ældste først. Eksempel-boliger (dem, portalen kan lægge ind med ét klik) er IKKE med: de er en rundvisning, ikke en portefølje.

Felter
  • idBoligens id. Brug det på /api/v1/boliger/{id}.
  • adresseGade og husnummer.
  • postnrPostnummer.
  • byBy.
  • boligtypeBoligens type, hvis den er sat.
  • m2Boligareal i kvadratmeter.
  • vaerelserAntal værelser.
  • byggeaarOpførelsesår.
  • energimaerkeEnergimærke, hvis det er sat.
  • statusBoligens tilstand i porteføljen (fx udlejet, ledig).
  • indkoebsprisKøbesum i kroner.
  • estimat_nuSeneste værdiansættelse i kroner, hvis der er sat en.
  • leje_pr_mdMånedsleje i kroner, som den står på boligen.
  • lejestartDatoen for lejemålets start, hvis den er sat på boligen.
  • leje_depositumDepositum i kroner, som det står på boligen.
  • oprettet_atHvornår boligen blev lagt ind.
Eksempelsvar
{
  "data": [
    {
      "id": "3b6c9a12-77de-4f01-8b2a-5c9e0d41a778",
      "adresse": "Nørrebrogade 42, 3. th.",
      "postnr": "2200",
      "by": "København N",
      "boligtype": "lejlighed",
      "m2": 78,
      "vaerelser": 3,
      "byggeaar": 1932,
      "energimaerke": "D",
      "status": "udlejet",
      "indkoebspris": 3450000,
      "estimat_nu": 3900000,
      "leje_pr_md": 11200,
      "lejestart": "2024-08-01",
      "leje_depositum": 33600,
      "oprettet_at": "2026-03-14T09:31:02.000Z"
    }
  ],
  "next_cursor": null
}
Én bolig

GET /api/v1/boliger/{id}

Samme felter som listen. Svarer 404, hvis boligen ikke findes i den portefølje, nøglen hører til — også hvis den findes i en anden. De to skelnes ikke.

Felter
  • idBoligens id. Brug det på /api/v1/boliger/{id}.
  • adresseGade og husnummer.
  • postnrPostnummer.
  • byBy.
  • boligtypeBoligens type, hvis den er sat.
  • m2Boligareal i kvadratmeter.
  • vaerelserAntal værelser.
  • byggeaarOpførelsesår.
  • energimaerkeEnergimærke, hvis det er sat.
  • statusBoligens tilstand i porteføljen (fx udlejet, ledig).
  • indkoebsprisKøbesum i kroner.
  • estimat_nuSeneste værdiansættelse i kroner, hvis der er sat en.
  • leje_pr_mdMånedsleje i kroner, som den står på boligen.
  • lejestartDatoen for lejemålets start, hvis den er sat på boligen.
  • leje_depositumDepositum i kroner, som det står på boligen.
  • oprettet_atHvornår boligen blev lagt ind.
Eksempelsvar
{
  "data": {
    "id": "3b6c9a12-77de-4f01-8b2a-5c9e0d41a778",
    "adresse": "Nørrebrogade 42, 3. th.",
    "postnr": "2200",
    "by": "København N",
    "boligtype": "lejlighed",
    "m2": 78,
    "vaerelser": 3,
    "byggeaar": 1932,
    "energimaerke": "D",
    "status": "udlejet",
    "indkoebspris": 3450000,
    "estimat_nu": 3900000,
    "leje_pr_md": 11200,
    "lejestart": "2024-08-01",
    "leje_depositum": 33600,
    "oprettet_at": "2026-03-14T09:31:02.000Z"
  },
  "next_cursor": null
}
Lejemål

GET /api/v1/lejemaal

Kontrakterne på tværs af porteføljen, nyeste først. ⚠ Svaret bærer lejerens navn, e-mail og telefon. Det er personoplysninger, du som udlejer er dataansvarlig for — se sikkerhedsafsnittet.

Felter
  • idKontraktens id.
  • bolig_refBoligens id. Slå den op på /api/v1/boliger/{id}.
  • lejer_navnLejerens navn.
  • lejer_emailLejerens e-mail.
  • lejer_telefonLejerens telefonnummer.
  • start_datoLejemålets start.
  • ophoer_datoAftalt ophør, hvis lejemålet er tidsbegrænset. Ellers tom.
  • opsigelsesvarsel_mdrLejerens opsigelsesvarsel i måneder.
  • maanedslejeMånedsleje i kroner.
  • depositum_mdrDepositum, angivet i antal måneders leje.
  • forudbetalt_mdrForudbetalt leje, angivet i antal måneders leje.
  • reguleringReguleringsform, som den står i kontrakten.
  • naeste_reguleringNæste reguleringsdato, hvis der er sat en.
  • husdyr_tilladtOm husdyr er tilladt.
  • statusKontraktens tilstand (fx aktiv, ophørt).
  • oprettet_atHvornår kontrakten blev lagt ind.
Eksempelsvar
{
  "data": [
    {
      "id": "d1a4f8c3-2b90-4e77-a5f1-6c88b0e2d934",
      "bolig_ref": "3b6c9a12-77de-4f01-8b2a-5c9e0d41a778",
      "lejer_navn": "Jonas Bech",
      "lejer_email": "jonas.bech@example.dk",
      "lejer_telefon": "+45 20 11 22 33",
      "start_dato": "2024-08-01",
      "ophoer_dato": null,
      "opsigelsesvarsel_mdr": 3,
      "maanedsleje": 11200,
      "depositum_mdr": 3,
      "forudbetalt_mdr": 1,
      "regulering": "npi",
      "naeste_regulering": "2027-01-01",
      "husdyr_tilladt": false,
      "status": "aktiv",
      "oprettet_at": "2026-03-14T09:44:10.000Z"
    }
  ],
  "next_cursor": null
}
Frister

GET /api/v1/frister

De næste 365 dages hændelser, tidligste først: kontraktstart og -ophør, opsigelsesfrister, reguleringsdatoer, afdragsfrihedens udløb og vurderingernes årsdage. ⚠ Fristerne GEMMES ikke noget sted — de udledes af kontrakter, lån og vurderinger, hver gang du spørger. Retter du kilden, flytter fristen sig.

Felter
  • idFristens id: kildens id og fristens art, adskilt af et kolon (fx "…:ophoer"). Det er stabilt, så længe kilden er uændret — men det er IKKE en databasenøgle, og der findes ikke et endpoint at slå det op på.
  • datoDatoen, fristen falder på.
  • typeFristens art (fx ophoer, opsigelsesfrist, regulering).
  • titelFristen skrevet på dansk, som den står i kalenderen.
  • tekstFristens underlinje — som regel boligens adresse.
  • bolig_refBoligen, fristen hører til, hvis den hører til én. Ellers tom.
Eksempelsvar
{
  "data": [
    {
      "id": "d1a4f8c3-2b90-4e77-a5f1-6c88b0e2d934:ophoer",
      "dato": "2026-11-30",
      "type": "ophoer",
      "titel": "Lejemålet ophører",
      "tekst": "Nørrebrogade 42, 3. th.",
      "bolig_ref": "3b6c9a12-77de-4f01-8b2a-5c9e0d41a778"
    }
  ],
  "next_cursor": null
}
Sager

GET /api/v1/sager

Sagerne på tværs af porteføljen, nyeste først. ⚠ Sagens fritekst-beskrivelse er IKKE med — se sikkerhedsafsnittet om fritekstfelter.

Felter
  • idSagens id.
  • bolig_refBoligen, sagen hører til.
  • titelSagens overskrift.
  • statusSagens tilstand (fx aaben, loest).
  • prioritetSagens prioritet.
  • oprettet_atHvornår sagen blev oprettet.
  • afsluttet_atHvornår sagen blev lukket. Tom, så længe den er åben.
Eksempelsvar
{
  "data": [
    {
      "id": "7c2e0b41-9d33-4a58-b6f2-1e4c7a90d215",
      "bolig_ref": "3b6c9a12-77de-4f01-8b2a-5c9e0d41a778",
      "titel": "Utæt vandhane i køkkenet",
      "status": "aaben",
      "prioritet": "normal",
      "oprettet_at": "2026-08-19T07:02:55.000Z",
      "afsluttet_at": null
    }
  ],
  "next_cursor": null
}
Dokumenter

GET /api/v1/dokumenter

Hvad der ligger i arkivet: titel, kategori, filnavn, størrelse og type. ⚠ Der er INGEN vej til filens indhold gennem dette API og ingen download-adresse i svaret. Filerne hentes i portalen, hvor hver enkelt hentning kræver et login og et signeret link.

Felter
  • idDokumentets id.
  • bolig_refBoligen, dokumentet hører til, hvis det hører til én.
  • kontrakt_refKontrakten, dokumentet hører til, hvis det hører til én.
  • titelDokumentets titel.
  • kategoriDokumentets kategori.
  • filnavnFilens navn.
  • stoerrelse_bytesFilens størrelse i bytes.
  • mimeFilens type (MIME).
  • oprettet_atHvornår dokumentet blev lagt ind.
Eksempelsvar
{
  "data": [
    {
      "id": "b8f30c17-5e42-4d19-92a7-0af6c3e18b55",
      "bolig_ref": "3b6c9a12-77de-4f01-8b2a-5c9e0d41a778",
      "kontrakt_ref": "d1a4f8c3-2b90-4e77-a5f1-6c88b0e2d934",
      "titel": "Lejekontrakt A10",
      "kategori": "kontrakt",
      "filnavn": "lejekontrakt-a10.pdf",
      "stoerrelse_bytes": 184320,
      "mime": "application/pdf",
      "oprettet_at": "2026-03-14T09:52:31.000Z"
    }
  ],
  "next_cursor": null
}
Praktik

Paginering

  • Listerne leverer 50 rækker som udgangspunkt. Sæt `limit` for at få flere eller færre — højst 100. En større værdi klippes stille ned; svaret bærer selv, hvad du fik.

  • Er der mere, bærer svaret en `next_cursor`. Send den tilbage som `cursor` for at få næste side. Er der ikke mere, er den `null` — den er aldrig sat på den sidste side, så du skal ikke hente en tom side for at opdage, at du er færdig.

  • Markøren er uigennemsigtig. Læs den ikke, gem den ikke længere end til næste kald, og byg ikke logik på dens indhold: den peger på en række, ikke på et tal, netop så en ny bolig ikke får dig til at springe en over.

  • Er markøren forvansket, eller er dens række slettet imens, svarer API'et 400 med `ugyldig_markoer`. Start listen forfra frem for at fortsætte fra et ukendt sted.

Næste side
curl -H "Authorization: Bearer edk_din_noegle_her" \
  "https://ejendomsdrift.dk/api/v1/boliger?limit=25&cursor=NGY4YzJi…"

Kvote

  • 600 kald i timen pr. nøgle.

  • Hvert svar bærer `X-RateLimit-Remaining`, `X-RateLimit-Limit` og `X-RateLimit-Reset` — også de gode svar, så du kan se forbruget løbe ned, før du bliver standset.

  • Bliver du standset, er svaret 429 `for_mange_kald` med et `Retry-After`-hoved i sekunder.

  • Tælleren kører i hukommelsen på den enkelte serverinstans. Det er et værn mod en løbsk klient, ikke en afregningsgrænse — og det betyder, at det samlede antal i praksis kan blive lidt højere end tallet ovenfor. Byg ikke noget, der regner med at få mere end kvoten.

Fejl

Går noget galt, er svaret aldrig en halv liste. Det er et objekt med præcis ét felt, og statuskoden siger det samme som koden i det:

{
  "error": {
    "code": "ugyldig_noegle",
    "message": "Nøglen er ikke gyldig."
  }
}

Forgren på `code`, ikke på teksten. Teksten er dansk og skrevet til et menneske, der fejlsøger — den kan blive omformuleret. Koden bliver stående.

Sikkerhed

Hvad nøglen kan, og hvad den aldrig kan

Nøglen kan
  • Læse boliger, lejemål, frister, sager, dokumentliste og kontoens eget stamkort.
  • Kun i den ene portefølje, nøglen blev udstedt til. Hvert opslag filtreres på udlejeren, uanset hvad kaldet beder om.
Nøglen kan aldrig
  • Skrive, rette eller slette noget. Der findes ingen POST, PATCH eller DELETE i version 1.
  • Hente selve filerne i dokumentarkivet. /dokumenter leverer metadata — titel, kategori, filnavn, størrelse, type — og der er hverken en sti eller en download-adresse i svaret.
  • Se abonnement, betalinger eller andre nøgler.
  • Oprette flere nøgler. Det kræver et login i portalen.
  • Findes en ressource i en ANDEN portefølje, svarer API'et 404 — det samme som hvis den slet ikke fandtes. En forskel dér ville gøre det muligt at kortlægge, hvilke id'er der findes i huset.

  • En ukendt og en tilbagekaldt nøgle giver begge 401 med den samme besked, af samme grund.

  • Tilbagekaldelsen virker med det samme. Der er ingen cache mellem knappen og opslaget.

Lejernes oplysninger. Lejemålene bærer lejerens navn, e-mail og telefon. Det er personoplysninger, udlejeren er dataansvarlig for. Den, der udsteder nøglen, træffer beslutningen om at dele dem — og kan tilbagekalde den igen når som helst.

På udlejerens vegne

AI-assistenter

API'et er et almindeligt HTTP-API med en Bearer-nøgle og en OpenAPI 3.1-beskrivelse. En ekstern AI-assistent kan derfor arbejde på udlejerens vegne med udlejerens egen nøgle — læse porteføljen, holde øje med frister, svare på spørgsmål om lejemålene — uden at nogen skal dele et login.

Vi har ikke en færdig integration til en bestemt assistent, og der er ikke noget, der skal godkendes hos os. Der er en nøgle og en beskrivelse; resten er op til den, der bygger.

Assistenten kan ikke ændre noget. Det er værd at sige højt, fordi det er dét, der gør adgangen forsvarlig at give: det værste, en fejl i en klient kan gøre, er at læse for meget — ikke at rette i en kontrakt.

Version 1 og fremad

Versionen står i stien. Skal vi en dag ændre noget, der ville brække en klient, bliver det /api/v2, og v1 bliver stående.

Version 1 er ren læsning. Skrivning og webhooks er noget, vi gerne vil bygge — men der er ikke sat en dato på, og der er ikke lovet nogen noget. Bygger du på API'et og mangler en bestemt vej, så skriv til os: det er den slags, der afgør rækkefølgen.