{"components":{"schemas":{"Analysis":{"properties":{"dimensions":{"items":{"type":"object"},"type":"array"},"doors":{"items":{"$ref":"#/components/schemas/Opening"},"type":"array"},"layers":{"items":{"type":"object"},"type":"array"},"other_symbols":{"items":{"type":"object"},"type":"array"},"rooms":{"items":{"properties":{"area":{"properties":{"m2":{"type":"number"},"sqft":{"type":"number"}},"type":"object"},"doors":{"items":{"type":"string"},"type":"array"},"id":{"type":"string"},"ifc_space":{"description":"IFC / RVT: guid, number and name of the IfcSpace","type":"object"},"name":{"type":["string","null"]},"number":{"description":"IFC / RVT: the room number","type":["string","null"]},"perimeter":{"$ref":"#/components/schemas/Length"},"polygon":{"items":{"items":{"type":"number"},"maxItems":2,"minItems":2,"type":"array"},"type":"array"},"windows":{"items":{"type":"string"},"type":"array"}},"type":"object"},"type":"array"},"summary":{"description":"Counts, total wall length, net and gross areas (m\u00b2), units","type":"object"},"texts":{"items":{"type":"object"},"type":"array"},"units":{"properties":{"meters_per_unit":{"type":"number"},"name":{"type":"string"}},"type":"object"},"walls":{"items":{"properties":{"end":{"items":{"type":"number"},"maxItems":2,"minItems":2,"type":"array"},"exterior":{"type":"boolean"},"id":{"type":"string"},"layer":{"type":"string"},"length":{"$ref":"#/components/schemas/Length"},"openings":{"items":{"type":"string"},"type":"array"},"outline":{"items":{"items":{"type":"number"},"maxItems":2,"minItems":2,"type":"array"},"type":"array"},"start":{"items":{"type":"number"},"maxItems":2,"minItems":2,"type":"array"},"thickness":{"$ref":"#/components/schemas/Length"}},"type":"object"},"type":"array"},"warnings":{"items":{"type":"string"},"type":"array"},"windows":{"items":{"$ref":"#/components/schemas/Opening"},"type":"array"}},"type":"object"},"AnalyzeResponse":{"properties":{"analysis":{"$ref":"#/components/schemas/Analysis"},"drawing":{"description":"Only with include_drawing=true","type":"object"},"file":{"type":"string"},"source":{"description":"type (dwg/dxf/pdf/ifc/rvt); for PDFs also page, pages, scale, scale_source (user/text/estimated) and layers; for models level, levels [{name, elevation_m}], level_name, cut_height_m, schema and project","type":"object"},"timing":{"properties":{"conversion_s":{"type":"number"},"total_s":{"type":"number"}},"type":"object"},"warnings":{"items":{"type":"string"},"type":"array"}},"type":"object"},"Error":{"properties":{"code":{"description":"Stable machine-readable code","type":"string"},"error":{"description":"Human-readable message (English)","type":"string"}},"required":["error","code"],"type":"object"},"Length":{"properties":{"display":{"description":"Formatted in the drawing's unit system, e.g. 2'-6\" or 0.90 m","type":"string"},"m":{"description":"In meters","type":"number"},"value":{"description":"In drawing units","type":"number"}},"type":"object"},"Opening":{"properties":{"block":{"type":"string"},"center":{"items":{"type":"number"},"maxItems":2,"minItems":2,"type":"array"},"connects":{"description":"Room ids on both sides, or \"exterior\"","items":{"type":["string","null"]},"type":"array"},"door_type":{"enum":["single_swing","double_swing","sliding"],"type":"string"},"host_wall":{"type":["string","null"]},"id":{"type":"string"},"ifc":{"description":"IFC / RVT: guid, ifc_class, name, type, width_m, operation","type":"object"},"opens_into":{"type":["string","null"]},"outline":{"items":{"items":{"type":"number"},"maxItems":2,"minItems":2,"type":"array"},"type":"array"},"width":{"$ref":"#/components/schemas/Length"}},"type":"object"}},"securitySchemes":{"ApiKeyHeader":{"in":"header","name":"X-API-Key","type":"apiKey"},"BearerKey":{"bearerFormat":"dwgv_<id>_<secret>","scheme":"bearer","type":"http"}}},"info":{"description":"Analyze architectural DWG, DXF and vector PDF plans and IFC / Revit (RVT) building models: walls, rooms, doors, windows, dimensions, texts and symbols.\n\nBIM models (IFC, RVT) are analyzed one level (storey) at a time, as a floor plan cut 1.2 m above the level. Rooms come from the model's spaces, with their names and numbers, and every wall, door and window carries its IFC GUID, name and type. Revit files are converted to IFC in the background, so they are always sent through POST /uploads (a job) and take a few minutes.\n\nAuthenticate with an API key created in the app (Account \u2192 API keys), sent as `X-API-Key: <key>` or `Authorization: Bearer <key>`.\n\nDefault limits: 10 requests per minute per key and 100 requests per month per account. Every request counts, including failed ones.","title":"PlanWeave API","version":"1.0.0","x-limits":{"max_upload_mb":30,"monthly_quota":100,"rate_per_minute":10}},"openapi":"3.1.0","paths":{"/analyze":{"post":{"operationId":"analyze","parameters":[{"description":"Also return the display geometry of the whole drawing (polylines and texts per layer). Can be large.","in":"query","name":"include_drawing","required":false,"schema":{"default":false,"type":"boolean"}},{"description":"PDF only: the drawing scale N of 1:N. Without it the scale is read from a scale note in the drawing or estimated from door and wall sizes (see source.scale_source).","in":"query","name":"scale","required":false,"schema":{"maximum":5000,"minimum":1,"type":"number"}},{"description":"PDF only: 1-based page number. Default: the page with the most vector content.","in":"query","name":"page","required":false,"schema":{"minimum":1,"type":"integer"}},{"description":"IFC only: 1-based level (storey), in the order of source.levels (by elevation). Default: the main floor plan (the lowest level with most of the doors).","in":"query","name":"level","required":false,"schema":{"minimum":1,"type":"integer"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"properties":{"file":{"description":".dwg, .dxf, vector .pdf or .ifc, up to 30 MB","format":"binary","type":"string"}},"required":["file"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeResponse"}}},"description":"Analysis result","headers":{"X-Quota-Limit":{"description":"Requests allowed this calendar month (UTC)","schema":{"type":"integer"}},"X-Quota-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request. Codes: no_file, unsupported_type, empty_file, invalid_dwg, pdf_invalid, invalid_scale, pdf_page, ifc_invalid, ifc_level, rvt_invalid, rvt_requires_job"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Missing or invalid credentials. Codes: auth_required, invalid_api_key"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"File too large. Codes: too_large"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"The file could not be read. Codes: convert_failed, convert_timeout, parse_failed, pdf_scanned, pdf_no_drawing, pdf_encrypted, pdf_too_complex, ifc_empty, ifc_empty_level, rvt_failed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Limit reached. Codes: rate_limited, quota_exceeded","headers":{"Retry-After":{"schema":{"type":"integer"}},"X-Quota-Limit":{"description":"Requests allowed this calendar month (UTC)","schema":{"type":"integer"}},"X-Quota-Remaining":{"schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per minute for this key","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"schema":{"type":"integer"}}}},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Server error. Codes: internal, no_converter"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Revit conversion unavailable. Codes: rvt_unavailable"}},"summary":"Analyze a DWG, DXF, vector PDF or IFC file (Revit: use /uploads)"}},"/integrate":{"post":{"description":"The files are aligned on their walls (rotation, position and, for a PDF, scale) and merged in meters in the frame of the reference file (Revit/IFC, else DWG, else PDF). Rooms come from the model's spaces when there are any; every wall, room, door and window lists its ids in each file (`sources`). analysis.integration has the sources (transform, match score), the roles and the issues (room_area, room_name, room_missing, room_extra, room_merged, room_divided, door_missing, window_missing, door_width, window_width, wall_missing, wall_extra, wall_thickness, align_low, align_failed, pdf_scale). Not counted against the quota.","operationId":"integrate","parameters":[{"in":"query","name":"include_drawing","schema":{"type":"boolean"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"job_ids":{"items":{"type":"string"},"maxItems":3,"minItems":2,"type":"array"}},"required":["job_ids"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Integrated analysis (same JSON as /analyze, source.type = integrated)"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Bad request. Codes: integrate_count"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unknown job. Codes: job_not_found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not finished. Codes: job_not_ready"},"410":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Expired. Codes: job_expired"}},"summary":"Align and merge 2-3 finished jobs of the same floor (e.g. Revit + DWG + PDF) into one analysis"}},"/jobs/{id}":{"get":{"operationId":"getJob","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Status"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Unknown job. Codes: job_not_found"}},"summary":"Job status: awaiting_upload, queued, processing, done or error (with code)"}},"/jobs/{id}/result":{"get":{"operationId":"getJobResult","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}},{"in":"query","name":"include_drawing","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Analysis result"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Not finished. Codes: job_not_ready"},"410":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Expired. Codes: job_expired"}},"summary":"The analysis of a finished job (same JSON as /analyze)"}},"/jobs/{id}/start":{"post":{"operationId":"startJob","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"202":{"description":"Queued"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Upload incomplete. Codes: upload_incomplete"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Limit reached. Codes: rate_limited, quota_exceeded"}},"summary":"Queue the uploaded file for analysis (counts as one request)"}},"/uploads":{"post":{"operationId":"createUpload","requestBody":{"content":{"application/json":{"schema":{"properties":{"level":{"description":"IFC / RVT: 1-based level (storey)","type":"integer"},"name":{"type":"string"},"page":{"type":"integer"},"scale":{"type":"number"},"size":{"type":"integer"}},"required":["name","size"],"type":"object"}}},"required":true},"responses":{"201":{"description":"job_id, upload_url (resumable, chunks of chunk_size bytes with Content-Range), chunk_size"},"413":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"File too large. Codes: too_large"}},"summary":"Large file (up to 200 MB): create an analysis job and an upload URL"}}},"security":[{"ApiKeyHeader":[]},{"BearerKey":[]}],"servers":[{"url":"https://dwg-vis.web.app/api/v1"}],"x-large-files":"Files over 25 MB (up to 200 MB) and all Revit files: POST /uploads, PUT the file to upload_url in chunks (Content-Range), POST /jobs/{id}/start, poll GET /jobs/{id}, then GET /jobs/{id}/result."}
