# Start or join external meetings (ZAK)

<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

People (not bots) can use the Meeting SDK to start or join a meeting signed in to their Zoom account using a **Zoom Access Key (ZAK)** token. For example, someone might connect a calendar scheduling app from the Zoom App Marketplace to their Zoom account with OAuth, then join the meeting from your website using the Meeting SDK for web.

> **Note**
>
> This feature is not available to bots or AI notetakers that join external meetings.

Pass in the user's ZAK token to start or join a meeting with their Zoom identity or pass in an [alternative host's](https://support.zoom.us/hc/en-us/articles/208220166-Designating-an-alternative-host) ZAK token to start a webinar.

**Note:** If the user clicks **[Sign Me Out from All Devices](https://support.zoom.com/hc/en/article?id=zm_kb&sysparm_article=KB0060639)** in their Zoom profile, Zoom invalidates any existing prior ZAK tokens.

1.  [Implement an OAuth flow](/docs/integrations/oauth/#step-1-request-user-authorization) and request an access token. Use this access token to authorize subsequent API requests.

    > **OAuth login and app review requirements**
    >
    > -   Zoom OAuth supports Zoom login, SSO, and signing in with Apple, Google, and Facebook.
    > -   All apps must [go through app review](/docs/distribute/) in order to access meetings or webinars hosted outside the developer account that created the app. Additionally, the user must authorize your app.

2.  Use the [Get a user's token](/docs/api/users/#tag/users/get/users/{userId}/token) API to get a ZAK token. When you use this API, tokens expire after:

    -   2 hours for regular users identified by `userID`.
    -   90 days for API users created with `custCreate`.

    You can also set a custom time to live (TTL) for the token, up to a maximum of one year. It's a best practice to get the ZAK token right before you start the meeting.

    **Endpoint:** `GET https://api.zoom.us/v2/users/{userId}/token?type=zak`

    **Request Header:**

    ```json
    {
        "Authorization": "Bearer {{ACCESS_TOKEN}}"
    }
    ```

    **Response Code:** `200 OK`

    **Response Body:**

    ```json
    {
        "token": "{{ZAK_TOKEN}}"
    }
    ```

3.  Pass the ZAK token to the Meeting SDK to start or join the Zoom user's meeting or webinar. The role in the JWT determines whether the meeting will be started or joined with the ZAK: `1` to start, `0` to join.

    ```kotlin
    private fun startMeeting(zak: String) {

        val meetingService = ZoomSDK.getInstance().meetingService

        val startParams = StartMeetingParamsWithoutLogin().apply {
            zoomAccessToken = zak
            meetingNo = ""
        }

        meetingService.addListener(meetingServiceListener)

        val result = meetingService.startMeetingWithParams(this, startParams, StartMeetingOptions())

        if (result == MeetingError.MEETING_ERROR_SUCCESS) {
            // The SDK will attempt to join the meeting.
        }
    }
    ```

    ```swift
    private func startMeeting(zak: String) {
        let startParams = MobileRTCMeetingStartParam4WithoutLoginUser()
        startParams.zak = zak
        startParams.meetingNumber = "" // TODO: Add your meeting number
        startParams.userID = "" // TODO: Add your display name
        let meetingService = MobileRTC.shared().getMeetingService()
        meetingService?.delegate = self
        let meetingResult = meetingService?.startMeeting(with: startParams)
        if (meetingResult == .success) {
            // The SDK will attempt to join the meeting, see onMeetingStateChange callback.
        }
    }
    ```

    ```swift
    private func startMeeting(zak: String) {
        let startParams = ZoomSDKStartMeetingUseZakElements()

        startParams.meetingNumber = 0
        startParams.zak = zak
        startParams.userId = "someFakeID"
        startParams.displayName = "" // TODO: Enter your display name
        startParams.userType = SDKUserType_EmailLogin

        let meetingService = zoomSdk.getMeetingService()

        meetingService?.delegate = self

        let meetingResult = meetingService?.startMeeting(withZAK: startParams)

        if (meetingResult == ZoomSDKError_Success) {
            // The SDK will attempt to join the meeting, see onMeetingStatusChange callback.
        }
    }
    ```

    **Web (component view)**

    ```javascript
    client.join({
        signature: signature, // role in SDK Signature needs to be 1
        meetingNumber: meetingNumber,
        password: password,
        userName: userName,
        zak: zakToken, // the host's zak token
    });
    ```

    **Web (client view)**

    ```javascript
    ZoomMtg.join({
        signature: signature, // role in SDK Signature needs to be 1
        meetingNumber: meetingNumber,
        passWord: passWord,
        userName: userName,
        zak: zakToken, // the host's zak token
        success: (success) => {
            console.log(success);
        },
        error: (error) => {
            console.log(error);
        },
    });
    ```

    ```cpp
    void startMeeting() {
        // Start meeting for API user with StartParam object
        ZOOM_SDK_NAMESPACE::StartParam startMeetingParam;

        // Meeting credentials - replace with actual values
        const UINT64 meetingNumber = 1234567890;
        const wchar_t* zakToken = L"ZAK token for user";
        const wchar_t* userID = L"User ID or email for user";
        const wchar_t* userName = L"Display name for user";

        // Provide meeting credentials for API user using StartParam4WithoutLogin
        ZOOM_SDK_NAMESPACE::StartParam4WithoutLogin startMeetingWithoutLoginParam;

        startMeetingParam.userType = ZOOM_SDK_NAMESPACE::SDK_UT_WITHOUT_LOGIN;
        startMeetingWithoutLoginParam.zoomuserType = ZOOM_SDK_NAMESPACE::ZoomUserType_APIUSER;
        startMeetingWithoutLoginParam.meetingNumber = meetingNumber;

        // Starting a meeting without the user logging in requires a ZAK token
        startMeetingWithoutLoginParam.userZAK = zakToken;
        startMeetingWithoutLoginParam.userID = userID;
        startMeetingWithoutLoginParam.userName = userName;
        startMeetingParam.param.withoutloginStart = startMeetingWithoutLoginParam;

        ZOOM_SDK_NAMESPACE::SDKError startMeetingCallReturnValue(ZOOM_SDK_NAMESPACE::SDKERR_UNKNOWN);

        startMeetingCallReturnValue = yourMeetingServiceInstance->Start(startMeetingParam);

        if (startMeetingCallReturnValue == ZOOM_SDK_NAMESPACE::SDKError::SDKERR_SUCCESS)
        {
            // Start meeting call succeeded, listen for start meeting result using the onMeetingStatusChanged callback
        }
    }
    ```
