Guide

How to use Podbite webhooks

Webhooks let your server receive an HTTP POST from Podbite whenever something changes — a bite is created, a playlist is updated, items are reordered. Instead of polling the API, your code or automations react the moment the event happens.

Webhooks are available on the Automate plan.


What you'll need

  • An Automate plan subscription
  • A publicly reachable HTTPS endpoint on your server (not localhost)
  • A way to verify the request signature (recommended — takes about 10 lines of code)

1. Register an endpoint

Go to Account → Developers → Webhooks and click Add endpoint.

Enter your server's URL (https://api.example.com/webhooks/podbite). You can subscribe to all events or pick specific ones — leave all checkboxes unchecked to receive everything.

Click Add endpoint. A secret is shown exactly once — copy it now and store it somewhere safe (a secret manager, an environment variable). You'll use it to verify incoming requests.

You can register up to 3 active endpoints.


2. Verify the signature

Every delivery includes an X-Podbite-Signature header with the format sha256=<hex>. Verify it before processing the event:

const crypto = require("crypto");

function verifyWebhookSignature(rawBody, signatureHeader, secretHex) {
  const keyBytes = Buffer.from(secretHex, "hex"); // raw 32 bytes
  const expected = "sha256=" + crypto
    .createHmac("sha256", keyBytes)
    .update(rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signatureHeader),
  );
}

Important: use Buffer.from(secretHex, 'hex') not 'utf8'. The secret is raw bytes, not a text string. Using 'utf8' produces a key that's twice as long and a signature that never matches.

In Python the equivalent is:

import hmac, hashlib

def verify_webhook_signature(raw_body: bytes, signature_header: str, secret_hex: str) -> bool:
    key = bytes.fromhex(secret_hex)
    expected = "sha256=" + hmac.new(key, raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Reject requests where the signature doesn't match — they weren't sent by Podbite.


3. Handle the event

Every delivery is a JSON body with this envelope:

{
  "id": "evt_01jz...",
  "type": "bite.created",
  "created_at": "2026-07-03T12:00:00Z",
  "data": { ... }
}

The data shape depends on the event type:

Bite events

bite.created and bite.updatedbite.updated fires when the bite's own fields change: caption, comment, start_time, or end_time. It does not fire when a bite is added to or removed from a playlist — those changes fire playlist.items_updated on the affected playlists instead.

{
  "short_id": "abc123",
  "caption": "The moment I changed my mind about remote work",
  "comment": null,
  "start_time": 312,
  "end_time": 381,
  "source": "app",
  "episode": {
    "short_id": "ep001",
    "title": "Episode 42",
    "published_at": "2026-06-01T00:00:00Z"
  },
  "podcast": { "short_id": "pod001", "title": "The Changelog" },
  "created_at": "2026-07-03T12:00:00Z",
  "updated_at": "2026-07-03T12:00:00Z"
}

bite.deleted:

{ "short_id": "abc123", "deleted_at": "2026-07-03T12:05:00Z" }

Playlist events

playlist.created and playlist.updated:

{
  "short_id": "pl001",
  "name": "Best of Q2",
  "description": null,
  "source": "app",
  "created_at": "2026-07-03T12:00:00Z",
  "updated_at": "2026-07-03T12:00:00Z"
}

playlist.items_updated — fires when bites are added, removed, or reordered:

{
  "short_id": "pl001",
  "name": "Best of Q2",
  "items": [
    {
      "short_id": "abc123",
      "caption": "The moment I changed my mind",
      "order": 1
    },
    { "short_id": "def456", "caption": "On building in public", "order": 2 }
  ],
  "updated_at": "2026-07-03T12:05:00Z"
}

playlist.deleted:

{ "short_id": "pl001", "deleted_at": "2026-07-03T12:10:00Z" }

4. Respond quickly

Podbite expects a 2xx response within 10 seconds. If your server takes longer (because it's doing heavy processing), return 200 immediately and process the event asynchronously.

Failed deliveries (non-2xx or timeout) are retried automatically up to 3 times with increasing delays.


5. Test a delivery

From the Webhooks panel, click Send test next to any endpoint and pick an event type. A test delivery with synthetic data is sent immediately. Check the delivery log (click View deliveries) to confirm it arrived.

Test deliveries have "is_test": true in the envelope — you can filter these out in your handler if needed.


6. Rotate your secret

If your secret is ever exposed, click Rotate secret in the Webhooks panel. Update your server with the new secret before confirming — the old secret stops working immediately.


Using with Make, Zapier, or n8n

If you're connecting Podbite to an automation platform rather than writing server code, the setup is simpler — the platform gives you a webhook URL and handles the incoming request for you.

  1. In your automation platform, create a new workflow with a webhook trigger. The platform will give you a unique HTTPS URL (e.g. https://hook.eu2.make.com/abc123...).
  2. Register that URL as a Podbite webhook endpoint (step 1 above). Subscribe to whichever event types your workflow needs.
  3. Send a test delivery from the Podbite Webhooks panel — your platform will capture the payload and let you map the fields to the rest of your workflow.

Signature verification: most automation platforms don't support custom HMAC verification out of the box, so you'll typically skip that step. That's fine — the platform's own webhook URL is unguessable and the connection is HTTPS. For higher-assurance setups, Make and n8n both support custom header checks if you want to add a layer.

The event payload shape is the same as described in section 3 above — the platform will parse the JSON automatically and expose each field as a variable you can use in subsequent steps.


Delivery log

Click View deliveries on any endpoint to see the last 20 deliveries: event type, timestamp, status (delivered / pending / failed), and HTTP response code. Useful for debugging failed deliveries. If a delivery is marked failed due to a plan or endpoint issue rather than a network error, the reason is shown in the response body column.


Plan changes and webhook delivery

Webhooks are an Automate plan feature. If your subscription lapses or you downgrade, delivery stops immediately — active endpoints are preserved but no new events are sent. Any deliveries already queued for retry are marked failed. Reactivating Automate re-enables delivery for new events; past failed deliveries are not replayed.

Share highlights. Analytics that count.

Be among the first to get access.

Join the waitlist
festivitiesKaterina Limpitsounihttps://undraw.co/