---
title: "Webhooks | Hilfe | Wortfreunde"
description: "Receive real-time notifications when content changes in Wortfreunde"
url: "/de/hilfe/api/api-reference/webhooks"
---

# Hilfe

Hier findet ihr Anleitungen, Erklärungen und alles Wichtige rund um Wortfreunde. Damit ihr das Beste aus eurer Content Arbeit herausholen könnt.

# Webhooks

Webhooks let you receive real-time HTTP callbacks when events happen in Wortfreunde. Instead of polling the API for changes, your server gets notified automatically.

## Setup

Webhooks are configured in **Wortfreunde Studio** under **Settings** / **Webhooks**. You provide a URL, select which events to subscribe to, and receive a signature key for verifying deliveries.

## Events

Event

Description

`post.updated`

A published post's content was updated

`post.publishing_pending`

A post is ready to publish and awaiting confirmation via the API

`post.published`

A post was published

`post.unpublished`

A published post was reverted to draft

### API Platform Events

The `post.publishing_pending` and `post.unpublished` events are primarily used with **API platform channels**. When a post on an API platform channel reaches its scheduled time, Wortfreunde sets it to `publishing_pending` and fires the `post.publishing_pending` webhook. Your external system should then:

1.  Receive the webhook and process the post content
2.  Call `PATCH /channels/{channel_id}/posts/{id}/publish` to confirm publication
3.  Optionally provide `external_id` and `external_url` for tracking

See [Posts API, API Platform Publishing Workflow](/de/hilfe/api/api-reference/posts#api-platform-publishing-workflow) for the full flow.

## Payload

Every webhook delivery sends a `POST` request to your URL with a JSON body:

`{    " event " :  " post.updated " ,    " timestamp " :  " 2026-03-09T15:48:46Z " ,    " account " : {      " id " :  3 ,      " name " :  " Wertstifter GmbH "    },    " data " : {      " post " : {        " id " :  244 ,        " title " :  " Strukturelle Fokus-Voraussetzungen im Unternehmen " ,        " body " :  " Fokus ist keine Frage der Disziplin. Es ist eine Frage der Struktur... " ,        " teaser " :  null ,        " slug " :  null ,        " publication_status " :  " draft " ,        " created_at " :  " 2026-03-09T15:48:31.673Z " ,        " updated_at " :  " 2026-03-09T15:48:46.870Z " ,        " published_at " :  null ,        " meta_title " :  null ,        " meta_description " :  null ,        " tags " : [          {  " id " :  514 ,  " name " :  " Positionierung " },          {  " id " :  425 ,  " name " :  " Leadership " },          {  " id " :  660 ,  " name " :  " DeepWork " }        ],        " media " : [],        " channel " : {          " id " :  17 ,          " title " :  " LinkedIn " ,          " platform " :  " linkedin " ,          " team " :  null ,          " posts_count " : 6        }      }    }  }`

### Top-Level Fields

Field

Type

Description

`event`

string

Event type that triggered this delivery

`timestamp`

string

ISO 8601 timestamp of when the event occurred

`account`

object

The account that owns the resource

`account.id`

integer

Account identifier

`account.name`

string

Account display name

`data`

object

Event-specific payload

### Post Object

The `data.post` object contains the full post at the time of the event. See the [Posts API](/de/hilfe/api/api-reference/posts) for field descriptions.

## Signature Verification

Every webhook delivery is signed with HMAC-SHA256 using your signature key. Verify the following headers to ensure authenticity.

### Headers

Header

Description

`X-Wortfreunde-Signature`

HMAC-SHA256 signature of the request body

`X-Wortfreunde-Timestamp`

Unix timestamp of signature creation

`X-Wortfreunde-Event`

Event type that triggered this delivery

`X-Wortfreunde-Delivery`

Unique delivery identifier

### Verification Examples

#### Python

`import hmac  import hashlib   def  verify_webhook ( payload_body ,  signature ,  timestamp ,  secret ):      """ Verify a Wortfreunde webhook signature. """      message =  f " { timestamp } . { payload_body } "      expected =  hmac . new (          secret . encode (),          message . encode (),          hashlib . sha256      ). hexdigest ()  return  hmac . compare_digest ( expected ,  signature )`

#### PHP

`function  verifyWebhook ( string  $ payloadBody ,  string  $ signature ,  string  $ timestamp ,  string  $ secret ) : bool  {      $ message  =  $ timestamp  .  ' . '  .  $ payloadBody ;      $ expected  =  hash_hmac ( ' sha256 ' ,  $ message ,  $ secret ) ;      return  hash_equals ( $ expected ,  $ signature ) ;  }`

#### Ruby

`require  ' openssl '   def  verify_webhook ( payload_body ,  signature ,  timestamp ,  secret )    message =  " #{ timestamp } . #{ payload_body } "    expected =  OpenSSL :: HMAC . hexdigest ( ' SHA256 ' ,  secret ,  message )    Rack :: Utils . secure_compare ( expected ,  signature )  end`

Always verify the signature before processing a webhook. Without verification, an attacker could send forged payloads to your endpoint.

### Verification Steps

1.  Extract `X-Wortfreunde-Signature` and `X-Wortfreunde-Timestamp` from the request headers
2.  Concatenate the timestamp and raw request body with a `.` separator: `{timestamp}.{body}`
3.  Compute HMAC-SHA256 of the concatenated string using your signature key
4.  Compare the computed signature with the header value using a timing-safe comparison

Check that `X-Wortfreunde-Timestamp` is within a reasonable window (e.g. 5 minutes) to prevent replay attacks.

## Responding to Webhooks

Your endpoint should return a `2xx` status code within 10 seconds to acknowledge receipt. If the delivery fails, Wortfreunde will retry with exponential backoff.

Attempt

Delay

1

Immediate

2

1 minute

3

5 minutes

4

30 minutes

5

2 hours

After 5 failed attempts, the delivery is marked as failed. You can view delivery history and manually retry from **Settings** / **Webhooks** in Studio.

## Best Practices

-   **Respond quickly.** Process the payload asynchronously (e.g. queue it) and return `200` immediately. Don't block on database writes or external API calls.
-   **Verify signatures.** Always validate `X-Wortfreunde-Signature` before trusting the payload.
-   **Handle duplicates.** Use `X-Wortfreunde-Delivery` to deduplicate, the same event may be delivered more than once.
-   **Use HTTPS.** Your webhook URL should use HTTPS to protect the payload in transit.