{"openapi":"3.1.0","info":{"title":"Storm Pris API Actions","description":"ChatGPT-vennlig OpenAPI-spesifikasjon for prosjektering, pris, eksport og produktsøk. Kun stabile og parser-vennlige objektschemaer er inkludert.","version":"1.0"},"servers":[{"url":"https://api.ekbpro.com"}],"paths":{"/action-probe":{"get":{"summary":"Test actionflyt","description":"Enkel probe som bekrefter at API-et svarer.","operationId":"action_probe_action_probe_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionProbe"}}}}}}},"/action-probe-project":{"post":{"summary":"Test actionflyt med prosjektpayload","description":"Minimalt prosjektkall som bruker samme prosjektmodell som beregning, men bare returnerer en liten JSON-respons.","operationId":"action_probe_project_action_probe_project_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectActionProbe"}}}}}}},"/calculate/summary":{"post":{"summary":"Beregn prosjekt – kompakt sammendrag","description":"Kjører prosjekterings- og prismotoren og returnerer kun nøkkeldata: tilbudspris, stikk/lys per rom, antall kurser, last og eventuelle mangler. Bruk denne i stedet for /calculate for å unngå ResponseTooLarge på store prosjekter. Returnerer ready_for_export=true når prosjektet er klart for eksport.","operationId":"calculate_summary_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Kompakt beregningsresultat","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericObject"}}}}}}},"/project/drafts":{"post":{"summary":"Lagre prosjektutkast","description":"Lagrer et prosjektutkast med prosjekt-ID slik at GUI og ChatGPT kan hente samme prosjekt videre.","operationId":"save_project_draft_project_drafts_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDraftSaveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDraftMeta"}}}}}},"get":{"summary":"List prosjektutkast","description":"Returnerer liste over lagrede prosjektutkast.","operationId":"list_project_drafts","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericObject"}}}}}}},"/project/drafts/{draft_id}":{"get":{"summary":"Hent prosjektutkast","description":"Henter lagret prosjektutkast for videre arbeid i GUI eller ChatGPT.","operationId":"load_project_draft_project_drafts__draft_id__get","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectDraftDocument"}}}}}},"delete":{"summary":"Slett prosjektutkast","operationId":"delete_project_draft","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericObject"}}}}}}},"/design/house-from-text":{"post":{"summary":"Generer prosjektutkast fra tekst","description":"Tar en fritekstbeskrivelse og genererer et prosjektutkast med rom, punkter og priser.","operationId":"design_house_from_text","requestBody":{"required":true,"content":{"application/x-www-form-urlencoded":{"schema":{"type":"object","properties":{"description":{"type":"string"}},"required":["description"]}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCalculationResponse"}}}}}}},"/catalog/search":{"post":{"summary":"Søk produkt og pris for ChatGPT","description":"ChatGPT-vennlig katalogsøk for elnummer, varenummer og navnesøk. Returnerer ett felles responsformat med priser og trefftype.","operationId":"supplier_catalog_search_catalog_search_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierCatalogSearchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SupplierCatalogSearchResponse"}}}}}}},"/export/service-pdf-link":{"post":{"summary":"Eksporter serviceoppdrag som PDF","description":"Genererer et PDF-tilbud for et serviceoppdrag og returnerer en midlertidig nedlastingslenke.","operationId":"export_service_pdf_link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceEstimateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportFileLink"}}}}}}},"/export/pdf-link":{"post":{"summary":"Eksporter tilbud som nedlastingslenke","description":"Returnerer metadata og en midlertidig nedlastingslenke for PDF-filen.","operationId":"export_pdf_link_export_pdf_link_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportFileLink"}}}}}}},"/export/material-list-link":{"post":{"summary":"Eksporter materialliste som nedlastingslenke","description":"Returnerer metadata og en midlertidig nedlastingslenke for Excel-materiallisten.","operationId":"export_material_list_link_export_material_list_link_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportFileLink"}}}}}}},"/export/tavleplan":{"post":{"summary":"Returner tavleplan som JSON","description":"Genererer tavleplan for prosjektet og returnerer JSON-respons.","operationId":"export_tavleplan_export_tavleplan_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericObject"}}}}}}},"/export/plejd-bom":{"post":{"summary":"Returner Plejd-enhetsliste som JSON","description":"Genererer Plejd BOM og returnerer JSON-respons.","operationId":"export_plejd_export_plejd_bom_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericObject"}}}}}}},"/estimate/service/variants":{"get":{"summary":"List materialvarianter for service","description":"Returnerer tilgjengelige materialvarianter for serviceoppdrag (standard, elko, schneider, sg, abb).","operationId":"get_service_variants","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenericObject"}}}}}}},"/estimate/service":{"post":{"summary":"Estimér serviceoppdrag","description":"Calculates price for a service job without room structure. Send a list of work items using field name 'items' (NOT 'tasks') with 'point_code' and 'quantity' (NOT 'qty'). Use for single installations, replacement jobs and small jobs — not for full projects.","operationId":"estimate_service_estimate_service_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceEstimateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceEstimateResponse"}}}}}}},"/export/word-link":{"post":{"summary":"Eksporter tilbud som Word-dokument","description":"Beregner prosjektet og returnerer en midlertidig nedlastingslenke til tilbud i .docx-format. Brukeren kan åpne og redigere dokumentet.","operationId":"export_word_link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Nedlastingslenke til Word-dokument","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportFileLink"}}}}}}},"/export/course-registry-word-link":{"post":{"summary":"Eksporter kursfortegnelse som Word","description":"Beregner prosjektet og returnerer en midlertidig nedlastingslenke til kursfortegnelse i .docx-format. Presenter download_url som klikkbar lenke — ikke kall /downloads/{token}.","operationId":"export_course_registry_word_link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Nedlastingslenke til kursfortegnelse Word-dokument","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportFileLink"}}}}}}},"/export/course-registry-pdf-link":{"post":{"summary":"Eksporter kursfortegnelse som PDF","description":"Beregner prosjektet og returnerer en midlertidig nedlastingslenke til kursfortegnelse (kursliste) i PDF-format. Kursfortegnelsen viser alle kurser med sikringer, kabeltype og lastberegning. Presenter download_url som klikkbar lenke — ikke kall /downloads/{token}.","operationId":"export_course_registry_pdf_link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Nedlastingslenke til kursfortegnelse PDF","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportFileLink"}}}}}}},"/export/course-registry-excel-link":{"post":{"summary":"Eksporter kursfortegnelse som Excel","description":"Beregner prosjektet og returnerer en midlertidig nedlastingslenke til kursfortegnelse i .xlsx-format. Presenter download_url som klikkbar lenke — ikke kall /downloads/{token}.","operationId":"export_course_registry_excel_link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Nedlastingslenke til kursfortegnelse Excel","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportFileLink"}}}}}}},"/ga-generator/export-link":{"post":{"summary":"Generer GA/ETS CSV med nedlastingslenke","description":"Genererer GA/ETS CSV fra opplastet Excel og returnerer en midlertidig nedlastingslenke.","operationId":"ga_generator_export_link","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GAGeneratorRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportFileLink"}}}}}}},"/export/offer-package":{"post":{"summary":"Generer komplett eksportpakke (ett kall)","description":"Beregner prosjektet og genererer alle fire eksportdokumenter i ett kall: tilbud PDF, tilbud Word, materialliste Excel og kursfortegnelse PDF. Returner alle download_url-er som klikkbare lenker. Sjekk warnings — ikke-tom liste betyr at kundeinfo mangler i tilbudsdokumentene.","operationId":"export_offer_package","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectModel"}}}},"responses":{"200":{"description":"Nedlastingslenker til alle fire eksportdokumenter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferPackageLink"}}}}}}}},"components":{"schemas":{"GenericObject":{"type":"object","properties":{},"additionalProperties":true},"ActionProbe":{"type":"object","properties":{"ok":{"type":"boolean"},"message":{"type":"string"},"timestamp":{"type":"integer"}},"required":["ok","message","timestamp"]},"ProjectActionProbe":{"type":"object","properties":{"ok":{"type":"boolean"},"project_name":{"type":"string"},"room_count":{"type":"integer"},"system":{"type":"string"},"sales_markup":{"type":"number"}},"required":["ok","project_name","room_count","system","sales_markup"]},"LightingModel":{"type":"object","properties":{"spots":{"type":"integer","default":0},"lamp_points":{"type":"integer","default":0},"bench_lights":{"type":"integer","default":0}}},"RoomModel":{"type":"object","properties":{"name":{"type":"string"},"floor":{"type":"integer"},"room_type":{"type":"string","enum":["living_room","bedroom","kitchen","office","hallway","bathroom","laundry","storage_room","garage","balcony","technical_room","other"]},"area":{"type":"number"},"cable_run_m":{"type":"number","default":0},"bench_length":{"type":"number","default":0},"free_wall":{"type":"number","default":0},"equipment":{"type":"integer","default":0},"heating":{"type":"boolean","default":false},"thermostat":{"type":"boolean","default":false},"heating_type":{"type":"string","enum":["heating_cable","panel_heater","waterborne_floor","waterborne_radiator","heating_foil","heat_pump"]},"heating_power_w":{"type":"integer","default":0},"motion_sensor":{"type":"boolean","default":false},"temperature_sensor":{"type":"boolean","default":false},"co2_sensor":{"type":"boolean","default":false},"dali":{"type":"boolean","default":false},"audio":{"type":"boolean","default":false},"bathroom_exhaust_fan":{"type":"boolean","default":false,"description":"Sett true for å prise avtrekksvifte med fuktstyring (bad/vaskerom)"},"eating_area":{"type":"boolean","default":false,"description":"Kjøkken har spiseplass – gir ekstra stikkontakter"},"shutters":{"type":"integer","default":0,"description":"Antall persienner/screens i rommet (KNX/Plejd)"},"outlet_override":{"type":"boolean","default":false,"description":"Sett true for å overstyre automatisk stikkontaktberegning med outlet_single/double/quad"},"outlet_single":{"type":"integer","default":0},"outlet_double":{"type":"integer","default":0},"outdoor_outlets":{"type":"integer","default":0,"description":"Antall utendørs stikkontakter (IP44)"},"wireless_switches":{"type":"integer","default":0,"description":"Antall trådløse brytere (Plejd)"},"wireless_rotaries":{"type":"integer","default":0,"description":"Antall trådløse vridimmere (Plejd)"},"special_requirements":{"type":"string","description":"Fritekst for spesielle krav eller merknader til rommet"},"lighting":{"$ref":"#/components/schemas/LightingModel"}},"required":["name","floor","room_type","area"]},"ProjectModel":{"type":"object","properties":{"name":{"type":"string"},"floors":{"type":"integer","default":1},"system":{"type":"string","enum":["conventional","knx","plejd"]},"ruleset":{"type":"string","default":"nek400"},"project_mode":{"type":"string","default":"new_installation"},"sales_markup":{"type":"number","default":1.4},"address":{"type":"string"},"notes":{"type":"string"},"air_to_air_heat_pump_units":{"type":"integer","default":0,"description":"Antall luft-til-luft varmepumper i prosjektet"},"ev_charger_units":{"type":"integer","default":0,"description":"Antall elbilladerinstallasjoner (Zaptec)"},"customer_name":{"type":"string","default":"","description":"Kundens navn (person eller firma) — vises i tilbudsdokument. Spør alltid om dette før eksport av kundetilbud."},"customer_address":{"type":"string","default":"","description":"Kundens postadresse (gateadresse) — vises i tilbudsdokument"},"customer_postal":{"type":"string","default":"","description":"Kundens postnummer og poststed, f.eks. '1184 Oslo' — vises i tilbudsdokument"},"customer_contact":{"type":"string","default":"","description":"Kontaktperson hos kunden — vises i tilbudsdokument"},"rooms":{"type":"array","items":{"$ref":"#/components/schemas/RoomModel"}},"material_map_overrides":{"type":"object","additionalProperties":{"type":"string"},"default":{},"description":"Overstyrer standard produktvalg: punktkode → elnummer. Sett etter /catalog/search og bekreftelse. Eks: {\"double_outlet\": \"1501363\"} for sort finish."}},"required":["name","system","rooms"]},"ProjectCalculationResponse":{"type":"object","properties":{"name":{"type":"string"},"system":{"type":"string"},"offer_price":{"type":"number"},"price_details":{"$ref":"#/components/schemas/GenericObject"}},"required":["name","system","offer_price","price_details"],"additionalProperties":true},"ProjectDraftSaveRequest":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/ProjectModel"},"draft_id":{"type":"string"},"title":{"type":"string"},"source":{"type":"string","default":"gui"}},"required":["project"]},"ProjectDraftMeta":{"type":"object","properties":{"draft_id":{"type":"string"},"title":{"type":"string"},"source":{"type":"string"},"updated_at":{"type":"string"},"api_url":{"type":"string"},"gui_url":{"type":"string"}},"required":["draft_id","title","source","updated_at","api_url","gui_url"]},"ProjectDraftDocument":{"type":"object","properties":{"draft_id":{"type":"string"},"title":{"type":"string"},"source":{"type":"string"},"updated_at":{"type":"string"},"api_url":{"type":"string"},"gui_url":{"type":"string"},"project":{"$ref":"#/components/schemas/ProjectModel"}},"required":["draft_id","title","source","updated_at","api_url","gui_url","project"]},"OfferPackageLink":{"type":"object","description":"Komplett eksportpakke med alle fire dokumenter for et fullprosjekt.","properties":{"offer_pdf":{"$ref":"#/components/schemas/ExportFileLink","description":"Tilbud PDF — sendes til kunden"},"offer_word":{"$ref":"#/components/schemas/ExportFileLink","description":"Tilbud Word (redigerbart) — sendes til kunden"},"material_list_xlsx":{"$ref":"#/components/schemas/ExportFileLink","description":"Materialliste Excel — internt prosjektlederunderlag"},"course_registry_pdf":{"$ref":"#/components/schemas/ExportFileLink","description":"Kursfortegnelse PDF — internt prosjektlederunderlag"},"warnings":{"type":"array","items":{"type":"string"},"default":[],"description":"Advarsler om manglende kundeinfo i tilbudsdokumentene. Tom liste = OK. Informer brukeren og tilby å generere på nytt med manglende info."}},"required":["offer_pdf","offer_word","material_list_xlsx","course_registry_pdf","warnings"]},"ExportFileLink":{"type":"object","properties":{"filename":{"type":"string"},"content_type":{"type":"string"},"size_bytes":{"type":"integer"},"download_url":{"type":"string"},"expires_in_seconds":{"type":"integer"},"warnings":{"type":"array","items":{"type":"string"},"default":[],"description":"Advarsler om manglende data i eksportfilen. Tom liste = ingen advarsler. Ikke-tom liste: informer brukeren og tilby å generere på nytt med manglende info."}},"required":["filename","content_type","size_bytes","download_url","expires_in_seconds"]},"FileUploadPayload":{"type":"object","properties":{"filename":{"type":"string"},"content_type":{"type":"string"},"content_base64":{"type":"string"}},"required":["filename","content_base64"]},"GAGeneratorRequest":{"type":"object","properties":{"file":{"$ref":"#/components/schemas/FileUploadPayload"},"sheet_name":{"type":"string"},"start_row":{"type":"integer","default":7},"end_row":{"type":"integer","default":100},"empty_lines":{"type":"integer","default":1},"output_filename":{"type":"string","default":"ga-export.csv"},"include_all_lights":{"type":"boolean","default":false},"include_all_heat":{"type":"boolean","default":false},"include_aerotemper":{"type":"boolean","default":false},"include_fancoil":{"type":"boolean","default":false},"include_screens":{"type":"boolean","default":false},"include_spjeld":{"type":"boolean","default":false}},"required":["file","sheet_name"]},"ProductPayload":{"type":"object","properties":{},"additionalProperties":true},"CostPayload":{"type":"object","properties":{},"additionalProperties":true},"SupplierCatalogItem":{"type":"object","properties":{"supplier_id":{"type":"string"},"elnummer":{"type":"string"},"vare_no":{"type":"string"},"lookup_key_type":{"type":"string"},"name":{"type":"string"},"brand":{"type":"string"},"purchase_price":{"type":["number","null"]},"list_price":{"type":["number","null"]},"currency":{"type":["string","null"]},"matched_on":{"type":["string","null"]},"product":{"anyOf":[{"$ref":"#/components/schemas/ProductPayload"},{"type":"null"}]},"cost":{"anyOf":[{"$ref":"#/components/schemas/CostPayload"},{"type":"null"}]}},"required":["supplier_id","elnummer","vare_no","lookup_key_type","name","brand","purchase_price","list_price","currency","matched_on","product","cost"]},"SupplierCatalogSearchRequest":{"type":"object","properties":{"query":{"type":"string"},"supplier_id":{"type":"string"},"search_mode":{"type":"string","enum":["auto","elnummer","name"],"default":"auto"},"limit":{"type":"integer","default":10}},"required":["query"]},"SupplierCatalogSearchResponse":{"type":"object","properties":{"query":{"type":"string"},"search_mode":{"type":"string"},"interpreted_mode":{"type":"string"},"count":{"type":"integer"},"exact_match":{"anyOf":[{"$ref":"#/components/schemas/SupplierCatalogItem"},{"type":"null"}]},"items":{"type":"array","items":{"$ref":"#/components/schemas/SupplierCatalogItem"}}},"required":["query","search_mode","interpreted_mode","count","exact_match","items"]},"ServiceWorkItem":{"type":"object","properties":{"point_code":{"type":"string","description":"Point code from active pricebook. Valid codes: double_outlet, single_outlet, outlet_ip44, switch_single, lamp_indoor, spot_ceiling_led, thermostat, heating_cable, panel_heater_800w, panel_heater_1000w, circuit_new_15a, bathroom_fan (standard/billig), bathroom_fan_humidity (fuktstyring), smoke_detector, hot_water_connect, ev_charger_zaptec, travel, rigging. IMPORTANT for heating_cable: quantity is always 1 regardless of floor area — it represents one complete cable job. To find the right cable product, calculate wattage from area (m² × 120–160 W/m²) and search /suppliers/products for the matching cable by wattage."},"quantity":{"type":"integer","description":"Number of units. Field name is 'quantity' (NOT 'qty', NOT 'count', NOT 'antall'). Required."},"description":{"type":"string","description":"Optional free-text description for the customer"}},"required":["point_code","quantity"]},"ServiceEstimateRequest":{"type":"object","properties":{"name":{"type":"string","description":"Name of the service job"},"items":{"type":"array","items":{"$ref":"#/components/schemas/ServiceWorkItem"},"description":"Array of work items. Field name is 'items' (NOT 'tasks', NOT 'work_items', NOT 'punkter'). Each item requires 'point_code' (string) and 'quantity' (integer)."},"sales_markup":{"type":"number","default":1.4,"description":"Markup on material cost (default 1.4 = 40%)"},"role":{"type":"string","default":"electrician","description":"Role to price: electrician, apprentice or engineer"}},"required":["name","items"],"example":{"name":"Testoppdrag","items":[{"point_code":"double_outlet","quantity":3},{"point_code":"switch_single","quantity":2},{"point_code":"spot_ceiling_led","quantity":4}]}},"ServiceEstimateResponse":{"type":"object","properties":{"name":{"type":"string"},"system":{"type":"string"},"role":{"type":"string"},"sales_markup":{"type":"number"},"offer_price":{"type":"number","description":"Total tilbudspris i NOK"},"total_hours":{"type":"number","description":"Sum arbeidstimar"},"material_cost":{"type":"number"},"labour_cost":{"type":"number"},"items":{"type":"array","items":{"$ref":"#/components/schemas/GenericObject"},"description":"Pris per arbeidspost"},"material_diagnostics":{"type":"object","properties":{"unmapped_points":{"type":"array","items":{"type":"string"}},"missing_costs":{"type":"array","items":{"type":"string"}},"has_issues":{"type":"boolean"}}},"pricebook":{"$ref":"#/components/schemas/GenericObject"}}}}}}