OpenVidu Meet Registered Members Tutorial#
This tutorial extends the External Members tutorial to show how to create OpenVidu Meet users with the Users API and grant them access to a room as registered members.
Whereas an external member is an anonymous participant who joins through a unique link, a registered member is a real OpenVidu Meet user added to a specific room: all registered members share the room's authenticated access URL and prove their identity by logging in with their own OpenVidu Meet credentials.
Building on the External Members tutorial, it adds the following:
- Users can create, list and delete OpenVidu Meet users.
- Users can add a registered user (instead of an external one) as a member of a room.
- A registered member joins the room by logging in with their OpenVidu Meet credentials.
The application uses the OpenVidu Meet API to manage users, rooms and room members, and the OpenVidu Meet WebComponent to embed the meeting.
Anonymous access vs. room members
OpenVidu Meet rooms can be accessed either through anonymous access links (used by the other tutorials) or by adding room members with personalized access and permissions. Registered members are one of the two kinds of room members (the other being external members). See Room Access for the full picture.
Running this tutorial#
1. Run OpenVidu Meet#
You need Docker Desktop. You can install it on Windows , Mac or Linux .
Run this command in Docker Desktop's terminal:
Info
For a detailed guide on how to run OpenVidu Meet locally, visit Try OpenVidu Meet locally .
2. Download the tutorial code#
3. Run the application#
To run this application, you need Node.js (≥ 18) installed on your device.
- Navigate into the application directory
- Install dependencies
- Run the application
Once the server is up and running, you can test the application by visiting http://localhost:6080. You should see a screen like this:
Understanding the code#
This tutorial builds upon the External Members tutorial: the room and member management, the application views and the shared helper functions are the same. Here we focus only on what is new — the Users API — and on the small changes needed to manage registered members instead of external ones.
Backend modifications#
This tutorial adds three endpoints to manage users, and slightly changes two of the existing member endpoints:
POST /users: Create a new OpenVidu Meet user. (new)GET /users: List the available users. (new)DELETE /users/:userId: Delete a user. (new)POST /rooms/:roomId/members: now adds a registered member, identified byuserIdinstead ofname.GET /rooms/:roomId/members: now filters bytype=registered.
The room endpoints (POST /rooms, GET /rooms, DELETE /rooms/:roomId) and the DELETE /rooms/:roomId/members/:memberId endpoint are identical to the External Members tutorial.
Create user#
The POST /users endpoint creates a new OpenVidu Meet user:
| index.js | |
|---|---|
| |
- The
userId,nameandpasswordare obtained from the request body. - If any of them is missing, the server returns a
400 Bad Requestresponse. - The user is created with the
room_memberrole. Among the available roles (admin,userandroom_member),room_memberis the most restricted: it can only access the rooms where it has been explicitly added as a member, and cannot create or manage rooms. - The server returns a
201 Createdresponse with the created user object.
This endpoint creates a user with the OpenVidu Meet API by sending a POST request to the users endpoint, including the userId, name, password and role. The userId must be between 5 and 20 characters and contain only lowercase letters, numbers and underscores (this is validated in the frontend form). The role is set to room_member. Among the available roles (admin, user and room_member), room_member is the most restricted: it can only access the rooms where it has been explicitly added as a member, and cannot create or manage rooms.
List users#
The GET /users endpoint retrieves the list of users:
| index.js | |
|---|---|
| |
- Fetch the users by sending a
GETrequest to theusersendpoint, filtering by theroom_memberrole (with a maximum of 100 users).
This endpoint lists only the room_member users. This keeps the tutorial focused on the users it creates and, in particular, excludes the root admin user, which cannot be deleted nor added as a room member.
Delete user#
The DELETE /users/:userId endpoint deletes a user:
| index.js | |
|---|---|
| |
- The
userIdis obtained from the request parameters. - Delete the user by sending a
DELETErequest to theusers/:userIdendpoint.
Deleting a user removes their account from OpenVidu Meet. Note that this will automatically remove the user from rooms where they are a member
Adapting the member endpoints#
Adding a member uses the same POST /rooms/:roomId/members endpoint as the External Members tutorial, but provides a userId instead of a name. This is the only difference, and it is what tells the API to create a member of type registered (linked to a user account) instead of external:
| index.js | |
|---|---|
| |
- The request body now carries a
userId(the registered user to add) instead of aname. - Providing
userId(and notname) is what tells the API to create a member of typeregistered. The member is linked to the user account, identified through authentication, and shares the same authenticated room access URL with the rest of the registered members.
Info
As in the External Members tutorial, you can fine-tune the member's permissions beyond the base role by including a customPermissions object in the request. See the addRoomMember operation in the REST API reference for the full list of permissions.
Listing members works the same way, but filters by type=registered instead of type=external:
| index.js | |
|---|---|
| |
- The only change from the External Members tutorial is the
type=registeredfilter, which retrieves the registered members instead of the external ones.
Removing a member (DELETE /rooms/:roomId/members/:memberId) is exactly the same as in the External Members tutorial: it revokes the member's access immediately and expels them if they are currently in the meeting.
Frontend modifications#
The frontend adds a panel to manage users and adapts the members view to add existing users as members. The joinRoom() function also changes to join through the room's authenticated URL. The rest (rooms management, view switching and the httpRequest() wrapper) is unchanged from the External Members tutorial.
Managing users#
When the "Create User" form is submitted, the createUser() function is called:
| app.js | |
|---|---|
| |
- Prevent the default form submission so the page is not reloaded.
- Get the
userId,nameandpasswordfrom the form inputs. Theuser-idinput enforces the format constraints (5-20 characters, lowercase letters, numbers and underscores) through HTML validation attributes. - Make a
POSTrequest to the/usersendpoint to create the user. - Add the new user to the local
usersmap and re-render the list. - If the request fails (for example, a duplicated
userId), the error message returned by the API is shown in the form.
The renderUsers() and deleteUser() functions follow the same pattern as their room counterparts in the External Members tutorial (renderRooms() and deleteRoom()): one renders the list of users from the users map, and the other calls DELETE /users/:userId and removes the user from the list.
Adapting the members view#
In the External Members tutorial you typed a free-text name to add a member. Here you instead pick one of the existing users from a dropdown, which is populated with the users that are not yet members of the room:
| app.js | |
|---|---|
| |
- Filter out the users that are already members of the room (a registered member's
memberIdequals the user'suserId). - Build one
<option>per available user, using theuserIdas the option value.
When the form is submitted, the addMember() function sends the selected userId (instead of a name) to the backend:
| app.js | |
|---|---|
| |
- Get the selected
userIdfrom the dropdown and the chosenbaseRole. - Make a
POSTrequest to the/rooms/:roomId/membersendpoint to add the member to the current room (currentRoomis the room whose members are being managed). - Add the returned member to the local
membersmap and re-render the list.
The way each member is rendered also changes slightly: since registered members do not have an individual access link, the getMemberListItemTemplate() function shows the member's id (its userId) and a single button to remove them — there is no copy-link or per-member join button like in the External Members tutorial. Instead, joining is done once per room, as shown next.
Joining the room as a registered member#
All registered members of a room share the same authenticated access URL, available in the access.registered.url property of the room object. The joinRoom() function embeds the OpenVidu Meet WebComponent pointing to that URL:
| app.js | |
|---|---|
| |
- Get the room's authenticated access URL from the
access.registered.urlproperty. Unlike the External Members tutorial (where each member had its own unique URL), this URL is the same for all registered members. - Inject the OpenVidu Meet WebComponent with the
room-urlattribute set to that URL. - Add a listener for the
closedevent so that, when the component is closed, the meeting is cleared and the members view is shown again.
Registered members log in inside the meeting
The authenticated access URL does not carry any secret. When the WebComponent loads it, OpenVidu Meet renders its own login form inside the component, and the member logs in with their OpenVidu Meet credentials (the userId and password created earlier). After logging in, OpenVidu Meet verifies that the user is a member of the room and lets them join with the permissions of their base role. Your application never handles the member's password: identity is proven through OpenVidu Meet's login, while membership and permissions are managed through the Room Members API.
Accessing this tutorial from other computers or phones#
To access this tutorial from other computers or phones, follow these steps:
-
Ensure network connectivity: Make sure your device (computer or phone) is connected to the same network as the machine running OpenVidu Meet and this tutorial.
-
Configure OpenVidu Meet for network access: Start OpenVidu Meet by following the instructions in the Accessing OpenVidu Meet from other computers or phones section.
-
Update the OpenVidu Meet server URL: Modify the
OV_MEET_SERVER_URLenvironment variable in your.envfile to match the URL shown when OpenVidu Meet starts. -
Update the OpenVidu Meet WebComponent script URL: In the
public/index.htmlfile, update the<script>tag that includes the OpenVidu Meet WebComponent to use the same base URL as above. -
Restart the tutorial to apply the changes:
-
Access the tutorial: Open your browser and navigate to
https://192-168-1-100.openvidu-local.dev:6443(replacing192-168-1-100with your actual private IP) on the computer where you started the tutorial or any device in the same network.
Connecting this tutorial to an OpenVidu Meet production deployment#
If you have a production deployment of OpenVidu Meet (installed in a server following deployment steps ), you can connect this tutorial to it by following these steps:
-
Update the server URL: Modify the
OV_MEET_SERVER_URLenvironment variable in the.envfile to point to your OpenVidu Meet production deployment URL. -
Update the API key: Ensure the
OV_MEET_API_KEYenvironment variable in the.envfile matches the API key configured in your production deployment. See Generate an API Key section to learn how to obtain it. -
Update the OpenVidu Meet WebComponent script URL: In the
public/index.htmlfile, update the<script>tag that includes the OpenVidu Meet WebComponent to use the same base URL as above. -
Restart the tutorial to apply the changes:
Make this tutorial accessible from other computers or phones
By default, this tutorial runs on http://localhost:6080 and is only accessible from the local machine. If you want to access it from other computers or phones, you have the following options:
- Use tunneling tools: Configure tools like VS Code port forwarding , ngrok , localtunnel , or similar services to expose this tutorial to the internet with a secure (HTTPS) public URL.
- Deploy to a server: Upload this tutorial to a web server and configure it to be accessible with a secure (HTTPS) public URL. This can be done by updating the source code to manage SSL certificates or configuring a reverse proxy (e.g., Nginx, Apache) to serve it.

