Skip to content
Skip to main content

Get notified when a transcript is ready

Last updated:

After you send a Notetaker bot to a call, there’s no clean signal for when the meeting actually ends or when the transcript finishes processing. Polling the media endpoint on a timer means you either check too often and waste requests, or check too rarely and make your users wait. Processing time also varies with meeting length, so a fixed interval never fits every call. Webhooks remove the guesswork: Nylas pushes a notification the instant a recording or transcript becomes available, and your handler reacts in one step.

This recipe wires up two Notetaker triggers so your app reacts to state changes and grabs media as soon as it’s ready, instead of polling.

Two triggers cover the full lifecycle. The notetaker.meeting_state event reports state changes as the bot joins, records, and leaves, and notetaker.media fires once the recording and transcript finish processing and are ready to download. Subscribing to both means you track the meeting live and still get a clean “files are ready” signal at the end.

Create the webhook with one POST /v3/webhooks/ request. Pass your HTTPS endpoint as webhook_url, the two triggers in trigger_types, and an optional notification_email_addresses list that Nylas alerts if delivery starts failing. The endpoint must return 200 OK within 10 seconds.

When you create the webhook, the API sends a GET request with a challenge query parameter that your endpoint echoes back to confirm the URL. For the full create flow and the challenge handshake, see using webhooks with Nylas.

The notetaker.media event arrives when processing finishes, with status and state set to available. The payload’s data.object carries the bot identifiers plus a media object holding signed download URLs. You don’t get the file bytes in the webhook; you get the IDs you need to fetch them. Across all Notetaker events, the payload shape stays the same except for the inner state and media fields.

The two IDs you extract are data.object.id (the Notetaker ID) and data.object.grant_id. Together they build the media endpoint URL in the next step. The media object also reports recording_duration in seconds and recording_file_format, so your handler can branch on file type before downloading.

When the notetaker.media event lands, call GET /v3/grants/<NYLAS_GRANT_ID>/notetakers/<NOTETAKER_ID>/media using the two IDs from the payload to get fresh signed URLs for the recording, transcript, summary, and action items. The signed links the endpoint returns expire after 3,600 seconds (one hour), so fetch and store the files right away rather than queuing the work for later.

The handler below verifies the trigger type, pulls the IDs, and requests the media. Return 200 OK fast and move the download to a background job if it’s slow, since Nylas treats anything past the 10-second window as a failed delivery.

These details decide whether your handler stays reliable in production. Each one maps to a real field in the notetaker.meeting_state payload or a delivery behavior shared by every Nylas webhook. Plan for all four before you ship; ordering and retries cause most of the surprises.

The notetaker.meeting_state payload carries both a top-level state and a more specific meeting_state field. When state is connecting, meeting_state is waiting_for_entry. When state is attending, it’s recording_active, the signal that recording started. When state is failed_entry, meeting_state is one of 12 error reasons: error, internal_error, bad_meeting_code, bad_meeting_link, sign_in_required, entry_denied, no_response, cannot_join, meeting_capacity_reached, admission_timeout, network_error, or cancelled. Branch on these to retry, alert, or re-invite the bot.

Every notification carries an X-Nylas-Signature header: a hex-encoded HMAC-SHA256 of the raw request body, signed with your webhook_secret. Recompute the HMAC over the unmodified body and reject any request that doesn’t match before you act on it. See secure a webhook for the verification details and where the webhook_secret comes from, and webhook best practices for retries and compressed delivery.

Nylas retries delivery when your endpoint doesn’t return 200 OK, so the same notetaker.media event can arrive more than once. Each payload includes a webhook_delivery_attempt counter and a stable top-level id. Key your processing on that id (or on the Notetaker ID) so a duplicate delivery doesn’t trigger a second download or a duplicate database row.

Webhooks aren’t guaranteed to arrive in the order events happened, so a later meeting_state change can land before an earlier one. Trust the time field on each payload rather than arrival order, and treat notetaker.media as the authoritative “ready” signal instead of inferring readiness from a sequence of state events.