Skip to content

Data Ingestion

Data ingestion endpoints receive raw signal data captured during a test session. Events, facial analysis frames, and voice segments are sent in batches. All three endpoints are write-only and return a confirmation with counts of accepted and rejected records.

Batch Format

Every ingestion request uses the same top-level structure:

{
"sessionId": "sess_001",
"batch": [ ]
}

Items in batch that fail validation are rejected individually. The rest are accepted. The response always reports both counts.

Endpoints

POST /api/data/events JWT

Ingest a batch of behavioral interaction events for a session

Each item in batch represents one discrete interaction event captured in the tester’s browser or device.

Request body

{
"sessionId": "sess_001",
"batch": [
{
"eventType": "click",
"targetSelector": "#checkout-btn",
"timestamp": "2026-03-16T10:14:32.120Z",
"x": 540,
"y": 210,
"viewport": { "width": 1440, "height": 900 }
},
{
"eventType": "scroll",
"targetSelector": "body",
"timestamp": "2026-03-16T10:14:35.400Z",
"scrollY": 820
},
{
"eventType": "input",
"targetSelector": "#email-field",
"timestamp": "2026-03-16T10:14:40.000Z",
"inputLength": 18
}
]
}

Event schema

FieldTypeRequiredDescription
eventTypestringYesOne of: click, scroll, input, focus, blur, navigation, error
targetSelectorstringYesCSS selector of the interacted element
timestampstring (ISO 8601)YesWhen the event occurred
xnumberNoHorizontal cursor position (pixels from left)
ynumberNoVertical cursor position (pixels from top)
scrollYnumberNoVertical scroll offset in pixels
inputLengthnumberNoCharacter count for input events (no raw content)
viewportobjectNo{ width, height } of the browser viewport

Response

{
"success": true,
"data": {
"sessionId": "sess_001",
"accepted": 3,
"rejected": 0,
"rejections": []
},
"error": null,
"metadata": null
}

Rejection entries include index (position in batch) and reason:

{
"rejections": [
{ "index": 2, "reason": "Missing required field: eventType" }
]
}
POST /api/data/facial JWT

Ingest a batch of facial analysis frames for a session

Each item in batch represents one analyzed video frame. Raw video is never sent; only pre-processed emotion and attention scores are accepted.

Request body

{
"sessionId": "sess_001",
"batch": [
{
"frameIndex": 0,
"timestamp": "2026-03-16T10:14:30.000Z",
"emotions": {
"neutral": 0.72,
"surprise": 0.14,
"confusion": 0.09,
"frustration": 0.05
},
"attentionScore": 0.91,
"gazeX": 0.53,
"gazeY": 0.47
},
{
"frameIndex": 1,
"timestamp": "2026-03-16T10:14:31.000Z",
"emotions": {
"neutral": 0.45,
"confusion": 0.38,
"frustration": 0.17
},
"attentionScore": 0.74,
"gazeX": 0.12,
"gazeY": 0.80
}
]
}

Frame schema

FieldTypeRequiredDescription
frameIndexintegerYesSequential frame number within the session
timestampstring (ISO 8601)YesWhen the frame was captured
emotionsobjectYesEmotion labels mapped to confidence scores (0.0 to 1.0). Scores must sum to approximately 1.0.
attentionScorenumber (0-1)YesEstimated tester attention level
gazeXnumber (0-1)NoNormalized horizontal gaze position
gazeYnumber (0-1)NoNormalized vertical gaze position

Response

{
"success": true,
"data": {
"sessionId": "sess_001",
"accepted": 2,
"rejected": 0,
"rejections": []
},
"error": null,
"metadata": null
}
POST /api/data/voice JWT

Ingest a batch of voice analysis segments for a session

Each item in batch represents one transcribed and analyzed audio segment. Audio files are never sent; only text transcripts and derived metrics are accepted.

Request body

{
"sessionId": "sess_001",
"batch": [
{
"segmentIndex": 0,
"startTime": "2026-03-16T10:14:30.000Z",
"endTime": "2026-03-16T10:14:38.200Z",
"transcript": "I'm trying to find the settings but I can't see where it is.",
"sentiment": "negative",
"sentimentScore": -0.62,
"hesitationCount": 2,
"wordsPerMinute": 124
},
{
"segmentIndex": 1,
"startTime": "2026-03-16T10:14:40.000Z",
"endTime": "2026-03-16T10:14:48.500Z",
"transcript": "Oh I see it now, it was hidden in the profile menu.",
"sentiment": "positive",
"sentimentScore": 0.71,
"hesitationCount": 0,
"wordsPerMinute": 138
}
]
}

Segment schema

FieldTypeRequiredDescription
segmentIndexintegerYesSequential segment number
startTimestring (ISO 8601)YesSegment start timestamp
endTimestring (ISO 8601)YesSegment end timestamp
transcriptstringYesTranscribed text of the spoken segment
sentimentstringYesOne of: positive, neutral, negative
sentimentScorenumber (-1 to 1)YesNumeric sentiment score
hesitationCountintegerNoCount of hesitation markers (um, uh, etc.)
wordsPerMinutenumberNoSpeaking rate

Response

{
"success": true,
"data": {
"sessionId": "sess_001",
"accepted": 2,
"rejected": 0,
"rejections": []
},
"error": null,
"metadata": null
}