Hilfe

Hier findest du Anleitungen, Erklärungen und alles Wichtige rund um Wortfreunde. Damit du das Beste aus deiner Content-Arbeit herausholst.

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

Method Endpoint Scope Description
GET /channels/{channel_id}/posts read:posts List posts in a channel
GET /channels/{channel_id}/posts/{id} read:posts Get a single post
PATCH /channels/{channel_id}/posts/{id}/publish write:posts Confirm publication of a pending post
PATCH /channels/{channel_id}/posts/{id}/unpublish write:posts Revert a published post to draft

List Posts

Retrieve a paginated list of posts for a given channel.

GET /channels/{channel_id}/posts

Path Parameters

Parameter Type Description
channel_id integer Channel ID

Query Parameters

Parameter Type Default Description
page integer 1 Page number
per_page integer 20 Items per page (max: 100)
limit integer - 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

Field Type Description
id integer Unique post identifier
title string Post title
teaser string Short summary / excerpt
slug string URL-safe identifier
publication_status string Status (see below)
created_at string ISO 8601 creation timestamp
updated_at string ISO 8601 last update timestamp
channel object The channel this post belongs to

Publication Status

Status Description
draft Not yet published
publishing_pending Scheduled and awaiting external confirmation (API platform only)
published Live and visible
scheduled Scheduled for future publication

Pagination

The meta object contains pagination details:

Field Type Description
page integer Current page number
pages integer Total number of pages
count integer Total number of posts in this channel
per_page integer Items per page

Get Post

Retrieve a single post with its full content.

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

Path Parameters

Parameter Type Description
channel_id integer Channel ID
id integer Post 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:

Field Type Description
body string Full post content in Markdown
published_at string \ null
tags array List of tag objects
media array List of attached media objects
meta_title string \ null
meta_description string \ null
external_id string \ null
external_url string \ null

Info

The body field contains the full Markdown content of the post. In the list endpoint, body is omitted to keep responses lightweight, use the teaser for previews.

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"
  }
}
Status Description
401 Invalid or missing API key
403 Insufficient scopes, requires read:posts or write:posts
404 Channel or post not found
422 Validation error (wrong status, wrong platform)
429 Rate 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

Parameter Type Description
channel_id integer Channel ID (must be API platform)
id integer Post ID

Request Body (optional)

{
  "post": {
    "external_id": "ext-12345",
    "external_url": "https://example.com/posts/12345"
  }
}
Field Type Description
post.external_id string Optional external system identifier for the published post
post.external_url string Optional 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

Code Error Code Description
403 - Token lacks write:posts scope
404 not_found Channel or post not found
422 only_api_platform Channel is not an API platform channel
422 invalid_status Post is not in publishing_pending status
422 no_publication No 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

Parameter Type Description
channel_id integer Channel ID (must be API platform)
id integer Post 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

Code Error Code Description
403 - Token lacks write:posts scope
404 not_found Channel or post not found
422 only_api_platform Channel is not an API platform channel
422 invalid_status Post is not in published status
422 no_publication No 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

Info

Unlike LinkedIn and Git platform channels (which publish directly), API platform posts remain editable even after publishing. Content changes do not automatically revert the publication status, instead, a post.updated webhook notifies the external system.