Export a Space Definition
Read a complete rooomSpaces space definition with an API key. Combine the space, objects and lights endpoints to inspect, back up or rebuild a space.
There is no single export file for a space. The space definition is the space document itself, and you read it with GET /spaces/{roomId}. Two smaller endpoints return parts of it: GET /spaces/{roomId}/objects resolves the catalogue objects used in the space, and GET /spaces/{roomId}/lights returns the lights. Together they give you everything you need to inspect a space or rebuild it in your own pipeline.
Not an import format
POST /resources/spaces/json is deprecated and will be removed. It accepts only an Apple RoomPlan JSON export and converts it into a space template (GLB) on the server. It does not accept the space definition described on this page, so you cannot use it to import objects, lights or camera settings.
Requirements
- An API key, sent as
Authorization: Bearer <API_KEY>. - The key needs the
space:readscope to read a space andspace:writeto change it. - The space must belong to the user who owns the API key. Any other space returns
401 Unauthorized, even if it is public.
| Method | Path | Scope | Returns |
|---|---|---|---|
GET | /spaces/{roomId} | space:read | The full space definition |
GET | /spaces/{roomId}/objects | space:read | Catalogue objects used in the space |
GET | /spaces/{roomId}/objects/{objectId} | space:read | One placed object |
GET | /spaces/{roomId}/lights | space:read | The lights of the space |
Find the Space ID
roomId is the ID of the space. List your own spaces with GET /rooms/own (scope space:read) and take the rid of the space you want.
curl https://api.rooom.com/rooms/own \
-H 'Authorization: Bearer <API_KEY>'Read the Space
GET /spaces/{roomId} returns the space with its placed objects already resolved.
curl https://api.rooom.com/spaces/<ROOM_ID> \
-H 'Authorization: Bearer <API_KEY>'The response is a JSON object. These are the keys you will use most:
| Key | Content |
|---|---|
id, name | Space ID and name |
roomdef_id, roomprebuilt_id | The space template and, if the space was created from one, the prebuilt it started from |
objects | Placed objects, see Placed Objects |
camera | Camera settings. In auto mode the response has no position; a camera set on the space itself has custom: true |
view, colorspace, scale | View settings, colour space (gamma unless set) and space scale (1.0 unless set) |
navmesh, environment, skybox | The value set on the space, otherwise the prebuilt's, otherwise the template's, otherwise an empty array |
dimensions | Dimensions of the space template |
roomdef_glb, roomdef_type | Mesh of the space template. Splat-based spaces have roomdef_splat and roomdef_type: "splat" instead |
lights | The lights of the space, if any are set |
viewers | Viewers of the space, each with title, token, created, owner, glb_exists, options and features |
Further keys such as walls, tours or background appear when the space uses them. New keys may be added over time, so read only the ones your application needs.
Placed Objects
Each entry in objects combines the catalogue object with its placement in the space:
idis the space object ID. Use it for every/spaces/{roomId}/objects/{objectId}call.object_idis the catalogue object ID andset_idthe selected material set.position,rotationandscalinghold the placement as{ "x", "y", "z" }.rotationandscalingare only present once they were set.- Text objects have
type: "font"and carryfontname,content,colorsandletter-thicknessinstead of a catalogue reference.
GET /spaces/{roomId}/objects/{objectId} returns a single entry in the same shape, or 404 Not Found.
Read Objects and Lights
GET /spaces/{roomId}/objects returns the catalogue objects that are placed in the space, with translated name and description and their material set information. It returns one entry per catalogue object, not per placement, and has no position data. Its id matches object_id in the space's objects.
GET /spaces/{roomId}/lights returns the lights array of the space, or an empty array.
To save a complete snapshot, store all three responses:
API_KEY='<API_KEY>'
ROOM_ID='<ROOM_ID>'
BASE='https://api.rooom.com/spaces'
curl -sf "$BASE/$ROOM_ID" -H "Authorization: Bearer $API_KEY" -o space.json
curl -sf "$BASE/$ROOM_ID/objects" -H "Authorization: Bearer $API_KEY" -o objects.json
curl -sf "$BASE/$ROOM_ID/lights" -H "Authorization: Bearer $API_KEY" -o lights.jsonRebuild or Change a Space
There is no endpoint that imports a saved space definition in one call. You can recreate the object layout step by step with the space:write scope:
- Create a space from a template or prebuilt with
POST /spaces/create. - Add each object with
POST /spaces/{roomId}/objects/add. The response contains the new space objectid. - Move all objects into place with one
POST /spaces/{roomId}/objects/transformcall. - Apply scaling per object with
POST /spaces/{roomId}/objects/{objectId}/updateScale.
These routes do not change the camera, lights, environment or skybox.
Add an Object
POST /spaces/{roomId}/objects/add takes multipart/form-data. For a catalogue object send objectId and optionally setId to pick one of its material sets; without it the default set is used. For a text object send type=font with content, fontname, color-diffuse, color-emissive and letter-thickness.
curl -X POST https://api.rooom.com/spaces/<ROOM_ID>/objects/add \
-H 'Authorization: Bearer <API_KEY>' \
-F 'objectId=<CATALOGUE_OBJECT_ID>'{ "id": "<SPACE_OBJECT_ID>" }INFO
Catalogue objects are always placed at the origin, and the position and rotation fields are ignored for them. Only text objects use position[x|y|z] and rotation[x|y|z] from this request. Move catalogue objects with the transform call below.
Move Several Objects
POST /spaces/{roomId}/objects/transform sets the absolute position and rotation of several objects in one request. The body is JSON. Each item needs the space object id and may contain position, rotation or both. Each of them needs all three of x, y and z. Rotation is in degrees and reduced modulo 360.
curl -X POST https://api.rooom.com/spaces/<ROOM_ID>/objects/transform \
-H 'Authorization: Bearer <API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"objects": [
{
"id": "<SPACE_OBJECT_ID>",
"position": { "x": 1.5, "y": 0, "z": -2 },
"rotation": { "x": 0, "y": 90, "z": 0 }
}
]
}'{ "status": "ok", "updated": ["<SPACE_OBJECT_ID>"] }| Status | Meaning |
|---|---|
200 OK | All items were applied. updated lists their IDs |
400 Bad Request | objects is missing or empty |
403 Forbidden | The space could not be loaded for the key's user |
422 Unprocessable Entity | Some items could not be applied. error.details.updated lists the applied IDs and error.details.failed describes each rejected item |
{
"error": {
"message": "Some objects could not be updated",
"code": 422,
"type": "unprocessable_entity",
"details": {
"updated": ["<SPACE_OBJECT_ID>"],
"failed": ["Invalid object id: <UNKNOWN_ID>"]
}
}
}WARNING
If the space changes between reading and writing, for example because someone edits it in the editor, the request writes nothing. All requested IDs are then returned in failed. Read the space again and retry.
Single-Object Updates
| Method | Path | Body | Response |
|---|---|---|---|
POST | /spaces/{roomId}/objects/{objectId}/updatePosition | Form fields x, y, z | The stored position |
POST | /spaces/{roomId}/objects/{objectId}/updateRotation | Form fields x, y, z in degrees | The stored rotation |
POST | /spaces/{roomId}/objects/{objectId}/updateScale | Form field scale for uniform scaling, or scale-x, scale-y, scale-z (missing axes become 1) | status and the stored scaling |
DELETE | /spaces/{roomId}/objects/{objectId} | None | deleted lists linked objects that were removed with it |
updatePosition keeps objects that are constrained to the floor at y = 0. The transform call applies no such correction. For several objects, prefer the transform call: it is a single request and a single write.
Errors
| Status | Cause |
|---|---|
401 Unauthorized | Missing or invalid API key, missing scope, or the space belongs to another user |
404 Not Found | The space does not exist, or {objectId} is not an object placed in this space (any /spaces/{roomId}/objects/{objectId} route) |
See Errors for the general error format.