{
  "schema_version": 2,
  "language": "sv",
  "kind": "account-bound-product-api",
  "verified_at": "2026-09-10",
  "description": "Ett granskat urval av BIMR:s befintliga produkt-API. Åtkomst med användarsession och kontots behörigheter. Ingen separat API-nyckel eller utfästelse om versionsstabilitet.",
  "statuses": {
    "read": "Alla kontoroller",
    "act": "Utförare och uppåt",
    "manage": "Förvaltare och ägare",
    "token": "Avgränsad länk"
  },
  "families": [
    {
      "id": "portfolio",
      "title": "Hela fastighetsbeståndet",
      "summary": "Byggnader, modellfiler och uppgifter med samma identitet genom hela flödet.",
      "audience": "Fastighetsägare, förvaltare och systemintegratörer",
      "dependency": "Läsningen följer kontot. Modellbiblioteket kan även innehålla märkta exempelbyggnader. Registeruppgifter har sina egna källor och villkor.",
      "endpoints": [
        {
          "method": "GET",
          "path": "/api/projects",
          "name": "Lista byggnader och modellfiler",
          "status": "read",
          "result": "Byggnads-ID, namn, ägarkoppling och modeller med status och antal element. Exempelbyggnader anges med is_sample.",
          "input": "Ingen frågekropp. Svaret är {projects:[…]}; listan har ingen sidindelning.",
          "handler": "withTenant"
        },
        {
          "method": "GET",
          "path": "/api/properties",
          "name": "Läs fastighetsregistret",
          "status": "read",
          "result": "Kontots byggnader och registrerade fastighetsuppgifter, även när en 3D-modell saknas.",
          "input": "Ingen frågekropp. Skilj saknade uppgifter från värdet noll.",
          "handler": "withTenant"
        },
        {
          "method": "GET",
          "path": "/api/properties/:id/facts",
          "name": "Hämta byggnadens underlag",
          "status": "read",
          "result": "Registrerade fakta och underlag för den valda byggnaden.",
          "input": "id är byggnadens UUID. Registeruppgifter beror på tillgängligt underlag.",
          "handler": "withTenant"
        },
        {
          "method": "PATCH",
          "path": "/api/properties/:id",
          "name": "Uppdatera byggnadens uppgifter",
          "status": "manage",
          "result": "Ändrar tillåtna uppgifter på kontots befintliga byggnad.",
          "input": "Byggnads-ID och JSON med de fält som ska ändras. Behåll byggnadens ID när adressen kompletteras.",
          "handler": "canManage"
        },
        {
          "method": "GET",
          "path": "/api/karta",
          "name": "Läs beståndets lägesbild",
          "status": "read",
          "result": "Byggnader, placering och behov av uppmärksamhet från samma underlag som BIMR:s karta.",
          "input": "Ingen frågekropp. Byggnader utan koordinater hanteras som oplacerade.",
          "handler": "withTenant"
        }
      ]
    },
    {
      "id": "documents",
      "title": "Från pärm till byggnadsunderlag",
      "summary": "Dokument, ritningar och anteckningar kopplas till rätt byggnad.",
      "audience": "Fastighetsägare, förvaltare och systemintegratörer",
      "dependency": "Inläsningen kan skapa uppgifter, datum och utkast enligt kontots styrning. En mottagen fil är inte en garanti för att alla sidor kunnat tolkas.",
      "endpoints": [
        {
          "method": "POST",
          "path": "/api/documents",
          "name": "Lämna dokument till inläsningen",
          "status": "act",
          "result": "Läser och registrerar dokumentet med lässtatus och byggnadskoppling.",
          "input": "multipart: file och valfritt project_id. JSON-anteckning: name, content och project_id. PDF/bild kan ange allow_ai=false för att avstå AI-läsning av skannat innehåll. Ljud har en separat transkriptionsväg.",
          "handler": "canActPooled"
        },
        {
          "method": "GET",
          "path": "/api/documents",
          "name": "Lista dokument och lässtatus",
          "status": "read",
          "result": "Dokumentnamn, typ, datum, byggnad, antal sidor, läsmetod och status.",
          "input": "limit 1–200, standard 100; offset från 0. Svaret innehåller documents, total, limit, offset och has_more.",
          "handler": "withTenant"
        },
        {
          "method": "PATCH",
          "path": "/api/documents/:id",
          "name": "Koppla dokumentet till rätt byggnad",
          "status": "act",
          "result": "Uppdaterar byggnadskopplingen och låter dokumentets uppgifter följa byggnaden.",
          "input": "JSON: {project_id}. Både dokument och målbyggnad måste tillhöra kontot.",
          "handler": "canAct"
        },
        {
          "method": "GET",
          "path": "/api/documents/:id/file",
          "name": "Öppna originalet",
          "status": "read",
          "result": "Originalfilens bytes med filens innehållstyp.",
          "input": "Dokument-ID och Bearer-session. Filen är inte en publik nedladdning.",
          "handler": "custom-session"
        },
        {
          "method": "GET",
          "path": "/api/documents/cost",
          "name": "Läs uppmätt inläsningskostnad",
          "status": "read",
          "result": "Kontots egen historik för AI-läsning, till underlag för ett större dokumentintag.",
          "input": "Ingen frågekropp. Utan historik saknas ett uppmätt genomsnitt.",
          "handler": "withTenant"
        }
      ]
    },
    {
      "id": "models",
      "title": "Modeller och byggnadsdelar",
      "summary": "IFC in, läsbara modellfiler ut och markeringar som följer rätt element.",
      "audience": "Fastighetsägare, förvaltare och systemintegratörer",
      "dependency": "Modellnedladdningen ger Fragments, inte IFC-export. V-BIM:s ritningstolkning och IFC-generering sker i appens modelleringsflöde och har ingen fristående konverteringsrutt i detta API.",
      "endpoints": [
        {
          "method": "POST",
          "path": "/api/upload",
          "name": "Läs in en IFC-modell",
          "status": "manage",
          "result": "Konverterar och registrerar en modell för byggnaden. Modellstatus läses via /api/projects.",
          "input": "multipart: file, project eller project_id. Standardgräns 250 MiB, serverkonfigurerbar. Två samtidiga inläsningar som standard; upptagen server svarar 503.",
          "handler": "custom-manage"
        },
        {
          "method": "GET",
          "path": "/api/models/:id/frag",
          "name": "Hämta modellens visningsfil",
          "status": "read",
          "result": "Binär Fragments-fil för modellvisning.",
          "input": "Modellens UUID och Bearer-session. En giltig delningslänk kan också ge tillgång till sin modell via ?s=token.",
          "handler": "custom-model"
        },
        {
          "method": "GET",
          "path": "/api/markups",
          "name": "Läs sparade markeringar",
          "status": "read",
          "result": "Namngivna urval av modellens byggnadsdelar.",
          "input": "Ingen frågekropp. Svaret är {markups:[…]}.",
          "handler": "withTenant"
        },
        {
          "method": "POST",
          "path": "/api/markups",
          "name": "Spara ett urval av byggnadsdelar",
          "status": "act",
          "result": "Sparar en markering och returnerar dess id.",
          "input": "JSON: name och element_map. Kartan använder modellnamn och modellens verkliga lokala element-ID:n.",
          "handler": "canAct"
        }
      ]
    },
    {
      "id": "operations",
      "title": "Datum, ärenden och byggnadens historia",
      "summary": "Följ arbetet från beståndets kalender till den enskilda byggnaden.",
      "audience": "Fastighetsägare, förvaltare och systemintegratörer",
      "dependency": "Planerat arbete är skilt från utfört arbete. Datum och historik behåller sitt underlag; ett AI-utkast är inte en mänsklig bekräftelse.",
      "endpoints": [
        {
          "method": "GET",
          "path": "/api/agenda",
          "name": "Läs vad som behöver uppmärksamhet",
          "status": "read",
          "result": "Beståndets prioriterade agenda från registrerade datum och ärenden.",
          "input": "Ingen frågekropp. Agendan är ett begränsat urval, inte en fullständig export.",
          "handler": "withTenant"
        },
        {
          "method": "GET",
          "path": "/api/kalender",
          "name": "Hämta kalenderns underlag",
          "status": "read",
          "result": "Registrerade skyldigheter, utförda åtgärder, byggnader och intervallkatalog.",
          "input": "Svaret innehåller obligations, actions, buildings och catalog. Bokade ärenden hämtas separat via /api/jobs.",
          "handler": "withTenant"
        },
        {
          "method": "GET",
          "path": "/api/projects/:id/actions",
          "name": "Läs byggnadens historia",
          "status": "read",
          "result": "Åtgärder med ankare och underlag för vald byggnad.",
          "input": "Byggnadens UUID. Behåll source, status och date_precision när historiken visas.",
          "handler": "withTenant"
        },
        {
          "method": "GET",
          "path": "/api/jobs",
          "name": "Läs ärenden och arbetsorder",
          "status": "read",
          "result": "Kontots ärenden med status och registrerade bokningar.",
          "input": "Ingen frågekropp. Svaret är {jobs:[…]}.",
          "handler": "withTenant"
        },
        {
          "method": "POST",
          "path": "/api/arenden",
          "name": "Registrera ett ärende",
          "status": "act",
          "result": "Skapar ett öppet ärende på vald byggnad.",
          "input": "JSON med title och project_id; beskrivning och ankare kan knyta ärendet till platsen.",
          "handler": "canAct"
        },
        {
          "method": "POST",
          "path": "/api/jobs/:id/schedule",
          "name": "Boka tid för ett ärende",
          "status": "act",
          "result": "Sparar ärendets planerade tid.",
          "input": "JSON: scheduled_at. Bokningen ändrar inte ett registrerat besiktningskrav.",
          "handler": "canAct"
        }
      ]
    },
    {
      "id": "energy",
      "title": "Förbrukning genom hela beståndet",
      "summary": "Månadsavläsningar och byggnadsvisa överblickar med beräkningsgrund.",
      "audience": "Fastighetsägare, förvaltare och systemintegratörer",
      "dependency": "Årsjämförelser kräver tillräckliga avläsningar. Väderkorrigering beror på station och underlag. Bevara källor och markeringar för uppskattade värden.",
      "endpoints": [
        {
          "method": "GET",
          "path": "/api/forbrukning",
          "name": "Läs beståndets förbrukning",
          "status": "read",
          "result": "Sammanställning över kontots byggnader för valt år.",
          "input": "?year=2025. År 2000–2100 accepteras; saknat eller ogiltigt år använder innevarande år.",
          "handler": "withTenant"
        },
        {
          "method": "GET",
          "path": "/api/forbrukning/:projectId",
          "name": "Följ en byggnads energianvändning",
          "status": "read",
          "result": "Byggnadens serier och överblick med underlag för beräkningarna.",
          "input": "Byggnadens UUID och valfritt ?year=2025.",
          "handler": "withTenant"
        },
        {
          "method": "POST",
          "path": "/api/forbrukning/import",
          "name": "Läs in en förbrukningstabell",
          "status": "act",
          "result": "Tolkar tabellen och visar vad som kan registreras. Förhandsgranskning är standard.",
          "input": "JSON: text, valfritt project_id och formatinställningar. dryRun måste uttryckligen vara false för att spara.",
          "handler": "canAct"
        }
      ]
    },
    {
      "id": "assistant",
      "title": "Frågor som når ända in i modellen",
      "summary": "Byggnadens underlag och modellens verkliga element möter samma assistent.",
      "audience": "Fastighetsägare, förvaltare och systemintegratörer",
      "dependency": "Ett AI-svar kan innehålla verktygsåtgärder. Vyn måste genomföra och kvittera en visningsåtgärd. En fristående HTTP-klient får ingen 3D-vy bara genom svaret.",
      "endpoints": [
        {
          "method": "POST",
          "path": "/api/chat",
          "name": "Fråga byggnaden och styr en ansluten vy",
          "status": "read",
          "result": "Svarstext och åtgärder. Behörighet och aktiv yta avgör vilka verktyg assistenten får använda.",
          "input": "JSON: messages, valfritt house, surface, loaded, selection och viewer.capabilities. explode drar isär våningar i vyn. Kontots roll begränsar skrivverktyg; chat är inte en generell read-only-rutt.",
          "handler": "withTenantPooled"
        }
      ]
    },
    {
      "id": "sharing",
      "title": "Överlämningar med avgränsad åtkomst",
      "summary": "Visa utvalda byggnadsdelar och prenumerera på kalendern genom återkallbara länkar.",
      "audience": "Fastighetsägare, förvaltare och systemintegratörer",
      "dependency": "Länken är en behörighet. Skydda den som en hemlighet. En modellfil kan innehålla mer än de visuellt markerade delarna.",
      "endpoints": [
        {
          "method": "POST",
          "path": "/api/markups/:id/share",
          "name": "Skapa en modellänk",
          "status": "act",
          "result": "En tidsbegränsad länk för markeringen och tillhörande modeller.",
          "input": "Markeringens id. Valfri JSON: label och days. Returnerar en länk, inte ett automatiskt e-postutskick.",
          "handler": "canAct"
        },
        {
          "method": "GET",
          "path": "/api/share/:token",
          "name": "Öppna en delad markering",
          "status": "token",
          "result": "Underlaget som den giltiga delningslänken ger åtkomst till.",
          "input": "Länkens token. Kontosession behövs inte; utgången eller återkallad länk ger ingen åtkomst.",
          "handler": "custom-share"
        },
        {
          "method": "DELETE",
          "path": "/api/shares/:id",
          "name": "Återkalla en modellänk",
          "status": "act",
          "result": "Stänger länken för fortsatta läsningar.",
          "input": "Länkens id, inte dess hemliga token. Redan nedladdade filer återkallas inte.",
          "handler": "canAct"
        },
        {
          "method": "POST",
          "path": "/api/kalender/ics",
          "name": "Skapa en kalenderprenumeration",
          "status": "act",
          "result": "En tidsbegränsad kalenderlänk för hela kontots kalender.",
          "input": "Valfri JSON: label. Giltighet 365 dagar. Använd länken som returneras; den omfattar kontot, inte en valfri byggnad.",
          "handler": "canAct"
        },
        {
          "method": "GET",
          "path": "/api/kalender.ics",
          "name": "Hämta kalendern som ICS",
          "status": "token",
          "result": "Kalenderdata i text/calendar för prenumerationen.",
          "input": "Använd hela länken från /api/kalender/ics. Länkens token ersätter kontosessionen.",
          "handler": "custom-calendar"
        }
      ]
    }
  ]
}
