Issue with Generating Valid Zoom Meeting SDK Signature – Fails to Join Meeting

Meeting SDK Type and Version

Meeting SDK for Web – Version 3.13.1

Description
I’m having trouble generating a valid signature via API for joining meetings using the Zoom Meeting SDK. The client app either throws a “signature is invalid” message or fails to join the meeting entirely.

When I generate the signature using the [Zoom Test SDK JWT Generator] form [docs/meeting-sdk/auth] , it works perfectly. So the issue appears to be with the way the signature is generated server-side in my implementation.

Error?
One of the following occurs:

  • Signature is invalid.
  • Fails silently or hangs during “joining meeting.”

Troubleshooting Routes

  • Confirmed API Key, API Secret, Meeting Number, Role, and Timestamp are correct
  • Double-checked JWT generation logic and structure against [Zoom’s documentation][docs/meeting-sdk/auth/]
  • Signature tested and working via Zoom’s Test SDK JWT Generator form
  • Verified timestamp is current (in seconds) and within acceptable range
  • Attempted using the Zoom Sample App with same credentials (results vary)

How To Reproduce
Steps to reproduce the behavior including:

  1. Authentication Method or App Type:
  • Using JWT signature generation via backend (Node.js)
  • Using Meeting SDK for Web (host/join a meeting)
  1. Errors:
  • When using backend-generated signature: Signature is invalid or meeting fails to join
  • When using Zoom’s Test SDK JWT generator: meeting joins successfully
  1. Browser/Client Type and Version:
  • Chrome version 136.0.7103.93 (Official Build) (64-bit)
  • Zoom SDK Web Client version 3.13.1

@mohmd-bh

Hi Mohammad, welcome to the community!

You’re definitely on the right track, especially since the Zoom Test SDK JWT Generator works — that confirms your credentials and values are good. The issue is likely in how your backend generates the signature.

Here’s a working example of how to generate a valid signature in Node.js using jsrsasign:

const KJUR = require('jsrsasign');

function generateSignature({ meeting, admin }) {
    const iat = Math.round(new Date().getTime() / 1000) - 30;
    const exp = iat + 60 * 60 * 2;

    const oHeader = {
        alg: 'HS256',
        typ: 'JWT'
    };

    const oPayload = {
        sdkKey: process.env.ZOOM_APP_KEY,
        mn: meeting.id,
        role: admin ? 1 : 0,
        iat: iat,
        exp: exp,
        appKey: process.env.ZOOM_APP_KEY,
        tokenExp: iat + 60 * 60 * (process.env.MEETING_DURATION_IN_HOURS || 3)
    };

    const sHeader = JSON.stringify(oHeader);
    const sPayload = JSON.stringify(oPayload);
    const signature = KJUR.jws.JWS.sign('HS256', sHeader, sPayload, process.env.ZOOM_APP_SECRET);

    return signature;
}

module.exports = {
    generateSignature
};

Tips:

  • Make sure ZOOM_APP_KEY and ZOOM_APP_SECRET are set correctly in your environment.
  • The meeting.id should be the full 10- or 11-digit meeting number.
  • role must be 1 for host, 0 for participant — double-check this matches your use case.
  • Your server’s clock must be synced (e.g., via NTP), or the signature may be invalid.

Important Step (Often Missed):
Make sure your Zoom app is Meeting SDK-enabled in the Zoom Marketplace:

  • Go to your Zoom Marketplace → Manage → Your General App
  • Navigate to Feature
  • Under Embed, toggle Meeting SDK to ON

Let me know if this resolves the issue or if you’d like help testing further.