Hilfe

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

Posts API

Posts are the content items within a channel, blog articles, LinkedIn posts, newsletter editions, etc. Posts are always accessed through their parent channel.

Endpoints

MethodEndpointScopeDescription
GET/channels/{channel_id}/postsread:postsList posts in a channel
GET/channels/{channel_id}/posts/{id}read:postsGet a single post
PATCH/channels/{channel_id}/posts/{id}/publishwrite:postsConfirm publication of a pending post
PATCH/channels/{channel_id}/posts/{id}/unpublishwrite:postsRevert a published post to draft

List Posts

Retrieve a paginated list of posts for a given channel.

GET /channels/{channel_id}/posts

Path Parameters

ParameterTypeDescription
channel_idintegerChannel ID

Query Parameters

ParameterTypeDefaultDescription
pageinteger1Page number
per_pageinteger20Items per page (max: 100)
limitinteger-Shorthand for per_page

Example Request

curl -s "https://api.wortfreunde.ch/v1/channels/161/posts?limit=2" \
  -H "Authorization: Bearer $WORTFREUNDE_API_KEY" | python3 -m json.tool

Response

{
  "data": [
    {
      "id": 214,
      "title": "Warum strukturierte Content-Planung mehr bringt als spontane Posts",
      "teaser": "Montagmorgen. Der Cursor blinkt. Was soll ich heute posten?...",
      "slug": "strukturierte-content-planung-vs-spontane-posts",
      "publication_status": "published",
      "created_at": "2026-03-02T16:54:36.465Z",
      "updated_at": "2026-03-09T05:00:48.275Z",
      "channel": {
        "id": 161,
        "title": "Blog",
        "platform": "git",
        "team": {
          "id": 42,
          "name": "Wortfreunde"
        },
        "posts_count": 3
      }
    },
    {
      "id": 208,
      "title": "Content-Produktion effizient gestalten: 7 Strategien fuer Fuehrungskraefte",
      "teaser": "Viele Fuehrungskraefte verbringen Stunden mit Posts, ohne Ergebnis...",
      "slug": "content-produktion-effizient-gestalten-strategien-fuer-fuehrungskraefte",
      "publication_status": "published",
      "created_at": "2026-02-28T10:03:19.931Z",
      "updated_at": "2026-02-28T10:08:20.763Z",
      "channel": {
        "id": 161,
        "title": "Blog",
        "platform": "git",
        "team": {
          "id": 42,
          "name": "Wortfreunde"
        },
        "posts_count": 3
      }
    }
  ],
  "meta": {
    "page": 1,
    "pages": 1,
    "count": 3,
    "per_page": 20
  }
}

Response Fields

FieldTypeDescription
idintegerUnique post identifier
titlestringPost title
teaserstringShort summary / excerpt
slugstringURL-safe identifier
publication_statusstringStatus (see below)
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last update timestamp
channelobjectThe channel this post belongs to

Publication Status

StatusDescription
draftNot yet published
publishing_pendingScheduled and awaiting external confirmation (API platform only)
publishedLive and visible
scheduledScheduled for future publication

Pagination

The meta object contains pagination details:

FieldTypeDescription
pageintegerCurrent page number
pagesintegerTotal number of pages
countintegerTotal number of posts in this channel
per_pageintegerItems per page

Get Post

Retrieve a single post with its full content.

GET /channels/{channel_id}/posts/{id}

Path Parameters

ParameterTypeDescription
channel_idintegerChannel ID
idintegerPost ID

Example Request

curl -s https://api.wortfreunde.ch/v1/channels/161/posts/214 \
  -H "Authorization: Bearer $WORTFREUNDE_API_KEY" | python3 -m json.tool

Response

{
  "data": {
    "id": 214,
    "title": "Warum strukturierte Content-Planung mehr bringt als spontane Posts",
    "body": "## Struktur\n\nDas Problem ist nicht fehlende Kreativitaet...",
    "teaser": "Montagmorgen. Der Cursor blinkt. Was soll ich heute posten?...",
    "slug": "strukturierte-content-planung-vs-spontane-posts",
    "publication_status": "published",
    "created_at": "2026-03-02T16:54:36.465Z",
    "updated_at": "2026-03-09T05:00:48.275Z",
    "published_at": "2026-03-09T05:00:48.269Z",
    "channel": {
      "id": 161,
      "title": "Blog",
      "platform": "git",
      "team": {
        "id": 42,
        "name": "Wortfreunde"
      },
      "posts_count": 3
    },
    "tags": [],
    "media": [],
    "meta_title": "Strukturierte Content-Planung vs. spontane Posts",
    "meta_description": "Erfahre, warum strukturierte Content-Planung mehr Sichtbarkeit und Resonanz bringt als spontane Posts."
  }
}

Response Fields

The single post response includes all fields from the list response, plus:

FieldTypeDescription
bodystringFull post content in Markdown
published_atstring | nullISO 8601 publication timestamp
tagsarrayList of tag objects
mediaarrayList of attached media objects
meta_titlestring | nullSEO title override
meta_descriptionstring | nullSEO description override
external_idstring | nullExternal system identifier (API platform only)
external_urlstring | nullURL where the post was published externally (API platform only)

Error Responses

Post Not Found

curl -s https://api.wortfreunde.ch/v1/channels/161/posts/99999 \
  -H "Authorization: Bearer $WORTFREUNDE_API_KEY"
{
  "error": {
    "code": "not_found",
    "message": "Post not found"
  }
}
StatusDescription
401Invalid or missing API key
403Insufficient scopes, requires read:posts or write:posts
404Channel or post not found
422Validation error (wrong status, wrong platform)
429Rate limit exceeded

Publish Post

Confirms publication of a post that is in publishing_pending status. This endpoint is used by external systems to complete the publishing workflow for API platform channels.

PATCH /channels/{channel_id}/posts/{id}/publish

Scope

Requires write:posts.

Path Parameters

ParameterTypeDescription
channel_idintegerChannel ID (must be API platform)
idintegerPost ID

Request Body (optional)

{
  "post": {
    "external_id": "ext-12345",
    "external_url": "https://example.com/posts/12345"
  }
}
FieldTypeDescription
post.external_idstringOptional external system identifier for the published post
post.external_urlstringOptional URL where the post was published externally

The post wrapper is optional, if omitted, no external fields are set.

Example Request

curl -s -X PATCH "https://api.wortfreunde.ch/v1/channels/42/posts/214/publish" \
  -H "Authorization: Bearer $WORTFREUNDE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"post": {"external_id": "wp-789", "external_url": "https://blog.example.com/my-post"}}' \
  | python3 -m json.tool

Response

Returns the updated post with publication_status: "published":

{
  "data": {
    "id": 214,
    "title": "My API Platform Post",
    "publication_status": "published",
    "published_at": "2026-03-10T14:30:00.000Z",
    "external_id": "wp-789",
    "external_url": "https://blog.example.com/my-post",
    "channel": {
      "id": 42,
      "title": "External Blog",
      "platform": "api"
    }
  }
}

Error Responses

CodeError CodeDescription
403-Token lacks write:posts scope
404not_foundChannel or post not found
422only_api_platformChannel is not an API platform channel
422invalid_statusPost is not in publishing_pending status
422no_publicationNo API publication record exists for the post

Unpublish Post

Reverts a published API platform post back to draft status.

PATCH /channels/{channel_id}/posts/{id}/unpublish

Scope

Requires write:posts.

Path Parameters

ParameterTypeDescription
channel_idintegerChannel ID (must be API platform)
idintegerPost ID

Example Request

curl -s -X PATCH "https://api.wortfreunde.ch/v1/channels/42/posts/214/unpublish" \
  -H "Authorization: Bearer $WORTFREUNDE_API_KEY" \
  | python3 -m json.tool

Response

Returns the updated post with publication_status: "draft":

{
  "data": {
    "id": 214,
    "title": "My API Platform Post",
    "publication_status": "draft",
    "published_at": null,
    "external_id": null,
    "external_url": null,
    "channel": {
      "id": 42,
      "title": "External Blog",
      "platform": "api"
    }
  }
}

Error Responses

CodeError CodeDescription
403-Token lacks write:posts scope
404not_foundChannel or post not found
422only_api_platformChannel is not an API platform channel
422invalid_statusPost is not in published status
422no_publicationNo API publication record exists for the post

API Platform Publishing Workflow

The API platform provides an async publishing workflow for external systems:

  1. Schedule, A post on an API platform channel is scheduled via the content plan
  2. Dispatch, At the scheduled time, Wortfreunde sets the post to publishing_pending and fires a post.publishing_pending webhook
  3. Publish, The external system receives the webhook, processes the post, and calls PATCH .../publish to confirm
  4. Update, If the post content changes after publishing, a post.updated webhook is fired so the external system can re-sync
  5. Unpublish, To revert, the external system calls PATCH .../unpublish, which fires a post.unpublished webhook