Based on: A worked playbook on Granola's webhook and public API, written from the bundled granola-meeting-actions example skill.
The meeting ends. The work starts.
Illustrative workflowMeeting notes arrive, the skill extracts actionable commitments, and your agent starts the work you have authorized. You come back to completed deliverables, progress you can follow, and decisions that need you.
This example uses fictional tasks and counts, not customer activity or a testimonial. The broader workflow requires skills, tools and permissions you configure; the two Granola skills below cover notes and tracked follow-ups.
Granola: the existing signed webhook preset and bundled meeting-actions skill provide the starting point for the playbook below.
Google Meet: an example alternative is to pass authorized meeting notes through a separately configured automation to a signed Skillhook webhook. This describes a custom webhook flow, not a native Google Meet connector; exporting and forwarding the notes requires your permission and setup.
The situation
Granola writes the notes. Someone then sends them to the people who were in the meeting, pulls out the action items, creates the tasks, and finds out what each item needs before anyone can act on it. Granola's webhook posts note.generated the moment a note is ready, with identifiers only (event_id, event_type, note_id, occurred_at); the content comes from the API with a key.
Two jobs, two skills. One writes to people (the notes to the attendees), the other writes to the tracker (the follow-ups). Keeping them apart keeps each one's rules short: the first never creates tasks, the second never sends email, and each asks for the decisions and approvals its work needs.
How it runs
- Granola. Two webhook endpoints (Settings → Connectors → Webhooks), one per skill, each subscribed to
note.generatedonly, each with its ownwhsec_…secret. - Two hosted URLs. Granola runs on a Mac that closes its lid; the cloud holds each delivery sealed for up to 72 hours and hands it over on the machine's next sync, where the Standard Webhooks signature is verified with the secret in its
.env. - skillhook.
auth: granola;whenkeepsevent_typetonote.generated(edits and access grants are acknowledged and skipped);dedupeonnote_idmeans one run per note within a day, however often Granola retries. - The jobs. Both fetch the note (
GET /v1/notes/{id}). The notes skill takes the recipients from the attendee list, tells internal addresses from external ones, drafts one email, and asks for approval of its content and exact recipients before sending with the mail tool the machine has. The follow-ups skill lists the commitments with an owner, a due date and whether they need research, creates one task per item in the tracker the machine has, assigned to the owner when the account matches the attendee's email, then does the research and writes what it found on each task. - The inbox. Each run under the meeting's title. The follow-ups run asks when an owner or a date is unclear, with the attendees' names as the options; the
needs_humanalert goes out; the pick resumes the run.
Set it up with your agent
Paste this into Claude Code or Codex with the skillhook plugin. It installs skillhook, finds the mail and tracker tools the machine has, creates both skills, turns on two hosted URLs and walks you through Granola's endpoints and a test meeting. It never asks for a secret; you run skillhook secret set in your own terminal. Paste the two SKILL.md files from the next section as your following messages.
The skills
Both start from the bundled granola-meeting-actions example (skillhook skills add granola-meeting-actions), which books calendar follow-ups. These two split email from tasks, add the research step, and name the decisions and approvals each needs. Every frontmatter field is one skillhook validates; INTERNAL_EMAIL_DOMAINS is plain configuration read from .env like a secret, because env: is how a skill gets a value.
Where a person comes in
- Every email and disclosure. The notes skill shows the complete draft and exact recipient list, flags external attendees, and asks for explicit approval before sending to anyone. Without approval it saves the draft and ends with
needs_human; no email is sent. The answer in the inbox resumes the run, which checks the approved scope before proceeding. - An owner or a due date that is unclear. The follow-ups skill asks one question for all such items, with the attendees' names (or "This week", "Next week", "No date") as options, and creates the clear items' tasks while it waits. Without an answer it creates the unclear ones unassigned, marked in their title, and ends with
needs_humannaming them; the pick in the inbox resumes the session, and the run finishes those tasks. - Alerts.
needs_humanwhen a question is open or a run ended on one;job_failedwhen the API key is missing or the note is not visible to it.
What to check after
- Deliveries. Two accepted deliveries per note, one per hosted URL. A
duplicateis Granola retrying; askippedone is anote.editedevent the filter left out, as intended. - The jobs. Under the meeting's title: the recipients and who was left out, the items with their owners, the tasks as links (
issue), the note (source), the email (message). - Replay once a cause is fixed (the API key, the mail tool, the tracker login):
replay_deliveryruns the delivery again without deduplication, and both skills look before they act, so a replay never sends a second email or creates a second task for the same note.