Webhooks
Receive real-time events from Presscart when articles change status or when comments are created, updated, or archived.
Webhooks let your application react to changes in Presscart in real time, without polling the API. You configure an endpoint URL, select the events you want to receive, and Presscart will POST a JSON payload to your endpoint whenever a matching event fires.
Available topics
| Topic | When it fires |
|---|---|
article.status_changed | An article transitions to a new content status, such as draft submitted, revision requested, pending publishing, or published. |
comment.created | An article comment is created in Presscart or through the Comments API. |
comment.updated | An article comment is updated. |
comment.archived | An article comment is archived. |
You can also subscribe to all events when creating a webhook; new topics added in the future will be delivered automatically. Internal comments are not delivered.
Create a webhook in the dashboard
- Open the Presscart app and switch to the workspace and profile you want to subscribe.
- Go to Webhooks from the sidebar.
- Click New webhook.
- Fill in the dialog:
- Endpoint URL — your server URL that will receive webhook events from Presscart. It must be reachable from the internet.
- Events to send — pick one or more topics, or choose All events.
- Click Add. You're taken to the webhook detail page.
- On the detail page, reveal and copy the Signing secret. Store it next to your endpoint configuration — you'll need it to verify deliveries (see Verifying signatures below).
You can edit the URL and topics, pause or resume the webhook, rotate the signing secret, view delivery metrics, and inspect individual delivery attempts from the same detail page.
Event payload
Every webhook delivery is a JSON POST to your endpoint with the same envelope:
{
"id": "evt_01HF8...",
"topic": "comment.created",
"time": "2026-03-20T10:00:00.000Z",
"metadata": {
"source": "presscart.comments"
},
"data": {
"id": "ReDLZTmGOG2A",
"content": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Can you clarify the requested change?" }
]
}
]
},
"author": { "name": "Jane Smith" },
"created_at": "2026-03-20T10:00:00.000Z",
"updated_at": "2026-03-20T10:00:00.000Z",
"parent_comment_id": null
}
}The shape of data depends on the topic.
article.status_changed
{
"article_id": "eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee",
"campaign_id": "66666666-6666-6666-6666-666666666666",
"profile_id": "22222222-2222-2222-2222-222222222222",
"status": {
"id": "44444444-4444-4444-4444-444444444444",
"prefix": "pending-content-brief"
},
"effective_at": "2026-03-20T10:00:00.000Z",
"changed_at": "2026-03-20T10:00:00.000Z"
}Use status.prefix (stable string identifier) rather than status.id when branching on status in your code.
comment.created, comment.updated, comment.archived
{
"id": "ReDLZTmGOG2A",
"content": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [{ "type": "text", "text": "Updated comment text." }]
}
]
},
"author": { "name": "Jane Smith" },
"created_at": "2026-03-20T10:00:00.000Z",
"updated_at": "2026-03-20T10:05:00.000Z",
"parent_comment_id": null
}id is the comment reference — the same value returned by the Comments API. For replies, parent_comment_id is the parent's reference. Comment author data includes the display name only; email addresses are not included in webhook payloads.
Verifying deliveries
Each webhook is signed with the signing secret shown on the webhook detail page. Store this secret server-side and use it to verify that incoming requests came from Presscart.
When your endpoint receives a webhook:
- Read the
x-hookdeck-signatureheader. - Compute an HMAC-SHA256 signature over the raw request body using your signing secret.
- Compare the expected signature with the header value using a timing-safe comparison.
Verify the raw request body before parsing JSON. If the signature is missing or invalid, reject the request.
Responding to deliveries
- Return a
2xxstatus code to acknowledge receipt. Anything else is treated as a failure. - Respond quickly (under a few seconds). Do heavy work asynchronously after acknowledging.
- Treat deliveries as at-least-once. The same event may arrive more than once on retries — deduplicate on the envelope
idor, for comment events, ondata.id. - Failed deliveries are retried automatically with backoff. You can manually retry an attempt from the webhook detail page.
Local development
Webhooks need a reachable endpoint URL. For quick local testing, use Hookdeck Console as a temporary request inspector:
- Open Hookdeck Console and create a temporary webhook URL.
- Create or edit your Presscart webhook and paste the Hookdeck Console URL as the endpoint.
- Trigger an event in Presscart, such as creating a comment or changing an article status.
- Inspect the request body, headers, response, and retries in Hookdeck Console.
If you want Presscart to reach a local server running on your machine, expose that local server with the Hookdeck CLI or a tunnel and use the generated public URL as the Presscart endpoint. You can keep separate webhooks for local, staging, and production.