Why SureTake?Pricing

Webhooks

What is a webhook?

A webhook lets SureTake automatically notify your systems the moment a recording session finishes processing. Each time a session's files are ready, we send an HTTP POST to a URL you provide, containing everything about that episode: the download links, session notes, and (optionally) a transcript.

It's how you automate the after-recording work: dropping files into cloud storage, kicking off an editing workflow, logging the episode, notifying your team, and so on. It works with tools like Zapier, Make, and n8n, or any endpoint you build yourself.

When does it fire?

Once per completed session, after every participant's track has finished uploading and converting, never per-file or mid-recording. You get a single recording.ready event with everything for that episode in one payload, so an automation can process the whole session at once (e.g. create one folder and drop all the files in).

It fires for your studio's own recordings and for your clients' recordings alike.

Adding a webhook

In Manage Clients, find the Webhooks section. Paste your endpoint URL (it must be https://) and, optionally, a label to help you tell multiple webhooks apart. The label is only for your own reference and is never sent in the payload.

Use the Test button to fire a sample payload to your URL so you can build against it before recording anything real.

Choosing which recordings trigger it

Your own recordings always trigger the webhook. For clients, each has its own Webhook switch in Manage Clients, set independently of their Email switch, so you can send some clients into your webhook, others to email, both, or neither.

Turn a client's Webhook switch off and no webhook fires for that client (their email notifications are unaffected, and vice versa).

What's in the recording.ready event

Every delivery is a JSON body shaped like this:

{
  "event": "recording.ready",
  "event_id": "b1f2...",          // unique per delivery, use to de-duplicate retries
  "version": "1",
  "timestamp": "2026-07-05T14:41:00Z",  // when the webhook fired
  "account_id": "...",
  "session_url": "https://app.suretake.io/share/...",  // shareable preview/download page
  "show":    { "id": "...", "name": "My Podcast" },
  "session": {
    "id": "...",
    "name": "Episode 12",
    "date": "2026-07-05",
    "started_at": "2026-07-05T14:03:00Z",  // full timestamp, for sorting
    "notes": "00:12:30 New topic\n00:41:05 Ad read",  // notes + markers, as text
    "notes_url": "https://app.suretake.io/api/share/.../notes"  // same notes as a .txt download
  },
  "client":  { "email": "guest@example.com", "name": "Jane Guest" },
  "track_count": 2,             // number of participant tracks in "tracks" below
  "tracks": [                   // ONLY individual participant recordings, no backup here
    {
      "type": "browser",       // an individual participant's local recording
      "recording_id": "...",
      "participant_id": "...",
      "name": "Host",
      "file_url": "https://.../host.mp4",
      "synced_url": null,       // present only if the participant joined late (time-aligned copy)
      "duration_seconds": 3120
    },
    {
      "type": "browser",
      "recording_id": "...",
      "participant_id": "...",
      "name": "Jane Guest",
      "file_url": "https://.../guest.mp4",
      "synced_url": null,
      "duration_seconds": 3115
    }
  ],
  // media_urls: flat "just grab these" list of participant files (same order as "tracks").
  // A no-code shortcut: map straight into a multi-file field, no code step. Already the
  // right file per track: the synced version when a track needed aligning, else file_url.
  "media_urls": [ "https://.../host.mp4", "https://.../guest.mp4" ],
  // The server-side recording of everyone together, kept OUT of "tracks" on purpose so
  // you can import just the participant recordings. Use it as a safety net if you want it.
  "combined_backup_url": "https://.../combined.mp4",
  "transcript": { "url": "https://.../transcript.docx" }  // or null (see Transcripts below)
}

A few notes: tracks holds only the individual participant recordings. It's an array whose length varies with the number of participants, so always iterate it rather than assuming a fixed count.

The combined backup (the single server-side recording of everyone together) is deliberately not in tracks; it's provided separately as combined_backup_url, so you can import just the participant files and treat the backup as an optional safety net.

What are the notes and notes_url?

session.notes is the plain-text notes taken during the session, including any timestamped markers (each on its own timestamped line, e.g. 00:12:30 New topic).

session.notes_url is that same text as a downloadable .txt file, so an automation can drop it into a folder alongside the media. Both are omitted or empty when no notes were taken.

What's the difference between tracks and media_urls?

They point at the same participant recordings, just two shapes for two kinds of consumer. tracks is the rich version: an array of objects with the full detail for each recording (participant name, duration, the recording id, each track's file URL, and a synced URL when someone joined late). Reach for it when you want to label, organize, or make decisions per file.

media_urls is the convenience version: a flat array of just the files to grab, in the same order. It exists purely to make no-code automations easy, since tools like Zapier, Make, and n8n often can't pull a nested field out of an array of objects without a code or formatter step. It's also the authoritative “just grab these” list: for any track that needed time-aligning (a late joiner), media_urls already points at the synced version, so you never have to check synced_url yourself.

For example, in a Descript import step you can map its media field directly to media_urls and it'll pull in every participant track at once, with no formatter or code step needed. The combined backup is intentionally in neither, on combined_backup_url.

Transcripts

Turn on Include transcript in automations in the Webhooks section to have a transcript generated automatically and included in the webhook. Off by default.

With it on, the webhook waits for a transcript to be generated from the session's combined backup, then includes a download link in transcript.url. The event holds for up to ~15 minutes for this; if the transcript isn't ready by then (or transcription fails), the event still fires, just with transcript set to null.

So the single event is never blocked: the transcript rides along when it's ready in time, and its absence never stops delivery. The generated transcript is the same one you can download from your dashboard.

How do I confirm a request really came from SureTake?

Each request carries an X-Webhook-Signature header, an HMAC-SHA256 of the raw request body, signed with your endpoint's secret (shown once when you create the endpoint; rotate it anytime). Recompute it on your end and compare. A match proves the request is genuine and untampered:

// Node.js: verify the request really came from SureTake
const crypto = require("crypto");

const signature = req.headers["x-webhook-signature"];
const expected = crypto
  .createHmac("sha256", YOUR_ENDPOINT_SECRET)   // the secret shown when you created the endpoint
  .update(rawRequestBody)                        // the raw body bytes, before JSON.parse
  .digest("hex");

const valid =
  signature &&
  crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
// if !valid -> reject the request

The request also includes an X-Webhook-Event header (recording.ready). Verifying is optional but recommended for anything sensitive. Most no-code tools (Zapier/Make) skip it and simply trust the URL, which is fine if you keep the URL private.

How soon after a session ends does the webhook arrive?

When a session ends we first upload and convert every participant's track, time-align any late joiners, then hold briefly, about five minutes, to let everything settle before firing, so the links never open to still-processing files.

For a typical recording, expect the webhook within roughly 5 to 10 minutes of the session ending. Longer sessions, or ones where a track needs recovery or alignment, take proportionally longer: the event simply waits until the whole session is genuinely ready, then fires once with everything included.

What if my endpoint is down?

Respond with any 2xx status to acknowledge receipt. If you don't, we retry a few times with increasing delays before giving up. Every attempt, success or failure and with the response code, is recorded in the webhook's Logs view, so you can see exactly what happened.

How long do the download links last?

The file links in the payload (tracks, combined backup, notes, transcript) are signed and valid for 7 days. Download the files within that window; the links then expire, so don't store the URLs long-term.

The recordings themselves remain available in your dashboard for your plan's full retention period; only the direct links expire.

What if a download fails, or something's missing from the payload?

Every payload includes a session_url, the same shareable link you see on your dashboard and in your email notifications. It opens the session's page in a browser, where every track, the combined backup, the notes, and the transcript can be viewed and downloaded directly.

So if a file link ever fails or a track hadn't finished processing at the moment the webhook fired, just open session_url to grab the files. And if the webhook never reached you at all, say your endpoint was down for every retry, nothing is lost: the recordings are always available from your SureTake dashboard for your plan's full retention period.

How do I avoid processing the same event twice?

Each delivery includes a unique event_id. If a retry causes you to receive the same event more than once, use event_id to recognize and skip the duplicate.

Still stuck? Email support.