CSAT Surveys
Configure and manage customer satisfaction surveys via the Aurion API.
⚠️ Preview — not yet in the public API
The endpoints on this page are part of the AurionAI helpdesk and are currently accessible only through an authenticated dashboard session. They are not yet exposed through public API keys — a request authenticated with
X-API-Keyreturns403. Public API-key access is planned. The reference below documents the intended contract.
CSAT Surveys
The CSAT API lets you manage customer satisfaction surveys that are automatically sent after conversation resolution. Surveys collect a rating (default 1-5 stars; configurable to emoji, thumbs, or an NPS 0-10 scale) and an optional text comment.
The admin endpoints (/surveys, the unprefixed list, /analytics, and GET/PUT /config) are authenticated by a dashboard session today — they are not reachable with an API key. The only genuinely API-key-free endpoints are the token-based public survey routes: GET /csat/rate, GET /csat/{token}, and POST /csat/{token}/submit.
How It Works
- A conversation is resolved
- After a configurable delay (1-72 hours, default driven by
survey_delay_hours), a CSAT survey email is sent - The customer clicks a one-click rating link or opens the full survey
- Results are aggregated in the analytics dashboard
List Surveys
Admin list of CSAT survey responses (dashboard session required; not API-key reachable).
curl "https://apps.aurionai.net/api/v1/csat/surveys?limit=10" \
-H "X-API-Key: itsm_sk_live_xxxx"limit defaults to 50 (range 1-200); offset defaults to 0.
Response:
{
"items": [
{
"id": "1f3c9a8e-0b21-4d77-9c54-2f1a6e8b0c3d",
"conversation_id": "0a2b4c6d-8e10-4321-b9a7-1c3e5f7a9b0d",
"contact_id": "7e9d1b3f-5a27-4c81-9f60-2d4b6a8c0e12",
"rating": 5,
"comment": "Very helpful, resolved my issue quickly!",
"channel": "email",
"sent_at": "2026-03-07T14:00:00Z",
"opened_at": "2026-03-07T16:05:00Z",
"responded_at": "2026-03-07T16:30:00Z",
"created_at": "2026-03-07T13:59:00Z"
}
],
"total": 85,
"limit": 10,
"offset": 0
}There is no status field — a survey's lifecycle is derived from its timestamps (see Survey Lifecycle).
Filtered Response List
GET /api/v1/csat (no /surveys suffix) returns the same items envelope but defaults limit to 50 with a max of 100, and accepts additional filters:
| Query param | Type | Description |
|---|---|---|
since | ISO-8601 datetime | Lower bound on responded_at (inclusive) |
until | ISO-8601 datetime | Upper bound on responded_at (inclusive) |
assignee_id | UUID | Filter by the rated conversation's assignee user |
team_id | UUID | Filter by the rated conversation's assignee team |
Filters compose with AND. If since is later than until, the endpoint returns 422.
curl "https://apps.aurionai.net/api/v1/csat?since=2026-03-01T00:00:00Z&until=2026-03-08T23:59:59Z&team_id=7e9d1b3f-5a27-4c81-9f60-2d4b6a8c0e12" \
-H "X-API-Key: itsm_sk_live_xxxx"CSAT Analytics
Get aggregated CSAT metrics and trends. This endpoint takes no query parameters — the trend is a fixed trailing 30-day window.
curl "https://apps.aurionai.net/api/v1/csat/analytics" \
-H "X-API-Key: itsm_sk_live_xxxx"Response:
{
"total_responses": 85,
"avg_score": 4.3,
"promoters": 66,
"passives": 12,
"detractors": 7,
"distribution": {
"1": 2,
"2": 5,
"3": 12,
"4": 30,
"5": 36
},
"trend_30d": [
{ "day": "2026-03-07", "count": 9, "avg_score": 4.44 }
],
"per_agent": [
{
"assignee_user_id": "8c1e2d3f-4a56-4789-b012-3c4d5e6f7a8b",
"assignee_name": "Jane Agent",
"response_count": 24,
"avg_score": 4.6,
"promoters": 20,
"passives": 3,
"detractors": 1
}
]
}distribution is keyed by integer rating. promoters/passives/detractors are computed from the rating buckets (≥4, =3, ≤2 respectively). trend_30d is an array of {day, count, avg_score} for the trailing 30 days; per_agent breaks the same metrics down per assignee.
One-Click Rating
Each survey email contains one-click rating links. When a customer clicks a rating, their response is recorded immediately:
GET https://apps.aurionai.net/api/v1/csat/rate?token=<survey_token>&rating=5This is a public endpoint — no authentication required. The survey token ensures only the intended recipient can respond. rating accepts 0-10 (to support NPS scales). On success it returns { "status": "thanks", "rating": "5" }. This route is intentionally excluded from the OpenAPI reference (include_in_schema=False), so it does not appear on the API reference page.
Get Survey Metadata
Fetch survey metadata and customization for rendering the public form. Public, token-based — no authentication required. Opening it marks the survey as opened (opened_at).
GET https://apps.aurionai.net/api/v1/csat/<token>Response:
{
"id": "1f3c9a8e-0b21-4d77-9c54-2f1a6e8b0c3d",
"tenant_id": "0a2b4c6d-8e10-4321-b9a7-1c3e5f7a9b0d",
"conversation_id": "7e9d1b3f-5a27-4c81-9f60-2d4b6a8c0e12",
"channel": "email",
"rating": null,
"already_responded": false,
"created_at": "2026-03-07T13:59:00Z",
"survey_question": null,
"rating_scale": "1-5",
"followup_enabled": false,
"followup_threshold": 3,
"followup_question": null,
"survey_question_translations": null,
"followup_question_translations": null
}The customization fields (survey_question, rating_scale, followup_*, and the per-locale *_translations maps) are merged from the tenant's CSAT configuration so the form can render without a second round-trip. Returns 404 if the token is unknown.
Submit Full Survey
For the full survey form with an optional comment and follow-up answer. Public, token-based — no authentication required.
curl -X POST "https://apps.aurionai.net/api/v1/csat/<token>/submit" \
-H "Content-Type: application/json" \
-d '{
"rating": 4,
"comment": "Good service, but took a bit long to respond.",
"followup_answer": "Faster first reply would help."
}'Request body:
| Field | Type | Description |
|---|---|---|
rating | integer (0-10) | Required. Score; the default 1-5 star scale uses 1-5, NPS uses 0-10 |
comment | string (≤2000) | Optional free-text comment |
followup_answer | string (≤2000) | Optional answer to the low-score follow-up prompt |
Response:
{
"ok": true,
"survey_id": "1f3c9a8e-0b21-4d77-9c54-2f1a6e8b0c3d",
"conversation_id": "7e9d1b3f-5a27-4c81-9f60-2d4b6a8c0e12",
"rating": 4
}Errors:
| Status | Body | Meaning |
|---|---|---|
404 | { "detail": "Survey not found" } | Token is unknown |
410 | { "detail": "Survey has expired" } | Survey link has expired |
409 | { "detail": "Survey already submitted" } | A response was already recorded for this token |
Survey Lifecycle
Surveys do not carry a status enum. State is derived from response timestamps:
| Timestamp | Set when |
|---|---|
sent_at | The survey email is dispatched |
opened_at | The recipient opens the full survey form (GET /csat/{token}) |
responded_at | The recipient submits a rating |
Expiry and duplicate-submission conditions surface only at submit time as HTTP errors: 410 for an expired survey, 409 for one that already has a response.
Rate Limits
| Endpoint | Limit |
|---|---|
List surveys (GET /csat/surveys) | 30/minute |
List responses (GET /csat) | 30/minute |
Analytics (GET /csat/analytics) | 30/minute |
Get survey metadata (GET /csat/{token}) | 30/minute |
Submit response (POST /csat/{token}/submit) | 10/minute |
The one-click rating link (GET /csat/rate) is not throttled.
Across the API, the global ceiling is 300 requests/minute per API key. On a 429 you get a Retry-After header (plus X-RateLimit-Limit and X-RateLimit-Remaining) and the body { "detail": "API key rate limit exceeded", "limit": 300 }. See Error Handling for the full error model.
Configuration
CSAT survey settings are managed via a dashboard session (the API key surface does not cover them) or in the admin dashboard under Configuration > CSAT. The configuration is stored as an extensible JSONB blob (csat_settings); the fields below are the ones the API validates and round-trips.
Get CSAT Configuration
curl "https://apps.aurionai.net/api/v1/csat/config" \
-H "X-API-Key: itsm_sk_live_xxxx"Response:
{
"enabled": true,
"survey_delay_hours": 2,
"survey_expiry_days": 7,
"survey_question": null,
"rating_scale": "1-5",
"followup_enabled": false,
"followup_threshold": 3,
"followup_question": null,
"survey_question_translations": null,
"followup_question_translations": null
}The response is the stored csat_settings blob; keys that were never set are absent or returned with their defaults.
Update CSAT Configuration
PUT /config accepts a partial update — only the fields you send are changed. Send null for a field to clear an override and fall back to the localized default.
curl -X PUT "https://apps.aurionai.net/api/v1/csat/config" \
-H "X-API-Key: itsm_sk_live_xxxx" \
-H "Content-Type: application/json" \
-d '{
"enabled": true,
"survey_delay_hours": 4,
"survey_expiry_days": 14,
"survey_question": "How did we do?",
"rating_scale": "nps-10",
"followup_enabled": true,
"followup_threshold": 6,
"followup_question": "What could we have done better?"
}'Configurable options:
| Field | Type | Description |
|---|---|---|
enabled | boolean | Enable or disable CSAT surveys |
survey_delay_hours | integer (1-72) | Hours after resolution before sending the survey |
survey_expiry_days | integer (1-30) | Days before the survey link expires |
survey_question | string (≤500) | Custom survey question; null falls back to the localized default |
rating_scale | enum | One of 1-5, emoji, thumbs, nps-10 |
followup_enabled | boolean | Show a low-score follow-up prompt |
followup_threshold | integer (0-10) | Ratings at or below this value trigger the follow-up prompt |
followup_question | string (≤500) | Prompt shown to detractors |
survey_question_translations | object | Per-locale override map for the survey question. Keys are locale codes (en, fr, nl, de, es, it, pl, sv, da, fi, pt); values ≤500 chars |
followup_question_translations | object | Per-locale override map for the follow-up prompt; same key/length rules |
Related Guides
- Analytics — CSAT analytics and trends
- Conversations — Conversations that trigger CSAT surveys
- Webhooks — Subscribe to
csat.*events