Quality API /api/v2/quality/evaluations returns empty array despite successful survey submission

We’re trying to tie CSAT scores back to specific interactions in our OpenTelemetry trace spans. The goal is to fetch the evaluation details immediately after a survey response comes in via webhook.

Here’s the flow:

  1. Contact completes survey.
  2. Webhook hits our Node.js service.
  3. Service calls GET /api/v2/quality/evaluations?interactionId={id}

The issue is the API returns an empty array [] even though the evaluation exists in the UI. We’ve verified the interactionId matches the one in the webhook payload. The interaction itself is retrievable via /api/v2/interactions/voice/{id}.

GET /api/v2/quality/evaluations?interactionId=5f8a9b2c-1234-5678-90ab-cdef12345678
Headers:
 Authorization: Bearer <valid_token>
 Accept: application/json

Response: 200 OK
Body: []

I’ve checked the documentation and it says evaluations are linked to interactions. Is there a delay before they appear in the API? Or do we need to use a different endpoint like /api/v2/quality/survey/summaries? We need the actual response text and score, not just aggregates. The trace context breaks if we can’t correlate the survey result to the initial call trace.

We’re using the standard REST API, not an SDK. The token has quality:evaluation:read scope. Any ideas why it’s returning empty? We’ve tried waiting up to 5 minutes. Nothing.

You’re likely hitting the standard evaluation processing delay. Quality evaluations aren’t instantly available via the API the moment a survey closes. There’s a backend job that processes the survey response, maps it to the interaction, and then persists the evaluation record. If you query immediately, the record simply isn’t there yet.

The interactionId parameter is correct, but timing is everything here. You’ll need to implement a retry mechanism with a backoff strategy. Don’t just hammer the API every second; that’ll get you rate-limited fast.

Here’s a quick Node.js snippet using axios to handle the polling. It waits for a maximum of 5 minutes, checking every 10 seconds.

const axios = require('axios');

async function fetchEvaluation(interactionId, accessToken) {
 const maxAttempts = 30; // 5 minutes total
 const intervalMs = 10000; // 10 seconds

 for (let i = 0; i < maxAttempts; i++) {
 try {
 const response = await axios.get(`https://api.mypurecloud.com/api/v2/quality/evaluations`, {
 params: { interactionId: interactionId },
 headers: { Authorization: `Bearer ${accessToken}` }
 });

 if (response.data.entities && response.data.entities.length > 0) {
 console.log('Evaluation found:', response.data.entities[0]);
 return response.data.entities[0];
 }
 } catch (error) {
 console.error('API Error:', error.response?.status, error.message);
 }

 // Wait before next attempt
 await new Promise(resolve => setTimeout(resolve, intervalMs));
 }

 console.warn('Evaluation not found within timeout window.');
 return null;
}

Keep in mind that if the survey was configured to be anonymous, the evaluation might not link back to the specific interaction in the way you expect. Double-check your survey settings in Architect. Also, ensure your service account has the quality:evaluation:view scope. Without that, you’ll get a 403, but an empty array usually just means “not ready yet”.