Appearance
Code examples
Inventory of spaces and assets
In this demo we generate a html table from querying spaces and assets from a floor
Loading space data
This example shows how to retrieve information about all the spaces in a floor.
With publishable token
js
const url = `https://api.archilogic.com/v2/space/?floorId=${floorId}&pubtoken=${publishableToken}`
const geoJson = await fetch(url).then(res => res.json())
const url = `https://api.archilogic.com/v2/space/?floorId=${floorId}&pubtoken=${publishableToken}`
const geoJson = await fetch(url).then(res => res.json())
With secret token
js
const authorization = `AL-Secret-Token ${secretToken}`
const url = `https://api.archilogic.com/v2/space/?floorId=${floorId}`
const geoJson = await fetch(url, { headers: { authorization } }).then(res => res.json())
const authorization = `AL-Secret-Token ${secretToken}`
const url = `https://api.archilogic.com/v2/space/?floorId=${floorId}`
const geoJson = await fetch(url, { headers: { authorization } }).then(res => res.json())
By iterating through the resources we can collect the information for each space.
Of main interest are the properties section of the Space object and the resource relations to count the assets in the space. To group spaces of the same type you can group them by the usage or program.
js
geoJson.features.forEach(ft => {
const spaceData = ft.properties
const { usage, program } = spaceData
const assetCount = ft.resourceRelations?.assets?.length || 0
})
geoJson.features.forEach(ft => {
const spaceData = ft.properties
const { usage, program } = spaceData
const assetCount = ft.resourceRelations?.assets?.length || 0
})
Loading asset data
The same way we can get the information on all assets in the floor.
With publishable token
js
const url = `https://api.archilogic.com/v2/asset/?floorId=${floorId}&pubtoken=${publishableToken}`
const geoJson = await fetch(url).then(res => res.json())
const url = `https://api.archilogic.com/v2/asset/?floorId=${floorId}&pubtoken=${publishableToken}`
const geoJson = await fetch(url).then(res => res.json())
With secret token
js
const authorization = `AL-Secret-Token ${secretToken}`
const url = `https://api.archilogic.com/v2/asset/?floorId=${floorId}`
const geoJson = await fetch(url, { headers: { authorization } }).then(res => res.json())
const authorization = `AL-Secret-Token ${secretToken}`
const url = `https://api.archilogic.com/v2/asset/?floorId=${floorId}`
const geoJson = await fetch(url, { headers: { authorization } }).then(res => res.json())
The properties section of the Asset object contains the name, manufacturer, categories and dimensions of the asset. To group asset of the same type group them via the productId.
js
geoJson.features.forEach(ft => {
const assetData = ft.properties
const productId = assetData.productId
})
geoJson.features.forEach(ft => {
const assetData = ft.properties
const productId = assetData.productId
})
Demo with code
Open in codesandbox Embedded iframe below:
Draw geo-referenced floor plan on a map using Leaflet.js
In this demo we use Leaflet.js to draw a floor plan and outlines of spaces in GeoJSON format on the map that were loaded from the REST API.
TIP
If the floor plan is not geo-referenced it will appear at LatLng = [0, 0]
Reach out to Archilogic Support if you want your floor plan to be geo-referenced
Both Leaflet.js and Mapbox GL JS allow to not load any map tiles
Load the SVG
POST
request to load the geo-referenced svg floor plan
js
const url = `https://api.archilogic.com/v2/floor/${floorId}/2d-image?pubtoken=${publishableToken}`
const { imageUrl, latLngBounds } = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
}).then(res => res.json())
const url = `https://api.archilogic.com/v2/floor/${floorId}/2d-image?pubtoken=${publishableToken}`
const { imageUrl, latLngBounds } = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' }
}).then(res => res.json())
Leaflet.js can directly use those values to draw the floor plan svg on the map It expects coordinates in Lat,Long format
js
L.imageOverlay(imageUrl, latLngBounds).addTo(map)
// zoom to the floor plan
map.fitBounds(latLngBounds)
L.imageOverlay(imageUrl, latLngBounds).addTo(map)
// zoom to the floor plan
map.fitBounds(latLngBounds)
Load the geoJSON geometry
GET
request to load the contours of the spaces by querying via floorId this gives us the resource data in GeoJSON format GeoJSON is standardized as coordinates in Long,Lat format
TIP
Make sure to include the geometry
query param
js
const url = `https://api.archilogic.com/v2/space?floorId=${floorId}&geometry=true&pubtoken=${publishableToken}`
const geoJson = await fetch(url).then(res => res.json())
const url = `https://api.archilogic.com/v2/space?floorId=${floorId}&geometry=true&pubtoken=${publishableToken}`
const geoJson = await fetch(url).then(res => res.json())
Leaflet.js allows you to draw that directly on the map
js
L.geoJSON(geoJson, options).addTo(map)
L.geoJSON(geoJson, options).addTo(map)
Demo with code
Open in codesandbox Screenshot below:
Draw a floor plan and space geometry using Mapbox GL
Mapbox GL JS offers better performance and smoother scaling than Leaflet.js because it uses WebGL. The downside of this is that it can not load SVG images into map layers so you either need to load the png directly from space API or load the SVG and convert it to any resolution you prefer on the fly.
also be aware that Mapbox GL JS expects all coordinates in Long,Lat format
Demo with code
In this example we load the floor plan and overlay the contours of meet
and socialize
spaces. Further the bounding boxes of all assets with subCategories desk
and taskChair
in work
spaces are also shown. Check the space taxonomy and product taxonomy for reference.
The demo loads the SVG from Space API and renders it client side into a png dataUrl to reach high resolution and short loading times.
Open in codesandbox Screenshot below:
Access private resources from front end
The following example demonstrates how to access a private floor from the front end using temporary access tokens and the floor plan engine.
Get the temporary access token
Create an API on your back-end to retrieve temporary access tokens
js
app.post('/api/get-access-token', async (req, res) => {
// https://developers.archilogic.com/space-api/v2/introduction.html#temporary-access-token
const apiUrl = 'https://api.archilogic.com/v2/temporary-access-token/create'
const { body } = await got.post(apiUrl, {
headers: {
Authorization: `AL-Secret-Token ${process.env.SECRET_TOKEN}`
},
json: {
scopes: [{ resource: 'floor', action: 'readPrivate' }],
durationSeconds: 3600
},
responseType: 'json'
})
res.send(body)
})
app.post('/api/get-access-token', async (req, res) => {
// https://developers.archilogic.com/space-api/v2/introduction.html#temporary-access-token
const apiUrl = 'https://api.archilogic.com/v2/temporary-access-token/create'
const { body } = await got.post(apiUrl, {
headers: {
Authorization: `AL-Secret-Token ${process.env.SECRET_TOKEN}`
},
json: {
scopes: [{ resource: 'floor', action: 'readPrivate' }],
durationSeconds: 3600
},
responseType: 'json'
})
res.send(body)
})
Use the temporary access token
Make your front end call that API and use the token then via the loadScene method
js
function getTemporaryAccessToken() {
return fetch(`/api/get-access-token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
scopes: [{ resource: 'floor', action: 'readPrivate' }]
})
}).then(response => response.json())
}
// authorization contains the temporary access token
// expiresAt can be used to check on when you need to request an new token
const { authorization, expiresAt } = await getTemporaryAccessToken()
const demoSceneId = 'bc78475e-0236-4b8d-9d7e-b4f46cd3f6fa'
const container = document.getElementById('hello-plan')
const floorPlan = new FloorPlanEngine(container)
await floorPlan.loadScene(demoSceneId, { authorization }).catch()
function getTemporaryAccessToken() {
return fetch(`/api/get-access-token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
scopes: [{ resource: 'floor', action: 'readPrivate' }]
})
}).then(response => response.json())
}
// authorization contains the temporary access token
// expiresAt can be used to check on when you need to request an new token
const { authorization, expiresAt } = await getTemporaryAccessToken()
const demoSceneId = 'bc78475e-0236-4b8d-9d7e-b4f46cd3f6fa'
const container = document.getElementById('hello-plan')
const floorPlan = new FloorPlanEngine(container)
await floorPlan.loadScene(demoSceneId, { authorization }).catch()
Demo with code
Open in codesandbox Screenshot below:
Setup webhooks
Webhooks are available from the following API endpoints: https://api.archilogic.com/v2/webhook
Before using webhooks, a destination endpoint must be set up which supports POST requests from the Archilogic domain.
Currently webhooks are supported for 2 resources: floor
with available actions
ts
type FloorAction = 'created' | 'updated' | 'deleted' | 'archived' | 'unarchived'
type FloorAction = 'created' | 'updated' | 'deleted' | 'archived' | 'unarchived'
and order
with available actions
ts
type OrderAction = 'created' | 'rejected' | 'completed'
type OrderAction = 'created' | 'rejected' | 'completed'
Webhook payload example:
ts
{
"type": "event",
"url": "https://webhook.site/179b5241-ab4f-42df-bdb4-7f3154c9177a",
"resource": "floor",
"action": "created",
"createdAt": "2023-11-22T13:44:10.255Z",
"data": {
"id": "abaaea05-5070-4c77-bd6c-4f26c5b71340"
}
}
{
"type": "event",
"url": "https://webhook.site/179b5241-ab4f-42df-bdb4-7f3154c9177a",
"resource": "floor",
"action": "created",
"createdAt": "2023-11-22T13:44:10.255Z",
"data": {
"id": "abaaea05-5070-4c77-bd6c-4f26c5b71340"
}
}
Create webhooks
Webhook objects must include the following required fields:
ts
{
active: boolean // webhook state
action: WebhookActions // FloorAction | OrderAction
resource: WebhookResources // 'floor' | 'order'
url: string // format like 'https://{your_destination_url}'
}
{
active: boolean // webhook state
action: WebhookActions // FloorAction | OrderAction
resource: WebhookResources // 'floor' | 'order'
url: string // format like 'https://{your_destination_url}'
}
Example:
ts
const authorization = `AL-Secret-Token ${secretToken}`
await fetch(`https://api.archilogic.com/v2/webhook`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
authorization
},
body: JSON.stringify({
active: true,
action: 'updated', // FloorAction | OrderAction
resource: 'floor', // 'floor' | 'order'
url: 'https://example.com'
})
})
const authorization = `AL-Secret-Token ${secretToken}`
await fetch(`https://api.archilogic.com/v2/webhook`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
authorization
},
body: JSON.stringify({
active: true,
action: 'updated', // FloorAction | OrderAction
resource: 'floor', // 'floor' | 'order'
url: 'https://example.com'
})
})
Get all webhooks
Example:
ts
const authorization = `AL-Secret-Token ${secretToken}`
const webhooks = await fetch(`https://api.archilogic.com/v2/webhook`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
authorization
}
})
const authorization = `AL-Secret-Token ${secretToken}`
const webhooks = await fetch(`https://api.archilogic.com/v2/webhook`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
authorization
}
})
Get webhook by ID
Url path parameter :webhookId
can be taken from the GET request.
ts
const webhook = await fetch(`https://api.archilogic.com/v2/webhook/:webhookId`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
authorization
}
})
const webhook = await fetch(`https://api.archilogic.com/v2/webhook/:webhookId`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
authorization
}
})
Update webhooks
Any of the webhook object's parameters could be passed to the request body.
Url path parameter :webhookId
can be taken from the GET request.
Example:
ts
const authorization = `AL-Secret-Token ${secretToken}`
// Deactivate webhook
await fetch(`https://api.archilogic.com/v2/webhook/:webhookId`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
authorization
},
body: JSON.stringify({
active: false
})
})
// Change webhook destination url
await fetch(`https://api.archilogic.com/v2/webhook/:webhookId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
authorization
},
body: JSON.stringify({
url: 'https://example1.com'
})
})
const authorization = `AL-Secret-Token ${secretToken}`
// Deactivate webhook
await fetch(`https://api.archilogic.com/v2/webhook/:webhookId`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
authorization
},
body: JSON.stringify({
active: false
})
})
// Change webhook destination url
await fetch(`https://api.archilogic.com/v2/webhook/:webhookId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
authorization
},
body: JSON.stringify({
url: 'https://example1.com'
})
})
Delete webhooks
Url path parameter :webhookId
can be taken from the GET request.
Example:
ts
const authorization = `AL-Secret-Token ${secretToken}`
await fetch(`https://api.archilogic.com/v2/webhook/:webhookId`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
authorization
}
})
const authorization = `AL-Secret-Token ${secretToken}`
await fetch(`https://api.archilogic.com/v2/webhook/:webhookId`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
authorization
}
})