Trial account trying to create user using api v2 oauth PHP "[message] => Invalid api key or secret."

Description
Greetings, I’m new to Zoom V2, although I have been using Zoom V1 API for a few months.

For this problem, I am using pure PHP 7.n to experiment with v2 commands.

I have a clientID and clientSecret.

For the very first test, get oauth token, works:

        public function getToken(){
            $params['params'] = array(
                                "grant_type" => "client_credentials",
                                "client_id" => $this->clientID,
                                "client_secret" => $this->clientSecret
                            );
            $params['url'] = "https://zoom.us/oauth/token";
            return $this->makeRequest($params);
        }

…where $this->getToken()->access_token will return a long oauth token string.

Then I try to pass that oauth token to my next function, “createUser”, which looks like this:

        public function createUser($params)
        {
            $params['url'] = "https://api.zoom.us/v2/users";
            $params['userInfo'] = array(
                                         "email" => "iuytfdfghjhg77@gmail.com",
                                         "type" => 1,
                                         "first_name" => "Gregory",
                                         "last_name" => "George"
                                        );

            $params['params'] = array(
                                       "access_token" => $this->getToken()->access_token,
                                       "action" => "create",
                                       "user_info" => $params['userInfo']
                                     );
            return $this->makeRequest($params);
        }

…where $this->makeRequest($params) does a cURL, and returns the response object.

Error
The response from my “createUser” function looks like this:

stdClass Object(
                    [code] => 200
                    [message] => **Invalid api key or secret.**
                )

Hey @gregory.george.lewis, thanks for posting and using Zoom!

Can you please try sending the access_token via the request header instead of a param?

"Authorization": "Bearer ACCESS_TOKEN_HERE"

Also due note that our V1 APIs will be shut off soon.

Thanks,
Tommy

Hi Tommy, thanks for the help.

I now pass the access_token using httpheader, like so:

    public function makeRequest($params)
    {
        $params['params']['client_id'] = $this->clientID;
        $params['params']['clientSecret'] = $this->clientSecret;
        $curl = curl_init();
        curl_setopt_array($curl, array(
                                        CURLOPT_URL => $params['url'],
                                        CURLOPT_SSL_VERIFYPEER => true,
                                        CURLOPT_RETURNTRANSFER => true,
                                        CURLOPT_POST => true,
                                        CURLOPT_POSTFIELDS => http_build_query($params['params'])
                                       )
            );
        if(isset($params['access_token'])){
            curl_setopt($curl,CURLOPT_HTTPHEADER, array("Authorization : Bearer " . $params['access_token']));
        }
        $response = curl_exec($curl);
        curl_close($curl);
        return json_decode($response);
    }

The response object is the same as before:

stdClass Object

(
[code] => 124
[message] => Invalid access token.
)

Hey @gregory.george.lewis,

Can you try removing the following code and try again?

$params['params']['client_id'] = $this->clientID;
$params['params']['clientSecret'] = $this->clientSecret;

The ClientID and ClientSecret should not be passed into the POST https://api.zoom.us/v2/users endpoint.

Also can you share your use case? If your app is only being used within your Zoom account, using a JWT Token is an easier flow.

Thanks,
Tommy

Thanks again, Tommy.

My use case will ultimately narrow down to two functions, on the client side where subscribers who fill out a form will generate a start_url for the meeting manager, and on the admin side where we can obtain the data set for each meeting, and do something with that data, like measure how long it lasted. There may be a few other things we would like to do, but start_url, join_url, and meeting data are the major events.


I removed the ClientID and ClientSecret from each request, except for the original request to get the access_token.

If I pass the access_token in the POSTFIELDS, I get a :

stdClass Object
(
    [code] => 200
    [message] => Invalid api key or secret.
) 

…This indicates to me that the access_token was successfully received (because the request does not return an invalid access token).

If I remove the access_token from the POSTFIELDS and instead include it as a header using CURLOPT_HEADER, I get a different error :

stdClass Object
(
    [code] => 124
    [message] => Invalid access token.
)

My cURL looks like this:

        $curl = curl_init();
        curl_setopt_array($curl, array(
                                        CURLOPT_URL => "https://api.zoom.us/v2/users",
                                        CURLOPT_SSL_VERIFYPEER => true,
                                        CURLOPT_RETURNTRANSFER => true,
                                        CURLOPT_POST => true,
                                        CURLOPT_POSTFIELDS => http_build_query(array(
                                            'action' => 'create',
                                            'user_info' => array(
                                                                 'email' => 'earthboar@gmail.com',
                                                                 'type' => '1',
                                                                 'first_name' => 'Gregory',
                                                                 'last_name' => 'George'
                                                                )
                                        )),
                                       )
        );
        CURL_SETOPT($curl,CURLOPT_HTTPHEADER, array("Authorization" => "Bearer eyJhbGciOiJIUzUxMiIsInYiOiIyLjAiLCJraWQiOiIwYmRkMmE4ZC0xZDkyLTRhYzctYTRjNC05NjhmYjNiYzU5NjIifQ.eyJhdWQiOiJodHRwczovL29hdXRoLnpvb20udXMiLCJ2ZXIiOiI2IiwibmJmIjoxNTc5Nzg4OTcwLCJjbGllbnRJZCI6Il9qckozV3c0VHFtbkQ5U1hBcGtpUVEiLCJpc3MiOiJ1cm46em9vbTpjb25uZWN0OmNsaWVudGlkOl9qckozV3c0VHFtbkQ5U1hBcGtpUVEiLCJhdXRoZW50aWNhdGlvbklkIjoiNDBjNjA2NDA5OTJjNDRmNTBlYThiZjJhOWJhMDM2NWEiLCJleHAiOjE1Nzk3OTI1NzAsInRva2VuVHlwZSI6ImNsaWVudF90b2tlbiIsImlhdCI6MTU3OTc4ODk3MCwidXNlcklkIjoiSEVWNFpCVmRSaXE0ZzBlNlFtSUtXUSIsImdyb3VwTnVtYmVyIjowLCJqdGkiOiI5NDhjZTY5NC04NTIwLTQ2NmUtYTljZi05OThkNjY5YzlkNTEifQ.f-gKyGsmlO-WyccPCXITLXarUyXBUBoyNIubQpEEaZYYW8GM79wOGnYH3nZZE5Ky6DbBKmuYwtnxQf2qWRhhnw"));
        $response = curl_exec($curl);
        curl_close($curl);

I don’t know what else to try. If there are any PHP API V2 examples out there, it would sure help me :slight_smile:

Thank you.

Right now I’m using this on localhost (my laptop). Not sure if it’s important.

I found a similar problem here: https://devforum.zoom.us/t/help-with-api-create-meeting-with-php/5189/5

I implemented the solution on that page, so now my cURL code looks like this:

        $headers = array(
                          "authorization:  Bearer {$params['access_token']}",
                          "content-type: application/json"
                        );
        
        $curl = curl_init();
        curl_setopt_array($curl, array(
                                        CURLOPT_URL => "https://api.zoom.us/v2/users",
                                        CURLOPT_SSL_VERIFYPEER => false,
                                        CURLOPT_RETURNTRANSFER => true,
                                        CURLOPT_POST => true,
                                        CURLOPT_POSTFIELDS => json_encode(array(
                                            'action' => 'create',
                                            'user_info' => array(
                                                                 'email' => 'earthboar@gmail.com',
                                                                 'type' => '1',
                                                                 'first_name' => 'Gregory',
                                                                 'last_name' => 'George'
                                                                )
                                        )),
                                       )
        );
        CURL_SETOPT($curl,CURLOPT_HTTPHEADER, $headers);
        $response = curl_exec($curl);
        curl_close($curl);

This results in :

stdClass Object
(
    [code] => 200
    [message] => Invalid api key or secret.
)

Is an “api key or secret” different from the client_id and client_secret? Do I need to include an api_key & api_secret in addition to the access_token?

Hey @gregory.george.lewis,

Can you try making the same request in Postman? I want to determine if the issue is with your code, or on Zoom’s side with the api key / secret.

Thanks,
Tommy

Working on it. My first time with Postman, so I’m learning it. My initial findings are, same response message:

{
  "code": 200,
  "message": "Invalid api key or secret."
}

In the URL space, I entered:

https://api.zoom.us/v2/users?api_key={my api key}&api_secret={my api secret key}&action=create&access_token={very long token string}

As a method, I selected POST. It’s highly likely my results reflect my lack of skill with Postman.

Also, I’m concurrently developing this script on a JWT app. Whichever one gets a valid response first wins.

Thanks again,

Gregory

1 Like

I modified the code, somewhat, that I found on this page (already cited):
https://devforum.zoom.us/t/help-with-api-create-meeting-with-php/5189/5

I am applying the code to my JWT project. It works on createMeeting, in as much as I get a long, beautiful stdClass Object in the response.

I don’t think I solved the problem in the original post, but I will probably depart from OAuth for now, and build out using the JWT project.

Thanks!

Gregory

1 Like

Hey @gregory.george.lewis,

For your OAuth or JWT request, this is the proper way to make it in Postman:

After Bearer add your JWT Token or you Access Token. THere is no need for api key and secret.

Example:

Let me know if you have additional questions :slight_smile:

Thanks,
Tommy