Listing OAuth clients and checking scopes via Genesys Cloud API

Hey folks. I’m trying to build a quick audit script to list all OAuth clients in our org and verify their scope assignments. We’ve got a hybrid setup and I need to ensure none of the legacy integrations are holding onto overly broad scopes like organization:all.

I’ve been looking at the /api/v2/oauth/clients endpoint. The docs say it returns a list of client objects. Here’s the basic cURL I’m using for testing:

curl -X GET "https://mycompany.mypurecloud.com/api/v2/oauth/clients" \
 -H "Authorization: Bearer <access_token>" \
 -H "Accept: application/json"

The response comes back with a 200 OK, which is good. The JSON payload looks something like this:

{
 "pageSize": 25,
 "pageNumber": 1,
 "total": 42,
 "entities": [
 {
 "id": "abc-123",
 "name": "Legacy CRM Connector",
 "clientId": "some-client-id",
 "scopes": [
 "organization:read",
 "conversation:write"
 ]
 }
 ]
}

My issue is with the pagination and filtering. The total is 42, but pageSize is 25. I have to loop through the pages to get the full list. Is there a query parameter I can pass to get all clients in one go? I tried pageSize=100 but it seems capped at 1000 and still feels clunky for a simple audit.

Also, I noticed some clients in the response don’t have a scopes array populated. They just show "scopes": []. Does that mean they have no scopes assigned, or is it a bug in the API response? If a client has no scopes, can it still authenticate? I’m worried about false positives in my audit script.

Here’s the Python snippet I’m using to fetch the pages:

import requests

def get_all_clients(base_url, token):
 headers = {
 "Authorization": f"Bearer {token}",
 "Accept": "application/json"
 }
 url = f"{base_url}/api/v2/oauth/clients"
 all_clients = []
 page = 1
 while True:
 params = {"pageSize": 100, "pageNumber": page}
 response = requests.get(url, headers=headers, params=params)
 if response.status_code != 200:
 print(f"Error: {response.status_code}")
 break
 data = response.json()
 if not data.get("entities"):
 break
 all_clients.extend(data["entities"])
 if len(data["entities"]) < data["pageSize"]:
 break
 page += 1
 return all_clients

Is there a better way to check the actual effective scopes? The scopes field in the client object seems static. If a client is linked to a user or role, do those scopes merge? I can’t find clear docs on how client scopes interact with user/role scopes during the OAuth grant flow.

Any pointers on the best practice for auditing this? I just want a clean list of client ID, name, and all possible scopes they can request.