Just noticed that my detail query returns null for wrapUpCode despite valid wrap-ups. I verified the recording and interaction data contains the correct code. The query uses standard grouping. Is this a known limitation or a scope issue? How do I ensure wrapUpCode populates correctly in analytics detail responses?
This is typically caused by the analytics api requiring explicit metric inclusion for non-aggregated fields in detail queries. the default grouping often strips interaction-level metadata like wrapUpCode to optimize payload size. you need to explicitly add wrapup.code to the metrics array in your request body, not just rely on the grouping keys.
here is the corrected python snippet using genesyscloud sdk in a jupyter cell:
from genesyscloud.analytics import AnalyticsApi
from genesyscloud.configuration import Configuration
# assuming you have a valid auth_client
config = Configuration()
config.host = "https://api.mypurecloud.com"
api_instance = AnalyticsApi(configuration=config)
query_body = {
"view": "interaction",
"interval": "PT1H",
"dateFrom": "2023-10-01T00:00:00Z",
"dateTo": "2023-10-02T00:00:00Z",
"groupings": ["user"],
"metrics": [
"wrapup.code", # CRITICAL: must be here for detail view
"wrapup.code.name", # optional: for readable name
"call.duration"
],
"selection": {
"type": "all"
}
}
try:
# use analytics_api_post_interaction_details
response = api_instance.post_analytics_interaction_details(body=query_body)
# parse into pandas for quick inspection
import pandas as pd
df = pd.json_normalize(response.entities)
print(df[['user.id', 'wrapup.code', 'call.duration']])
except Exception as e:
print(f"error: {e}")
check your oauth scopes too. you need analytics:interaction:view and potentially callcenter:wrapup:view if you are filtering by specific codes. the 403 you saw earlier might be related if the token lacks callcenter:wrapup:view. also, note that wrapup.code is null for automated wrap-ups or if the agent bypassed the wrap-up screen. verify the interaction status is complete. running this in a notebook lets you inspect the raw json entities before normalization.
it depends, but generally you need to watch your token lifecycle when polling analytics endpoints in a loop. the suggestion above is correct regarding the wrapup.code metric, but if you are fetching large datasets via the SDK, you will hit a 401 unauthorized error halfway through your aggregation job. the default oauth token expires in 60 minutes. if your detail query spans multiple pages or you are processing historical data, a static token will fail. you must implement an auto-refreshing token provider in your sdk client initialization. do not cache the token string. use the platformclient’s built-in refresh mechanism. here is how you configure it in python to ensure continuous access without manual token rotation:
from platform_sdk_v2 import platformclientv2
# configure client with auto-refresh enabled
config = platformclientv2.configuration
config.region = 'mypurecloud.com'
config.client_id = 'your_client_id'
config.client_secret = 'your_client_secret'
# crucial: ensure the token is refreshed automatically before expiry
client = platformclientv2.platformclientv2(config)
client.login()
# now run your analytics query
analytics_api = client.analytics_api
body = {
"metrics": ["wrapup.code", "talkTime", "holdTime"],
"groupBy": ["wrapup.code"],
"interval": "2023-01-01T00:00:00Z/2023-01-02T00:00:00Z"
}
try:
response = analytics_api.post_analytics_interactions_details(body)
# process response
except Exception as e:
# handle specific sdk errors, check if 401 indicates refresh failure
print(f"error: {e}")
always wrap your api calls in try-except blocks to catch transient 401s and trigger a manual refresh if the automatic one fails due to network latency. this pattern is essential for reliable webhook bridges and batch jobs.
The quickest way to solve this is to explicitly define the metric in your request payload. The suggestion above regarding wrapup.code is correct, but you also need to ensure your OAuth token has the analytics:report:read scope. Without it, the API silently drops certain interaction-level fields to prevent data leakage.
In my Chrome extension, I use the JS SDK platformClient.AnalyticsApi to fetch these details. Here is the exact configuration that works for me:
- Set the Metric: You must add
wrapup.codeto themetricsarray. - Define the Grouping: Use
interaction.idto keep it at the detail level. - Handle Token Refresh: Since I run this from a content script, I use
chrome.runtimemessaging to get a fresh token from the background script if the SDK cache is stale.
const request = {
metrics: [
{ metric: "wrapup.code" },
{ metric: "interaction.duration" }
],
groupBy: [
{ metric: "interaction.id" }
],
query: {
filter: {
operator: "and",
conditions: [
{
predicate: {
operator: "eq",
field: "interaction.type",
value: "call"
}
}
]
},
dateFrom: "2023-10-01T00:00:00.000Z",
dateTo: "2023-10-31T23:59:59.999Z"
}
};
try {
const response = await platformClient.AnalyticsApi.postAnalyticsDetailsQuery({
body: request
});
console.log("Wrap-up codes:", response.entities[0].metrics);
} catch (error) {
console.error("Analytics fetch failed:", error);
}
Check the Genesys Cloud Analytics API docs for the full schema. If you still see nulls, verify that the wrap-up was actually selected by the agent and not auto-applied by a flow, as flow-applied codes sometimes don’t propagate to the detail view immediately.