How to Extract Action Items from Meeting Transcripts with an LLM
Use Gregnote webhooks and an LLM to automatically identify action items, owners, and deadlines from every meeting — and push them to Jira, Linear, or Notion.
Gregnote Team
4 August 2026
Why action items get lost
Most meeting notes are either missing or forgotten within 24 hours. Action items buried in a transcript nobody reads don't drive outcomes. Automatically extracting them — and dropping them into the tools your team already uses — closes that gap.
The extraction prompt
The key to reliable extraction is a structured prompt that produces machine-readable output:
const EXTRACT_PROMPT = ` You are an assistant that extracts action items from meeting transcripts.
Return a JSON array. Each item must have: - "task": a concise description of what needs to be done - "owner": the name of the person responsible (or null if unclear) - "due": a due date if mentioned (ISO format, or null)
Only include concrete commitments — not general discussion.
Return [] if there are no action items.
;
Calling the LLM from your webhook handler
async function extractActionItems(segments) {
const transcript = segments
.filter(s => !s.is_bot)
.map(s => `${s.speaker}: ${s.text}`)
.join("\n");const response = await openai.chat.completions.create({ model: "gpt-4o", response_format: { type: "json_object" }, messages: [ { role: "system", content: EXTRACT_PROMPT }, { role: "user", content: transcript }, ], });
return JSON.parse(response.choices[0].message.content); } ```
Pushing to Linear
async function createLinearIssues(actionItems, meetingTitle) {
for (const item of actionItems) {
await linearClient.createIssue({
title: item.task,
description: `Action item from: ${meetingTitle}`,
assigneeId: await resolveLinearUserId(item.owner),
dueDate: item.due,
});
}
}Full webhook handler
app.post("/hooks/gregnote", async (req, res) => {
const { event, transcript } = JSON.parse(req.body);
if (event !== "meeting.completed") return res.sendStatus(200);const items = await extractActionItems(transcript.segments); if (items.length > 0) { await createLinearIssues(items, "Meeting " + new Date().toLocaleDateString()); }
res.sendStatus(200); }); ```
What you get
Every meeting your bot attends now produces a set of Linear issues — automatically assigned to the right people — within a minute of the meeting ending. No copy-pasting, no missed commitments.
Try it yourself
API key in 30 seconds. Free credit on sign-up. No card required.