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¶
-
Create Stream → Streams API
POST /hashtags -d '{"hashtag":"python","instance":"mastodon.social"}' -
Fetch Posts → Streams API
POST /hashtags/1/fetch?limit=50 -
Review Posts → Review API or Review Interface
PATCH /posts/42 -d '{"approved":true,"reviewer_notes":"Quality content"}' -
Monitor Queue → Statistics API
GET /stats -
Export Posts → Curated Queue API
GET /curated/next POST /curated/42/ack
Automated Review Workflow¶
-
Get unreviewed posts
GET /posts?reviewed=false&limit=100 -
Apply review logic (e.g., auto-approve low-spam)
PATCH /posts/42 -d '{"approved":true}' -
Monitor results
GET /stats/posts
Export Integration¶
-
Request next post
GET /curated/next -
Process (e.g., reblog)
# Your consumer logic here -
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¶
- Log in to FenLiu
- Navigate to Settings
- Scroll to API Key Management
- Click Generate New API Key
- 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())
Related Resources¶
- Authentication Guide - Detailed auth documentation
- API Overview - API basics and patterns
- Dashboard - Visual interface
- Review Interface - Manual review UI
- Queue Preview - Export queue monitoring
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¶
- Use Pagination: Always specify
skipandlimitfor large result sets - Filter Early: Use query parameters to reduce data transfer
- Handle Errors: Implement retry logic with exponential backoff
- Cache When Possible: Statistics change slowly; cache for 5-10 minutes
- Batch Operations: Use batch endpoints (e.g., batch-score) for multiple items
- Monitor Queue: Regularly check export queue status for pipeline health
- Document Decisions: Include reviewer notes when approving/rejecting
- 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