Webhooks reference — real-time event notifications

Subscribe to platform events and receive HTTP POST notifications in your own systems.

5 min read

Available events

  • article.created, article.updated, article.published, article.unpublished, article.archived
  • media.uploaded, media.updated, media.deleted
  • user.created, user.role_changed, user.deactivated
  • workflow.transitioned (article changed state)
  • subscription.updated, subscription.cancelled (Atlas billing events)

Subscribing to a webhook

POST /v1/webhooks
Content-Type: application/json

{
  "url": "https://yourapp.com/webhooks/journalify",
  "events": ["article.published", "article.updated"],
  "secret": "whsec_your_signing_secret"
}

Payload structure

{
  "event": "article.published",
  "tenant_id": "ten_abc123",
  "occurred_at": "2026-05-09T14:32:11Z",
  "data": {
    "article_id": "art_xyz789",
    "headline": "Mayor announces 2026 budget",
    "url": "https://yourpaper.com/2026/budget",
    "author_id": "usr_456",
    "published_at": "2026-05-09T14:32:11Z"
  }
}

Verifying webhook signatures

Every webhook request includes an X-Journalify-Signature header. Verify it before processing:

import hmac, hashlib

def verify(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Retries

Failed deliveries (non-2xx response) retry with exponential backoff: 1m, 5m, 30m, 2h, 12h, 24h. After 6 failed attempts, the webhook is automatically disabled and the owner is emailed.

Was this article helpful?

Was this helpful?

Can't find what you need, or spot something wrong? Let us know — every article is improved based on customer feedback.

Contact support