Quality Evaluation Form Failing to Map WEM Containment Duration Attributes

The Quality Management module is currently failing to map custom containment duration fields for web messaging sessions. Running a multi-client agency setup on US-EAST-1. The Architect flow (ID: WEM-UX-ONBOARD-09) tracks how long a visitor stays in the decision tree before hitting the agent handoff node. That duration gets pushed into a custom interaction attribute called wem_containment_sec. The UX team requires that exact metric inside the QA scoring rubric to measure bot friction, but the evaluation form keeps rejecting the mapping.

When the QA specialist attempts to save the updated form, the interface throws a validation block. Network tab shows a 422 Unprocessable Entity on the /api/v2/quality/forms endpoint. Payload reads:

{
 "code": "INVALID_VALUE",
 "message": "Attribute 'wem_containment_sec' is not recognized as a valid conversation property for WEM interactions.",
 "details": "Field mapping failed during schema validation."
}

Documentation for the Quality API barely mentions web engagement attributes. Mostly focused on voice and screenpop data. The flow definitely writes the variable before the handoff, and conversation detail logs show the value populating correctly in real-time. Console version is 23.12. Maybe the Quality engine just doesn’t index WEM custom attributes yet. Or there’s a schema extension step missing. The form builder interface locks up whenever you drag a custom metric into the scoring section.

Raw evaluation export CSV just leaves the column blank. Containment tracking is solid on the front end, but the backend scoring layer refuses to acknowledge it. Tried clearing the cache, rebuilding the form from scratch, toggling the WEM integration off and back on. Nothing changes the validation error. i’m not sure if the Quality API supports dynamic WEM variables at all. The scoring rubric needs that friction metric to actually justify the bot containment claims.

curl -X POST "https://api.us-east-1.genesys.cloud/api/v2/quality/forms" \
-H "Authorization: Bearer <token>" \
-d '{"formName": "WEM Containment QA", "sections": [{"fields": [{"attributeName": "wem_containment_sec"}]}]}'

you’re probably hitting the type mismatch again. wfm exports usually push these as strings or floats, but the qa form might be expecting an integer for the duration field. check the evaluation form definition in the api. if you set the attribute type to number in wfm, it should map cleanly to a numeric field in qa. here’s how you can verify the attribute config:

curl -X GET "https://api.mypurecloud.com/api/v2/quality/evaluationforms/{evaluationFormId}/attributes" \
 -H "Authorization: Bearer {access_token}" \
 -H "Content-Type: application/json"

look for wem_containment_sec in the response. if the type is string, change it to number.

are you running this against the latest sdk version?

attrs = client.analytics_api.post_analytics_interactions_query(body=query)
df = pd.DataFrame(attrs.entities)
print(df['wem_containment_sec'].dtype)

check the dtype. if it’s object, the qa form won’t parse it. cast to int64 before exporting.

the containment duration attribute needs to be explicitly typed as a number in the evaluation form configuration. if it’s registered as a string or generic text, the scoring engine can’t perform the arithmetic operations required for the rubric. you’ll run into validation errors when trying to save the form or calculate scores.

here’s how to verify the attribute type in your local docker setup. first, ensure your mock server is returning the correct schema. then, check the actual form definition via the api.

curl -X GET "https://api.mypurecloud.com/api/v2/quality/evaluationforms/{formId}" \
 -H "Authorization: Bearer <token>" | jq '.sections[].items[] | select(.name == "wem_containment_sec")'

look for the type field. it should be number. if it’s string, you’ll need to update the form definition.

{
 "name": "wem_containment_sec",
 "type": "number",
 "label": "Containment Duration (seconds)",
 "defaultValue": 0
}

also, watch out for timezone offsets in your local env. if your docker container is running in utc but your gc tenant is us-east, the timestamp parsing might shift the duration calculation by hours. this breaks the containment metric entirely. set TZ=US/Eastern in your .env file to match the production environment.

another gotcha: the attribute must exist in the interaction history before the evaluation form tries to pull it. if the wem session ends before the attribute is fully propagated, the field comes back as null. add a small delay in your test harness to ensure the attribute is committed to the interaction record.

check the raw json response from the mock server. if the value is "120" instead of 120, that’s your problem. the qa engine treats quotes as text. strip them out in your mock response generator.

this usually trips people up during local dev because the mock server is too lenient with types. production is strict. fix the type, fix the timezone, and it should map correctly.

Don’t map it as a raw number. The QA engine treats numeric attributes as strings during evaluation, which breaks any threshold logic you’re trying to apply. Use a boolean attribute for pass/fail scoring instead.