Introduction
Welcome to the Spot API documentation. The API is currently in beta phase and we are interested in your feedback. Please read this document to get started. You can contact us at dev@spotvirtual.com if you have any questions.
Changelog
- 01/01/2022: Spot moved from
spot.xyz
tospotvirtual.com
. - 11/22/2021: Initial version.
Basics
We currently offer a REST-based API.
Authentication
Before being able to access the API, you first have to create an access token. In your Spot user's preferences, navigate to the Advanced tab and enable the Developer mode toggle. Once the developer mode has been enabled, you will notice that a new API tab have appeared in the left side menu. It is in the API tab that you can create and manage access tokens.
Authorization
You can control what your access token has access to. After creating a new token, you must decide what scopes (types of resources and level of access) and what teams the token is able to access.
Currently the API has one type of resource; worlds and entities.
You can select the level of access:
- read-only
- read-write access (can modify existing entities)
- admin access (can create and delete entities)
More types will be added as we evolve the API.
Rate Limiting
At the moment we do not enforce any rate limits. We do ask that you apply common sense and do not overwhelm our API. We reserve the right to disable access tokens that cause problems.
Errors
The API aims to return proper status codes in all cases, and we recommend that you use them to see whether or not your requests were successful. If you receive errors then we recommend that you throttle and wait a moment before you retry the request. Here’s a list of common status codes and what they mean:
200 - OK
204 - No Content
400 - Bad Request
401 - Unauthorized
404 - Not Found
500 - Internal Server Error
502 - Bad Gateway
503 - Service Unavailable
504 - Gateway Timeout
Most successful requests result in the 200 status code. Some endpoints use the 204 status code to indicate a successful request (e.g. when deleting entities).
A response with the 400 status code means that the URL parameters or request data is somehow invalid.
A response with the 401 status code can means a couple of different things:
- the access token has been deleted or disabled
- the resource does not exist
- you have not granted access to the resource (should probably change to 404)
- you no longer have the required membership to the team (some actions require admin membership)
A response with the 404 status code means that the resource or entity does not exist.
5xx errors usually means that Spot is experiencing server issues, a planned downtime, or the input data was unexpected and resulted in a server error.
Making requests
Now that you have created an access token and authorized access for it, you are ready to make your first request.
Entity API Endpoint
First we need to decide what data we want to retrieve and what endpoint to use. The easiest endpoint to use is an endpoint to retrieve an entity and its properties. To get the endpoint for an object inside of Spot, simply right-click on it and click Edit.
You will notice that since Developer Mode is enabled, there’s a new text field at the bottom.
This is the endpoint for the entity itself. Click the Copy button to copy it.
Retrieve Entity Data
Use curl
to retrieve the entity data:
curl -H "Authorization: Bearer spot_abcdefgijklmnopqrstuvwxyz01234567890" \https://spotvirtual.com/api/world/cebc47ed-72ab-4522-bbc7-632e5adff627/entity/b81b4dc0-94e6-4771-9ae6-39bcf8941590
The above command should return JSON data similar to the following:
{"type": 2,"entityId": "b81b4dc0-94e6-4771-9ae6-39bcf8941590","assetId": "7c9f9680-878a-402e-a53c-12766d4b8ed2","transform": {"position": [15.5, 0.004999999999999999, 2.25],"rotation": [0, 0, 0, 1],"scale": [1, 1, 1]},"eventType": 6,"userId": "a659f37b-9492-4553-9e5c-10d34351f073","clientRev": 262,"properties": {"Primary Color": "#c3c3c3"}}
Update Entity Properties
We can send a PUT
request to the same endpoint to update the entity. For example, to update the Primary Color
property, we can run the following:
Use curl
to update the Primary Color
property:
curl -H "Authorization: Bearer spot_abcdefgijklmnopqrstuvwxyz01234567890" \-H "Content-Type: application/json" \-X PUT \-d '{"properties":{"Primary Color":"#e53e3e"}}' \https://spotvirtual.com/api/world/cebc47ed-72ab-4522-bbc7-632e5adff627/entity/b81b4dc0-94e6-4771-9ae6-39bcf8941590
The bean bag has now turned red.
Create A New Entity
We can create a copy of the bean bag with the following request. I have changed the position slightly, otherwise the copy would end up in the same position as the original.
curl -H "Authorization: Bearer spot_abcdefgijklmnopqrstuvwxyz01234567890" \-H "Content-Type: application/json" \-X POST \-d '{"type":2,"assetId":"7c9f9680-878a-402e-a53c-12766d4b8ed2","transform":{"position":[18.5,0.004999999999999999,2.25],"rotation":[0,0,0,1],"scale":[1,1,1]},"eventType":6,"userId":"a659f37b-9492-4553-9e5c-10d34351f073","properties":{"Primary Color":"#e53e3e"}}' \https://spotvirtual.com/api/world/cebc47ed-72ab-4522-bbc7-632e5adff627/entities
The above command should return JSON data similar to the following:
{"type": 2,"eventType": 6,"entityId": "fc2e3b3f-0b52-4f2f-b6ac-2915750692a2","userId": "a659f37b-9492-4553-9e5c-10d34351f073","assetId": "7c9f9680-878a-402e-a53c-12766d4b8ed2","transform": {"position": [18.5,0.004999999999999999,2.25],"rotation": [0,0,0,1],"scale": [1,1,1]},"properties": {"Primary Color": "#e53e3e"}}
There are now two red bean bag chairs.
The response above includes the state of the new entity, including its entityId
which was generated by the server.
Delete An Entity
If we don't like the new bean bag then we can delete it with the following request:
curl -H "Authorization: Bearer spot_abcdefgijklmnopqrstuvwxyz01234567890" \-X DELETE \https://spotvirtual.com/api/world/cebc47ed-72ab-4522-bbc7-632e5adff627/entity/fc2e3b3f-0b52-4f2f-b6ac-2915750692a2
The command will not print any output if it is successful. The bean bag that we created before should have disappeared from the world.
Endpoints
GET /api/worlds/<worldId>/floorplan
Get the floorplan of the world. At the moment you can’t update the floorplan through the API.
GET /api/worlds/<worldId>/entities
Get a list of all of the entities in the world (including all of the users).
POST /api/worlds/<worldId>/entities
Create a new entity. Requires the world admin scope.
GET /api/worlds/<worldId>/entity/<entityId>
Get a single entity.
PUT /api/worlds/<worldId>/entity/<entityId>
Update an entity.
DELETE /api/worlds/<worldId>/entity/<entityId>
Delete an entity. Requires the world admin scope.
Data objects
World Floorplan
The floorplan has the following shape:
Click to expand example data
{"height": 6,"corners": {"0": {"x": -21,"y": 15},"1": {"x": -21,"y": 37},"2": {"x": 16,"y": 37},"3": {"x": 16,"y": 15},"0b9441c5-a3b1-448d-85be-be774f075ff8": {"x": 7,"y": 37},"5ae3c71b-0b95-4051-85d0-fa86fa06b860": {"x": 7,"y": 50},"6ee6feaa-4a2c-4694-999b-0d8aeae59b6a": {"x": -24,"y": 37},"85b36252-b679-48eb-83a5-e32d59eae9ff": {"x": -24,"y": 50}},"walls": [{"corner1": "0","corner2": "1","frontMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}},"backMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}}},{"corner1": "1","corner2": "0b9441c5-a3b1-448d-85be-be774f075ff8","frontMaterial": {"materialId": "fb40d5e0-1bb8-4cb4-bdeb-ebb874d03ad1","properties": {"Color": "#1FFF4A","diffuseColor": "#fbfbfb"}},"backMaterial": {"materialId": "faa2c208-2455-4f23-986b-28ea94929c26","properties": {"Color": "#9FDEA6","diffuseColor": "#fbfbfb"}}},{"corner1": "2","corner2": "3","frontMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}},"backMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}}},{"corner1": "3","corner2": "0","frontMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}},"backMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}}},{"corner1": "1","corner2": "6ee6feaa-4a2c-4694-999b-0d8aeae59b6a","thickness": 0,"frontMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}}},{"corner1": "6ee6feaa-4a2c-4694-999b-0d8aeae59b6a","corner2": "85b36252-b679-48eb-83a5-e32d59eae9ff","thickness": 0,"frontMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}}},{"corner1": "85b36252-b679-48eb-83a5-e32d59eae9ff","corner2": "5ae3c71b-0b95-4051-85d0-fa86fa06b860","thickness": 0,"frontMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}}},{"corner1": "5ae3c71b-0b95-4051-85d0-fa86fa06b860","corner2": "0b9441c5-a3b1-448d-85be-be774f075ff8","thickness": 0,"frontMaterial": {"materialId": "1b36d86c-a65d-4532-abb2-86e7539ace62","properties": {"Color": "#1FFF4A","diffuseColor": "#9ad5fa"}}},{"corner1": "0b9441c5-a3b1-448d-85be-be774f075ff8","corner2": "2","frontMaterial": {"materialId": "fb40d5e0-1bb8-4cb4-bdeb-ebb874d03ad1","properties": {"Color": "#1FFF4A","diffuseColor": "#fbfbfb"}},"backMaterial": {"materialId": "faa2c208-2455-4f23-986b-28ea94929c26","properties": {"diffuseColor": "#fbfbfb"}}}],"rooms": [{"cornerIds": ["0b9441c5-a3b1-448d-85be-be774f075ff8","5ae3c71b-0b95-4051-85d0-fa86fa06b860","85b36252-b679-48eb-83a5-e32d59eae9ff","6ee6feaa-4a2c-4694-999b-0d8aeae59b6a","1"],"id": "e19841af-d56b-4bb0-a057-9631d160acae","floorMaterial": {"materialId": "8d356e1d-f81c-4ead-95cc-2d5f35b16220","properties": {"alpha": "","scaleFactor": "4","diffuseColor": "#fbfbfb"}},"isOutside": true},{"cornerIds": ["0","3","2","0b9441c5-a3b1-448d-85be-be774f075ff8","1"],"id": "7bf0bdf2-b29d-43db-80b6-567d15434ff2","floorMaterial": {"materialId": "4b3971ff-b9cb-4c2a-a854-d3f29006ff8e","properties": {"diffuseColor": ""}}}],"floorMaterial": {"materialId": "1e95cc53-1224-4b13-93c3-2f480b11c4ea","properties": {"Color": "#C3C3C3","diffuseColor": "#FECC96"}},"wallMaterial": {"materialId": "0bcc2b69-3a8d-5ff8-bd13-9b8dc874ad9b","properties": {"Color": "#cdd2cc"}},"exteriorMaterial": {"materialId": "0bcc2b69-3a8d-5ff8-bd13-9b8dc874ad9b","properties": {"Color": "#888888"}},"wallThickness": 0.32,"topColor": "#CCEAFC","lightDirection": [0,-1,0],"lightColor": "#FFFFFF","ambientColor": "#999999"}
World Entity
A world entity has the following shape:
Click to expand example data
{"type": 2,"entityId": "b81b4dc0-94e6-4771-9ae6-39bcf8941590","assetId": "7c9f9680-878a-402e-a53c-12766d4b8ed2","transform": {"position": [15.5, 0.004999999999999999, 2.25],"rotation": [0, 0, 0, 1],"scale": [1, 1, 1]},"eventType": 6,"userId": "a659f37b-9492-4553-9e5c-10d34351f073","clientRev": 262, // increments every time a user modifies the entity"properties": {// varies depending on the asset}}