Python SDK pagination drops next_page_token on analytics export before hitting S3

Step one: the daily export job needs to pull conversation details from CXone for the last twenty-four hours and dump the JSON into an S3 bucket. We’re running this on a London-based EC2 instance, so the UTC offset is handled. Here’s the loop structure I’m using with the Python SDK and boto3:

client = create_from_ini_file()
s3 = boto3.client(‘s3’, region_name=‘eu-west-2’)
token = None
while True:
resp = client.get_analytics_conversations_details(
date_from=‘2024-05-10T00:00:00Z’,
date_to=‘2024-05-11T00:00:00Z’,
view=‘default’,
next_page_token=token
)
s3.put_object(Bucket=‘analytics-dump’, Key=f’export_{token}.json’, Body=json.dumps(resp.body))
token = resp.next_page_token
if not token:
break

The issue pops up around the third or fourth page. The SDK returns a next_page_token on the first two calls, but suddenly it returns None even though the total count in the response header says we’re only at twelve hundred records out of eight thousand. I’ve printed the raw response headers and the X-Genesys-Next-Page-Token is definitely there, yet the SDK wrapper swallows it. The script crashes on the second run because token becomes None prematurely. I’m getting a 429 Too Many Requests right after the token drops. Makes me think the SDK is misreading the rate limit headers and bailing out early. It’s weird because the resp.headers show x-genesys-next-page-token: abc123xyz, but resp.next_page_token is empty. Raw logs confirm it. Is the Python SDK version 2.18.1 missing a header mapping for analytics pagination? Or should I be using requests directly to grab the token and pass it manually? The boto3 upload works fine once the payload is correct. Just need to figure out why the wrapper drops the token. The bucket stays empty.