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.