Plinth pushes signed, retried events to the endpoints you register here. For the consumer side —
verifying signatures and handling events — see Receiving webhooks.
Create an endpoint
curl -X POST https://api.useplinth.com/v1/webhook-endpoints \
-H "Authorization: Bearer sk_test_DOCS_SHARED_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://yourapp.com/api/plinth/webhook", "description": "Production" }'
The http(s) endpoint that receives events.
Event types to subscribe to. Omit or pass [] to receive all events.
{
"object": "webhook_endpoint",
"id": "whep_01KWG...",
"url": "https://yourapp.com/api/plinth/webhook",
"description": "Production",
"enabled": true,
"event_types": [],
"secret": "whsec_a51e29ea...",
"created_at": "2026-07-02T00:00:00Z",
"updated_at": "2026-07-02T00:00:00Z"
}
The secret (whsec_…) is returned only on create and rotate. Store it — it signs every
delivery to this endpoint. Normal reads omit it.
List endpoints
curl https://api.useplinth.com/v1/webhook-endpoints \
-H "Authorization: Bearer sk_test_DOCS_SHARED_KEY"
Returns { "object": "list", "data": [ <webhook_endpoint>, … ] } (secrets omitted).
Update an endpoint
PATCH any of url, description, enabled, event_types.
curl -X PATCH https://api.useplinth.com/v1/webhook-endpoints/whep_01KWG... \
-H "Authorization: Bearer sk_test_DOCS_SHARED_KEY" \
-H "Content-Type: application/json" \
-d '{ "enabled": false }'
Rotate the signing secret
Issues a fresh whsec_… (returned once) and invalidates the old one.
curl -X POST https://api.useplinth.com/v1/webhook-endpoints/whep_01KWG.../rotate-secret \
-H "Authorization: Bearer sk_test_DOCS_SHARED_KEY"
Delete an endpoint
curl -X DELETE https://api.useplinth.com/v1/webhook-endpoints/whep_01KWG... \
-H "Authorization: Bearer sk_test_DOCS_SHARED_KEY"
Inspect deliveries
Every event × endpoint produces a delivery row with status and retry history — the same data the
dashboard Webhooks view shows.
curl https://api.useplinth.com/v1/webhook-endpoints/whep_01KWG.../deliveries \
-H "Authorization: Bearer sk_test_DOCS_SHARED_KEY"
{
"object": "list",
"counts": { "succeeded": 12, "retrying": 1 },
"data": [
{
"object": "webhook_delivery",
"id": "whd_01KWG...",
"event_type": "subscription.activated",
"status": "succeeded",
"attempts": 1,
"response_code": 200,
"error": null,
"next_retry_at": null,
"last_attempt_at": "2026-07-02T00:00:01Z",
"created_at": "2026-07-02T00:00:00Z"
}
]
}
A failed delivery (non-2xx or timeout) retries with exponential backoff up to 8 attempts, then is
marked failed. status is one of pending | retrying | succeeded | failed.
Resend a delivery
Re-queue a delivery for an immediate re-attempt (e.g. after fixing your endpoint).
curl -X POST https://api.useplinth.com/v1/webhook-endpoints/whep_01KWG.../deliveries/whd_01KWG.../resend \
-H "Authorization: Bearer sk_test_DOCS_SHARED_KEY"
See the event catalog for every event type and its payload.