Skip to content

Posts API

Retrieve, filter, and manage posts collected from Fediverse streams.

Overview

The Posts API provides access to FenLiu's post database. Posts are collected from monitored hashtag streams and can be filtered, reviewed, and exported. Each post contains metadata about its source, content, AI classification, and review status.

Post Lifecycle

  1. Fetched: Post retrieved from Fediverse (via Streams API)
  2. Classified: AI text and image checks run (see AI Classification)
  3. Reviewed: human review (approve/reject) or auto-rejected by filters
  4. Exported: post delivered via the Curated Queue API

Authentication

All Posts API endpoints require API key authentication via X-API-Key header:

curl -H "X-API-Key: your-api-key" \
  http://localhost:8000/api/v1/posts

See Authentication Guide for details.

Endpoints

GET /api/v1/posts

List posts with filtering and pagination.

Request

curl -H "X-API-Key: your-api-key" \
  "http://localhost:8000/api/v1/posts?skip=0&limit=50&approved=true"

Query Parameters

Parameter Type Default Description
skip integer 0 Number of items to skip (pagination)
limit integer 100 Number of items to return (max 1000)
stream_id integer - Filter by source stream (optional)
approved boolean - Filter by approval status (optional)
reviewed boolean - Filter by review status (optional)
queue_status string - Filter by queue status: pending, reserved, delivered, error

Response (200 OK)

{
  "items": [
    {
      "id": 42,
      "post_id": "https://example.com/users/alice/statuses/123",
      "url": "https://example.com/@alice/123",
      "content": "<p>Check out this amazing post!</p>",
      "author_username": "alice",
      "instance": "example.com",
      "created_at": "2026-03-02T10:30:00Z",
      "reviewed_at": "2026-03-02T11:00:00Z",
      "approved": true,
      "hashtags": ["python", "programming"],
      "media_attachments": [
        {
          "type": "image",
          "url": "https://example.com/media/abc123.jpg"
        }
      ],
      "ai_would_reject": false,
      "vision_category": "real_cat",
      "queue_status": "pending",
      "stream_id": 1
    }
  ],
  "total": 150,
  "skip": 0,
  "limit": 50
}

GET /api/v1/posts/{id}

Get detailed information about a specific post.

curl -H "X-API-Key: your-api-key" \
  http://localhost:8000/api/v1/posts/42

Error Responses

{ "detail": "Post not found" }  // 404

PATCH /api/v1/posts/{id}

Update a post (review/approve).

Request

curl -X PATCH \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "approved": true
  }' \
  http://localhost:8000/api/v1/posts/42
Field Type Required Description
approved boolean No Set approval status

Error Responses

{ "detail": "Post not found" }  // 404

DELETE /api/v1/posts/{id}

Delete a post from the database.

curl -X DELETE \
  -H "X-API-Key: your-api-key" \
  http://localhost:8000/api/v1/posts/42

Filtering Examples

Filter by Approval Status

curl "http://localhost:8000/api/v1/posts?approved=true" \
  -H "X-API-Key: your-api-key"

Filter by Stream

curl "http://localhost:8000/api/v1/posts?stream_id=1" \
  -H "X-API-Key: your-api-key"

Filter by Review Status

curl "http://localhost:8000/api/v1/posts?reviewed=false" \
  -H "X-API-Key: your-api-key"

Filter by Queue Status

curl "http://localhost:8000/api/v1/posts?queue_status=pending" \
  -H "X-API-Key: your-api-key"

Examples

Python

import httpx

api_key = "your-api-key"
base_url = "http://localhost:8000/api/v1"
headers = {"X-API-Key": api_key}

async with httpx.AsyncClient() as client:
    response = await client.get(
        f"{base_url}/posts",
        params={"approved": True, "limit": 100},
        headers=headers,
    )
    posts = response.json()["items"]

    response = await client.patch(
        f"{base_url}/posts/42",
        json={"approved": True},
        headers=headers,
    )

cURL

export API_KEY="your-api-key"
export BASE_URL="http://localhost:8000/api/v1"

curl "$BASE_URL/posts?approved=true" -H "X-API-Key: $API_KEY"
curl "$BASE_URL/posts/42" -H "X-API-Key: $API_KEY"
curl -X PATCH "$BASE_URL/posts/42" \
  -H "X-API-Key: $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"approved":true}'


Best Practices

  1. Pagination: always use skip and limit for large result sets
  2. Filtering: use query parameters to reduce data transfer
  3. Monitoring: track queue_status for export pipeline health