Python SDK analytics export to S3 getting 403 on large datasets

Hey everyone.

I am trying to build a daily export job for Genesys Cloud analytics data. The goal is simple. Pull the data using the Python SDK and push it directly to an S3 bucket using boto3. I don’t want to save it to disk first. It feels cleaner that way.

I have the authentication working. The genesyscloud client connects fine. I can fetch small reports without any issues. But when the dataset grows, things break. Specifically, I am hitting a 403 Forbidden error from S3. It happens during the upload part.

Here is the logic I am using. I fetch the data in chunks and stream it.

import boto3
from genesyscloud import analytics_api

s3_client = boto3.client('s3')
api_instance = analytics_api.AnalyticsApi(api_client)

def upload_analytics(report_id):
 # Get the data
 api_response = api_instance.get_analytics_report(report_id)
 
 # Stream to S3
 s3_client.put_object(
 Bucket='my-genesys-exports',
 Key=f'daily/{report_id}.json',
 Body=api_response
 )

The error message from boto3 says ClientError: An error occurred (403) when calling the PutObject operation: Forbidden. The IAM role attached to the EC2 instance has s3:PutObject permissions. I verified this manually using the AWS CLI and it works. So it is not a permission issue on the AWS side.

I suspect the issue is with how the Python SDK returns the object. Maybe the api_response is not a valid binary stream or bytes object? Or perhaps the content type is missing? I tried adding ContentType='application/json' but it did not help.

Has anyone done this before? How do you handle the payload conversion? I am running this in a US West region. The latency is fine.

Any pointers on the correct way to pass the SDK response to boto3 would be appreciated. I am stuck on this.