Skip to main content

Action items

Action items are persisted as first-class objects derived from the LLM analysis. Each item carries a provider-neutral intent and optional intentMetadata so the client can render launcher chips (Calendar, Gmail, dialer, …) without the backend constructing deep links.

GET /api/actions​

List the authenticated user's action items. Newest first.

Response — 200 OK​

[
{
"id": "a1b2c3d4-...",
"callRecordId": "f0a1d2e3-...",
"title": "Send revised pricing",
"description": "Revised pricing sheet by Friday",
"dueDate": "2026-06-26",
"status": "OPEN",
"sourceText": "priority=high; segments=seg_0002; text=\"I'll send the revised quote…\"",
"createdAt": "2026-05-29T13:00:42Z",
"updatedAt": "2026-05-29T13:00:42Z",
"ownerSpeakerId": "spk_1",
"ownerSpeakerLabel": "Speaker 1",
"ownerDisplayName": null,
"ownerRole": "USER",
"sourceSegmentIds": ["seg_0002"],
"intent": "email",
"intentMetadata": {
"toEmail": "alex@acme.com",
"toName": "Alex",
"subject": "Revised pricing sheet",
"bodyPreview": "Attaching the revised pricing reflecting the 12-month discount we discussed."
}
}
]

Fields​

FieldTypeNotes
idUUIDStable row id. Use for PATCH /api/actions/{id}.
callRecordIdUUIDParent call. Filter client-side for per-call views.
titlestringShort action title from the LLM.
descriptionstringLonger context. Nullable.
dueDateISO dateYYYY-MM-DD. Null when the transcript didn't resolve one.
statusenumOPEN, IN_PROGRESS, DONE, or DISMISSED.
sourceTextstringForensic payload (priority, cited segments, excerpt).
ownerSpeakerIdstringStable spk_N from the normalised transcript.
ownerSpeakerLabelstringDisplay label at extraction time.
ownerDisplayNamestringRefined name when known.
ownerRolestringUSER / CONTACT / UNKNOWN.
sourceSegmentIdsstring[]Segment ids the LLM cited as evidence.
intentstringProvider-neutral classification — see below.
intentMetadataobjectTyped payload for deep-link construction. All fields optional.

Intent classification​

The LLM classifies each action item with an abstract intent. The client (Android today, others later) decides which app(s) to offer as chips.

intentMeaningTypical chips (client-side)
meetingSchedule a video / phone meetingGoogle Calendar, Meet, Zoom, Teams
emailSend / draft an emailGmail, default mail app
callPhone the contact backDialer
messageSend a chat / SMSWhatsApp, SMS, Telegram
reminderSelf-reminder, no other partyCalendar reminder
taskTrack in a task systemShare sheet / task app
noneNo launchable intentNo chips

When the transcript was explicit about a provider ("let's hop on Zoom"), the LLM may set intentMetadata.providerHint (meet | zoom | teams | phone for meetings; whatsapp | sms | telegram for messages). This is a hint — the client makes the final call about which chip to show or prioritise.

intentMetadata by intent​

Every field is optional. The LLM is instructed never to invent emails, phone numbers, or times not grounded in the transcript.

IntentTypically populated fields
meetingproviderHint, attendees: [{name, email?}], proposedAt (ISO datetime), durationMinutes, title, location
emailtoEmail, toName, subject, bodyPreview
callphoneNumber, contactName
messagechannel, phoneNumber or handle, bodyPreview
reminderremindAt (ISO datetime), title, notes
tasktitle, notes
none(empty / omitted)

GET /api/calls/{callId}/action-items​

List the persistent action items attached to a specific call. Returns the same shape as GET /api/actions but scoped to one call. Includes both AI-extracted items (source: "AI") and user-created items (source: "MANUAL").

Response — 200 OK​

Same array shape as GET /api/actions. Each item now also carries:

FieldTypeNotes
priorityenumLOW, MEDIUM, or HIGH. Null on legacy AI-extracted items.
sourcestring"AI" (extracted by pipeline) or "MANUAL" (created by user). Null on very old rows.

POST /api/calls/{callId}/action-items​

Create a manual action item attached to a call.

Request​

{
"title": "Send revised pricing",
"description": "Attach the updated Q3 sheet",
"dueDate": "2026-06-30",
"priority": "HIGH"
}
FieldRequiredNotes
titleYesShort action title.
descriptionNoLonger context.
dueDateNoYYYY-MM-DD.
priorityNoLOW, MEDIUM, or HIGH.

Response — 201 Created​

The created ActionItemResponse with source: "MANUAL".

Errors​

StatusCause
400Missing title or invalid field.
404Call not found or owned by another user.

PUT /api/action-items/{id}​

Full replacement of a user-editable action item (title, description, dueDate, priority, status). All fields must be supplied; use the current values for fields the user did not change.

Request​

{
"title": "Send revised pricing",
"description": "Attach the updated Q3 sheet",
"dueDate": "2026-06-30",
"priority": "HIGH",
"status": "OPEN"
}
FieldRequiredNotes
titleYes
descriptionNoPass null to clear.
dueDateNoYYYY-MM-DD. Pass null to clear.
priorityNoLOW, MEDIUM, or HIGH. Pass null to clear.
statusYesOPEN, IN_PROGRESS, DONE, or DISMISSED.

Response — 200 OK​

The updated ActionItemResponse.

Errors​

StatusCause
400Missing required field or invalid value.
404Item not found or owned by another user.

DELETE /api/action-items/{id}​

Hard-deletes an action item. Idempotent — returns 404 if already deleted.

Response — 204 No Content​

Errors​

StatusCause
404Item not found or owned by another user.

PATCH /api/actions/{id}​

Update an action item's status. Today only status is settable. Prefer PUT /api/action-items/{id} for full edits.

Request​

{ "status": "DONE" }

status must be one of "OPEN", "IN_PROGRESS", "DONE", or "DISMISSED". The legacy values PENDING and COMPLETED were renamed in V19 and are no longer accepted.

Response — 200 OK​

The updated ActionItemResponse (same shape as above, including intent and intentMetadata).

Errors​

StatusCause
400Missing or invalid status.
404Item missing or owned by another user.

Client integration notes​

  • Chips are a client concern. The backend classifies intent and extracts metadata; the Android app maps intent → list of ChipSpec (label + icon + Intent builder).
  • Two surfaces, same chips. intent + intentMetadata are returned on both GET /api/actions (the Actions tab) and on the action items inside GET /api/calls/{id}/analysis (the call-detail screen). The app renders identical integration chips on both via a shared renderer, so a call's action items show Calendar/Gmail/Call/Reminder chips inline — not only in the global Actions tab.
  • Completion is server-side. After the user finishes work in the target app, they tap the checkbox → PATCH /api/actions/{id} with { "status": "DONE" }. To un-complete, send { "status": "OPEN" }.
  • Full edit via PUT. Use PUT /api/action-items/{id} to update title, description, due date, priority, and status in one request. PATCH /api/actions/{id} remains for status-only toggles.
  • Manual creation. Users can add their own tasks on a call via POST /api/calls/{callId}/action-items. These items have source: "MANUAL" and priority can be set at creation time.
  • Priority. priority is LOW, MEDIUM, or HIGH. AI-extracted items may have null priority on older rows; the client should handle null gracefully (omit the badge rather than crash).
  • Legacy rows. Items extracted before intent classification was added have intent: null — render no chips.
  • Privacy. toEmail and phoneNumber are only populated when spoken in the transcript (or from call-log enrichment the user already consented to). The LLM is told to leave fields null rather than guess.