Skip to main content

Intake State API (LiveKit-first)

This API is a lightweight state/persistence surface for intake sessions when conversational orchestration runs outside domain-chatbot (for example, in LiveKit).

Base prefix: /query/intake/session

Authentication and domain

  • Uses existing get_current_user_or_api_key_via_request.
  • Domain resolution uses the same resolve_intake_domain_for_request(...) behavior as existing intake endpoints.
  • A valid user JWT or domain API key is required.

Endpoints

POST /query/intake/session/init

Creates or loads a session for a known form_id.

Request:

{
"form_id": "assessment_intake",
"language": "en",
"intake_domain": "llhuk",
"session_start_timestamp": "20260602_103000",
"form_state": {}
}

Response (success):

{
"ok": true,
"session": {
"form_id": "assessment_intake",
"session_start_timestamp": "20260602_103000",
"form_state": {},
"missing_required": ["full_name"],
"progress": {
"total_required": 8,
"missing_required": 8,
"completed_required": 0
},
"form_submitted": false,
"language": "en"
},
"form_schema": { "...": "schema" }
}

PATCH /query/intake/session/{session_id}/fields

Applies one or more field updates to session state.

Request:

{
"form_id": "assessment_intake",
"language": "en",
"intake_domain": "llhuk",
"updates": [
{ "field_id": "full_name", "value": "John Smith" },
{ "field_id": "email", "value": "john@example.com" }
]
}

Repeatable group updates:

  • Add item: { "op": "add_repeatable_item", "group_id": "work_experiences" }
  • Update item subfield: { "group_id": "work_experiences", "item_index": 0, "field_id": "company", "value": "Aventora" }

Response includes recorded, errors, and normalized session snapshot.

POST /query/intake/session/{session_id}/validate

Runs required-field validation against current state (or supplied form_state).

Request:

{
"form_id": "assessment_intake",
"language": "en",
"intake_domain": "llhuk"
}

Response:

{
"ok": false,
"missing_required": ["phone"],
"session": { "...": "snapshot" }
}

POST /query/intake/session/{session_id}/submit

Runs final intake submit path using existing semantic validation + integration submit logic.

Request:

{
"form_id": "assessment_intake",
"language": "en",
"intake_domain": "llhuk",
"form_state": { "...": "optional override" },
"intake_review_token": null
}

Response:

{
"ok": true,
"form_submitted": true,
"message": "Your assessment has been submitted successfully.",
"errors": [],
"missing_required": [],
"session": { "...": "snapshot" }
}

GET /query/intake/session/{session_id}?form_id=...&language=en

Loads persisted session snapshot and schema.

Response:

{
"ok": true,
"session": { "...": "snapshot" },
"form_schema": { "...": "schema" }
}

POST /query/intake/session/{session_id}/reset

Deletes persisted runtime intake answers for the session so a voice interview can start clean (same session_id, empty form_state on next bootstrap).

Request:

{
"form_id": "criminal_law_intake",
"intake_domain": "llhuk"
}

POST /query/intake/session/{session_id}/voice-turn

Runs one deterministic voice interview turn (same warm intro, acknowledgements, and field prompts as POST /query/intake/continue with lock_turn_language: true). Use this from LiveKit/BackendLK instead of hand-rolling field labels.

Request:

{
"form_id": "real_estate_intake",
"language": "en",
"intake_domain": "llhuk",
"bootstrap_only": true,
"user_message": null,
"voice_confirm_submit": false,
"is_anonymous": false,
"user_profile": { "id": 1, "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com" }
}

Response (success):

{
"ok": true,
"answer": "Hi — I'm your intake assistant. ... Whenever you're ready, What is your first and last name?",
"form_submitted": false,
"review_pending": false,
"pending_field_id": "first_name",
"session": { "...": "snapshot" },
"form_schema": { "...": "schema" }
}

Notes

  • Existing /query/intake and /query/intake/continue remain available for backward compatibility.
  • init, patch, validate, and submit are state-only; use voice-turn for conversational copy.