All endpoints (except /api/auth/login and the public
GET /api/share/:shareId) require a Bearer token in the
Authorization header.
You have two ways to obtain a token:
# 1) Short-lived (24h) token via username + password
curl -X POST https://echov.projectsndev.com/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"YOUR_USERNAME","password":"YOUR_PASSWORD"}'
# 2) Long-lived API token (after logging in once)
curl -X POST https://echov.projectsndev.com/api/auth/generate-api-token \
-H "Authorization: Bearer SHORT_LIVED_TOKEN"
Then send the token with every call:
Authorization: Bearer YOUR_TOKEN.
Click the green Authorize button below to test endpoints right in this page.
Most state-mutating endpoints (color, cube, lightbeam, label, model update) also broadcast a WebSocket message via the central WSS server, so anyone viewing your scene (your own browser sessions or your shared / iframed pages) updates instantly without polling.
window.EchoV)
The standalone Fragments viewer (/viewer/viewer.html) exposes a global
window.EchoV object that mirrors the one in app.html.
It works for both logged-in users and anonymous share visitors — when the viewer
is opened via a ?share=<id> URL, the sharer's token is written
to sessionStorage automatically, so all EchoV.api.* HTTP
wrappers below stay authenticated.
Open the viewer, press F12, and try:
EchoV.getModelIds() EchoV.flyToModel(EchoV.getModelIds()[0]) EchoV.setElementsColor(EchoV.getModelIds()[0], [86582], '#ff0000') await EchoV.api.element.info(EchoV.getModelIds()[0], 86582) await EchoV.api.cube.list()
| Property | Description |
|---|---|
EchoV.fragments | The FRAGS.FragmentsModels instance. |
EchoV.world | The OBC.World (camera + scene + renderer). |
EchoV.scene | Underlying THREE.Scene. |
EchoV.camera | OBC.SimpleCamera (use .controls for camera-controls API). |
EchoV.renderer | OBC.SimpleRenderer. |
EchoV.refresh() | Force fragments.update(true). |
| Method | Description |
|---|---|
getAllModels() | Map<modelId, FragmentsModel>. |
getModelIds() | Array of all loaded modelIds. |
getModel(id) | Single FragmentsModel by id. |
getModelInfo(id) | { id, name, visible, origin }. |
getVisibleModels() | Array of currently-visible modelIds. |
showModel(id) / hideModel(id) / toggleModel(id) | Per-model visibility. |
showAllModels() / hideAllModels() | Bulk visibility. |
| Method | Description |
|---|---|
getCameraState() | { position: [x,y,z], target: [x,y,z] }. |
setCameraState({ position, target }, animate?) | Move camera to a saved view. |
flyToModel(id, animate?) | Fit camera to a single model's bounding sphere. |
fitToAll(animate?) | Zoom to fit every visible model. |
| Method | Description |
|---|---|
getModelOrigin(id) | Returns the model's THREE.Vector3 position. |
setModelOrigin(id, x?, y?, z?) | Set the model's origin (any subset). |
adjustModelOrigin(id, dx?, dy?, dz?) | Relative move. |
| Method | Description |
|---|---|
setModelTransparency(id, opacity) | Per-model material opacity (0 - 1). |
setAllModelsTransparency(opacity) | Bulk opacity (RED-QUEEN-MODE-style). |
| Method | Description |
|---|---|
setElementsColor(modelId, localIds, color, opacity?) | Highlight a list of elements. |
resetElementsColor(modelId, localIds?) | Reset highlight (omit ids to reset whole model). |
setCategoryColor(modelId, category, color, opacity?) | Highlight every element of an IFC category. Returns the count. |
getCategories(modelId) | List IFC categories for a model. |
getCategoryElements(modelId, category) | List localIds of an IFC category. |
getElementData(modelId, localIds, opts?) | Wraps FragmentsModel.getItemsData. |
| Method | Description |
|---|---|
EchoV.clipper.addPlane(point, normal) | Create a clipping plane from a point + normal. |
EchoV.clipper.deleteAll() | Remove every clipping plane. |
EchoV.clipper.list() | Return the underlying clipper plane Map. |
EchoV.panels.toggleClipper / toggleModelsTree / toggleShare() | Show/hide each side panel. |
EchoV.panels.closeAll() | Hide every floating panel. |
EchoV.share.capture() | Snapshot current viewer state (camera, visibility, planes). |
EchoV.share.apply(state) | Restore a previously captured state. |
EchoV.api.*
Thin fetch() wrappers around the REST endpoints documented below.
They reuse the JWT in sessionStorage.token automatically (set
either by /login.html or by the share-loading code in viewer.ts).
| Method | REST endpoint |
|---|---|
EchoV.api.element.info(modelId, localId) | GET /api/localid/:modelId/:localId/info |
EchoV.api.element.location(modelId, localId) | GET /api/localid/:modelId/:localId/estimate-location |
EchoV.api.element.boundingBox(modelId, localId) | GET /api/boundingbox/:modelId/:localId |
EchoV.api.element.export(modelId) | GET /api/localid/:modelId/export |
EchoV.api.cube.{ add, list, deleteAll, create, update, delete } | POST/GET/DELETE /api/cube/* & /api/localid/:modelId/:localId/cube |
EchoV.api.lightBeam.{ add, update, delete, list } | POST/PUT/DELETE/GET /api/lightbeam/* |
EchoV.api.label.{ add, update, delete } | POST/PUT/DELETE /api/label/:modelId/:localId |
EchoV.api.color.{ set, reset, batch } | POST /api/color/{set,reset,batch} |
EchoV.api.boundingBoxHighlight.{ get, set } | GET/POST /api/boundingbox/:modelId/:localId/highlight |
EchoV.api.markers.{ list, create, update, delete } | GET/POST/PUT/DELETE /api/markers |
EchoV.api.status.{ list, get, set, setBatch, delete } | GET/POST/DELETE /api/status/* |
EchoV.api.userModels.list() | GET /api/models |
EchoV.api.folders.list() | GET /api/folders |
EchoV.api.raw(path, options?) | Escape hatch — call any endpoint with the current bearer token. |