API Call on ZCC Contacts returns truncated list and last page is empty

Quick description.

An API call to obtain a list of all contacts from an address book gets truncated
From the web application we obtain 13349 contacts. But through the API call it gets only 9900, and the last page returns 0 contacts.

API Call

url = f'https://api.zoom.us/v2/contact_center/address_books/{ZOOM_ADDRESS_BOOK_ID}/contacts'

headers = {
    'Authorization': f'Bearer {bearer_token}',
    'Content-Type': 'application/json'
}
params = {
    'page_size': 300
}

After the first page, we obtain the next_page_token and add it to the parameters.

next_page_token = contact_data.get('next_page_token')
params['next_page_token'] = next_page_token

Error

Next page token: HQwbvRHYKas3MWMnMz0hphrRVQgMU37kgB32
Params for next request: {'page_size': 300, 'next_page_token': 'HQwbvRHYKas3MWMnMz0hphrRVQgMU37kgB32'}
https://api.zoom.us/v2/contact_center/address_books/79..........PKg/contacts
{'Authorization': 'Bearer eyJzdiI6Ij.......RAA', 'Content-Type': 'application/json'}
{'page_size': 300, 'next_page_token': 'HQwbvRHYKas3MWMnMz0hphrRVQgMU37kgB32'}
300
Response --
<Response [200]>
Fetched 300 contacts
Total contacts so far: 9600
Next page token: ConBJcJFpySRggksDwoJtt8OYrj0jLpFva33
Params for next request: {'page_size': 300, 'next_page_token': 'ConBJcJFpySRg......Jtt8OYrj0jLpFva33'}
https://api.zoom.us/v2/contact_center/address_books/79..........PKg/contacts
{'Authorization': 'Bearer eyJzdiI6Ij.......RAA', 'Content-Type': 'application/json'}
{'page_size': 300, 'next_page_token': 'ConBJcJFpySRggksDwoJtt8OYrj0jLpFva33'}
300
Response --
<Response [200]>
Fetched 300 contacts
Total contacts so far: 9900
Next page token: ohVHsJQ4vMKi7FJPsZ8Uk9h7V0ANTd2NNh34
Params for next request: {'page_size': 300, 'next_page_token': 'ohVHsJQ4vMKi7FJPsZ8Uk9h7V0ANTd2NNh34'}
https://api.zoom.us/v2/contact_center/address_books/79..........PKg/contacts
{'Authorization': 'Bearer eyJzdiI6Ij.......RAA', 'Content-Type': 'application/json'}
{'page_size': 300, 'next_page_token': 'ohVHsJQ4vMKi7FJPsZ8Uk9h7V0ANTd2NNh34'}
300
Response --
<Response [200]>
Fetched 0 contacts
Total contacts so far: 9900
Next page token: 
Failed to get the API response: list indices must be integers or slices, not str. Ending...
0

How To Reproduce - Python

The following code gets the first page, and obtain the user_id, and account_number for each contact on the current page. Gets the next_page_token and obtains the next page contacts. Repeats until the next_page_token is empty that means it finished obtaining all the contacts. Returns the list of contact_id and account_number.

def get_contacts_zcc():
    def refresh_bearer_token():
        global bearer_token
        bearer_token = get_zoom_bearer_token(ZOOM_ACCOUNT_ID, ZOOM_CLIENT_CREDENTIALS)

    url = f'https://api.zoom.us/v2/contact_center/address_books/{ZOOM_ADDRESS_BOOK_ID}/contacts'
    contacts = []
    headers = {
        'Authorization': f'Bearer {bearer_token}',
        'Content-Type': 'application/json'
    }
    params = {
        'page_size': 300
    }

    try:
        while True:
            for attempt in range(max_attempts):
                response = requests.get(url, headers=headers, params=params, timeout=timeout_seconds)
                print(url)
                print(headers)
                print(params)
                print(timeout_seconds)
                print("Response --")
                print(response)
                if response.status_code == 200:
                    break
                elif response.status_code == 401:  # Unauthorized, possibly due to invalid token
                    print(f"Attempt {attempt + 1} failed with status code {response.status_code}. Response: {response.content}. Refreshing token and retrying...")
                    refresh_bearer_token()
                    headers['Authorization'] = f'Bearer {bearer_token}'
                else:
                    print(f"Attempt {attempt + 1} failed with status code {response.status_code}. Response: {response.content}. Retrying...")
            else:
                raise Exception(f"Failed to connect to API after {max_attempts} attempts.")

            contact_data = response.json()
            new_contacts = contact_data.get('contacts', [])
            print(f"Fetched {len(new_contacts)} contacts")
            contacts.extend(new_contacts)
            print(f"Total contacts so far: {len(contacts)}")

            next_page_token = contact_data.get('next_page_token')
            print(f"Next page token: {next_page_token}")
            if not next_page_token:  # Check if next_page_token is None or an empty string
                break
            params['next_page_token'] = next_page_token
            print(f"Params for next request: {params}")

        contact_info = [{'contact_id': contacts['contact_id'], 'account_number': contacts.get('account_number')} for
                        contact in contacts]
        return contact_info
    except Exception as e:
        print(f"Failed to get the API response: {e}. Ending...")
        return []

And the function to obtain the bearer token is the next one.

def get_zoom_bearer_token(account_id, client_credentials):
    url = f'https://zoom.us/oauth/token?grant_type=account_credentials&account_id={account_id}'
    headers = {
        'Authorization': f'Basic {client_credentials}',
        'Content-Type': 'application/json'
    }
    try:
        response = requests.post(url, headers=headers)
        response.raise_for_status()
        token_data = response.json()
        return token_data.get('access_token')
    except requests.exceptions.RequestException as e:
        print(f"Failed to get Zoom bearer token: {e}")
        return None

Thanks a lot for your kind help.

Hi @andresr
Thanks for reaching out to us and welcome to the Zoom Developer Forum!
I will send you a private message to get more information about this so I can open a support ticket on your behalf.
Cheers,
Elisa

1 Like