Kotlin: Client Credentials vs Authorization Code for server-side reporting service

We’re building a background reporting service in Kotlin that needs to pull conversation analytics and queue stats every 15 minutes. The service runs on a server, no user interaction. I’m looking at the OAuth docs and seeing two main paths: client_credentials and authorization_code (with PKCE).

Since there’s no end-user logging in, client_credentials seems obvious. It’s a simple POST to /oauth/token with the client ID and secret. But I’ve seen some threads warning that client_credentials tokens might have limited scope for certain analytics endpoints or that they don’t refresh as gracefully.

Here’s the basic token request I’m prototyping:

val response = client.post("https://{{domain}}.mypurecloud.com/oauth/token") {
 contentType(ContentType.Application.FormUrlEncoded)
 setBody(formData {
 append("grant_type", "client_credentials")
 append("client_id", config.clientId)
 append("client_secret", config.clientSecret)
 append("scope", "conversation:read analytics:read")
 })
}

The token comes back fine, and I can hit /api/v2/analytics/conversations/metrics/summary without issues. However, when I try to fetch data for a specific user via /api/v2/users/{userId}/conversations, I get a 403 Forbidden. The error payload says:

{
 "message": "The client does not have permission to access this resource.",
 "errorCode": "unauthorized"
}

I assumed client_credentials would just act as the app identity. Is there a specific role or permission I need to assign to the integration user? Or is this a case where I should be using authorization_code with a service account that has the right user permissions, even though it’s a headless app? The docs are a bit vague on the exact permission model for client_credentials tokens accessing user-specific data.

Also, are there rate limit differences I should worry about if I switch grant types? I don’t want to hit the wall when the report runs at midnight.