# Error code=401 when create a meeting using Java API call

**URL:** <https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408>\
**Category:** API and Webhooks\
**Tags:** api\
**Created:** [March 7, 2025, 3:01pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408 "2025-03-07T15:01:48Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Glenn1](https://avatars.discourse-cdn.com/v4/letter/g/3ec8ea/32.png) [@Glenn1](https://devforum.zoom.us/u/Glenn1)\
**Post date:** [March 7, 2025, 3:01pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/1 "2025-03-07T15:01:48Z")

</div>

**API Endpoint(s) and/or Zoom API Event(s)**  
[https://api.zoom.us/v2/users/me/meetings](https://api.zoom.us/v2/users/me/meetings)

**Description**  
I am trying to use the API for server-to-server Oath create of a meeting and provide the meeting link to my user. To create the meeting I’m making a OkHttp call to url [https://api.zoom.us/v2/users/me/meetings](https://api.zoom.us/v2/users/me/meetings).

See my code example below. Note the call to get the token works just fine.

**Error**  
When I try to make the call this is the error I get when running the meeting request:  
{protocol=h2, code=401, message=, url=[https://api.zoom.us/v2/users/me/meetings](https://api.zoom.us/v2/users/me/meetings)}

**How To Reproduce**  
This is my code snip  
private String zoomTokenGenerate() throws Exception  
{

```
    String ZOOM_OAUTH_URL = "https://zoom.us/oauth/token";

    OkHttpClient client = new OkHttpClient();
    MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
    RequestBody body = RequestBody.create("grant_type=client_credentials",mediaType);

    Request request = new Request.Builder()
            .url(ZOOM_OAUTH_URL)
            .post(body)
            .addHeader("Authorization", "Basic " + Base64.getEncoder().encodeToString((ZOOM_API_CLI_KEY + ":" + ZOOM_API_SECRET).getBytes()))
            .build();

```

// ============== this is the line that produces the error  
Response response = client.newCall(request).execute();  
//===============  
String responseBody = response.body().string();

```
    JSONObject json = new JSONObject(responseBody);

    return json.getString("access_token");
    
} // zoomTokenGenerate

public String createZoomMeeting() throws Exception 
{
    OkHttpClient client = new OkHttpClient();

    // Generate JWT token
    String jwtToken = this.zoomTokenGenerate();

    MediaType mediaType = MediaType.parse("application/json");

    JSONObject bodyProps = new JSONObject();
    bodyProps.put("topic", "Test Meeting");
    bodyProps.put("type", 2); // Scheduled meeting
    bodyProps.put("settings",new JSONObject().put("host_video", true).put("participant_video", true));
    
    String requestBody = bodyProps.toString();
    RequestBody body = RequestBody.create(requestBody,mediaType);

    Request request = new Request.Builder()
            .url("https://api.zoom.us/v2/users/me/meetings")
            .post(body)
            .addHeader("Content-Type", "application/json")
            .addHeader("Authorization", "Bearer " + jwtToken)
            .build();   

    try (Response response = client.newCall(request).execute()) {
        if (!response.isSuccessful()) {
            throw new IOException("Unexpected code " + response);
        }

        String responseBody = response.body().string();
        JSONObject jsonResponse = new JSONObject(responseBody);
        return jsonResponse.getString("join_url");
    }
} // createZoomMeeting

```

---

<div class="post-metadata">

**Author:** ![alexm](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alexm/32/67701_2.png) [@alexm](https://devforum.zoom.us/u/alexm)\
**Post date:** [March 7, 2025, 3:30pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/2 "2025-03-07T15:30:35Z")

</div>

Hi @Glenn1, welcome to the forum!

An HTTPS Error `401` indicates to me that your auth header is incorrect. Looking at this line:

> [@Glenn1](#):
>
> `RequestBody body = RequestBody.create("grant_type=client_credentials",mediaType);`

In my application, the `grant_type` I’m using is `account_credentials` not `client_credentials`, so give that a shot.

EDIT: Just to add, I’m also specifying my account ID in the request, which I don’t see in yours:  
`oauth/token?grant_type=account_credentials&account_id=${MY_ZOOM_ACCOUNT_ID}`

---

<div class="post-metadata">

**Author:** ![alexm](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alexm/32/67701_2.png) [@alexm](https://devforum.zoom.us/u/alexm)\
**Post date:** [March 7, 2025, 4:55pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/4 "2025-03-07T16:55:01Z")

</div>

No worries. I’m suggesting you try replacing “client\_credentials” with “account\_credentials”, and also appending your request to add “account\_id” with the appropriate info. Good luck!

---

<div class="post-metadata">

**Author:** ![Glenn1](https://avatars.discourse-cdn.com/v4/letter/g/3ec8ea/32.png) [@Glenn1](https://devforum.zoom.us/u/Glenn1)\
**Post date:** [March 7, 2025, 6:51pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/5 "2025-03-07T18:51:07Z")

</div>

> [@alexm](#):
>
> token?grant\_type=account\_credentials&account\_id=${MY\_ZOOM\_ACCOUNT\_ID}

Thank you. That worked. Now I’m having an issue with the meeting link that was generated / created. It makes a meeting but I need the meeting to be setup so that the first person that clicks the link becomes the host or set it up as a no host meeting. Do you have any ideas on how I can do that? Thanks in advance.

---

<div class="post-metadata">

**Author:** ![alexm](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alexm/32/67701_2.png) [@alexm](https://devforum.zoom.us/u/alexm)\
**Post date:** [March 7, 2025, 7:08pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/6 "2025-03-07T19:08:15Z")

</div>

> [@Glenn1](#):
>
> I need the meeting to be setup so that the first person that clicks the link becomes the host or set it up as a no host meeting. Do you have any ideas on how I can do that?

Hi Glenn glad to hear you overcame the auth issue.

When you successfully create a meeting, you should receive a JSON object back that, among other things, contains properties `join_url` and `start_url`; The person you want to be the host should use the `start_url` and the other guest(s) use should the `join_url`. You may want to subsequently set `join_before_host: false` in your meeting creation parameters.

---

<div class="post-metadata">

**Author:** ![Glenn1](https://avatars.discourse-cdn.com/v4/letter/g/3ec8ea/32.png) [@Glenn1](https://devforum.zoom.us/u/Glenn1)\
**Post date:** [March 7, 2025, 8:29pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/7 "2025-03-07T20:29:13Z")

</div>

Thanks for your continued assist on this. You have been great so far. I tried your latest suggestion and both the start\_url and join\_url come out the same.

These are my current start settings:  
JSONObject bodyProps = new JSONObject();  
bodyProps.put(“topic”,“Test Meeting 2”);  
bodyProps.put(“type”, 2); // Scheduled meeting  
bodyProps.put(“alternative\_hosts”,“”);  
bodyProps.put(“participant\_join\_before\_host”,false);  
bodyProps.put(“duration”,15);  
bodyProps.put(“settings”,new JSONObject().put(“host\_video”,true).put(“participant\_video”,true));

---

<div class="post-metadata">

**Author:** ![Glenn1](https://avatars.discourse-cdn.com/v4/letter/g/3ec8ea/32.png) [@Glenn1](https://devforum.zoom.us/u/Glenn1)\
**Post date:** [March 7, 2025, 9:18pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/8 "2025-03-07T21:18:30Z")

</div>

Just messing around with options. This is what I have set now and it still is gives a “waiting” for host when I join:  
JSONObject bodyProps = new JSONObject();  
bodyProps.put(“topic”,“Test Meeting 4”);  
bodyProps.put(“type”,1); // 2 = Scheduled meeting; 1 = Instant Meeting  
bodyProps.put(“alternative\_hosts”,“”);  
bodyProps.put(“schedule\_type”,“personal”);  
bodyProps.put(“participant\_join\_before\_host”,true);  
bodyProps.put(“waiting\_room”,false);  
bodyProps.put(“duration”,15);  
bodyProps.put(“settings”,new JSONObject().put(“host\_video”,true).put(“participant\_video”,true));

---

<div class="post-metadata">

**Author:** ![alexm](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alexm/32/67701_2.png) [@alexm](https://devforum.zoom.us/u/alexm)\
**Post date:** [March 7, 2025, 10:07pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/9 "2025-03-07T22:07:52Z")

</div>

If it helps, here’s an example of the JSON I use for meeting creation:

```auto
     {
            default_password: true,
            settings: {
              alternative_hosts_email_notification: false,
              audio: "voip",
              continuous_meeting_chat: {
                enable: false,
                auto_add_invited_external_users: false,
              },
              email_notification: false,
              encryption_type: "enhanced_encryption",
              focus_mode: false,
              host_video: true,
              meeting_authentication: false,
              mute_upon_entry: false,
              jbh_time: 0,
              join_before_host: true,
              participant_video: true,
              private_meeting: true,
              registrants_confirmation_email: false,
              registrants_email_notification: false,
              use_pmi: false,
              waiting_room: false,
              watermark: false,
              },
            start_time: format(sub(new Date(), { minutes: 1 }), "yyyy-MM-ddTHH:mm:ss"),
            timezone: "UTC",
            type: 2,
     }

```

Bear in mind there’s some functions in there from the javascript library `date-fns` (`sub()` and `format()`) that I’m using to make the start time be now-minus-1-minute for my own weird use case, you can ignore. But this should be helpful.

---

<div class="post-metadata">

**Author:** ![Glenn1](https://avatars.discourse-cdn.com/v4/letter/g/3ec8ea/32.png) [@Glenn1](https://devforum.zoom.us/u/Glenn1)\
**Post date:** [March 7, 2025, 11:34pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/10 "2025-03-07T23:34:02Z")

</div>

Thanks. I will try some of those settings.

---

<div class="post-metadata">

**Author:** ![elisa.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/elisa.zoom/32/47836_2.png) [@elisa.zoom](https://devforum.zoom.us/u/elisa.zoom)\
**Post date:** [March 10, 2025, 2:34pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/11 "2025-03-10T14:34:34Z")

</div>

Thanks @alexm for chiming in on this thread!

Just adding to what Alex shared, there is a setting in your Zoom Account that must be enabled manually to be able to set the “join\_before\_host” to true.

Head over to the Admin Tab \> Account Management \> Account settings \> Meeting \> Schedule meeting \> “Allow participants to join before host”

 ![Screenshot 2025-03-10 at 10.34.00 AM](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/d/d/dd008074a1fbe876b2f0cc94572c7aeda521c906.png)

---

<div class="post-metadata">

**Author:** ![Glenn1](https://avatars.discourse-cdn.com/v4/letter/g/3ec8ea/32.png) [@Glenn1](https://devforum.zoom.us/u/Glenn1)\
**Post date:** [March 10, 2025, 5:07pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/12 "2025-03-10T17:07:54Z")

</div>

Thank you for the help. This has worked. Now all I need to do is figure out how to get it to not send an e-mail to me every time the meeting attendees join the meeting. If you have any idea on that it would be great. Thanks again.

---

<div class="post-metadata">

**Author:** ![alexm](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/alexm/32/67701_2.png) [@alexm](https://devforum.zoom.us/u/alexm)\
**Post date:** [March 10, 2025, 6:01pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/13 "2025-03-10T18:01:38Z")

</div>

Try `email_notification: false` in your settings object 🙂

---

<div class="post-metadata">

**Author:** ![Glenn1](https://avatars.discourse-cdn.com/v4/letter/g/3ec8ea/32.png) [@Glenn1](https://devforum.zoom.us/u/Glenn1)\
**Post date:** [March 10, 2025, 9:46pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/14 "2025-03-10T21:46:31Z")

</div>

Thank you. I was trying to figure out how to do it on a meeting by meeting basis through the API. But, changing that made it work and since the account in question will only be creating meetings via the API it will work for me.

---

<div class="post-metadata">

**Author:** ![Glenn1](https://avatars.discourse-cdn.com/v4/letter/g/3ec8ea/32.png) [@Glenn1](https://devforum.zoom.us/u/Glenn1)\
**Post date:** [March 10, 2025, 9:49pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/15 "2025-03-10T21:49:13Z")

</div>

Didn’t seem to work. I found something online that said it should be notification\_email: false instead. But, that didn’t work either. But, I just went into my Zoom account and changed the setting for all meetings on that user account and it appears to have worked. Simple solution for me because the account in question is only going to be used for the API meeting creates.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/6/1/614bdd549b610bbaa46ff934617683a02bdaa03c.png) [@system](https://devforum.zoom.us/u/system)\
**Post date:** [March 11, 2025, 9:49pm UTC](https://devforum.zoom.us/t/error-code-401-when-create-a-meeting-using-java-api-call/129408/16 "2025-03-11T21:49:56Z")

</div>

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.
