Quality and CSAT
The quality system tracks customer satisfaction across every conversation and aggregates it into account-level health scores. oHallo computes CSAT scores using a multi-dimensional model (outcome, process, environment) derived from conversation signals rather than traditional survey responses. Circuit breakers trigger automatically when quality drops below configured thresholds, pausing the AI pipeline until a human acknowledges and resolves the issue.
Required scope: quality:read for GET endpoints, quality:write for POST and PATCH endpoints.
Get quality stats
Section titled “Get quality stats”Retrieve aggregate quality statistics for a workspace over a given period.
curl "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/quality/stats?period=last_30d" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
period | string | No | Predefined period: last_7d, last_30d, last_90d (default last_30d) |
from | string | No | Start of custom range in ISO 8601 format (overrides period) |
to | string | No | End of custom range in ISO 8601 format (overrides period) |
Response:
{ "periodStart": "2026-02-24T00:00:00.000Z", "periodEnd": "2026-03-25T23:59:59.999Z", "conversationsScored": 312, "averageComposite": 4.21, "averageOutcome": 4.35, "averageProcess": 4.18, "averageEnvironment": 4.10, "averageConfidence": 0.82, "averageDisconfirmation": 0.14, "circuitBreakersTriggered": 1, "resolutionRate": 0.91}Get conversation quality
Section titled “Get conversation quality”Retrieve the CSAT score for a single conversation. Scores are computed after the conversation is resolved.
curl "https://api.ohallo.eu/api/conversations/c9f8e7d6-b5a4-3210-fedc-ba9876543210/quality" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "conversationId": "c9f8e7d6-b5a4-3210-fedc-ba9876543210", "outcomeScore": 4.5, "processScore": 4.2, "environmentScore": 4.0, "compositeScore": 4.23, "disconfirmation": 0.08, "confidence": 0.87, "signalCount": 6, "scoredAt": "2026-03-15T14:35:00.000Z"}| Field | Description |
|---|---|
outcomeScore | How well the customer’s problem was resolved (1.0 to 5.0) |
processScore | How smooth and efficient the interaction was (1.0 to 5.0) |
environmentScore | How well the tone, language, and presentation met expectations (1.0 to 5.0) |
compositeScore | Weighted average of the three dimension scores |
disconfirmation | Gap between the customer’s expected service level and perceived service level (0.0 to 1.0, lower is better) |
confidence | How confident the model is in the computed scores (0.0 to 1.0) |
signalCount | Number of conversation signals used to derive the scores |
Get account health
Section titled “Get account health”Retrieve the rolling quality health summary for an account. Account health is computed from the recent conversations associated with all contacts in the account.
curl "https://api.ohallo.eu/api/accounts/12345678-abcd-4f01-a345-678901234567/quality" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "accountId": "12345678-abcd-4f01-a345-678901234567", "rollingComposite": 3.85, "rollingOutcome": 3.92, "rollingProcess": 3.78, "rollingEnvironment": 3.85, "resolutionRate": 0.88, "conversationCount": 42, "churnRisk": "medium", "consecutiveLow": 2, "trend": "declining"}| Field | Description |
|---|---|
rollingComposite | Rolling average composite score across recent conversations |
rollingOutcome | Rolling average outcome dimension score |
rollingProcess | Rolling average process dimension score |
rollingEnvironment | Rolling average environment dimension score |
resolutionRate | Fraction of conversations that reached a resolution |
conversationCount | Total conversations included in the rolling window |
churnRisk | Computed risk level: low, medium, high, or critical |
consecutiveLow | Number of consecutive conversations scoring below the low-composite threshold |
trend | Direction of recent scores: improving, stable, or declining |
List circuit breakers
Section titled “List circuit breakers”Retrieve the active circuit breakers for a workspace. A circuit breaker triggers when quality metrics fall below the configured thresholds and pauses the AI pipeline for the affected scope until a human acknowledges and resolves the issue.
curl "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/quality/circuit-breakers" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "items": [ { "id": "11223344-5566-4788-99aa-bbccddeeff00", "scopeKey": "account:acc_12345678-abcd-ef01-2345-678901234567", "reason": "3 consecutive conversations scored below composite threshold (3.0) for account Nordic Parts ApS", "triggeredAt": "2026-03-15T10:00:00.000Z", "acknowledgedBy": null, "acknowledgedAt": null, "resolvedAt": null } ], "total": 1}acknowledgedBy identifies the actor that acknowledged the circuit breaker. It is the Kinde user id from the JWT (kp_<32hex>) on dashboard requests, or the literal string api-key:<apiKeyId> on API-key requests. It is null until the breaker is acknowledged. Treat it as an opaque string up to 255 characters; do not parse it as a UUID.
Acknowledge circuit breaker
Section titled “Acknowledge circuit breaker”Acknowledge a circuit breaker to indicate a human is aware of the quality issue and investigating. The actor is extracted automatically from the authentication token — either the Kinde user id (JWT path) or api-key:<apiKeyId> (API-key path) — and recorded in acknowledgedBy.
Required scope: quality:write
curl -X POST "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/quality/circuit-breakers/11223344-5566-4788-99aa-bbccddeeff00/acknowledge" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "id": "11223344-5566-4788-99aa-bbccddeeff00", "scopeKey": "account:acc_12345678-abcd-ef01-2345-678901234567", "reason": "3 consecutive conversations scored below composite threshold (3.0) for account Nordic Parts ApS", "triggeredAt": "2026-03-15T10:00:00.000Z", "acknowledgedBy": "kp_5439c07799a346d7aabf941ea369c7fa", "acknowledgedAt": "2026-03-15T11:30:00.000Z", "resolvedAt": null}Resolve circuit breaker
Section titled “Resolve circuit breaker”Resolve a circuit breaker to re-enable the AI pipeline for the affected scope. A circuit breaker must be acknowledged before it can be resolved.
Required scope: quality:write
curl -X POST "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/quality/circuit-breakers/11223344-5566-4788-99aa-bbccddeeff00/resolve" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "id": "11223344-5566-4788-99aa-bbccddeeff00", "scopeKey": "account:acc_12345678-abcd-ef01-2345-678901234567", "reason": "3 consecutive conversations scored below composite threshold (3.0) for account Nordic Parts ApS", "triggeredAt": "2026-03-15T10:00:00.000Z", "acknowledgedBy": "kp_5439c07799a346d7aabf941ea369c7fa", "acknowledgedAt": "2026-03-15T11:30:00.000Z", "resolvedAt": "2026-03-15T14:00:00.000Z"}Get CSAT configuration
Section titled “Get CSAT configuration”Retrieve the current CSAT configuration for a workspace. These settings control how satisfaction scores are collected and how circuit breakers are triggered.
curl "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/csat-config" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx"Response:
{ "workspaceId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "emailInlineEnabled": true, "emailFollowupEnabled": false, "linkExpiryDays": 14, "followUpDelayMinutes": 60, "thresholdResolutionFailure": 2.0, "thresholdLowComposite": 3.0, "circuitBreakerCount": 3, "circuitBreakerWindowHours": 72, "baselineOutcome": null, "baselineProcess": null, "baselineEnvironment": null}Update CSAT configuration
Section titled “Update CSAT configuration”Update CSAT settings for a workspace. Only the fields you include in the request body are changed.
Required scope: quality:write
curl -X PATCH "https://api.ohallo.eu/api/workspaces/a1b2c3d4-e5f6-7890-abcd-ef1234567890/csat-config" \ -H "Authorization: Bearer sf_live_v1_a3Bx9kLmP2qR7wYz4nDfGhJkQpStUvWx" \ -H "Content-Type: application/json" \ -d '{ "emailFollowupEnabled": true, "followUpDelayMinutes": 120, "circuitBreakerCount": 5, "baselineOutcome": 4.0 }'Request body (all fields optional):
| Field | Type | Description |
|---|---|---|
emailInlineEnabled | boolean | Include a satisfaction link in the resolution email |
emailFollowupEnabled | boolean | Send a separate follow-up email requesting satisfaction feedback |
linkExpiryDays | integer (1-90) | Number of days before a satisfaction link expires |
followUpDelayMinutes | integer (0-10080) | Minutes to wait after resolution before sending a follow-up email |
thresholdResolutionFailure | number (1.0-5.0) | Composite score below which a conversation is flagged as a resolution failure |
thresholdLowComposite | number (1.0-5.0) | Composite score threshold for the circuit breaker counter |
circuitBreakerCount | integer (1-100) | Number of consecutive low-scoring conversations before a circuit breaker triggers |
circuitBreakerWindowHours | integer (1-168) | Time window in hours for counting consecutive low scores |
baselineOutcome | number or null (1.0-5.0) | Expected baseline for the outcome dimension; used to compute disconfirmation |
baselineProcess | number or null (1.0-5.0) | Expected baseline for the process dimension |
baselineEnvironment | number or null (1.0-5.0) | Expected baseline for the environment dimension |
Response: Returns the full updated CSAT configuration.