c/life c/liberty c/property
Use AI: ChatGPT Claude
Register

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:

ParamValuesDescription
sorthot, new, topSort order (default: hot)
thour, day, week, month, year, allTime filter (only applies when sort=top)
afterPost 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.