Fjela
API-dokumentasjon
To endepunkter, én header og et JSON-svar du kan tegne rett på siden.
Kom i gang
Skaff deg en API-nøkkel
Logg inn og lag en på siden for API-nøkler. Du ser den bare én gang, og vi lagrer bare en hash av den, så legg den et trygt sted før du går videre. Nøklene ser slik ut:
fp_live_….Send inn en plantegning i PDF
curl -X POST https://api.fjela.com/api/v1/jobs \ -H "X-API-Key: fp_live_..." \ -F "input_file=@floorplan.pdf" # → {"id": "8a2f3c91-...", "status": "queued", ...}Hent resultatet
curl https://api.fjela.com/api/v1/jobs/8a2f3c91-6b7d-4e12-9f0a-3d5e7c8b1a44 \ -H "X-API-Key: fp_live_..." # Spør på nytt til "status" er "done" eller "failed".Bruk den samme nøkkelen som du sendte inn med – en jobb er bare synlig for nøkkelen som opprettet den. Alt du sender inn, dukker også opp under Jobber, med formene tegnet rett på din egen PDF – ofte den raskeste måten å dobbeltsjekke et svar på.
Autentisering
Hver forespørsel har nøkkelen din med i headeren X-API-Key. Ingen OAuth-dans og ingen tokenbytting – nøkkelen er alt du trenger.
X-API-Key: fp_live_...Hver nøkkel har en fartsgrense – 60 forespørsler i minuttet, med mindre oversikten viser en annen grense ved siden av den – og spørringene teller med, så la det gå noen sekunder mellom hver gang. Trekker du tilbake en nøkkel, gjelder det med én gang.
Endepunkter
| Endepunkt | Innhold | Hva det gjør |
|---|---|---|
POST/api/v1/jobs | multipart/form-data | Send inn en plantegning i PDF som input_file. Du får jobben tilbake med én gang, med status queued. |
GET/api/v1/jobs/{id} | — | Hent én jobb. Spør på nytt til statusen er done eller failed. |
Bare den første siden i en PDF blir lest, men alle sidene i fila teller mot sidekvoten på kontoen din – så send én tegning per fil. Filene kan være på opptil 25 MB.
Jobbstatuser
En jobb går bare én vei: queued → processing → done eller failed.
| Status | Betydning |
|---|---|
| I kø | Mottatt og venter på en ledig maskin. Ingenting er lest ennå. |
| Behandles | Vi jobber med tegningen. Vanligvis under en time, litt lenger når mange tegninger står i kø. |
| Ferdig | result er fylt ut. Her stopper det – du kan slutte å spørre. |
| Feilet | error_message forteller hva som gikk galt. Her stopper det også. |
Feil
Feil kommer tilbake som JSON, med en melding som forteller hva som gikk galt.
| HTTP | Når |
|---|---|
| 400 | Opplastingen ble avvist: ikke en PDF, tom, over 25 MB, passordbeskyttet eller uleselig – eller den ville tatt kontoen over sidekvoten. |
| 401 | Headeren X-API-Key mangler, eller nøkkelen er ukjent eller trukket tilbake. |
| 404 | Ingen slik jobb for denne nøkkelen. En jobb er bare synlig for nøkkelen som sendte den inn. |
| 429 | Over fartsgrensen for nøkkelen. Vent så mange sekunder som Retry-After-headeren sier, og prøv igjen. |
| 503 | Køen var utilgjengelig et øyeblikk. Jobben ble merket som feilet – send den inn på nytt. |
Svaret
En jobb som har nådd status: "done", kortet ned til ett element per liste. En ekte tegning har dusinvis av hver.
{
"id": "8a2f3c91-6b7d-4e12-9f0a-3d5e7c8b1a44",
"status": "done",
"result": {
"engine": "fjela-7d1c43a9",
"pages": 1,
"page_size": { "width": 4961.0, "height": 3508.0 },
"walls": [
{ "id": "wall_000", "polygon": [[1015.0, 1006.2], [1043.1, 1006.6], [1043.9, 952.2], …] }
],
"openings": [
{
"id": "door_000", "kind": "door",
"polygon": [[3214.5, 749.3], [3218.3, 642.5], [3191.1, 641.5], [3187.2, 748.3]],
"hinge": null, "swing_polygon": null, "direction_margin": null
}
],
"labels": [
{
"id": "label_000", "text": "Stue", "kind": "room_name", "score": 0.97,
"polygon": [[612.0, 1104.0], [734.0, 1104.0], [734.0, 1146.0], [612.0, 1146.0]]
}
],
"suggested_scale": { "ratio": "1:100", "denominator": 100, "mm_per_px": 8.466667, "source": "text" },
"wall_graph": {
"version": "2.1.0",
"px_per_m": 118.6111,
"scale_source": "doors",
"polygons": [
{
"id": 0,
"polygon": [[1963.4, 522.4], [1854.2, 520.7], …], "holes": [],
"polygon_m": [[16.5533, -4.4043], [15.6326, -4.39], …], "holes_m": [],
"area_m2": 0.6529
}
],
"openings": [
{
"id": "door_006", "kind": "door", "subkind": null, "score": 0.963, "extent": "measured",
"polygon": [[3192.7, 643.7], [3191.1, 749.2], [3218.9, 749.6], [3220.5, 644.1]],
"polygon_m": [[26.9173, -5.4268], [26.9039, -6.3163], [27.1383, -6.3199], [27.1518, -5.4304]],
"clear_m": 0.89, "depth_m": 0.234, "opening_id": "door_000"
}
],
"orphan_openings": [
{
"kind": "door", "subkind": null, "score": 0.96,
"point": [3287.4, 1625.3], "point_m": [27.7158, -13.7028],
"opening_id": "door_020"
}
],
"stats": { "n_polygons": 43, "wall_area_m2": 55.155, "openings_hosted": 61, "openings_orphaned": 4, … }
}
},
"result_file": "https://…",
"error_message": "",
"created_at": "2026-09-10T18:52:59Z",
"started_at": "2026-09-10T18:53:01Z",
"finished_at": "2026-09-10T19:00:54Z"
}Feltoversikt
| Felt | Betydning |
|---|---|
| status | queued → processing → done eller failed. Spør på nytt til den er en av de to siste. |
| result_file | En signert lenke som varer en kort stund, til resultatet som PDF: siden din med veggene, dørene og vinduene tegnet inn. Hent jobben på nytt for en fersk lenke. null til jobben er ferdig, og i de sjeldne tilfellene der tegningen av den feilet. |
| error_message | Bare fylt ut når status er failed. |
| result.engine | Versjonen som laget resultatet. Den endres når resultatene kan endre seg, så et svar kan spores tilbake til den. |
| result.page_size | Sidens rasterstørrelse i piksler. Alle polygon og point i resultatet bruker denne enheten og dette origo – øverst til venstre, +x mot høyre, +y nedover – så de kan tegnes rett på et bilde av siden i denne størrelsen. |
| result.walls[] | Veggene: hvert polygon er en lukket ring av [x, y]-punkter (det første punktet gjentas ikke). Vil du ha selve planen – vegger med hull og i meter, med åpningene målt inn – bruker du wall_graph. |
| result.openings[] | Alle dører og vinduer som ble funnet. kind er "door" eller "window" (skyvedører regnes som dører), og polygonet er et rektangel med fire hjørner langs veggen. |
| result.openings[].hinge | Sammen med swing_polygon: hvilken vei døra slår – hengselsiden og området dørbladet sveiper over. direction_margin sier hvor tydelig slaget står på tegningen (0 er rent myntkast). Alle tre er null for vinduer, og for dører der slaget ikke lar seg lese. |
| result.labels | Tekst lest av siden – også på skannede tegninger uten tekstlag i PDF-en. kind ("room_name", "area", "scale" eller "other") er et mønstersøk i teksten, og teksten er ikke koblet til et rom. |
| result.suggested_scale | Tegningens målestokk, for eksempel "1:100", lest av tegningens egen tekst (source "text", eller "ocr" på en skann), sjekket mot en ny lesing av tittelfeltet ("llm") og mot selve arket — målsettingene, målestokklinjalen, dørbreddene — og aldri gjettet: alle feltene er null og source er "unknown" når ingenting på tegningen sier noe. confidence er "confirmed" når en måling av arket er enig med den påskrevne målestokken, "read" når ingenting kunne måles, "disputed" når en måling er uenig, og "measured" når målingen har erstattet en påskrevet målestokk som var feil for arket (source "dimensions", "scale_bar" eller "doors"). Når den blir funnet, gjør mm_per_px om en hvilken som helst pikselavstand til millimeter; evidence viser hvert vitne og avgjørelsen. |
| result.wall_graph | Selve planen. polygons er veggene, med vinduer som er tegnet som hel vegg skåret ut, og openings er dørene og vinduene som rektangler målt inn på de veggene, fra karm til karm og like dype som veggen. null når det ikke gikk å lage en plan for tegningen; veggene og åpningene over blir likevel levert. Eldre resultater (versjon 1.x) har en aksegraf (nodes og walls) i stedet – sjekk version. |
| result.wall_graph.px_per_m | Sidepiksler per meter for alle _m-verdier i planen. scale_source sier hvor tallet kommer fra: "doors" (medianen av den frie bredden på tegningens egne dørblad, regnet som 0,9 m – foretrukket, fordi en påskrevet målestokk av og til er feil, mens et dørblad ikke er det), "scale" (den påskrevne målestokken), "walls" (den typiske veggen regnet som 200 mm) eller "none" (ingen vegger og ingen målestokk; planen er tom). |
| result.wall_graph.polygons[] | polygon er den ytre ringen og holes de indre – rommene veggene omslutter – i sidepiksler. polygon_m og holes_m er de samme ringene i meter fra sidens øverste venstre hjørne med y oppover, klare for en CAD-fil, og area_m2 er veggarealet. |
| result.wall_graph.openings[] | kind er "door" eller "window" – eller "opening" for et gap uten dør eller vindu – og en skyvedør har subkind: "slider". clear_m er den frie bredden, depth_m veggtykkelsen der, og opening_id peker tilbake til result.openings. extent sier hvordan bredden ble funnet: measured, fra karm til karm; shared, én av flere åpninger i samme gap (en dør og vinduet ved siden av), hver med sin egen bredde; clamped, et gap bredere enn en slik åpning noen gang er, kuttet ned til vanlig bredde; nominal, én av en rekke som deler et bredt gap, som en glassfasade; eller band, et vindu som er tegnet som hel vegg, skåret ut med sin egen lengde. |
| result.wall_graph.orphan_openings | Dører og vinduer ingen vegg kunne ta imot. De blir levert i stedet for å bli kastet: som regel betyr det at en vegg mangler der. point og point_m gir midtpunktet. |
| result.wall_graph.stats | Tall for et raskt overblikk: n_polygons, wall_area_m2, openings_hosted (også fordelt på extent), openings_orphaned og noen til. |
Et ord om nøyaktighet. Resultatene lages automatisk, ikke for hånd for hver tegning. Regn med at en form i ny og ne havner litt feil eller mangler, særlig på uvanlige tegninger.