Home / Docs / Docs

I’m not receiving webhooks

Symptom

You registered a webhook, but your endpoint never receives PinBridge deliveries, or receives some and then stops.

Causes and fixes

1. Only two events exist

PinBridge emits exactly two webhook events: pin.published and pin.failed. Any other event name you subscribe to (for example schedule.created or asset.uploaded) will never fire, because those are activity-log actions, not webhook events. Make sure your webhook subscribes to pin.published and/or pin.failed.

2. The webhook is not enabled

A webhook only delivers when it is enabled (is_enabled). Confirm it is on:

curl -H "X-API-Key: $PINBRIDGE_API_KEY" \
  "https://api.pinbridge.io/v1/webhooks"

If is_enabled is false, update the webhook to enable it.

3. Your endpoint must return 2xx

A delivery counts as successful only if your endpoint returns an HTTP 2xx status. Any other status (or a network error) is treated as a failure and retried.

  • Respond 200 (any 2xx) as soon as you receive the payload.
  • Do your processing after responding, not before, so slow work does not cause a timeout.

4. Respond within the timeout

Each attempt has a 30-second timeout. If your endpoint takes longer, the attempt is counted as failed. Acknowledge fast, process async.

5. Retries are finite

Failed deliveries are retried up to 5 attempts with exponential backoff (roughly 2, 4, 8, 16 minutes after the first attempts). After that the delivery is marked permanently failed and will not be retried. If your endpoint was down for a while, expect to miss those deliveries; fix the endpoint before the retries run out.

6. Signature mismatch

If you verify signatures (recommended) and your check fails, you may be rejecting valid deliveries. PinBridge signs with HMAC-SHA256 over the raw JSON request body only (no timestamp), and sends the hex digest in the X-PinBridge-Signature header. Also sent: X-PinBridge-Event (the event type) and X-PinBridge-Delivery-ID.

To verify:

  • Compute HMAC-SHA256(secret, raw_body) and hex-encode it.
  • Compare against X-PinBridge-Signature using a constant-time comparison.
  • Use the raw request bytes, not a re-serialized JSON object. Re-serializing changes the bytes and breaks the signature.
  • There is no timestamp in the signed string; do not expect a Stripe-style t=...,v1=... header.

The secret is set when you create the webhook (16 to 255 characters, required). If you rotate it, update your verifier too.

7. Payload shape

Only these fields are sent, and the event type is in the header, not the body:

// pin.published
{ "pin_id": "...", "pinterest_pin_id": "...", "title": "...", "published_at": "..." }

// pin.failed
{ "pin_id": "...", "error_code": "...", "error_message": "..." }

If your handler expects a top-level event or timestamp field in the body, that is why it looks empty. Read the event type from X-PinBridge-Event.

Last updated September 12, 2026Was this page helpful? Tell us →