← API Reference

Note Q&A (Interview)

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

StepActionDetails
1Set active notePOST /api/threads/:threadId/active-note
2Start interviewevent.type: "user_text" with activeTool: "interview"
3Receive questionSSE ui event with qid, choices (A-E), allowSkip
4Answer questionevent.type: "interview_answer" with qid + choiceId or action
5Repeat 3-4Until all questions answered or action: "end"
6FinalizationAI generates proposed edits. complete event includes noteUpdate artifact.
7Apply editsCall updateNote mutation with the returned noteMd to persist.

Step 1: Set active note

Request
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

Request
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:

SSE 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

Choose an option
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"
      }
    }
  }'
Free text answer (choice E)
{
  "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"
    }
  }
}
Skip a question
{
  "threadId": "...",
  "actionId": "...",
  "event": {
    "type": "interview_answer",
    "payload": { "qid": "q-abc-001", "action": "skip" }
  }
}
End interview early
{
  "threadId": "...",
  "actionId": "...",
  "event": {
    "type": "interview_answer",
    "payload": { "qid": "q-abc-001", "action": "end" }
  }
}

Payload reference

NameTypeRequiredDescription
qidstringRequiredQuestion ID from the ui event payload
choiceId"A"|"B"|"C"|"D"|"E"OptionalSelected choice. Required when action is "continue". Omit for skip/end.
freeTextstringOptionalFree-text answer. Required when choiceId is "E".
action"continue"|"skip"|"end"Requiredcontinue = answer and proceed, skip = skip this question, end = finalize now
noteIdstringOptionalOptional. 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:

SSE complete event (after finalization)
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:

Apply the proposed edits
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

CodeRetryableMeaning
ACTIVE_NOTE_REQUIREDNoNo active note set on thread. Call set active-note first.
INTERVIEW_IN_PROGRESSNoSent user_text while interview is running. Answer the question instead.
INTERVIEW_FINALIZINGYesFinalization in progress. Retry after ~1.5s.
INTERVIEW_OUT_OF_SYNCNoqid does not match current question cursor.

Important notes

  • While an interview is running, user_text events are blocked. You must answer or end the interview first.
  • Each answer request needs a fresh actionId (UUID).
  • Use the same threadId for 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.