Skip to main content

Documentation Index

Fetch the complete documentation index at: https://jam.dev/docs/llms.txt

Use this file to discover all available pages before exploring further.

Jam provides webhooks so you can receive HTTP push notifications whenever a Jam is created. Use them to trigger CI builds, forward bug reports to external systems, post to Slack, file tickets automatically, or kick off any workflow that should react to a new Jam in real time. Webhooks are scoped to a Jam workspace. Configure them per workspace to match each team’s tooling. Jam supports the following webhook events:
  • jam.created: fired when a new Jam is captured from any origin (Chrome extension, iOS app, dashboard, Fin (Intercom) integration, or recording link). This is the event most integrations should subscribe to.
  • intercom.recorder.recorded: fired when a customer submits a screen recording through Jam’s Intercom integration. Use this to tweak the Fin AI Agent setup, for example, to react when a recording arrives mid-conversation.
  • intercom.recorder.opted_out: fired when a customer declines to record through Jam’s Intercom integration. Same use case, feeding Fin’s decision logic.
If you are not configuring the Fin AI Agent, you only need jam.created.

How does a webhook work?

A webhook push is an HTTP POST request sent to a URL you choose. Jam triggers it automatically when a jam is created. Your webhook consumer is an HTTP endpoint. It must:
  • Be available at a publicly accessible HTTPS, non-localhost URL.
  • Respond to the push with HTTP 200 (“OK”).
Each message is attempted based on the following schedule, where each period is started following the failure of the preceding attempt:
  • Immediately
  • 5 seconds
  • 5 minutes
  • 30 minutes
  • 2 hours
  • 5 hours
  • 10 hours
  • 10 hours (in addition to the previous)
If an endpoint is removed or disabled delivery attempts to the endpoint will be disabled as well. For example, an attempt that fails three times before eventually succeeding will be delivered roughly 35 minutes and 5 seconds following the first attempt.

Getting started

First, build a webhook consumer for Jam’s webhook agent to call. You can deploy your own HTTP server, or use a function platform like Netlify Functions, Vercel Functions, or Cloudflare Workers. For testing, services like RequestBin work well. In addition, you can also use no-code/low-code tools such as Zapier and n8n. Once your consumer accepts requests, configure the webhook for your workspace.
Zapier is a no-code automation platform that connects your favorite apps (like Gmail, Slack, and Google Sheets) so they can work together with Jam via webhooks.This is an example of how to set up a webhook to notify Slack whenever someone records a Jam via a Recording Link.

You can use this template and follow the steps below:\
1

Go to Zapier and create a new automation called "Zap"

2

Select the Trigger option and pick Custom > Webhooks

Image
3

Set the Trigger Event to "Catch Hook" and click Continue and skip to Test

Clean Shot 2026 05 19 At 12 09 21@2x
4

Copy the webhook URL

Clean Shot 2026 05 19 At 12 11 20@2x
5

Go to your Jam workspace and create a webhook for jam.created with the Zapier URL

6

Go to Testing and click Send Example

Clean Shot 2026 05 19 At 12 17 32@2x
7

Go back to your Zapier workflow and test your trigger

It should look something like this\
Clean Shot 2026 05 19 At 12 19 36@2x
8

Add next step, flow controls > Paths

Select “Origin,” “Exactly matches,” and “recording_link” to trigger Slack only for incoming Recording Links Jams.\
Clean Shot 2026 05 19 At 12 22 33@2x
9

Add Slack as Action and configure the step

Clean Shot 2026 05 19 At 12 28 55@2x
10

Test your workflow and hit Publish

Clean Shot 2026 05 19 At 12 32 25@2x

A minimal webhook consumer

Deployed on Netlify, a basic consumer looks like this:
const { createHmac } = require('node:crypto');

export default async (request) => {
  const payload = await request.text();
  const event = JSON.parse(payload);

  // Verify signature
  const signature = createHmac("sha256", Netlify.env.get('WEBHOOK_SECRET'))
    .update(payload)
    .digest("hex");
  if (signature !== request.headers.get('jam-signature')) {
    return new Response(null, { status: 400 });
  }

  // Do something with the jam, e.g. post to Slack, file a ticket, kick off a CI run.

  return new Response(null, { status: 200 });
};

export const config = {
  path: "/my-jam-webhook"
};

Creating a webhook

In the Jam dashboard, go to Settings → Integrations → WebhooksManage. From there, you have two ways to set up an endpoint. Manual endpoint setup
  1. Click Add Endpoint.
  2. Enter your endpoint URL
  3. Select the events to subscribe to (currently jam.created).
  4. Confirm creation.
Intercom Fin connector Only relevant if you are tuning Jam’s Intercom Fin AI Agent setup.
  1. Select Intercom Fin from the Webhook dropdown.
  2. Paste the URL provided by Intercom.
  3. Subscribe to intercom.recorder.recorded and intercom.recorder.opted_out.
  4. Confirm creation.
Jam returns a signing secret when the endpoint is created. Store it as WEBHOOK_SECRET (or whatever name fits your stack) and use it to verify incoming requests. The webhook is enabled by default. Capture a jam to test it.

Webhook Portal

The Webhook Portal (also under Settings → Integrations → Webhooks) gives you operational visibility into every endpoint:
  • Delivery logs for each attempt, with success and failure status.
  • Replay for failed deliveries so you can re-fire a payload after fixing your consumer.
  • Signing secret for verifying request authenticity.
  • Success rate and delivery statistics over time.
  • Full payload inspection, including headers and body, for any past delivery.
Use the portal to debug consumer issues and to confirm that retries land cleanly once your endpoint is back online.

Webhook payload

The payload arrives as JSON over HTTPS with these headers:
Accept-Charset: utf-8
Content-Type: application/json; charset=utf-8
Jam-Delivery: 234d1a4e-b617-4388-90fe-adc3633d6b72
Jam-Event: jam.created
Jam-Signature: 766e1d90a96e2f5ecec342a99c5552999dd95d49250171b902d703fd674f5086
User-Agent: Jam-Webhook
HTTP headerDescription
Jam-DeliveryA UUID (v4) that uniquely identifies this delivery.
Jam-EventThe event name. Currently always jam.created.
Jam-SignatureHMAC-SHA256 signature of the raw request body, hex-encoded.

jam.created body

FieldTypeDescription
jamIdstringUnique ID of the Jam.
jamUrlstringShareable URL where the Jam can be viewed.
teamIdstringID of the workspace the Jam belongs to.
typestringOne of video, screenshot, sessionReplay.
createdAtstringISO 8601 timestamp when the Jam was created.
titlestringJam title.
descriptionstringJam description. May be empty.
authorobjectThe user who captured the Jam. Includes email (required) and name.
mediaobjectURLs for the captured media. Includes videoUrl, screenshotUrl, thumbnailUrl where applicable.
systemInfoobjectCapture environment. Includes browser (name, version), os (name, version), and screen (width, height).
Required fields: jamId, jamUrl, teamId, type, createdAt, title, author, media, systemInfo.

Example payload

{
  "jamId": "2174add1-f7c8-44e3-bbf3-2d60b5ea8bc9",
  "jamUrl": "https://jam.dev/c/2174add1-f7c8-44e3-bbf3-2d60b5ea8bc9",
  "teamId": "dc844923-f9a4-40a3-825c-dea7747e57d6",
  "type": "video",
  "createdAt": "2026-05-14T12:53:18.084Z",
  "title": "Checkout button does nothing on Safari",
  "description": "Repro: add item to cart, hit checkout. Console shows a TypeError.",
  "author": {
    "email": "[email protected]",
    "name": "Alex Smith"
  },
  "media": {
    "videoUrl": "https://media.jam.dev/.../video.mp4",
    "thumbnailUrl": "https://media.jam.dev/.../thumb.jpg"
  },
  "systemInfo": {
    "browser": { "name": "Safari", "version": "17.4" },
    "os": { "name": "macOS", "version": "14.4.1" },
    "screen": { "width": 1512, "height": 982 }
  }
}