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
| Event | Sent when |
|---|---|
pin.published | Pinterest accepted the pin; data.pinterest_pin_id is filled |
pin.failed | The pin gave up after its retries; data.error explains why |
pin.scheduled | A pin was accepted with a future publish_at |
account.disconnected | Pinterest 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.