Note Q&A (Interview)
The Note Q&A tool (internally called "interview") deepens a note through a structured multi-turn Q&A flow. The AI generates 3-5 questions based on the note content. After all questions are answered (or ended early), the AI proposes edits to the note based on your answers.
Flow overview
| Step | Action | Details |
|---|---|---|
| 1 | Set active note | POST /api/threads/:threadId/active-note |
| 2 | Start interview | event.type: "user_text" with activeTool: "interview" |
| 3 | Receive question | SSE ui event with qid, choices (A-E), allowSkip |
| 4 | Answer question | event.type: "interview_answer" with qid + choiceId or action |
| 5 | Repeat 3-4 | Until all questions answered or action: "end" |
| 6 | Finalization | AI generates proposed edits. complete event includes noteUpdate artifact. |
| 7 | Apply edits | Call updateNote mutation with the returned noteMd to persist. |
Step 1: Set active note
curl -X POST https://narrativelion.com/api/threads/your-thread-uuid/active-note \
-H "Authorization: Bearer nlk_your_key" \
-H "Content-Type: application/json" \
-d '{ "noteId": "your-note-uuid" }'Step 2: Start interview
curl -N https://narrativelion.com/api/chat/stream \
-H "Authorization: Bearer nlk_your_key" \
-H "Content-Type: application/json" \
-d '{
"threadId": "your-thread-uuid",
"actionId": "unique-action-uuid",
"event": {
"type": "user_text",
"payload": {
"text": "start interview",
"activeTool": "interview"
}
}
}'Step 3: Receive question (SSE ui event)
The stream emits token events (question text) followed by a structured ui event:
event: ui
data: {
"eventType": "ui",
"kind": "interview_question",
"payload": {
"qid": "q-abc-001",
"choices": {
"A": "Perspective 1 text",
"B": "Perspective 2 text",
"C": "Perspective 3 text",
"D": "Perspective 4 text",
"E": "Other (provide your own answer)"
},
"allowSkip": true,
"allowContinue": true
}
}Step 4: Answer a question
curl -N https://narrativelion.com/api/chat/stream \
-H "Authorization: Bearer nlk_your_key" \
-H "Content-Type: application/json" \
-d '{
"threadId": "your-thread-uuid",
"actionId": "unique-action-uuid-2",
"event": {
"type": "interview_answer",
"payload": {
"qid": "q-abc-001",
"choiceId": "B",
"action": "continue"
}
}
}'{
"threadId": "your-thread-uuid",
"actionId": "unique-action-uuid-3",
"event": {
"type": "interview_answer",
"payload": {
"qid": "q-abc-001",
"choiceId": "E",
"freeText": "My own perspective on this topic...",
"action": "continue"
}
}
}{
"threadId": "...",
"actionId": "...",
"event": {
"type": "interview_answer",
"payload": { "qid": "q-abc-001", "action": "skip" }
}
}{
"threadId": "...",
"actionId": "...",
"event": {
"type": "interview_answer",
"payload": { "qid": "q-abc-001", "action": "end" }
}
}Payload reference
| Name | Type | Required | Description |
|---|---|---|---|
qid | string | Required | Question ID from the ui event payload |
choiceId | "A"|"B"|"C"|"D"|"E" | Optional | Selected choice. Required when action is "continue". Omit for skip/end. |
freeText | string | Optional | Free-text answer. Required when choiceId is "E". |
action | "continue"|"skip"|"end" | Required | continue = answer and proceed, skip = skip this question, end = finalize now |
noteId | string | Optional | Optional. Must match the thread's active note if provided. |
Finalization and applying edits
When the last question is answered (or action: "end" is sent), the AI analyzes all answers and generates proposed edits. The complete event includes a noteUpdate artifact:
event: complete
data: {
"eventType": "complete",
"finalMessage": "Draft updated with your insights. Ready for your review.",
"artifacts": {
"noteUpdate": {
"mode": "patch",
"noteId": "your-note-uuid",
"noteMd": "# Updated note content...",
"patches": [
{ "patchId": "sec_1", "title": "Update section: Overview", "rationale": "...", "anchor": {...}, "replacement": "..." }
]
}
}
}The noteUpdate artifact is a proposal only.
The server does not automatically write it to the note. To persist the changes, call updateNote with the returned noteMd:
mutation {
updateNote(
noteId: "your-note-uuid"
noteMd: "<the full noteMd string from artifacts.noteUpdate.noteMd>"
) {
id
updatedAt
}
}To selectively apply changes, inspect the patches array and construct your own merged noteMd before calling updateNote.
Error codes
| Code | Retryable | Meaning |
|---|---|---|
ACTIVE_NOTE_REQUIRED | No | No active note set on thread. Call set active-note first. |
INTERVIEW_IN_PROGRESS | No | Sent user_text while interview is running. Answer the question instead. |
INTERVIEW_FINALIZING | Yes | Finalization in progress. Retry after ~1.5s. |
INTERVIEW_OUT_OF_SYNC | No | qid does not match current question cursor. |
Important notes
- While an interview is running,
user_textevents are blocked. You must answer or end the interview first. - Each answer request needs a fresh
actionId(UUID). - Use the same
threadIdfor all requests in one interview session. - If you reconnect mid-interview (e.g. start again with
activeTool: "interview"), the existing interview state is resumed. - Each turn is a separate HTTP POST. The server persists interview state (cursor, answers) between requests.