Interview Lifecycle API Reference
Version: 1.0
Last Updated: 2026-07-16
All endpoints are located under /api/v1/interviews/ and require the X-Tenant-ID header for tenant scoping.
Create Interview
Purpose
Initialize a new interview session for a survey respondent.
URL
/api/v1/interviews
Method
POST
Authentication
Bearer token authentication required.
Permissions
forms:session:create
Request Body
{
"survey_id": "uuid",
"session_token": "string",
"respondent_id": "uuid (optional)",
"total_questions": 50,
"survey_name": "string (optional)",
"interview_metadata": {}
}| Field | Type | Required | Description |
|---|---|---|---|
survey_id | UUID | Yes | Survey to conduct |
session_token | string | Yes | Unique session identifier |
respondent_id | UUID | No | Respondent being interviewed |
total_questions | integer | No | Expected question count |
survey_name | string | No | Display name |
interview_metadata | object | No | Additional metadata |
Response
{
"id": "uuid",
"tenant_id": "uuid",
"survey_id": "uuid",
"session_token": "string",
"status": "created",
"started_at": null,
"paused_at": null,
"completed_at": null,
"terminated_at": null,
"current_page": 0,
"answered_count": 0,
"created_at": "ISO8601"
}Error Responses
| Status | Description |
|---|---|
| 400 | Missing tenant ID or invalid survey |
| 401 | Authentication required |
| 403 | Insufficient permissions |
| 500 | Internal server error |
Example Request
curl -X POST "http://form-service:8010/api/v1/interviews" \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \
-H "X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{
"survey_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"session_token": "interview_abc123",
"respondent_id": "r1e2s3p4-o5n6d7e8t9t0"
}'List Interviews
Purpose
Retrieve paginated list of interviews with optional filtering.
URL
/api/v1/interviews
Method
GET
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by status |
survey_id | UUID | No | Filter by survey |
interviewer_id | UUID | No | Filter by interviewer |
respondent_id | UUID | No | Filter by respondent |
search | string | No | Search by session token |
sort | string | No | Sort field |
skip | integer | No | Default: 0 |
limit | integer | No | Default: 20, max: 100 |
Response
{
"items": [...],
"total": 100,
"skip": 0,
"limit": 20,
"has_next": true,
"has_previous": false
}Get Interview
Purpose
Retrieve details of a specific interview.
URL
/api/v1/interviews/{interview_id}
Method
GET
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Response
{
"id": "uuid",
"tenant_id": "uuid",
"survey_id": "uuid",
"respondent_id": "uuid",
"interviewer_id": "uuid",
"session_token": "string",
"status": "in_progress",
"started_at": "ISO8601",
"last_heartbeat_at": "ISO8601",
"current_page": 15,
"answered_count": 15,
"total_questions": 50,
"created_at": "ISO8601",
"updated_at": "ISO8601"
}Error Responses
| Status | Description |
|---|---|
| 400 | Missing tenant ID |
| 401 | Authentication required |
| 403 | Insufficient permissions |
| 404 | Interview not found |
Update Interview
Purpose
Update interview metadata and progress.
URL
/api/v1/interviews/{interview_id}
Method
PATCH
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Request Body
{
"current_page": 20,
"answered_count": 20,
"total_questions": 50,
"interview_metadata": {}
}| Field | Type | Description |
|---|---|---|
current_page | integer | Current navigation position |
answered_count | integer | Questions answered |
total_questions | integer | Total questions in survey |
interview_metadata | object | Additional metadata |
Response
Updated InterviewDto.
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid data or missing tenant ID |
| 409 | Concurrent modification detected |
Transition Interview
Purpose
Change interview status through valid lifecycle transitions.
URL
/api/v1/interviews/{interview_id}/transition
Method
POST
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Request Body
{
"to_status": "in_progress",
"form_data": {},
"is_complete": false,
"current_page": 50,
"version_id": "uuid (optional)",
"edit_response_id": "uuid (optional)"
}Valid Transitions
created → in_progress
in_progress → paused
in_progress → completed
in_progress → terminated
completed → needs_revision
needs_revision → in_progressResponse
Updated InterviewDto.
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid status or transition not allowed |
| 404 | Interview not found |
Interview Heartbeat
Purpose
Ping to indicate interview is still active.
URL
/api/v1/interviews/{interview_id}/heartbeat
Method
POST
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Response
{
"status": "in_progress",
"heartbeat_at": "2026-07-16T10:30:00.000Z"
}Error Responses
| Status | Description |
|---|---|
| 400 | Interview not heartbeat-eligible |
| 404 | Interview not found |
Get Termination Details
Purpose
Retrieve termination information for a terminated interview.
URL
/api/v1/interviews/{interview_id}/termination
Method
GET
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Response
{
"id": "uuid",
"interview_id": "uuid",
"terminated_by": "uuid",
"terminated_at": "ISO8601",
"termination_reason": "refused_to_continue",
"explanatory_text": "Respondent declined to answer sensitive questions",
"data_saved": true,
"retry_submission_available": false
}Error Responses
| Status | Description |
|---|---|
| 404 | No termination record found |
List Termination Policies
Purpose
Retrieve available termination reason options and policies.
URL
/api/v1/interviews/termination-policies
Method
GET
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Response
[
{
"value": "refused_to_continue",
"label": "Refused to Continue",
"description": "Respondent declined to continue the interview"
}
]Retry Submission
Purpose
Retry submission for a terminated interview with partial data.
URL
/api/v1/interviews/{interview_id}/retry-submission
Method
POST
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Response
Updated TerminationDto.
Delete Interview
Purpose
Soft-delete an interview (only if status is "created").
URL
/api/v1/interviews/{interview_id}
Method
DELETE
Authentication
Bearer token authentication required.
Permissions
forms:session:delete
Response
No content (204) on success.
Error Responses
| Status | Description |
|---|---|
| 400 | Interview not in "created" status |
| 403 | Insufficient permissions |
List Interview Events
Purpose
Retrieve audit trail of interview state changes.
URL
/api/v1/interviews/{interview_id}/events
Method
GET
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Response
[
{
"id": "uuid",
"interview_id": "uuid",
"event_type": "interview.started",
"to_status": "in_progress",
"actor_id": "uuid",
"created_at": "ISO8601"
}
]Resolve Interview by Session Token
Purpose
Look up an interview using its session token.
URL
/api/v1/interviews/resolve/by-session-token/{session_token}
Method
GET
Authentication
Bearer token authentication required.
Permissions
forms:session:read
Response
InterviewDto for the matching interview.
Error Responses
| Status | Description |
|---|---|
| 404 | Interview not found |
