Webhooks
Receive real-time notifications when recordings are processed
Pocket sends webhook notifications to your endpoint when recording events occur. Use webhooks to trigger automations in tools like n8n, Zapier, and Make, or in your own backend.
Supported Events
Processing Events
| Event | Fired When |
|---|---|
transcription.completed | Transcript generation is complete |
summary.completed | Full post-processing is complete (summary, actions, tags, and related outputs) |
summary.regenerated | Full summary package is regenerated |
summary.updated | Summary text is regenerated |
mind_map.completed | Mind map generation is complete |
action_items.regenerated | Action items are regenerated |
speakers.labeled | Speaker labels are resolved in the transcript |
User Actions
| Event | Fired When |
|---|---|
transcript.edited | A user edits transcript text or speaker labels |
action_items.updated | A user edits or completes an action item |
recording.created | A recording is created or uploaded |
recording.deleted | A recording is deleted |
recording.merged | Two or more recordings are merged |
translation.completed | Transcript translation is complete |
Setup
Configure webhook destinations in the Pocket app integrations UI for personal webhooks. Organization owners and admins can additionally configure organization-wide webhooks via the Pocket organization API:
| Method | Path | Description |
|---|---|---|
GET | /api/v1/organization/:orgId/webhooks | List org webhook integrations |
GET | /api/v1/organization/:orgId/webhooks/:id | Fetch a specific org integration |
POST | /api/v1/organization/:orgId/webhooks | Create an org webhook integration (admin only) |
PUT | /api/v1/organization/:orgId/webhooks/:id | Update an org webhook integration (admin only) |
DELETE | /api/v1/organization/:orgId/webhooks/:id | Remove an org webhook integration (admin only) |
POST | /api/v1/organization/:orgId/webhooks/:id/test | Send a sample payload to verify the endpoint (admin only) |
When a recording event fires for a user who belongs to one or more organizations, Pocket delivers the event to that user's personal webhook(s) and to every active organization's webhook(s) in addition.
New personal webhooks automatically get a signing secret. Pocket shows the plaintext secret once when the webhook is created, and again only if you rotate it. Store it in your own secret manager before closing the dialog.
Delivery
| Setting | Value |
|---|---|
| HTTP method | POST |
| Content-Type | application/json |
| User-Agent | HeyPocket-Webhook/1.0 |
| Timeout | 30 seconds |
| Retries | 3 attempts (exponential backoff 1sā30s) |
| Delivery guarantee | At-least-once |
Payload Structure
Every payload includes a top-level user object identifying the recording owner. Organization-scoped deliveries also include an organization object so the receiver knows which org's webhook fired.
{
"event": "summary.completed",
"timestamp": "2026-02-18T12:00:00.000Z",
"user": {
"id": "user_abc123",
"email": "alice@example.com"
},
"organization": {
"id": "org_def456"
},
"recording": {
"id": "rec_abc123",
"title": "Team Standup",
"description": "Weekly sync",
"duration": 1800,
"language": "English",
"recordingAt": "2026-02-17T15:02:00.000Z",
"createdAt": "2026-02-18T11:30:00.000Z"
},
"summarizations": {
"sum_456": {
"id": "row_789",
"summarizationId": "sum_456",
"processingStatus": "completed",
"v2": {
"summary": {
"title": "Team Standup",
"emoji": "š",
"markdown": "## Key Decisions\n\n...",
"bulletPoints": ["Ship v2 by Friday", "Review design docs"]
},
"actionItems": {
"version": "3",
"actionItems": [
{
"id": "subtask_1",
"parentTaskId": "task_1",
"title": "Ship v2 by Friday",
"dueDate": "2026-02-20",
"status": "TODO",
"globalActionItemId": "gai_001",
"isCompleted": false,
"is_completed": false
}
]
},
"mindMap": { "nodes": [], "edges": [] },
"speakerMindMap": null,
"clusterMindMap": null,
"contextMindMap": null,
"flowMindMap": null
},
"settings": {
"modelId": "gpt5",
"themeId": "auto_detect",
"language": "English"
},
"autoInitiated": true,
"createdAt": "2026-02-18T12:00:00.000Z",
"updatedAt": "2026-02-18T12:00:05.000Z"
}
},
"transcript": [
{
"speaker": "SPEAKER_00",
"speakerName": "Alice",
"text": "Let's go over this week's priorities.",
"start": 0.0,
"end": 3.5
},
{
"speaker": "SPEAKER_01",
"text": "Sounds good.",
"start": 3.5,
"end": 4.2
}
],
"speakers": {
"SPEAKER_00": {
"name": "Alice",
"speakerId": "spk_abc123"
}
}
}Speaker Names
| Field | Meaning |
|---|---|
transcript[].speaker | The raw speaker label from the transcript, such as SPEAKER_00 or USER_SPEAKER_.... |
transcript[].speakerName | The name shown for that speaker in Pocket. Omitted when the speaker has no name yet. |
speakers | Maps each named speaker label to { name, speakerId }. Labels without a name are not listed. Sent only with the transcript, so it is left out when the webhook excludes the transcript. |
A speaker's name is shared by every recording they appear in. Renaming or merging a speaker sends a transcript.edited webhook for each of those recordings, so every payload carries the updated name. Renaming a speaker for one recording only sends it for that recording.
Recording Timestamps
| Field | Meaning |
|---|---|
recording.recordingAt | When the recording started, in UTC (ISO 8601). Pocket device recordings use the device clock, so this stays accurate when the device syncs hours or days after the conversation. Add recording.duration (seconds) to get the end time. |
recording.createdAt | When the recording was uploaded to Pocket. |
timestamp | When this webhook was sent. |
Use recordingAt rather than the recording title to find when a conversation happened. The default title is a display string in the owner's local time, and it usually changes after processing.
Signature Verification
Each personal webhook created in the current app includes HMAC-SHA256 signature headers. Older webhook rows without a secret may continue to send unsigned deliveries until you rotate or recreate the webhook.
| Header | Description |
|---|---|
X-HeyPocket-Signature | HMAC-SHA256 of {timestamp}.{rawBody} using your secret |
X-HeyPocket-Timestamp | Unix timestamp (ms) of the delivery |
Verify each request by computing HMAC-SHA256(secret, "${timestamp}.${rawBody}") and comparing it to X-HeyPocket-Signature. Use the exact raw JSON request body bytes you received, before parsing or re-serializing.
const crypto = require('crypto');
function verifySignature(secret, timestamp, body, signature) {
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${body}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}When Webhooks Fire
Webhooks fire for processing completion events and user-driven updates (recordings, transcripts, action items, and translations).