Python SDK: S3 upload fails with AccessDenied when using Genesys Cloud Analytics API

Building a daily analytics export job in Python to pull conversation metrics and write them to S3. We’re using the genesyscloud-python SDK to fetch the data and boto3 for the storage side. The issue is that the put_object call in boto3 is throwing an AccessDenied error, even though the IAM role attached to the Lambda function has full S3 permissions.

Here’s the relevant snippet from our export.py script:

import boto3
from genesyscloud.platform.client import PlatformClient

# Auth setup omitted for brevity
platform_client = PlatformClient()
analytics_api = platform_client.analytics_api

# Fetch data
data_response = analytics_api.post_analytics_conversations_details(
 body=QueryRequest(...)
)

# Serialize and upload
s3_client = boto3.client('s3')
json_data = json.dumps(data_response.body.to_dict())

try:
 s3_client.put_object(
 Bucket='analytics-exports-prod',
 Key=f'conversations/{date}.json',
 Body=json_data.encode('utf-8')
 )
except ClientError as e:
 print(f"S3 Error: {e.response['Error']['Message']}")

The error message is An error occurred (AccessDenied) when calling the PutObject operation: Access Denied. I’ve checked the trust policy on the role, and it looks correct. The Lambda is running in the same region as the bucket.

It feels like the platform_client session might be interfering with the boto3 session, or maybe there’s a credential scope issue I’m missing. We’ve tried switching to instance profile credentials instead of the environment variables, but same result. Anyone seen this before? The Genesys SDK uses requests, boto3 uses botocore, so they shouldn’t clash. But maybe the OAuth token is leaking into the S3 request? Not sure how that would happen. The code is simple enough. Just want to get the JSON into the bucket without manual intervention. The job runs at 02:00 CT, so timing shouldn’t matter. Any ideas on what could cause this specific AccessDenied when the IAM policy is clearly permissive?