The response feeds endpoint allows developers to track changes to participant responses incrementally, rather than repeatedly fetching entire datasets. Each feed query returns a list of response events (created, updated, rejected, or deleted) along with a cursor that marks the current position in the change log.
Developers can:
Request a feed for a specific testId or across multiple tests.
Use the returned cursor token to fetch only new events since the last poll.
Handle batched changes efficiently with predictable ordering.
Reduce load on clients and servers by avoiding full refreshes.
This makes it simple to keep a local data store, dashboard, or integration layer in sync with the latest state of responses.
For applications that poll frequently or need to minimize API calls, the testResultChangesCount query provides a more performant way to check for changes before fetching detailed data.
Why use testResultChangesCount?
Instead of fetching all change events every time you poll, testResultChangesCount returns:
count — The number of unique test results that have changed
latestCursor — The cursor of the most recent change
This allows you to:
Check if any changes exist without transferring full change data
Get the latest cursor to use in subsequent testResultChanges queries
Skip unnecessary API calls when no changes have occurred
Reduce bandwidth by only fetching detailed changes when needed
Query structure
query checkForChanges {
testResultChangesCount(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b") {
count
latestCursor
}
}
query checkForChanges {
testResultChangesCount(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b") {
count
latestCursor
}
}
query checkForChanges {
testResultChangesCount(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b") {
count
latestCursor
}
}
With sinceCursor parameter
query checkForNewChanges {
testResultChangesCount(
testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b"
sinceCursor: "ut_16898ccbfd404ee792df4a4a5ae884b0"
) {
count
latestCursor
}
}query checkForNewChanges {
testResultChangesCount(
testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b"
sinceCursor: "ut_16898ccbfd404ee792df4a4a5ae884b0"
) {
count
latestCursor
}
}query checkForNewChanges {
testResultChangesCount(
testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b"
sinceCursor: "ut_16898ccbfd404ee792df4a4a5ae884b0"
) {
count
latestCursor
}
}Check for changes since a specific cursor:
{
"data": {
"testResultChangesCount": {
"count": 3,
"latestCursor": "ut_801c0cb2d10043b4bc37a3c29df54a1d"
}
}
}{
"data": {
"testResultChangesCount": {
"count": 3,
"latestCursor": "ut_801c0cb2d10043b4bc37a3c29df54a1d"
}
}
}{
"data": {
"testResultChangesCount": {
"count": 3,
"latestCursor": "ut_801c0cb2d10043b4bc37a3c29df54a1d"
}
}
}If no changes have occurred:
{
"data": {
"testResultChangesCount": {
"count": 0,
"latestCursor": "ut_16898ccbfd404ee792df4a4a5ae884b0"
}
}
}{
"data": {
"testResultChangesCount": {
"count": 0,
"latestCursor": "ut_16898ccbfd404ee792df4a4a5ae884b0"
}
}
}{
"data": {
"testResultChangesCount": {
"count": 0,
"latestCursor": "ut_16898ccbfd404ee792df4a4a5ae884b0"
}
}
}We offer a feed of response updates for a specific test that you can to keep track of responses that have been created, updated, rejected or deleted since your last check.
When you request the testResultChanges query for the first time you will receive the full change history for a specific test.
Each change entry returns a cursor - you should store this.
When you make subsequent requests you can pass the stored cursor as the sinceCursor argument to receive back only changes that have occurred since your previous check.
Here we're going to select a UserTestNode using its UUID. For an explanation of how to find a test's UUID, see Projects.
query changeFeed {
testResultChanges(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b") {
edges {
node {
cursor
responseUuid
testResultId
changeType
changedAt
}
}
}
}query changeFeed {
testResultChanges(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b") {
edges {
node {
cursor
responseUuid
testResultId
changeType
changedAt
}
}
}
}query changeFeed {
testResultChanges(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b") {
edges {
node {
cursor
responseUuid
testResultId
changeType
changedAt
}
}
}
}query changeFeed {
testResultChanges(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b", sinceCursor: "ut_16898ccbfd404ee792df4a4a5ae884b0") {
edges {
node {
cursor
responseUuid
testResultId
changeType
changedAt
}
}
}
}query changeFeed {
testResultChanges(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b", sinceCursor: "ut_16898ccbfd404ee792df4a4a5ae884b0") {
edges {
node {
cursor
responseUuid
testResultId
changeType
changedAt
}
}
}
}query changeFeed {
testResultChanges(testUUID: "ut_74b72d9f-fe10-4ae0-83ee-acc61b431e1b", sinceCursor: "ut_16898ccbfd404ee792df4a4a5ae884b0") {
edges {
node {
cursor
responseUuid
testResultId
changeType
changedAt
}
}
}
}Please note that responses are not available in the feed until they're finalised, at which point they'll be recorded as UPDATED.
{
"extensions": {
"ratelimit": {
"window_reset": "2025-10-01T13:59:00+00:00",
"cost": 0,
"remaining": 30000
}
},
"data": {
"testResultChanges": {
"edges": [
{
"node": {
"cursor": "ut_801c0cb2d10043b4bc37a3c29df54a1d",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "VIDEO_TRANSCRIPTION_UPDATED",
"changedAt": "2025-10-01T10:37:17.365122+00:00"
}
},
{
"node": {
"cursor": "ut_d370ab06745540718bb1e933ead6bdb9",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "VIDEO_UPDATED",
"changedAt": "2025-10-01T10:35:50.472564+00:00"
}
},
{
"node": {
"cursor": "ut_a9e9c320448c49958bd51ca8ebbe0e88",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "UPDATED",
"changedAt": "2025-10-01T10:35:46.592420+00:00"
}
}
]
}
}
}
{
"extensions": {
"ratelimit": {
"window_reset": "2025-10-01T13:59:00+00:00",
"cost": 0,
"remaining": 30000
}
},
"data": {
"testResultChanges": {
"edges": [
{
"node": {
"cursor": "ut_801c0cb2d10043b4bc37a3c29df54a1d",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "VIDEO_TRANSCRIPTION_UPDATED",
"changedAt": "2025-10-01T10:37:17.365122+00:00"
}
},
{
"node": {
"cursor": "ut_d370ab06745540718bb1e933ead6bdb9",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "VIDEO_UPDATED",
"changedAt": "2025-10-01T10:35:50.472564+00:00"
}
},
{
"node": {
"cursor": "ut_a9e9c320448c49958bd51ca8ebbe0e88",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "UPDATED",
"changedAt": "2025-10-01T10:35:46.592420+00:00"
}
}
]
}
}
}
{
"extensions": {
"ratelimit": {
"window_reset": "2025-10-01T13:59:00+00:00",
"cost": 0,
"remaining": 30000
}
},
"data": {
"testResultChanges": {
"edges": [
{
"node": {
"cursor": "ut_801c0cb2d10043b4bc37a3c29df54a1d",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "VIDEO_TRANSCRIPTION_UPDATED",
"changedAt": "2025-10-01T10:37:17.365122+00:00"
}
},
{
"node": {
"cursor": "ut_d370ab06745540718bb1e933ead6bdb9",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "VIDEO_UPDATED",
"changedAt": "2025-10-01T10:35:50.472564+00:00"
}
},
{
"node": {
"cursor": "ut_a9e9c320448c49958bd51ca8ebbe0e88",
"responseUuid": "ut_response_25e1df40-f6cc-436e-abe3-ac7d1b6dc533",
"testResultId": 833433,
"changeType": "UPDATED",
"changedAt": "2025-10-01T10:35:46.592420+00:00"
}
}
]
}
}
}
The changeType field indicates what kind of change occurred:
UPDATED — The response data was updated (this is the initial completion event)
VIDEO_UPDATED — The video recording was processed or updated
VIDEO_TRANSCRIPTION_UPDATED — The transcript for the video was generated or updated
REJECTED — The response was rejected (e.g., failed quality checks)