Error using postVoicemailSearch in SDK

Hi Everyone!

So I successfully used the POST endpoint /api/v2/voicemail/search in the API Explorer using the following query:
{
"query": [{
"fields": ["read","deleted"],
"type": "EXACT",
"value": "false"
},
{
"type": "EXACT",
"fields": ["owner"],
"value": "GROUP"
}
]
}

When I try to use that same query in the postVoicemailSearch(body) function from the Javascript SDK (version "purecloud-platform-client-v2": "^113.2.0") I get a "400 - BAD_REQUEST" error or a "400 - The request could not be understood by the server due to malformed syntax" depending on the format for the query in the body object. See comments in code below to identify when each error is returned (please note that if testing this code you have to uncomment any query object you would like to test because both queries are commented out):

function searchActiveOrgsForUnreadVoiceMail(orgConfig) {

const apiClientInstance = platformClient.ApiClient.instance;

let apiInstance = new platformClient.VoicemailApi();

apiClientInstance.setEnvironment(orgConfig.api_url);

apiClientInstance.loginClientCredentialsGrant(orgConfig.oauth_client_id, orgConfig.oauth_client_secret)

.then(()=> {

    // Do authenticated things

    console.log('Logged in successfully.');

    let body = {

        pageSize: 100, 

        pageNumber: 1,

        /**************************

         * WITH THIS query object I get error:

         * statusCode: 400 - The request could not be understood by the server due to malformed syntax.

        ***************************/

        // query: {

        //     fields: ['read, deleted'],

        //     type: 'EXACT',

        //     value: false,

        //     group: {

        //         fields: ['owner'],

        //         type: 'EXACT',

        //         value: 'GROUP'

        //     }

        // }

        

        /**************************

         * WITH THIS query object I get error:

         * statusCode: 400 - BAD_REQUEST

        ***************************/

        // query: [{

        //         fields: ['read, deleted'],

        //         type: 'EXACT',

        //         value: 'false'

        //     },

        //     {

        //         type: 'EXACT',

        //         fields: ['owner'],

        //         value: 'GROUP'

        //     }

        // ]

    }; // Object | Search request options

    return apiInstance.postVoicemailSearch(body)

})

.then((data) => {

    // console.log(`postVoicemailSearch success! data: ${JSON.stringify(data, null, 2)}`);

    console.log(data);

})

.catch((error) => {

    // Handle failure response

    loggerApi.error('Error in function searchActiveOrgsForUnreadVoiceMail. Logging details.');

    loggerApi.error(error.body && error.body.status ? `${error.body.status} - ${error.body.message}` : error.body.message);

    // sendJobExportErrorEmail(error);

});

}

Any ideas on how can I resolve this issue?

Be sure to review the schema for the request of POST /api/v2/voicemail/search. Several properties in your examples are using types inconsistent with the documented types, which means your request is malformed when compared to the documented schema. Also, the response body often contains useful error information if the request failed validation (as opposed to directly malformed JSON syntax). Can you share that as well?

So should I use the query format (as an object) in the SDK documentation:
query: {

            fields: ['read, deleted'],

            type: 'EXACT',

            value: 'false',

            group: {

                fields: ['owner'],

                type: 'EXACT',

                value: 'GROUP'

            }

        }

Or this one (as an array) that I used and worked in the API Explorer:
query: [{

                fields: ['read, deleted'],

                type: 'EXACT',

                value: 'false'

            },

            {

                type: 'EXACT',

                fields: ['owner'],

                value: 'GROUP'

            }

        ]

Refer to this documentation, it looks like the SDK doc's example is missing the container. Your original request doesn't match the SDK doc example either though; value is a string.

What's in the error body you're getting back?

I tried 'false' (as string) and false (as boolean) and neither works.

BTW this is the structure of the body object according to the SDK documentation and it is exactly what I have, just excluding none required properties:
https://developer.genesys.cloud/api/rest/client-libraries/javascript/VoicemailApi#postVoicemailSearch
{
"sortOrder": String,
"sortBy": String,
"pageSize": Number,
"pageNumber": Number,
"sort": {
"sortOrder": String,
"sortBy": String,
},
"expand": [String],
"query": {
"endValue": String,
"values": [String],
"startValue": String,
"fields": [String],
"value": String,
"operator": String,
"group": {
"endValue": String,
"values": [String],
"startValue": String,
"fields": [String],
"value": String,
"operator": String,
"group": {
"endValue": String,
"values": [String],
"startValue": String,
"fields": [String],
"value": String,
"operator": String,
"group": {
"endValue": String,
"values": [String],
"startValue": String,
"fields": [String],
"value": String,
"operator": String,
"group": {
"endValue": String,
"values": [String],
"startValue": String,
"fields": [String],
"value": String,
"operator": String,
"group": {
"endValue": String,
"values": [String],
"startValue": String,
"fields": [String],
"value": String,
"operator": String,
"group": {
"endValue": String,
"values": [String],
"startValue": String,
"fields": [String],
"value": String,
"operator": String,
"group": [VoicemailSearchCriteria],
"dateFormat": String,
"type": String,
},
"dateFormat": String,
"type": String,
},
"dateFormat": String,
"type": String,
},
"dateFormat": String,
"type": String,
},
"dateFormat": String,
"type": String,
},
"dateFormat": String,
"type": String,
},
"dateFormat": String,
"type": String,
},
}

I also noticed that according to the documentation the query object is not required so I removed it from the body object but I still get the 400 - BAD_REQUEST so I'm not sure what is the issue.

Please any help with this would be much appreciated.

What's in the error body you're getting back?

Error body:
{
"status": 400,
"headers": {
"content-type": "application/json",
"content-length": "198",
"connection": "close",
"date": "Wed, 02 Jun 2021 17:32:01 GMT",
"inin-correlation-id": "412c1f94-ac76-4b62-b596-54e4894871de",
"strict-transport-security": "max-age=600; includeSubDomains",
"cache-control": "no-cache, no-store, must-revalidate",
"pragma": "no-cache",
"expires": "0",
"x-cache": "Error from cloudfront",
"via": "1.1 d5385d9a6bccb3289338c8f9df4440ac.cloudfront.net (CloudFront)",
"x-amz-cf-pop": "MIA3-C5",
"x-amz-cf-id": "Qzzhcdvp83lBxrlqd__7UcEcW4hlIFv6zYkiRCyAimhyNSrz9258aQ=="
},
"body": {
"message": "The request could not be understood by the server due to malformed syntax.",
"code": "bad.request",
"status": 400,
"contextId": "412c1f94-ac76-4b62-b596-54e4894871de",
"details": [],
"errors": []
},
"text": "{"message":"The request could not be understood by the server due to malformed syntax.","code":"bad.request","status":400,"contextId":"412c1f94-ac76-4b62-b596-54e4894871de","details":[],"errors":[]}",
"error": {
"status": 400,
"response": {
"req": {
"method": "POST",
"url": "https://api.mypurecloud.com/api/v2/voicemail/search",
"data": {
"pageSize": 100,
"pageNumber": 1,
"query": {
"fields": [
"read, deleted"
],
"type": "EXACT",
"value": "false",
"group": {
"fields": [
"owner"
],
"type": "EXACT",
"value": "GROUP"
}
}
},
"headers": {
"user-agent": "node-superagent/3.8.3",
"authorization": "Bearer iaugyw1WkUJxxIE-...",
"content-type": "application/json",
"accept": "application/json"
}
},
"header": {
"content-type": "application/json",
"content-length": "198",
"connection": "close",
"date": "Wed, 02 Jun 2021 17:32:01 GMT",
"inin-correlation-id": "412c1f94-ac76-4b62-b596-54e4894871de",
"strict-transport-security": "max-age=600; includeSubDomains",
"cache-control": "no-cache, no-store, must-revalidate",
"pragma": "no-cache",
"expires": "0",
"x-cache": "Error from cloudfront",
"via": "1.1 d5385d9a6bccb3289338c8f9df4440ac.cloudfront.net (CloudFront)",
"x-amz-cf-pop": "MIA3-C5",
"x-amz-cf-id": "Qzzhcdvp83lBxrlqd__7UcEcW4hlIFv6zYkiRCyAimhyNSrz9258aQ=="
},
"status": 400,
"text": "{"message":"The request could not be understood by the server due to malformed syntax.","code":"bad.request","status":400,"contextId":"412c1f94-ac76-4b62-b596-54e4894871de","details":[],"errors":[]}"
}
}
}

In this case, it is an actual JSON deserialization error because the request is not valid in some way. This specific type of error message is suppressed because it's a low level error from the service and can contain privileged information. The shareable portion of the error for this correlation id is: Error code [bad.request] type [JsonMappingException] message [Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: [line: 1, column: 40]]. That means you're using an object where you should be using an array. Column 40 refers to the character's position in the JSON string you sent in the body, which you can get via JSON.stringify(body).

Thank you Tim for your help and patience with this. Can you send me how should I format the body object when using the postVoicemailSearch from the Javascript SDK if I'm looking to get back 100 records per page (pageSize: 100) and looking for fields ('read' and 'deleted') = false and 'owner' field = GROUP

Exactly the same as the working example in API Explorer or Postman. If you're using exactly the same request body and it's not working with the SDK, please provide a snippet of the code you're using to create and send that one request without modifying it in any way and I'll try it out.

That is the weird thing. When I make test using the API Explorer from genesys (on the web) i don't get any errors, but when I try using postman or the javascript SDK, I get the error. See attached images

You're using client credentials in the postman example, correct? It appears that the error you're getting is because the resource is failing when client credentials are used. Please report this via opening a case with Genesys Cloud Care. The specific issue to report is that POST /api/v2/voicemail/search isn't handling client credentials correctly and is causing the request to fail; it's trying to look up permissions from a user, which doesn't exist when client credentials are used. This behavior doesn't appear to be intentional; resources will return the not.a.user error code when they explicitly deny access via client credentials (instead of the generic bad.request).

Note that the error in postman is a different error and different cause than the malformed request errors.

Understood, yes we are using client credentials grant type with the Javascript SDK, we will submit a case for this issue. Thank you Tim for your help with this! Much appreciated!

Hi Tim!

It seems that cloud care cannot pinpoint the issue that we are having with the endpoint POST /api/v2/voicemail/search. Can you please give us some insight on what we should send them that will help to identify the issue? We already sent them everything they ask for like Screenshots and ININ-Correlation-Id but they still can't find the issue, not sure why because they should be able to reproduce the error by using the Javascript SDK for Node JS and use a OAuth with client credentials grant type.

What's the case number? I'll ask for it to be escalated.

The case number is 0002930994. Thank you!

There is some internal progress that hasn't been communicated publicly yet. I've added some additional information to assist. It looks like they're making progress. If you don't get anything back via the care case in a few days, let me know and I'll check in with them again.

Understood, thank you Tim! We really appreciate the assistance on this topic as it's an urgent matter for one of our clients to have this functionality.

@Jordan_Hunter1 The Care engineer should be following up in the case soon, but I wanted to follow up here as well. As it turns out, this resource isn't meant to work with client credentials because the resource checks the user's group membership, something that client credentials can't have. So the bug is only that it's not explicitly denying the request using the not.a.user error code, not that it's not working. You can request new features and share your use case, like allowing this resource to work with client credentials, at https://genesyscloud.ideas.aha.io/ideas.

The only way to use this resource is to use a user-based auth token. This means you must implement one of the implicit, auth code, or SAML2 Bearer authorization grants in your application, which are user-based and will yield an auth token that can be used with this resource. That's why this works in the dev tools and not in your app. I don't know what your architecture is, but this will require a user to use a browser to complete the OAuth flow to authorize the application. The SAML2 Bearer grant is the only one that might avoid that requirement, but that mandates that you're using a SSO provider already. Let me know if you have questions about implementing these grants.