How to join a meeting with “Require authentication to join: Internal Users” security enabled using the SDK for web meetings?

I’m trying to integrate the SDK for web meetings to join meetings that have the “Require authentication to join: Internal Users” security option enabled. Could someone please guide me on how to resolve this issue? Appreciate any help in advance!

@enya.santos ,

If this setting is enabled, participants will need to use their ZAK token to authenticate themselves when joining the meeting.

Hi, @chunsiong.zoom ,

How do I obtain the zak token for a user?


If you are the admin / owner / developer associated with the user’s tenant, you can use server to server oauth app, use the access token to get the user’s ZAK token.

If you are not, then you will need to use OAuth App, prompt the user for permission to get their ZAK token, and use the access token to get the user’s ZAK token.

@chunsiong.zoom ,

I’m encountering an issue despite passing the zak token. Here’s the error message I’m receiving:


errorCode: 3051
reason: "Require login"
url:  "{...}"

The meeting is configured with ‘Require authentication’.

Here’s the code snippet used to obtain the zak token:

await fetch(`${}/token?type=tk`, {
      method: "GET",
      headers: {
        "Authorization": `Bearer ${access_token}`

And here’s the component view code:

const { default: ZoomMtgEmbedded } = await import('@zoom/meetingsdk/embedded');
const client = ZoomMtgEmbedded.createClient();


    meetingNumber: meetingNumber,
    password: passWord?.trim(),
    userName: `${fullName}`,
    userEmail: email,

Zoom Meeting SDK version used:

"meetingsdk^3.6.0": "link:@zoom/meetingsdk^3.6.0"

@enya.santos I believe this is client side. Did you managed to get a valid ZAK token, or did this throw a CORS error?


I managed to generate a valid ZAK token successfully. Here’s an example: eyJ0eXAiOiJKV1QiLCJzdiI6IjAwMDAwMSIsInptX3NrbSI6InptX28ybSIsImFsZyI6IkhTMjU2In0.eyJhdWQiOiJjbGllbnRzbSIsInVpZCI6IjB6d243c0h5UlBPZmRlMkJCb3VCclEiLCJpc3MiOiJ3ZWIiLCJzayI6IjAiLCJzdHkiOjEsIndjZCI6InVzMDYiLCJjbHQiOjAsImV4cCI6MTcxNTM1OTQ4MSwiaWF0IjoxNzE1MzUyMjgxLCJhaWQiOiJtUWFCdjlnX1RQS0hybHV3ZkFuMGV3IiwiY2lkIjoiIn0.4LQZchv3kDGVomTSjLqFirh9v5-OEk9_WfKIt6HJcEQ

The route has been changed to ‘’.

Additionally, please note that in the settings, the role is set to 0.

@enya.santos another thing to check is, did you use promises to ensure that the ZAK token is returned before calling client.join ?

@chunsiong.zoom, yes, please check the full code below:

"use client"
import React, { useEffect, useRef } from 'react';
import { getSignature, getZakToken } from '../../domain/zoom';
import { EmbeddedClient, SuspensionViewType } from '@zoom/meetingsdk/embedded';
import { getCookie } from 'cookies-next';
import { isTokenExpired } from './utils/is-token-expired';
import { useRouter } from 'next/navigation';

export default function ZoomSDK({sdkKey, meetingNumber, password}: Props) {
  const router = useRouter();

  const zoomRef = useRef(null);
  const clientRef = useRef<typeof EmbeddedClient>()
  const role = 0;
  const zoomConfig = {
    meetingNumber: meetingNumber,
    password: password?.trim(),
    userName: "User",
    userEmail: "",

  async function startMeeting(signature: any, zak?: string) {
    if (!zoomRef.current) return;
    try {
      const { default: ZoomMtgEmbedded } = await import('@zoom/meetingsdk/embedded');
      const client = ZoomMtgEmbedded.createClient();
      clientRef.current = client

      await client.init({
        debug: true,
        zoomAppRoot: zoomRef.current,
        language: 'en-US',
        customize: {
          video: {
            defaultViewType: 'galery' as SuspensionViewType,
            popper: {
              disableDraggable: true
            isResizable: true,
          chat: {
            popper: {
              disableDraggable: false,
              anchorReference: 'anchorEl',
              placement: 'right-end'
      console.log('[startMeeting] zak passing:', zak)
      await client.join({ signature, zak, ...zoomConfig });
      window.addEventListener('beforeunload', async () => {
        await client.leaveMeeting(); 
    } catch (error) {

  async function setMeeting() {
    try {
      const zoomAccessToken = getCookie('zoom-access')
      const isExpired = isTokenExpired(zoomAccessToken);
      if(!isExpired && zoomAccessToken) {
        const zoomZakToken = await getZakToken(zoomAccessToken)
        return zoomZakToken?.token;
      } else {
    } catch(err) {
  useEffect(() => {
    const fetchMeeting = async () => {
      try {
        const zoomZakToken = await setMeeting()   
        const signatureResponse = await getSignature(meetingNumber, role)
        await startMeeting(signatureResponse.signature, zoomZakToken)
      } catch(err) {


    return () => {
      window.removeEventListener('beforeunload', () => {})

      const cleanup = async () => {
        if(clientRef.current) await clientRef.current.leaveMeeting();
  }, [])

  return (
    <div className="w-full">
        className="w-full h-full flex justify-center items-center" 
 "dependencies": {
    "@zoom/meetingsdk": "^3.6.1"

I am trying to join as a participant in a meeting or webinar that requires authentication.

@chunsiong.zoom , thank you for your attention. The issue has been resolved by removing the library with npm remove @zoom/meetingsdk and then reinstalling it with npm install @zoom/meetingsdk.

Thanks again for your help!

1 Like