Skip to content

API Reference Guide

Welcome to the FenLiu API documentation. This guide covers all available REST API endpoints organized by category.

Quick Start

Authentication

All API endpoints require authentication via the X-API-Key header:

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

Complete Authentication Guide →

Base URL

http://localhost:8000/api/v1

For production, replace localhost:8000 with your FenLiu instance URL.

API Categories

🌊 Hashtag Streams API

Manage Fediverse hashtag streams for monitoring and post collection.

Endpoints: - GET /hashtags - List all streams - POST /hashtags - Create new stream - GET /hashtags/{id} - Get stream details - PATCH /hashtags/{id} - Update stream - DELETE /hashtags/{id} - Delete stream - POST /hashtags/{id}/fetch - Fetch posts for stream - POST /hashtags/fetch-all - Fetch all active streams

Use Cases: Monitor hashtags, manage data sources, track collection progress


📝 Posts API

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

Endpoints: - GET /posts - List posts with advanced filtering - GET /posts/{id} - Get post details - PATCH /posts/{id} - Update post - DELETE /posts/{id} - Delete post - GET /posts/{id}/score - Get spam score analysis - POST /posts/{id}/recalculate - Recalculate spam score - POST /posts/batch-score - Batch score multiple posts

Features: - Advanced filtering by approval status, spam score, stream, queue status - Detailed spam score analysis with rule breakdown - Batch operations for efficiency

Use Cases: Search posts, analyze content, adjust scores, bulk operations


Review API

Manage post review and approval workflows.

Endpoints: - PATCH /posts/{id} - Approve/reject posts with notes

Review Decisions: - Approve: Mark post as high-quality for export - Reject: Mark post as spam or low-quality - Score Adjustment: Override automatic spam scoring - Add Notes: Document review reasoning

Use Cases: Manual review workflows, bulk approval, conditional review logic


🚀 Curated Queue API

Distribute approved posts to external consumers (e.g., Zhongli reblog bot).

Endpoints: - GET /curated/next - Reserve and return next pending post - POST /curated/{post_id}/ack - Confirm successful export - POST /curated/{post_id}/nack - Return post to queue (transient error) - POST /curated/{post_id}/error - Mark as permanently failed - POST /curated/{post_id}/requeue - Manually re-queue errored post

Queue States: pending → reserved → delivered (ack), pending (nack), or error

Reliability: At-least-once delivery with automatic timeout recovery

Use Cases: Export integration, consumer communication, error handling


🚫 Reblog Controls API

Manage export filters and blocklists for the Curated Queue.

Endpoints: - GET /reblog-controls/settings - Get filter settings - PUT /reblog-controls/settings - Update settings - GET /reblog-controls/blocked-users - List blocked users - POST /reblog-controls/blocked-users - Block a user - DELETE /reblog-controls/blocked-users/{id} - Unblock user - GET /reblog-controls/blocked-hashtags - List blocked hashtags - POST /reblog-controls/blocked-hashtags - Block a hashtag - DELETE /reblog-controls/blocked-hashtags/{id} - Unblock hashtag

Filter Options: - Require media attachments for export - Auto-reject posts from blocked users on fetch - Auto-reject posts with blocked hashtags on fetch

Use Cases: Content filtering, blocklist management, export policy enforcement


📊 Statistics API

Retrieve system statistics and analytics.

Endpoints: - GET /stats - Overall system statistics - GET /stats/posts - Detailed post statistics - GET /stats/streams - Stream-level statistics

Metrics: - Post counts by status (approved, rejected, unreviewed) - Spam score distribution - Export queue breakdown - Stream performance and approval rates - Daily activity (fetched, reviewed, approved)

Use Cases: Dashboard widgets, health monitoring, performance tracking, stream analysis


🔑 API Keys Management

Manage your API keys for authentication.

Endpoints: - GET /api-keys/status - Check current API key status - POST /api-keys/generate - Generate new API key - POST /api-keys/revoke - Revoke current API key

Best Practices: - Store API keys securely (environment variables) - Rotate keys periodically - Never commit keys to version control - Use least privilege (read-only keys when possible)


Common Patterns

Pagination

List endpoints support pagination:

GET /posts?skip=0&limit=50
Parameter Default Max
skip 0 -
limit 100 1000

Filtering

Most list endpoints support filtering:

# Filter by approval status
GET /posts?approved=true

# Filter by spam score range
GET /posts?spam_score_min=0&spam_score_max=50

# Filter by stream
GET /posts?stream_id=1

# Combine filters
GET /posts?approved=true&spam_score_max=30&stream_id=1

Error Responses

All errors follow standard format:

{
  "detail": "Descriptive error message"
}
Status Meaning
200 OK - Request successful
201 Created - Resource created
204 No Content - Success, no body
400 Bad Request - Invalid input
404 Not Found - Resource doesn't exist
409 Conflict - Resource already exists or state conflict
422 Unprocessable - Validation error
500 Server Error

Language Examples

All endpoints include examples in multiple languages:

Python (httpx)

import httpx

async with httpx.AsyncClient() as client:
    response = await client.get(
        "http://localhost:8000/api/v1/posts",
        headers={"X-API-Key": "your-api-key"},
        params={"approved": True, "limit": 50}
    )
    posts = response.json()

JavaScript (fetch)

const response = await fetch(
  "http://localhost:8000/api/v1/posts?approved=true&limit=50",
  { headers: { "X-API-Key": "your-api-key" } }
);
const posts = await response.json();

cURL

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

Workflow Examples

Complete Curation Pipeline

  1. Create StreamStreams API

    POST /hashtags -d '{"hashtag":"python","instance":"mastodon.social"}'
    

  2. Fetch PostsStreams API

    POST /hashtags/1/fetch?limit=50
    

  3. Review PostsReview API or Review Interface

    PATCH /posts/42 -d '{"approved":true,"reviewer_notes":"Quality content"}'
    

  4. Monitor QueueStatistics API

    GET /stats
    

  5. Export PostsCurated Queue API

    GET /curated/next
    POST /curated/42/ack
    

Automated Review Workflow

  1. Get unreviewed posts

    GET /posts?reviewed=false&limit=100
    

  2. Apply review logic (e.g., auto-approve low-spam)

    PATCH /posts/42 -d '{"approved":true}'
    

  3. Monitor results

    GET /stats/posts
    

Export Integration

  1. Request next post

    GET /curated/next
    

  2. Process (e.g., reblog)

    # Your consumer logic here
    

  3. Acknowledge or error

    POST /curated/42/ack        # Success
    POST /curated/42/nack       # Transient error, retry later
    POST /curated/42/error -d '{"reason":"..."}' # Permanent failure
    


Rate Limiting

Currently, FenLiu does not enforce rate limiting. For production deployments, implement rate limiting at the reverse proxy level (nginx, Cloudflare, etc.).


Testing Your API

Generate API Key

  1. Log in to FenLiu
  2. Navigate to Settings
  3. Scroll to API Key Management
  4. Click Generate New API Key
  5. Copy and store securely

Test Connection

curl -H "X-API-Key: YOUR_KEY_HERE" \
  http://localhost:8000/api/v1/stats

Python Test Script

import httpx
import asyncio

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

    async with httpx.AsyncClient() as client:
        # Test stats endpoint
        response = await client.get(f"{base_url}/stats", headers=headers)
        print(f"Status: {response.status_code}")
        print(f"Stats: {response.json()}")

asyncio.run(test_api())


Troubleshooting

401 Unauthorized

  • Missing or invalid API key
  • Check header is exactly X-API-Key: your-key
  • Generate new key if lost

404 Not Found

  • Resource doesn't exist
  • Verify resource ID is correct
  • List endpoints to find resources

409 Conflict

  • Resource already exists (creating duplicate)
  • Post state conflict (e.g., acking non-reserved post)
  • Check current state before updating

422 Unprocessable

  • Request body validation error
  • Check required fields and formats
  • Verify spam scores are 0-100

500 Server Error

  • Server-side issue
  • Check logs for details
  • Restart server if persistent

Best Practices

  1. Use Pagination: Always specify skip and limit for large result sets
  2. Filter Early: Use query parameters to reduce data transfer
  3. Handle Errors: Implement retry logic with exponential backoff
  4. Cache When Possible: Statistics change slowly; cache for 5-10 minutes
  5. Batch Operations: Use batch endpoints (e.g., batch-score) for multiple items
  6. Monitor Queue: Regularly check export queue status for pipeline health
  7. Document Decisions: Include reviewer notes when approving/rejecting
  8. Test Thoroughly: Test your integration before going live

API Versioning

Current API version: v1

All endpoints use the /api/v1/ base path. Future breaking changes will introduce /api/v2/ while maintaining /api/v1/ for backward compatibility.


Support

  • Issues: Report bugs on GitHub/Codeberg
  • Questions: Check FAQ or documentation
  • Contributing: See development guide