Skip to content

Save a world

PUT
/spaces/maps/{map}/draft
curl --request PUT \
--url https://spaces.work.optidata.cloud/api/spaces/maps/a28e5bf3-26b4-4a34-9f98-9a116a2700ca/draft \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "group_areas": { "3f1c9a2e-7b4d-4e8a-9c21-5d6e7f8a9b0c": [ [ 10, 4 ], [ 11, 4 ], [ 10, 5 ], [ 11, 5 ] ] } }'

Saves the map document, the group areas, or both. Each save increases version. Builders only.

The map document is checked for what a world must have (type, width, height, tilewidth, tileheight, layers); group areas must fit inside the map. Send at least one of data and group_areas.

map
required
string

The world’s identifier.

Media typeapplication/json
Any of:
object
data
required

A Tiled map in its JSON format (orthogonal, 32×32 tiles). It must carry type, width, height, tilewidth, tileheight and layers. The Spaces client reads a Ground tile layer and the object layers Wall, Chair, Objects, ObjectsOnCollide, GenericObjects, GenericObjectsOnCollide, Computer, Whiteboard, Basement and VendingMachine; the easiest way to get a valid document is to create a world without data and edit the blank one it returns.

object
type
required
string
Allowed value: map
width
required
integer
height
required
integer
tilewidth
required
integer
tileheight
required
integer
layers
required
Array<object>
object
key
additional properties
any
tilesets
Array<object>
object
key
additional properties
any
key
additional properties
any
group_areas

Zones of the world reserved for groups: an object keyed by group id, each holding the [x, y] tile cells of that group’s area. Members of the group may edit the world inside its area even when they are not builders. Cells must lie inside the map.

object | null
Examples
Exampleareas

Reserve a zone for a group

{
"group_areas": {
"3f1c9a2e-7b4d-4e8a-9c21-5d6e7f8a9b0c": [
[
10,
4
],
[
11,
4
],
[
10,
5
],
[
11,
5
]
]
}
}

The saved world, without its map document.

Media typeapplication/json
object
identifier
required
string
name
required
string
source_map

The world this one was copied from, if any.

string | null
status
required
string
Allowed values: draft active
is_active
required
boolean
version
required

Grows with every saved change.

integer
activated_at
string | null format: date-time
created_by_uuid
string | null
updated_by_uuid
string | null
created_at
string format: date-time
updated_at
string format: date-time
Examples
Examplesaved
{
"identifier": "a305115b-efef-44ed-a2a2-ebc1d8e988e8",
"name": "Head office — 2026 layout",
"source_map": null,
"status": "draft",
"is_active": false,
"version": 2,
"activated_at": null,
"created_by_uuid": "2d9e8f70-1a3b-4c5d-8e9f-a0b1c2d3e4f5",
"updated_by_uuid": "2d9e8f70-1a3b-4c5d-8e9f-a0b1c2d3e4f5",
"created_at": "2026-10-19T11:53:34-03:00",
"updated_at": "2026-10-19T11:53:58-03:00"
}

No authentication key was sent.

Media typeapplication/json

Authentication failures use an error key rather than message.

object
error
required
string
Examples
Examplemissing

No bearer token sent

{
"error": "JWT passport exception: Missing bearer token in request"
}

The caller is not allowed to do this (see “Who may do what”), or the authentication key is not recognised (empty message).

Media typeapplication/json
object
message
required
string
Examples

Not the space's owner

{
"message": "You do not have permission to update this space."
}

Nothing has this identifier.

Media typeapplication/json
object
message
required
string
Examplegenerated
{
"message": "example"
}

The authentication key is expired or not recognised. Get a fresh one and retry.

Media typeapplication/json

Authentication failures use an error key rather than message.

object
error
required
string
Examples
Exampleexpired
{
"error": "JWT passport expired: Passport expired"
}

Nothing to save, or the document or the areas are not valid.

Media typeapplication/json
object
message
required

The first validation message.

string
errors
required

Validation messages keyed by field name.

object
key
additional properties
Array<string>
Examples
{
"message": "Send the map, the group areas, or both.",
"errors": {
"data": [
"Send the map",
"the group areas",
"or both."
]
}
}