# Join external meetings as a bot (OBF)

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

Bots and other non-human users can use the Meeting SDK to join meetings with an **On Behalf of (OBF)** token that associates them with the account owner who authorized them. For example, someone might use OAuth to connect an AI Notetaker app from the Zoom App Marketplace to their Zoom account, authorizing it to join their meetings as a companion using the Meeting SDK.

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 [Users API](/docs/api/users/#tag/users/get/users/{userId}/token) to get an OBF token. When you use this API, tokens expire after 2 hours.

    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 OBF token right before you start the meeting.

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

    **Request Header:**

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

    **Response Code**: `200 OK`

    **Response Body**:

    ```json
    {
        "token": "{{OBF_TOKEN}}"
    }
    ```

3.  Pass the OBF token to the Meeting SDK to start the Zoom user's meeting or webinar. OBF apps can only join a meeting once their verified associated owner is in a meeting or webinar, and must leave a meeting or webinar when their owner leaves.

    ```kotlin
    private fun startMeeting(obf: String) {
    val meetingService = ZoomSDK.getInstance().meetingService
    val startParams = StartMeetingParamsWithoutLogin().apply {
        onBehalfToken = obf
        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(obf: String) {
        let startParams = MobileRTCMeetingStartParam4WithoutLoginUser()
        startParams.onBehalfToken = obf
        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(obf: String) {
        let startParams = ZoomSDKStartMeetingUseObfElements()

        startParams.meetingNumber = 0
        startParams.onBehalfToken = obf
        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(withOBF: 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,
        obfToken: obfToken, // the host's OBF token
    });
    ```

    **Web (client view)**

    ```javascript
    ZoomMtg.join({
        signature: signature, // role in SDK Signature needs to be 1
        meetingNumber: meetingNumber,
        passWord: passWord,
        userName: userName,
        obfToken: obfToken, // the host's OBF 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 with an OBF token
        startMeetingWithoutLoginParam.onBehalfToken = obfToken;
        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
        }
    }
    ```
