API/Webhooks

Webhooks

Receive signed events when a pin is published or fails.

Rather than polling a pin until it publishes, let Pincast tell you.

Register an endpoint

In the dashboard, open Webhooks and add an https URL. The signing secret is shown once, at creation — store it, it is never displayed again.

Events

EventSent when
pin.publishedPinterest accepted the pin; data.pinterest_pin_id is filled
pin.failedThe pin gave up after its retries; data.error explains why
pin.scheduledA pin was accepted with a future publish_at
account.disconnectedPinterest revoked the account tokens

Payload

{
  "id": "delivery id",
  "type": "pin.published",
  "created_at": 1788190709990,
  "data": { }
}

Verify the signature

Every request carries:

X-Pincast-Signature: t=<timestamp>,v1=<hmac_sha256>

Compute the HMAC-SHA256 of <timestamp>.<raw body> with your endpoint secret, then compare it to v1.

Two things matter:

  • Use the raw body, before any JSON parsing. Re-serializing changes the bytes and the signature will never match.
  • Compare in constant time (crypto.timingSafeEqual, hmac.compare_digest). A plain === returns as soon as two bytes differ, which leaks the expected signature one byte at a time.

Reject any request whose signature does not verify.

Retries

Answer with any 2xx to acknowledge. Anything else — or a timeout past ten seconds — counts as a failure and Pincast retries with a growing backoff: 2 s, 8 s, 32 s, 128 s, then 512 s.

After 20 consecutive failures the endpoint is disabled and stops receiving events. Re-enable it from the dashboard once your side is back.

Because of retries, your handler must be idempotent: the same event can arrive twice. Deduplicate on the payload id.