Sign in

Liveblocks REST API

Liveblocks REST API allows developers to interact programmatically with their Liveblocks account and services using HTTP requests. With the API, developers can retrieve, set, and update room-related data, users, permissions, schemas, and more. The Liveblocks API is organized around REST.

The API has predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.

To use the API endpoints, you need to add your secret key to the request’s authorization header. Except for the public authorization endpoint.

$curl https://api.liveblocks.io/v2/* \  -H 'Authorization: Bearer '

Auth

This endpoint lets your application server (your back end) obtain a token that one of its clients (your frontend) can use to enter a Liveblocks room. You use this endpoint to implement your own application’s custom authentication endpoint. When making this request, you’ll have to use your secret key.

Important: The difference with an ID token is that an access token holds all the permissions, and is the source of truth. With ID tokens, permissions are set in the Liveblocks back end (through REST API calls) and "checked at the door" every time they are used to enter a room.

Note: When using the @liveblocks/node package, you can use Liveblocks.prepareSession in your back end to build this request.

You can pass the property userId in the request’s body. This can be whatever internal identifier you use for your user accounts as long as it uniquely identifies an account. The property userId is used by Liveblocks to calculate your account’s Monthly Active Users. One unique userId corresponds to one MAU.

Additionally, you can set custom metadata to the token, which will be publicly accessible by other clients through the user.info property. This is useful for storing static data like avatar images or the user’s display name.

Lastly, you’ll specify the exact permissions to give to the user using the permissions field. This is done in an object where the keys are room names, or room name patterns (ending in a *), and a list of permissions to assign the user for any room that matches that name exactly (or starts with the pattern’s prefix). For tips, see Manage permissions with access tokens.

Request body

POST
https://api.liveblocks.io/v2/authorize-user
{  "userId": "user-123",  "userInfo": {    "name": "bob",    "avatar": "https://example.org/images/user123.jpg"  },  "organizationId": "acme-corp",  "permissions": {    "my-room-1": [      "*:write"    ],    "my-room-2": [      "*:write"    ],    "my-room-*": [      "*:read"    ]  }}

Response

Status:

Success. Returns an access token that can be used to enter one or more rooms.

{  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIi..."}

This endpoint lets your application server (your back end) obtain a token that one of its clients (your frontend) can use to enter a Liveblocks room. You use this endpoint to implement your own application’s custom authentication endpoint. When using this endpoint to obtain ID tokens, you should manage your permissions by assigning user and/or group permissions to rooms explicitly, see our Manage permissions with ID tokens section.

Important: The difference with an access token is that an ID token doesn’t hold any permissions itself. With ID tokens, permissions are set in the Liveblocks back end (through REST API calls) and "checked at the door" every time they are used to enter a room. With access tokens, all permissions are set in the token itself, and thus controlled from your back end entirely.

Note: When using the @liveblocks/node package, you can use Liveblocks.identifyUser in your back end to build this request.

You can pass the property userId in the request’s body. This can be whatever internal identifier you use for your user accounts as long as it uniquely identifies an account. The property userId is used by Liveblocks to calculate your account’s Monthly Active Users. One unique userId corresponds to one MAU.

If you want to use group permissions, you can also declare which groupIds this user belongs to. The group ID values are yours, but they will have to match the group IDs you assign permissions to when assigning permissions to rooms, see Manage permissions with ID tokens).

Additionally, you can set custom metadata to the token, which will be publicly accessible by other clients through the user.info property. This is useful for storing static data like avatar images or the user’s display name.

Request body

POST
https://api.liveblocks.io/v2/identify-user
{  "userId": "user-123",  "organizationId": "acme-corp",  "groupIds": [    "marketing",    "engineering"  ],  "userInfo": {    "name": "bob",    "avatar": "https://example.org/images/user123.jpg"  }}

Response

Status:

Success. Returns an ID token that can be used to enter one or more rooms.

{  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIi..."}

Room

get/rooms

Get rooms

This endpoint returns a list of your rooms. The rooms are returned sorted by creation date, from newest to oldest. You can filter rooms by room ID prefixes, metadata, users accesses, and groups accesses. Corresponds to liveblocks.getRooms.

There is a pagination system where the cursor to the next page is returned in the response as nextCursor, which can be combined with startingAfter. You can also limit the number of rooms by query.

Filtering by metadata works by giving key values like metadata.color=red. Of course you can combine multiple metadata clauses to refine the response like metadata.color=red&metadata.type=text. Notice here the operator AND is applied between each clauses.

Filtering by groups or userId works by giving a list of groups like groupIds=marketing,GZo7tQ,product or/and a userId like userId=user1. Notice here the operator OR is applied between each groupIds and the userId.

Parameters

  • limit optional

    A limit on the number of rooms to be returned. The limit can range between 1 and 100, and defaults to 20.

    • Minimum: 1
    • Maximum: 100
    • Default: 20
    20
  • startingAfter optional

    A cursor used for pagination. Get the value from the nextCursor response of the previous page.

    eyJjcmVhdGVkQXQiOjE2NjAwMDA5ODgxMzd9
  • organizationId optional

    A filter on organization ID.

    org_123456789
  • query optional

    Query to filter rooms. You can filter by roomId and metadata, for example, metadata["roomType"]:"whiteboard" AND roomId^"liveblocks:engineering". Learn more about filtering rooms with query language.

    metadata["color"]:"blue"
  • userId optional

    A filter on users accesses.

    user-123
  • groupIds optional

    A filter on groups accesses. Multiple groups can be used.

    group1,group2

Request

GET
https://api.liveblocks.io/v2/rooms

Response

Status:

Success. Returns the list of rooms, the next page cursor, and the next page URL.

{  "nextCursor": "W1siaWQiLCJVRzhWYl82SHRUS0NzXzFvci1HZHQiXSxbImNyZWF0ZWRBdCIsMTY2MDAwMDk4ODEzN11d",  "data": [    {      "type": "room",      "id": "HTOGSiXcORTECjfNBBLii",      "lastConnectionAt": "2022-08-08T23:23:15.281Z",      "createdAt": "2022-08-08T23:23:15.281Z",      "organizationId": "org_123456789",      "metadata": {        "name": [          "My room"        ],        "type": [          "whiteboard"        ]      },      "defaultAccesses": [        "*:write"      ],      "groupsAccesses": {        "product": [          "*:write"        ]      },      "usersAccesses": {        "vinod": [          "*:write"        ]      }    }  ]}
post/rooms

Create room

This endpoint creates a new room. id and defaultAccesses are required. When provided with a ?idempotent query argument, will not return a 409 when the room already exists, but instead return the existing room as-is. Corresponds to liveblocks.createRoom, or to liveblocks.getOrCreateRoom when ?idempotent is provided.

  • defaultAccesses is the default room permission list, for example [], ["*:read"], ["*:write"], or a more granular permission list.
  • metadata could be key/value as string or string[]. metadata supports maximum 50 entries. Key length has a limit of 40 characters maximum. Value length has a limit of 256 characters maximum. metadata is optional field.
  • usersAccesses contains user-specific permission lists. It can contain 1000 ids maximum. Id length has a limit of 256 characters. usersAccesses is optional field.
  • groupsAccesses contains group-specific permission lists and is optional.

Parameters

  • idempotent optional

    When provided, will not return a 409 when the room already exists, but instead return the existing room as-is. Corresponds to liveblocks.getOrCreateRoom.

    true

Request body

POST
https://api.liveblocks.io/v2/rooms
{  "id": "my-room-3ebc26e2bf96",  "defaultAccesses": [    "*:write"  ],  "metadata": {    "color": "blue"  },  "usersAccesses": {    "alice": [      "*:write"    ]  },  "groupsAccesses": {    "product": [      "*:write"    ]  }}

Response

Status:

Success. Returns the created room.

{  "type": "room",  "id": "my-room-3ebc26e2bf96",  "lastConnectionAt": "2022-08-22T15:10:25.225Z",  "createdAt": "2022-08-22T15:10:25.225Z",  "organizationId": "org_123456789",  "metadata": {    "color": "blue"  },  "defaultAccesses": [    "*:write"  ],  "groupsAccesses": {    "product": [      "*:write"    ]  },  "usersAccesses": {    "alice": [      "*:write"    ]  }}
get/rooms/:roomId

Get room

This endpoint returns a room by its ID. Corresponds to liveblocks.getRoom.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}

Response

Status:

Success. Returns the room.

{  "type": "room",  "id": "react-todo-list",  "lastConnectionAt": "2022-08-04T21:07:09.380Z",  "createdAt": "2022-07-13T14:32:50.697Z",  "organizationId": "org_123456789",  "metadata": {    "color": "blue",    "size": "10",    "target": [      "abc",      "def"    ]  },  "defaultAccesses": [    "*:write"  ],  "groupsAccesses": {    "marketing": [      "*:write"    ]  },  "usersAccesses": {    "alice": [      "*:write"    ],    "vinod": [      "*:write"    ]  }}
post/rooms/:roomId

Update room

This endpoint updates specific properties of a room. Corresponds to liveblocks.updateRoom.

It’s not necessary to provide the entire room’s information. Setting a property to null means to delete this property. For example, if you want to remove access to a specific user without losing other users: { "usersAccesses": { "john": null } } defaultAccesses, metadata, usersAccesses, groupsAccesses can be updated.

  • defaultAccesses is the default room permission list, for example [], ["*:read"], ["*:write"], or a more granular permission list.
  • metadata could be key/value as string or string[]. metadata supports maximum 50 entries. Key length has a limit of 40 characters maximum. Value length has a limit of 256 characters maximum. metadata is optional field.
  • usersAccesses contains user-specific permission lists. It can contain 1000 ids maximum. Id length has a limit of 256 characters. usersAccesses is optional field.
  • groupsAccesses contains group-specific permission lists and is optional.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}
{  "defaultAccesses": [    "*:write"  ],  "usersAccesses": {    "vinod": [      "*:write"    ],    "alice": [      "*:write"    ]  },  "groupsAccesses": {    "marketing": [      "*:write"    ]  },  "metadata": {    "color": "blue"  }}

Response

Status:

Success. Returns the updated room.

{  "type": "room",  "id": "react-todo-list",  "lastConnectionAt": "2022-08-04T21:07:09.380Z",  "createdAt": "2022-07-13T14:32:50.697Z",  "organizationId": "org_123456789",  "metadata": {    "color": "blue",    "size": "10",    "target": [      "abc",      "def"    ]  },  "defaultAccesses": [    "*:write"  ],  "groupsAccesses": {    "marketing": [      "*:write"    ]  },  "usersAccesses": {    "alice": [      "*:write"    ],    "vinod": [      "*:write"    ]  }}
delete/rooms/:roomId

Delete room

This endpoint deletes a room. A deleted room is no longer accessible from the API or the dashboard and it cannot be restored. Corresponds to liveblocks.deleteRoom.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request

DELETE
https://api.liveblocks.io/v2/rooms/{roomId}
get/rooms/:roomId/prewarm

Prewarm room

Speeds up connecting to a room for the next 10 seconds. Use this when you know a user will be connecting to a room with RoomProvider or enterRoom within 10 seconds, and the room will load quicker. Corresponds to liveblocks.prewarmRoom.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/prewarm
post/rooms/:roomId/upsert

Upsert (update or create) room

This endpoint updates specific properties of a room. Corresponds to liveblocks.upsertRoom.

It’s not necessary to provide the entire room’s information. Setting a property to null means to delete this property. For example, if you want to remove access to a specific user without losing other users: { "usersAccesses": { "john": null } } defaultAccesses, metadata, usersAccesses, groupsAccesses can be updated.

  • defaultAccesses is the default room permission list, for example [], ["*:read"], ["*:write"], or a more granular permission list.
  • metadata could be key/value as string or string[]. metadata supports maximum 50 entries. Key length has a limit of 40 characters maximum. Value length has a limit of 256 characters maximum. metadata is optional field.
  • usersAccesses contains user-specific permission lists. It can contain 1000 ids maximum. Id length has a limit of 256 characters. usersAccesses is optional field.
  • groupsAccesses contains group-specific permission lists and is optional.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/upsert
{  "update": {    "usersAccesses": {      "vinod": [        "*:write"      ],      "alice": [        "*:write"      ]    },    "groupsAccesses": {      "marketing": [        "*:write"      ]    },    "metadata": {      "color": "blue"    }  },  "create": {    "defaultAccesses": [      "*:write"    ]  }}

Response

Status:

Success. Returns the updated or created room.

{  "type": "room",  "id": "react-todo-list",  "lastConnectionAt": "2022-08-04T21:07:09.380Z",  "createdAt": "2022-07-13T14:32:50.697Z",  "organizationId": "org_123456789",  "metadata": {    "color": "blue",    "size": "10",    "target": [      "abc",      "def"    ]  },  "defaultAccesses": [    "*:write"  ],  "groupsAccesses": {    "marketing": [      "*:write"    ]  },  "usersAccesses": {    "alice": [      "*:write"    ],    "vinod": [      "*:write"    ]  }}
post/rooms/:roomId/update-room-id

Update room ID

This endpoint permanently updates the room’s ID. All existing references to the old room ID will need to be updated. Returns the updated room. Corresponds to liveblocks.updateRoomId.

Parameters

  • roomId required

    The new ID for the room

    my-room-id

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/update-room-id
{  "newRoomId": "new-room-id"}

Response

Status:

Success. Returns the updated room with the new ID.

{  "type": "room",  "id": "react-todo-list",  "lastConnectionAt": "2022-08-04T21:07:09.380Z",  "createdAt": "2022-07-13T14:32:50.697Z",  "organizationId": "org_123456789",  "metadata": {    "color": "blue",    "size": "10",    "target": [      "abc",      "def"    ]  },  "defaultAccesses": [    "*:write"  ],  "groupsAccesses": {    "marketing": [      "*:write"    ]  },  "usersAccesses": {    "alice": [      "*:write"    ],    "vinod": [      "*:write"    ]  }}
post/rooms/:roomId/update-organization-id

Update room organization ID

This endpoint updates the room's organization ID. The fromOrganizationId must match the room's current organization ID. Returns the updated room.

Parameters

  • roomId required

    The ID of the room

    my-room-id

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/update-organization-id
{  "fromOrganizationId": "org_123456789",  "toOrganizationId": "org_987654321"}

Response

Status:

Success. Returns the updated room with the new organization ID.

{  "type": "room",  "id": "react-todo-list",  "lastConnectionAt": "2022-08-04T21:07:09.380Z",  "createdAt": "2022-07-13T14:32:50.697Z",  "organizationId": "org_987654321",  "metadata": {    "color": "blue",    "size": "10",    "target": [      "abc",      "def"    ]  },  "defaultAccesses": [    "*:write"  ],  "groupsAccesses": {    "marketing": [      "*:write"    ]  },  "usersAccesses": {    "alice": [      "*:write"    ],    "vinod": [      "*:write"    ]  }}
get/rooms/:roomId/active-users

Get active users

This endpoint returns a list of users currently present in the requested room. Corresponds to liveblocks.getActiveUsers.

For optimal performance, we recommend calling this endpoint no more than once every 10 seconds. Duplicates can occur if a user is in the requested room with multiple browser tabs opened.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/active-users

Response

Status:

Success. Returns the list of active users for the specified room.

{  "data": [    {      "type": "user",      "connectionId": 16,      "id": "alice",      "info": {}    },    {      "type": "user",      "connectionId": 20,      "id": "bob",      "info": {}    }  ]}
post/rooms/:roomId/presence

Set ephemeral presence

This endpoint sets ephemeral presence for a user in a room without requiring a WebSocket connection. The presence data will automatically expire after the specified TTL (time-to-live). This is useful for scenarios like showing an AI agent's presence in a room. The presence will be broadcast to all connected users in the room. Corresponds to liveblocks.setPresence.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/presence
{  "userId": "agent-123",  "data": {    "status": "active",    "cursor": {      "x": 100,      "y": 200    }  },  "userInfo": {    "name": "AI Assistant",    "avatar": "https://example.org/images/agent123.jpg"  },  "ttl": 60}
post/rooms/:roomId/broadcast-event

Broadcast event to a room

This endpoint enables the broadcast of an event to a room without having to connect to it via the client from @liveblocks/client. It takes any valid JSON as a request body. The connectionId passed to event listeners is -1 when using this API. Corresponds to liveblocks.broadcastEvent.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/broadcast-event
{  "type": "EMOJI",  "emoji": "🔥"}

Storage

get/rooms/:roomId/storage

Get Storage document

Returns the contents of the room’s Storage tree. Corresponds to liveblocks.getStorageDocument.

The default outputted format is called “plain LSON”, which includes information on the Live data structures in the tree. These nodes show up in the output as objects with two properties, for example:

{  "liveblocksType": "LiveObject",  "data": ...}

If you’re not interested in this information, you can use the simpler ?format=json query param, see below.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • format optional

    Use the json format to output a simplified JSON representation of the Storage tree. In that format, each LiveObject and LiveMap becomes a simple JSON object, each LiveList becomes a simple JSON array, and each LiveFile becomes its metadata object. This is a lossy format because information about the original data structures is not retained, but it may be easier to work with.

    Allowed values: plain-lson, json
    json

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/storage

Response

Status:

Success. Returns the room’s Storage as JSON.

{  "liveblocksType": "LiveObject",  "data": {    "aLiveObject": {      "liveblocksType": "LiveObject",      "data": {        "a": 1      }    },    "aLiveList": {      "liveblocksType": "LiveList",      "data": [        "a",        "b"      ]    },    "aLiveMap": {      "liveblocksType": "LiveMap",      "data": {        "a": 1,        "b": 2      }    },    "aLiveFile": {      "liveblocksType": "LiveFile",      "data": {        "id": "fl_abc123456789012345678",        "name": "photo.png",        "size": 12345,        "mimeType": "image/png"      }    }  }}
post/rooms/:roomId/storage

Initialize Storage document

This endpoint initializes or reinitializes a room’s Storage. The room must already exist. Calling this endpoint will disconnect all users from the room if there are any, triggering a reconnect. Corresponds to liveblocks.initializeStorageDocument.

The format of the request body is the same as what’s returned by the get Storage endpoint.

For each Liveblocks data structure that you want to create, you need a JSON element having two properties:

  • "liveblocksType" => "LiveObject" | "LiveList" | "LiveMap" | "LiveFile"
  • "data" => contains the nested data structures (children) and data.

The root’s type can only be LiveObject.

A utility function, toPlainLson is included in @liveblocks/client from 1.0.9 to help convert LiveObject, LiveList, LiveMap, and LiveFile to the structure expected by the endpoint.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/storage
{  "liveblocksType": "LiveObject",  "data": {    "aLiveObject": {      "liveblocksType": "LiveObject",      "data": {        "a": 1      }    },    "aLiveList": {      "liveblocksType": "LiveList",      "data": [        "a",        "b"      ]    },    "aLiveMap": {      "liveblocksType": "LiveMap",      "data": {        "a": 1,        "b": 2      }    },    "aLiveFile": {      "liveblocksType": "LiveFile",      "data": {        "id": "fl_abc123456789012345678",        "name": "photo.png",        "size": 12345,        "mimeType": "image/png"      }    }  }}

Response

Status:

Success. The Storage is initialized. Returns the room’s Storage as JSON.

{  "liveblocksType": "LiveObject",  "data": {    "aLiveObject": {      "liveblocksType": "LiveObject",      "data": {        "a": 1      }    },    "aLiveList": {      "liveblocksType": "LiveList",      "data": [        "a",        "b"      ]    },    "aLiveMap": {      "liveblocksType": "LiveMap",      "data": {        "a": 1,        "b": 2      }    },    "aLiveFile": {      "liveblocksType": "LiveFile",      "data": {        "id": "fl_abc123456789012345678",        "name": "photo.png",        "size": 12345,        "mimeType": "image/png"      }    }  }}
delete/rooms/:roomId/storage

Delete Storage document

This endpoint deletes all of the room’s Storage data. Calling this endpoint will disconnect all users from the room if there are any. Corresponds to liveblocks.deleteStorageDocument.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request

DELETE
https://api.liveblocks.io/v2/rooms/{roomId}/storage
patch/rooms/:roomId/storage/json-patch

Apply JSON Patch to Storage

Applies a sequence of JSON Patch operations to the room's Storage document, useful for modifying Storage. Operations are applied in order; if any operation fails, the document is not changed and a 422 response with a helpful message is returned.

Paths and data types: Be as specific as possible with your target path. Every parent in the chain of path segments must be a LiveObject, LiveList, or LiveMap. Complex nested objects passed in add or replace operations are automatically converted to LiveObjects and LiveLists. LiveText is a leaf node: only the LiveText node itself is addressable, not fields under its serialized data. Use replace with a string or a LiveTextData array to replace the whole node, for example /text with [["Hello"]]; use remove on /text to remove the node. LiveText versioning is internal and is not part of this API.

Performance: For large Storage documents, applying a patch can be expensive because the full state is reconstructed on the server to apply the operations. Very large documents may not be suitable for this endpoint.

For a full guide with examples, see Modifying storage via REST API with JSON Patch.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request body

PATCH
https://api.liveblocks.io/v2/rooms/{roomId}/storage/json-patch
[  {    "op": "add",    "path": "/score",    "value": 42  },  {    "op": "remove",    "path": "/oldKey"  }]
[  {    "op": "add",    "path": "/layers/-",    "value": "newLayer"  }]
[  {    "op": "add",    "path": "/photo",    "value": {      "liveblocksType": "LiveFile",      "data": {        "id": "fl_abc123456789012345678",        "name": "photo.png",        "size": 12345,        "mimeType": "image/png"      }    }  }]
get/rooms/:roomId/storage/files/:fileId

Get Storage file

Returns an uploaded Storage file's metadata and a presigned download URL. The URL expires after one hour.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • fileId required

    ID of the Storage file

    fl_abc123456789012345678

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/storage/files/{fileId}

Response

Status:

Success. Returns the file metadata and presigned download URL.

{  "id": {    "type": "string",    "pattern": "^fl_[A-Za-z0-9_-]{21}$"  },  "name": {    "type": "string"  },  "size": {    "type": "integer",    "minimum": 0  },  "mimeType": {    "type": "string"  },  "url": {    "type": "string",    "format": "uri",    "description": "Presigned download URL"  },  "expiresAt": {    "type": "string",    "format": "date-time",    "description": "Expiration time of the presigned URL"  }}
put/rooms/:roomId/storage/files/:fileId/upload/:name

Upload Storage file

Uploads a file's bytes to a room and returns the metadata needed to create a LiveFile. For large files, use the multipart upload operations instead. Repeating the request with the same file ID, name, and file size returns the existing upload.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • fileId required

    ID for the Storage file

    fl_abc123456789012345678
  • name required

    Name of the file

    photo.png
  • fileSize optional

    Expected file size in bytes.

    • Minimum: 0
    • Maximum:
    • Default:
    12345

Request body

PUT
https://api.liveblocks.io/v2/rooms/{roomId}/storage/files/{fileId}/upload/{name}

Response

Status:

Success. Returns the uploaded file metadata.

{  "id": {    "type": "string",    "pattern": "^fl_[A-Za-z0-9_-]{21}$",    "description": "ID of the uploaded Storage file",    "example": "fl_abc123456789012345678"  },  "name": {    "type": "string",    "description": "Original file name",    "example": "photo.png"  },  "size": {    "type": "integer",    "minimum": 0,    "description": "File size in bytes",    "example": 12345  },  "mimeType": {    "type": "string",    "description": "File MIME type",    "example": "image/png"  }}
post/rooms/:roomId/storage/files/:fileId/multipart/:name

Create Storage file multipart upload

Starts a multipart upload for a Storage file.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • fileId required

    ID for the Storage file

    fl_abc123456789012345678
  • name required

    Name of the file

    video.mp4
  • fileSize optional

    Expected file size in bytes

    • Minimum: 0
    • Maximum:
    • Default:
    10485760

Request

POST
https://api.liveblocks.io/v2/rooms/{roomId}/storage/files/{fileId}/multipart/{name}

Response

Status:

Success. Returns identifiers for the multipart upload.

{  "fileId": {    "type": "string",    "pattern": "^fl_[A-Za-z0-9_-]{21}$"  },  "uploadId": {    "type": "string"  }}
put/rooms/:roomId/storage/files/:fileId/multipart/:uploadId/:partNumber

Upload Storage file multipart part

Uploads one part of a Storage file multipart upload.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • fileId required

    ID of the Storage file

    fl_abc123456789012345678
  • uploadId required

    ID returned when the multipart upload was created

  • partNumber required

    One-based part number

    • Minimum: 1
    • Maximum:
    • Default:
    1

Request body

PUT
https://api.liveblocks.io/v2/rooms/{roomId}/storage/files/{fileId}/multipart/{uploadId}/{partNumber}

Response

Status:

Success. Returns the uploaded part's number and ETag.

{  "partNumber": {    "type": "integer",    "minimum": 1  },  "etag": {    "type": "string"  }}
post/rooms/:roomId/storage/files/:fileId/multipart/:uploadId/complete

Complete Storage file multipart upload

Completes a multipart upload and returns the metadata needed to create a LiveFile.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • fileId required

    ID of the Storage file

    fl_abc123456789012345678
  • uploadId required

    ID returned when the multipart upload was created

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/storage/files/{fileId}/multipart/{uploadId}/complete
{  "parts": {    "type": "array",    "items": {      "type": "object",      "properties": {        "partNumber": {          "type": "integer",          "minimum": 1        },        "etag": {          "type": "string"        }      },      "required": [        "partNumber",        "etag"      ],      "additionalProperties": false    }  }}

Response

Status:

Success. Returns the uploaded file metadata.

{  "id": {    "type": "string",    "pattern": "^fl_[A-Za-z0-9_-]{21}$",    "description": "ID of the uploaded Storage file",    "example": "fl_abc123456789012345678"  },  "name": {    "type": "string",    "description": "Original file name",    "example": "photo.png"  },  "size": {    "type": "integer",    "minimum": 0,    "description": "File size in bytes",    "example": 12345  },  "mimeType": {    "type": "string",    "description": "File MIME type",    "example": "image/png"  }}
delete/rooms/:roomId/storage/files/:fileId/multipart/:uploadId

Abort Storage file multipart upload

Aborts a multipart upload and discards its uploaded parts.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • fileId required

    ID of the Storage file

    fl_abc123456789012345678
  • uploadId required

    ID returned when the multipart upload was created

Request

DELETE
https://api.liveblocks.io/v2/rooms/{roomId}/storage/files/{fileId}/multipart/{uploadId}

Yjs

get/rooms/:roomId/ydoc

Get Yjs document

This endpoint returns a JSON representation of the room’s Yjs document. Corresponds to liveblocks.getYjsDocument.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • formatting optional

    If present, YText will return formatting.

  • key optional

    Returns only a single key’s value, e.g. doc.get(key).toJSON().

    root
  • type optional

    Used with key to override the inferred type, i.e. "ymap" will return doc.get(key, Y.Map).

    Allowed values: ymap, ytext, yxmltext, yxmlfragment, yarray
    ymap

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/ydoc

Response

Status:

Success. Returns the room’s Yjs document as JSON.

{  "someYText": "Contents of YText"}
put/rooms/:roomId/ydoc

Send a binary Yjs update

This endpoint is used to send a Yjs binary update to the room’s Yjs document. You can use this endpoint to initialize Yjs data for the room or to update the room’s Yjs document. To send an update to a subdocument instead of the main document, pass its guid. Corresponds to liveblocks.sendYjsBinaryUpdate.

The update is typically obtained by calling Y.encodeStateAsUpdate(doc). See the Yjs documentation for more details. When manually making this HTTP call, set the HTTP header Content-Type to application/octet-stream, and send the binary update (a Uint8Array) in the body of the HTTP request. This endpoint does not accept JSON, unlike most other endpoints.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • guid optional

    ID of the subdocument

    subdoc-guid-123

Request body

PUT
https://api.liveblocks.io/v2/rooms/{roomId}/ydoc

This endpoint returns the room's Yjs document encoded as a single binary update. This can be used by Y.applyUpdate(responseBody) to get a copy of the document in your back end. See Yjs documentation for more information on working with updates. To return a subdocument instead of the main document, pass its guid. Corresponds to liveblocks.getYjsDocumentAsBinaryUpdate.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • guid optional

    ID of the subdocument

    subdoc-guid-123

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/ydoc-binary

Version History

get/rooms/:roomId/versions

Get Version History

This endpoint returns a list of version history snapshots for the room. The versions are returned sorted by creation date, from newest to oldest. Corresponds to liveblocks.getVersionHistory.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • limit optional

    A limit on the number of versions to be returned. The limit can range between 1 and 100, and defaults to 20.

    • Minimum: 1
    • Maximum: 100
    • Default: 20
    20
  • cursor optional

    A cursor used for pagination. Get the value from the nextCursor response of the previous page.

    eyJjcmVhdGVkQXQiOjE2NjAwMDA5ODgxMzd9

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/versions

Response

Status:

Success. Returns the list of version history snapshots and the next page cursor.

{  "data": [    {      "id": "vh_abc123",      "createdAt": "2024-10-15T10:30:00.000Z",      "authors": [        {          "id": "user-123"        },        {          "id": "user-456"        }      ]    }  ],  "nextCursor": "eyJjcmVhdGVkQXQiOiIyMDI0LTEwLTE1VDEwOjMwOjAwLjAwMFoifQ=="}
post/rooms/:roomId/versions

Create version history snapshot

This endpoint creates a new version history snapshot of the room, capturing both its Storage and Yjs documents. Corresponds to liveblocks.createVersionHistorySnapshot.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request

POST
https://api.liveblocks.io/v2/rooms/{roomId}/versions

Response

Status:

Success. Returns the created version ID.

{  "data": {    "id": "vh_abc123"  }}
get/rooms/:roomId/versions/:versionId/yjs

Get Yjs document version

This endpoint returns a specific version of the room's Yjs document encoded as a binary Yjs update. Corresponds to liveblocks.getYjsVersion.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • versionId required

    ID of the version

    vh_abc123

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/versions/{versionId}/yjs
delete/rooms/:roomId/versions/:versionId

Delete a version

This endpoint permanently deletes a version from the room's history. Corresponds to liveblocks.deleteVersion.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • versionId required

    ID of the version

    vh_abc123

Request

DELETE
https://api.liveblocks.io/v2/rooms/{roomId}/versions/{versionId}

Comments

get/rooms/:roomId/threads

Get room threads

This endpoint returns the threads in the requested room. Corresponds to liveblocks.getThreads.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • query optional

    Query to filter threads. You can filter by metadata, resolved, and visibility, for example, metadata["status"]:"open" AND metadata["color"]:"red" AND resolved:true AND visibility:"private". Learn more about filtering threads with query language.

    metadata["color"]:"blue"

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/threads

Response

Status:

Success. Returns list of threads in a room.

{  "data": [    {      "type": "thread",      "id": "thread-id",      "roomId": "room-id",      "comments": [        {          "type": "comment",          "threadId": "thread-id",          "roomId": "room-id",          "id": "comment-id",          "userId": "string",          "createdAt": "2019-08-24T14:15:22Z",          "editedAt": "2019-08-24T14:15:22Z",          "deletedAt": "2019-08-24T14:15:22Z",          "body": {},          "metadata": {},          "reactions": [],          "attachments": []        }      ],      "createdAt": "2019-08-24T14:15:22Z",      "metadata": {},      "resolved": false,      "visibility": "public",      "updatedAt": "2019-08-24T14:15:22Z"    }  ]}
post/rooms/:roomId/threads

Create thread

This endpoint creates a new thread and the first comment in the thread. Corresponds to liveblocks.createThread.

A comment’s body is an array of paragraphs, each containing child nodes. Here’s an example of how to construct a comment’s body, which can be submitted under comment.body.

{  "version": 1,  "content": [    {      "type": "paragraph",      "children": [{ "text": "Hello " }, { "text": "world", "bold": true }]    }  ]}

metadata supports maximum 50 entries. Key length has a limit of 40 characters maximum. Value length has a limit of 4000 characters maximum for strings.

Parameters

  • roomId required

    ID of the room

    my-room-id

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/threads
{  "comment": {    "userId": "alice",    "createdAt": "2022-07-13T14:32:50.697Z",    "body": {      "version": 1,      "content": []    },    "metadata": {      "tag": "important",      "spam": false    }  },  "metadata": {    "color": "blue"  }}

Response

Status:

Success. Returns the created thread.

{  "type": "thread",  "id": "thread-id",  "roomId": "room-id",  "comments": [    {      "type": "comment",      "threadId": "thread-id",      "roomId": "room-id",      "id": "comment-id",      "userId": "alice",      "createdAt": "2022-07-13T14:32:50.697Z",      "body": {},      "metadata": {},      "reactions": [],      "attachments": []    }  ],  "createdAt": "2022-07-13T14:32:50.697Z",  "updatedAt": "2022-07-13T14:32:50.697Z",  "metadata": {    "color": "blue"  },  "resolved": false,  "visibility": "public"}
get/rooms/:roomId/threads/:threadId

Get thread

This endpoint returns a thread by its ID. Corresponds to liveblocks.getThread.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • threadId required

    ID of the thread

    th_abc123

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/threads/{threadId}

Response

Status:

Success. Returns requested thread.

{  "type": "thread",  "id": "thread-id",  "roomId": "room-id",  "comments": [    {      "type": "comment",      "threadId": "thread-id",      "roomId": "room-id",      "id": "comment-id",      "userId": "string",      "createdAt": "2019-08-24T14:15:22Z",      "editedAt": "2019-08-24T14:15:22Z",      "deletedAt": "2019-08-24T14:15:22Z",      "body": {},      "metadata": {},      "reactions": [],      "attachments": []    }  ],  "createdAt": "2019-08-24T14:15:22Z",  "metadata": {},  "resolved": false,  "visibility": "public",  "updatedAt": "2019-08-24T14:15:22Z"}
delete/rooms/:roomId/threads/:threadId

Delete thread

This endpoint deletes a thread by its ID. Corresponds to liveblocks.deleteThread.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • threadId required

    ID of the thread

    th_abc123

Request

DELETE
https://api.liveblocks.io/v2/rooms/{roomId}/threads/{threadId}
get/rooms/:roomId/threads/:threadId/participants

Get thread participantsDeprecated

Deprecated. Prefer using thread subscriptions instead.

This endpoint returns the list of thread participants. It is a list of unique user IDs representing all the thread comment authors and mentioned users in comments. Corresponds to liveblocks.getThreadParticipants.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • threadId required

    ID of the thread

    th_abc123

Request

GET
https://api.liveblocks.io/v2/rooms/{roomId}/threads/{threadId}/participants

Response

Status:

Success. Returns the thread’s participants

{  "participantIds": [    "user-1",    "user-2"  ]}
post/rooms/:roomId/threads/:threadId/metadata

Edit thread metadata

This endpoint edits the metadata of a thread. The metadata is a JSON object that can be used to store any information you want about the thread, in string, number, or boolean form. Set a property to null to remove it. Corresponds to liveblocks.editThreadMetadata.

metadata supports maximum 50 entries. Key length has a limit of 40 characters maximum. Value length has a limit of 4000 characters maximum for strings.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • threadId required

    ID of the thread

    th_abc123

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/threads/{threadId}/metadata
{  "metadata": {    "color": "yellow"  },  "userId": "alice",  "createdAt": "2023-07-13T14:32:50.697Z"}

Response

Status:

Success. Returns the updated metadata.

{  "color": "yellow"}
post/rooms/:roomId/threads/:threadId/mark-as-resolved

Mark thread as resolved

This endpoint marks a thread as resolved. The request body must include a userId to identify who resolved the thread. Returns the updated thread. Corresponds to liveblocks.markThreadAsResolved.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • threadId required

    ID of the thread

    th_abc123

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/threads/{threadId}/mark-as-resolved
{  "userId": {    "type": "string",    "description": "The user ID of the user who marked the thread as resolved."  }}

Response

Status:

Success. Returns the updated thread.

{  "type": {    "const": "thread"  },  "id": {    "type": "string"  },  "roomId": {    "type": "string"  },  "comments": {    "type": "array",    "items": {      "type": "object",      "properties": {        "type": {          "const": "comment"        },        "threadId": {          "type": "string"        },        "roomId": {          "type": "string"        },        "id": {          "type": "string"        },        "userId": {          "type": "string"        },        "createdAt": {          "type": "string",          "format": "date-time"        },        "editedAt": {          "type": "string",          "format": "date-time"        },        "deletedAt": {          "type": "string",          "format": "date-time"        },        "body": {          "type": "object",          "properties": {            "version": {              "type": "integer"            },            "content": {              "type": "array",              "items": {                "type": "object",                "additionalProperties": true              }            }          },          "required": [            "version",            "content"          ],          "additionalProperties": false,          "example": {            "version": 1,            "content": [              {                "type": "paragraph",                "children": [                  {                    "text": "Hello "                  },                  {                    "text": "world",                    "bold": true                  }                ]              }            ]          }        },        "metadata": {          "type": "object",          "additionalProperties": {            "oneOf": [              {                "type": "string",                "maxLength": 4000              },              {                "type": "number"              },              {                "type": "boolean"              }            ]          },          "required": [],          "examples": [            {              "tag": "important",              "spam": false            }          ],          "description": "Custom metadata attached to a comment. Supports maximum 50 entries. Key length has a limit of 40 characters maximum. Value length has a limit of 4000 characters maximum for strings.",          "maxProperties": 50,          "propertyNames": {            "maxLength": 40          }        },        "reactions": {          "type": "array",          "items": {            "type": "object",            "properties": {              "userId": {                "type": "string"              },              "createdAt": {                "type": "string",                "format": "date-time"              },              "emoji": {                "type": "string"              }            },            "required": [              "userId",              "emoji",              "createdAt"            ],            "additionalProperties": false,            "examples": [              {                "emoji": "👨‍👩‍👧",                "createdAt": "2022-07-13T14:32:50.697Z",                "userId": "alice"              }            ]          }        },        "attachments": {          "type": "array",          "items": {            "type": "object",            "properties": {              "type": {                "type": "string",                "const": "attachment"              },              "id": {                "type": "string"              },              "mimeType": {                "type": "string"              },              "name": {                "type": "string"              },              "size": {                "type": "integer"              }            },            "required": [              "type",              "id",              "mimeType",              "name",              "size"            ],            "additionalProperties": false,            "example": {              "type": "attachment",              "id": "at_abc123",              "mimeType": "image/png",              "name": "screenshot.png",              "size": 12345            }          }        }      },      "required": [        "type",        "threadId",        "roomId",        "id",        "userId",        "createdAt",        "metadata",        "reactions",        "attachments"      ],      "examples": [        {          "type": "comment",          "threadId": "thread-id",          "roomId": "room-id",          "id": "comment-id",          "userId": "string",          "createdAt": "2019-08-24T14:15:22Z",          "editedAt": "2019-08-24T14:15:22Z",          "deletedAt": "2019-08-24T14:15:22Z",          "body": {},          "metadata": {},          "reactions": [],          "attachments": []        }      ]    }  },  "createdAt": {    "type": "string",    "format": "date-time"  },  "metadata": {    "type": "object",    "additionalProperties": {      "oneOf": [        {          "type": "string",          "maxLength": 4000        },        {          "type": "number"        },        {          "type": "boolean"        }      ]    },    "required": [],    "examples": [      {        "color": "blue",        "age": 25      }    ],    "description": "Custom metadata attached to a thread. Supports maximum 50 entries. Key length has a limit of 40 characters maximum. Value length has a limit of 4000 characters maximum for strings.",    "maxProperties": 50,    "propertyNames": {      "maxLength": 40    }  },  "resolved": {    "type": "boolean"  },  "visibility": {    "type": "string",    "enum": [      "public",      "private"    ]  },  "updatedAt": {    "type": "string",    "format": "date-time"  }}
post/rooms/:roomId/threads/:threadId/mark-as-unresolved

Mark thread as unresolved

This endpoint marks a thread as unresolved. The request body must include a userId to identify who unresolved the thread. Returns the updated thread. Corresponds to liveblocks.markThreadAsUnresolved.

Parameters

  • roomId required

    ID of the room

    my-room-id
  • threadId required

    ID of the thread

    th_abc123

Request body

POST
https://api.liveblocks.io/v2/rooms/{roomId}/threads/{threadId}/mark-as-unresolved
{  "userId": {    "type": "string",    "description": "The user ID of the user who marked the thread as unresolved."  }}

Response

Status:

Success. Returns the updated thread.

{  "type": {    "const": "thread"  },  "id": {    "type": "string"  },  "roomId": {    "type": "string"  },  "comments": {    "type": "array",    "items": {      "type": "object",      "properties": {        "type": {          "const": "comment"        },        "threadId": {          "type": "string"        },        "roomId": {          "type": "string"        },        "id": {          "type": "string"        },        "userId": {          "type": "string"        },        "createdAt": {          "type": "string",          "format": "date-time"        },        "editedAt": {          "type": "string",          "format": "date-time"        },        "deletedAt": {          "type": "string",          "format": "date-time"        },        "body": {          "type": "object",          "properties": {            "version": {              "type": "integer"            },            "content": {              "type": "array",              "items": {                "type": "object",                "additionalProperties": true              }            }          },          "required": [            "version",            "content"          ],          "additionalProperties": false,          "example": {            "version": 1,            "content": [              {                "type": "paragraph",                "children": [                  {                    "text": "Hello "                  },                  {                    "text": "world",                    "bold": true                  }                ]              }            ]          }        },        "metadata": {          "type": "object",          "additionalProperties": {            "oneOf": [              {                "type": "string",                "maxLength": 4000              },              {                "type": "number"              },              {                "type": "boolean"              }            ]          },          "required": [],          "examples": [            {              "tag": "important",              "spam": false            }          ],          "description": "Custom metadata attached to a comment. Supports maximum 50 entries. Key length has a limit of 40 characters maximum. Value length has a limit of 4000 characters maximum for strings.",          "maxProperties": 50,          "propertyNames": {            "maxLength": 40          }        },        "reactions": {          "type": "array",          "items": {            "type": "object",            "properties": {              "userId": {                "type": "string"              },              "createdAt": {                "type": "string",                "format": "date-time"              },              "emoji": {                "type": "string"              }            },            "required": [              "userId",              "emoji",              "createdAt"            ],            "additionalProperties": false,            "examples": [              {                "emoji": "👨‍👩‍👧",                "createdAt": "2022-07-13T14:32:50.697Z",                "userId": "alice"              }            ]          }        },        "attachments": {          "type": "array",          "items": {            "type": "object",            "properties": {              "type": {                "type": "string",                "const": "attachment"              },              "id": {                "type": "string"              },              "mimeType": {                "type": "string"              },              "name": {                "type": "string"              },              "size": {                "type": "integer"              }            },            "required": [              "type",              "id",              "mimeType",              "name",              "size"            ],            "additionalProperties": false,            "example": {              "type": "attachment",              "id": "at_abc123",              "mimeType": "image/png",              "name": "screenshot.png",              "size": 12345            }          }        }      },      "required": [        "type",        "threadId",        "roomId",        "id",        "userId",        "createdAt",        "metadata",        "reactions",        "attachments"      ],      "examples": [        {          "type": "comment",          "threadId": "thread-id",          "roomId": "room-id",          "id": "comment-id",          "userId": "string",          "createdAt": "2019-08-24T14:15:22Z",          "editedAt": "2019-08-24T14:15:22Z",          "deletedAt": "2019-08-24T14:15:22Z",          "body": {},