Webhook events you can subscribe to

The full list of webhook event types Journalify emits, with payload schemas and delivery semantics.

5 min read

Envelope schema

Every webhook payload uses the same envelope. The event-specific fields live under data:

{
  "id": "evt_01HXYZABC123",
  "type": "story.published",
  "occurred_at": "2026-05-23T09:14:22Z",
  "tenant_id": "ten_5f3a9c",
  "data": {
    "// event-specific fields go here, see below": null
  }
}
  • id — unique event id. Use it for idempotency keys in your receiver — Journalify may retry on transient failures.
  • type — dot-separated event name. New events may be added at any time; treat unknown types as no-op rather than failing.
  • occurred_at — ISO-8601 UTC timestamp when the event was created.
  • tenant_id — the newsroom the event belongs to. Useful when one webhook endpoint receives traffic from multiple tenants.
  • data — the event-specific body. Fields are versioned additively; do not assume an exhaustive shape.

Story events

Emitted as a story moves through the editorial workflow:

  • story.published — a story transitions to published
  • story.unpublished — a previously published story is taken down
  • story.updated — title, body, byline, or metadata of a published story changed
  • story.deleted — a story is permanently deleted

Example data for story.published:

{
  "id": "sty_8a2f1c",
  "headline": "Mayor announces 2026 budget",
  "lede": "$2.3B in new investments across transport and education.",
  "byline": ["usr_4567"],
  "department_id": "politics",
  "tags": ["politics", "budget"],
  "published_at": "2026-05-23T09:14:22Z",
  "url": "https://cloud.journalify.app/news/sty_8a2f1c"
}

Today data.url points to the canonical editorial draft URL inside the Journalify newsroom. Once social auto-post ships, data.canonical_url will also be present and point to your own published site URL — use canonical_url when present, fall back to url otherwise.

Media events

  • media.uploaded — a new asset is added to the media library
  • media.deleted — an asset is removed

Example data for media.uploaded:

{
  "id": "med_b71c4e",
  "kind": "image",
  "mime_type": "image/jpeg",
  "size_bytes": 482910,
  "width": 4032,
  "height": 3024,
  "caption": "Mayor at press conference",
  "credit": "Sarah Khalifa / Desert News",
  "uploaded_at": "2026-05-23T09:11:08Z",
  "uploaded_by": "usr_4567"
}

Assignment events

  • assignment.created — an editor assigns a story idea to a reporter
  • assignment.completed — the reporter marks the assignment done (or the linked story is published)

Example data for assignment.created:

{
  "id": "asn_3e9b7a",
  "title": "2026 budget reaction from opposition",
  "brief": "Get quotes from the three main opposition figures within 4 hours.",
  "due_at": "2026-05-23T13:00:00Z",
  "assignee_id": "usr_8821",
  "assigner_id": "usr_4567",
  "department_id": "politics"
}

Audit events

Account-level security events. Useful for piping into your SIEM:

  • api_key.created — a new API key is issued for the tenant
  • api_key.revoked — an API key is revoked or expires

Example data for api_key.created:

{
  "api_key_id": "jnf_abc12345",
  "name": "Mailchimp digest",
  "scopes": ["stories:read"],
  "created_by": "usr_4567",
  "expires_at": null
}

Delivery semantics

  • At-least-once — a single event may be delivered more than once on retry. De-duplicate on event id.
  • Per-subscription ordering is best-effort. Do not rely on receiving story.published strictly before story.updated for the same story id — instead, compare occurred_at in your handler.
  • A failed delivery does not block subsequent events for the same subscription.
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