txt server ========== A shared text feed. Post from the web or via Telegram bot. Read via HTTP API — build whatever reader you want. There is no official app. The API is the product. HOW TO POST ----------- Option 1 — Web (no account needed): Go to https://txt.endusergeek.com Type a username, type your message, hit txt. First post: you'll be asked to set a PIN (min 4 chars). That PIN locks your username. Keep it somewhere. After that, a login token is saved in the browser — you won't need to enter your PIN again until it expires (7 days). Option 2 — Telegram bot: Find @tpot_txt_bot and send any text message. Your Telegram username is your identity. No PIN needed. BOT COMMANDS (Telegram only) ----------------------------- /delete {id} — open a community vote to delete your post /approve_delete {id} — vote to approve a pending deletion (must have posted in last 24h to vote) /help — this info DELETION RULES -------------- - Only the post author can request deletion - Vote is open for 7 days - Passes when approvals exceed 50% of DAU (users who posted in last 24h) - One active deletion request per post at a time READ API -------- Base URL: https://txt.endusergeek.com/api No auth required. All responses JSON. GET /api/posts Returns recent posts, newest first. Parameters: limit default 50, max 200 before ISO timestamp — posts older than this (paginate back) after ISO timestamp — posts newer than this (poll for updates) author filter by username search filter by text content (case-insensitive substring, e.g. #word) Response: { "posts": [ { "id": 42, "author": "alice", "text": "hello from the feed", "timestamp": "2026-04-21T03:14:00Z" } ], "has_more": true } GET /api/posts/{id} Single post. 404 if deleted or nonexistent. GET /api/meta Server stats. { "name": "our txt server", "post_count": 42, "user_count": 7, "dau_today": 3, "oldest_post": "2026-04-21T00:00:00Z", "pending_deletions": 0 } GET /api/deletions Active deletion votes and their current status. GET /api/users/{username} Check whether a username has a PIN registered. { "exists": true } GET /api/posts.rss RSS feed of recent posts. Works in any RSS reader. Same filter params as /api/posts: author subscribe to a single user search subscribe to a keyword or #hashtag Examples: All posts: https://txt.endusergeek.com/api/posts.rss One user: https://txt.endusergeek.com/api/posts.rss?author=alice A hashtag: https://txt.endusergeek.com/api/posts.rss?search=%23word POST API -------- Authentication: username+PIN or JWT token. PINs are hashed (bcrypt) server-side — not stored in plaintext. Don't lose yours. POST /api/auth Exchange username+PIN for a JWT (valid 7 days). Only works for existing accounts — does not create new ones. Request: { "username": "alice", "pin": "your-pin" } Response: { "token": "...", "username": "alice", "expires_in": 604800 } Errors: 401 wrong PIN, 429 account locked POST /api/posts Submit a post. Two auth options: Option A — token (preferred for scripts): { "text": "hello", "token": "" } Option B — username+PIN (also creates new accounts): { "text": "hello", "username": "alice", "pin": "your-pin" } First post with a new username creates the account. On success, response includes a "token" field — store it. Username: 1-32 alphanumeric/underscore characters. PIN: at least 4 characters. Success response: { "id": 43, "author": "alice", "text": "hello from the api", "timestamp": "2026-04-21T03:15:00Z", "token": "..." ← only present on PIN auth, not token auth } Errors: 400 — bad username, empty text, text too long, PIN too short 401 — wrong PIN or expired/invalid token 429 — account locked (too many wrong PINs) or rate limit BUILDING A READER ----------------- Minimal (curl): curl https://txt.endusergeek.com/api/posts Poll for new posts (Python): import requests, time last = None while True: params = {"after": last} if last else {} r = requests.get("https://txt.endusergeek.com/api/posts", params=params) posts = r.json()["posts"] for p in reversed(posts): print(f"[{p['author']}] {p['text']}") if posts: last = posts[0]["timestamp"] time.sleep(30) Post from a script (Python): import requests # Get a token once (valid 7 days): r = requests.post("https://txt.endusergeek.com/api/auth", json={"username": "alice", "pin": "your-pin"}) token = r.json()["token"] # Post using the token: r = requests.post("https://txt.endusergeek.com/api/posts", json={"text": "posted from a script", "token": token}) print(r.json()) # Or just post with username+PIN directly (creates account if new): r = requests.post("https://txt.endusergeek.com/api/posts", json={"username": "alice", "pin": "your-pin", "text": "hello"}) print(r.json()) WHAT THIS IS NOT ---------------- No images, embeds, rich media, likes, reposts, DMs, search, edits, read receipts, or algorithmic feed. Chronological only.