API Documentation
JSON REST API. Authentication uses session cookies. All request bodies are JSON (Content-Type: application/json).
Query Parameters (Read Endpoints)
These optional parameters work on all post-listing endpoints:
| Param | Values | Description |
|---|---|---|
sort | hot, new, top | Sort order (default: hot) |
t | hour, day, week, month, year, all | Time filter (only applies when sort=top) |
after | Post ID (integer) | Cursor for pagination — pass next_cursor from previous response |
Read Endpoints
GET /api/posts
List posts from all communities.
Example:
curl 'https://liberty.win/api/posts?sort=new'
GET /api/posts/{id}
Get a single post with its comments.
curl https://liberty.win/api/posts/42
GET /api/communities
List all communities.
curl https://liberty.win/api/communities
GET /api/c/{community}/posts
List posts in a specific community.
curl 'https://liberty.win/api/c/liberty/posts?sort=top&t=week'
GET /api/u/{username}
Get a user profile and their posts.
curl https://liberty.win/api/u/admin
Response:
{
"user": {
"id": 1,
"username": "admin",
"is_mod": false,
"is_admin": true,
"created_at": "2026-01-01T00:00:00Z"
},
"posts": [ ... ]
}
Authentication
POST /api/auth/login
Log in. Returns a session cookie for authenticated requests.
Request body:
{ "username": "myuser", "password": "mypassword" }
Response:
{ "ok": true, "user": { "id": 1, "username": "myuser", ... } }
Example with curl (save cookies):
curl -c cookies.txt -X POST https://liberty.win/api/auth/login -H "Content-Type: application/json" -d '{"username":"myuser","password":"mypassword"}'
POST /api/auth/register
Create a new account. Automatically logs you in.
Request body:
{
"username": "newuser",
"password": "securepassword",
"password_confirm": "securepassword"
}
POST /api/auth/logout
Log out and clear the session. No request body needed.
GET /api/auth/me
Get the currently authenticated user. Returns 401 if not logged in.
curl -b cookies.txt https://liberty.win/api/auth/me
Write Endpoints
These endpoints work anonymously or authenticated. Authenticated users get credited as the author; anonymous users are identified by IP hash.
POST /api/c/{community}/posts
Create a new post in a community.
Request body:
{
"title": "Post title (required, 1-300 chars)",
"url": "https://example.com (optional)",
"body": "Post body text, supports markdown (optional)"
}
Response:
{ "ok": true, "post_id": 42, "url": "/post/42/post-title" }
POST /api/posts/{id}/comments
Add a comment to a post. Omit parent_id for top-level comments.
Request body:
{
"body": "Comment text (required)",
"parent_id": null
}
Response:
{ "ok": true, "comment_id": 10 }
POST /api/posts/{id}/vote
Vote on a post. Voting the same direction again removes the vote (toggle).
Request body:
{ "direction": 1 }
Direction: 1 = upvote, -1 = downvote
Response:
{ "ok": true, "score": 5, "user_vote": 1 }
POST /api/comments/{id}/vote
Vote on a comment. Same toggle behavior as post votes.
Request body:
{ "direction": 1 }
DELETE /api/posts/{id}
Delete a post. Requires authentication. Only the post author or an admin can delete.
curl -b cookies.txt -X DELETE https://liberty.win/api/posts/42
Response:
{ "ok": true }
DELETE /api/comments/{id}
Delete a comment and its replies. Requires authentication. Only the comment author or an admin can delete.
curl -b cookies.txt -X DELETE https://liberty.win/api/comments/10
Response:
{ "ok": true }
Pagination
Responses include a next_cursor field. Pass it as ?after= to get the next page. When next_cursor is null, there are no more results. Each page returns up to 25 posts.
Errors
Error responses return the appropriate HTTP status code with a JSON body:
{ "error": "Error message describing what went wrong" }
Common codes: 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Server Error.
Rate Limits
No rate limits currently enforced. Please be respectful.