A connected social accounts token has expired
Authorizations
API key prefixed with jcr_. To obtain a key programmatically
(no dashboard required), see POST /v1/authorize.
Body
The JSON body POSTed to your endpoint.
Test deliveries from POST /webhooks/{id}/test use this same envelope,
but their data is a fixed {test: true, …} object rather than real
event data, and their event is whichever event you subscribed to first.
Branch on data.test before treating data as an event payload.
Deliveries are at-least-once. Dedup on id, which is stable across
every attempt and every replay of an event. Do not use the
X-Juicer-Delivery-Id header for this — it is regenerated on every
attempt, so a receiver that processed a delivery but answered too slowly
will see the retry under a different value. The same id also arrives
at every webhook you have subscribed to that event, once per endpoint.
Failed deliveries are retried automatically. A non-2xx response, a
timeout, or a connection error fails that attempt, and the next one is
scheduled 30s, then 2m, 8m, 32m and 2h later — six attempts in all,
spread over roughly 2h45m. Answer within 10 seconds — 30 for
post.created, whose body carries a whole sync batch — and do your
processing after responding. Every attempt is its own row in
GET /webhooks/{webhook_id}/deliveries, carrying its own http_status
and error_message, and attempt_number counts attempts within one
delivery: a new pending row means the next attempt is queued, and
failed on attempt 6 means Juicer has given up.
Once the retries are exhausted, replay the event yourself with
POST /webhooks/{webhook_id}/deliveries/{id}/redeliver. That queues a
fresh delivery of the same event under the same id, with its own full
run of automatic retries.
Only a delivery that exhausts its retries counts against the webhook's
health, so a single flaky endpoint burns one failure, not six. After 10
consecutive failed deliveries the webhook's status flips to disabled
and deliveries stop — including redeliveries, which are accepted but
never sent — until you re-enable it with PATCH /webhooks/{id}
(status: active). Re-enabling resets consecutive_failures to 0, so a
recovered endpoint starts over with the full budget. A successful
delivery resets it too.
Verify authenticity by computing HMAC-SHA256 over the raw request body
with your webhook's secret and comparing to X-Juicer-Signature
(formatted sha256=<hex>). Parsing and re-serializing the JSON before
hashing will not match.
The webhook event's id, and your idempotency key. Retrievable via
GET /webhook_events/{id}.
Also sent in the X-Juicer-Event header.
post.created, social_account.expiring, social_account.expired When the event was recorded, in UTC.
Sent for post.created. One event covers a whole sync, so posts holds
every post that sync newly created — a source's first sync commonly
carries tens of posts. Posts the sync merely updated (refreshed
engagement counts, edited captions) are not included.
Posts held for moderation are included; check moderation_status if you
only want ones visible in the feed.
moderation_status is the state at ingestion, not a settled verdict.
A post queued for AI moderation is delivered as moderated and is
commonly approved a few seconds later; a human can approve or reject at
any time after that. Neither sends another event — post.created is the
only post event Juicer emits. A subscriber that keeps only public
posts from this payload therefore drops posts that did become public, so
re-read them through GET /feeds/{feed_id}/posts for the settled status.
- Option 1
- Option 2
- Option 3
Response
Return any 2xx to acknowledge. Any other response, a timeout, or a
connection error fails the attempt and is retried up to 5 times with
growing backoff; see WebhookDeliveryBody for the full contract.