From e78c9db6e01862dfbbfd4206ac29291c780a1615 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Fri, 15 May 2026 15:04:31 +0000 Subject: [PATCH] Update wiki page 'API-Reference' --- API-Reference.md | 294 ++++++++++++++++++++++------------------------- 1 file changed, 136 insertions(+), 158 deletions(-) diff --git a/API-Reference.md b/API-Reference.md index de38ef3..25d8b1c 100644 --- a/API-Reference.md +++ b/API-Reference.md @@ -1,8 +1,8 @@ # API Reference -**Base URL:** `/api/v1` -**Data format:** JSON -**Interactive docs:** `/api/swagger` (served by the backend at runtime) +**Base URL:** `/` (all REST endpoints at root) +**API port:** `8000` (default) +**Interactive docs:** `/docs` (Swagger UI) · `/scalar` (Scalar UI) ## Authentication @@ -11,90 +11,46 @@ | JWT | `Authorization: Bearer ` | Web client (short-lived) | | API Key | `Authorization: ApiKey ` | Third-party apps (long-lived) | -Generate API keys from the Settings → API Keys page. +Obtain a JWT from `POST /auth/login`. Generate API keys from Settings → API Keys. --- -## Auth Endpoints +## Auth ### `POST /auth/register` - -Creates a new user account. - -**Public** — no auth required. +Create a new user account. **Public.** ```json -{ - "username": "frutiger", - "email": "aero@example.com", - "password": "strongpassword123" -} +{ "username": "frutiger", "email": "aero@example.com", "password": "..." } ``` | Status | Meaning | |---|---| -| 201 | Created — returns new User object (password omitted) | -| 400 | Bad Request — invalid input | -| 409 | Conflict — username or email already exists | - ---- +| 201 | Created — returns User object | +| 400 | Bad Request | +| 409 | Conflict — username or email taken | ### `POST /auth/login` - -Authenticates a user and returns a JWT. - -**Public** — no auth required. +Authenticate and receive a JWT. **Public.** ```json -{ - "username": "frutiger", - "password": "strongpassword123" -} +{ "username": "frutiger", "password": "..." } ``` -**Response:** -```json -{ - "token": "eyJhbGci..." -} -``` - -| Status | Meaning | -|---|---| -| 200 | OK — returns JWT | -| 400 | Bad Request | -| 401 | Unauthorized | +Response: `{ "token": "eyJ..." }` --- -## User & Profile Endpoints +## Users & Profiles ### `GET /users/{username}` - -Retrieves the public profile of a user. - -**Public.** - -| Status | Meaning | -|---|---| -| 200 | OK — returns public User object | -| 404 | Not Found | - ---- +Public profile. Content negotiation: returns AP actor JSON if `Accept: application/activity+json`, otherwise REST profile. ### `GET /users/me` - -Retrieves the full profile of the authenticated user (includes private fields like email). - -**Required:** JWT. - ---- +Authenticated user's full profile (includes email). **JWT required.** ### `PUT /users/me` - -Updates the authenticated user's profile. - -**Required:** JWT. +Update profile. **JWT required.** ```json { @@ -107,146 +63,175 @@ Updates the authenticated user's profile. } ``` -- `topFriends`: up to 8 usernames displayed on your profile -- `customCss`: sanitized on the server (malicious patterns stripped) +`customCss` is sanitized server-side. `topFriends` accepts up to 5 usernames. ---- +### `GET /users` +List all users with stats. **Public.** ### `GET /users/{username}/thoughts` - -All thoughts for a specific user, paginated. - -**Public.** +User's thoughts, paginated. **Public.** --- -## Thoughts Endpoints +## Thoughts ### `POST /thoughts` - -Creates a new thought. - -**Required:** JWT or API Key. +Create a thought. **JWT or API Key required.** ```json -{ - "content": "This is my first thought! #welcome" -} +{ "content": "Hello world! #welcome", "visibility": "public" } ``` +`visibility`: `public` | `followers` | `private`. Hashtags parsed automatically. Max 128 chars. + | Status | Meaning | |---|---| -| 201 | Created — returns new Thought object | -| 400 | Bad Request (e.g. content > 128 chars) | +| 201 | Created | +| 400 | Content too long or invalid | -Hashtags in `content` are parsed automatically. - ---- +### `GET /thoughts/{id}` +Get a single thought. **Public** (respects visibility). ### `DELETE /thoughts/{id}` +Delete own thought. **JWT or API Key required.** -Deletes a thought. Caller must be the author. +### `GET /thoughts/{id}/thread` +Full reply thread. **Public.** -**Required:** JWT or API Key. - -| Status | Meaning | -|---|---| -| 204 | No Content | -| 403 | Forbidden | -| 404 | Not Found | +### `PUT /thoughts/{id}` +Edit thought content. **JWT required.** Broadcasts `Update(Note)` to federation. --- -## Social Endpoints +## Social ### `POST /users/{username}/follow` - -Follow a user. - -**Required:** JWT. - -| Status | Meaning | -|---|---| -| 204 | No Content | -| 404 | Not Found | -| 409 | Conflict — already following | - ---- +Follow a local user. **JWT required.** ### `DELETE /users/{username}/follow` +Unfollow. **JWT required.** -Unfollow a user. +### `GET /users/{username}/followers` +Follower list. **Public.** -**Required:** JWT. +### `GET /users/{username}/following` +Following list. **Public.** + +### `POST /thoughts/{id}/like` +Like a thought. **JWT required.** Sends `Like` activity to remote authors. + +### `DELETE /thoughts/{id}/like` +Unlike. **JWT required.** + +### `POST /thoughts/{id}/boost` +Boost (announce) a thought. **JWT required.** Broadcasts `Announce`. + +### `DELETE /thoughts/{id}/boost` +Undo boost. **JWT required.** + +### `POST /users/{username}/block` +Block a user. **JWT required.** Delivers `Block` activity. --- +## Feed & Discovery + ### `GET /feed` +Home feed — thoughts from followed users, reverse-chronological. **JWT required.** -The authenticated user's main feed — thoughts from all followed users in reverse-chronological order, paginated. - -**Required:** JWT. - ---- - -## Discovery Endpoints +### `GET /feed/public` +Public feed — all public thoughts. **Public** (optional auth for like/boost state). ### `GET /tags/popular` - -List of currently trending tags. - -**Public.** - ---- +Popular tags list. **Public.** ### `GET /tags/{tagName}` - -All thoughts with a specific tag, paginated, chronological. - -**Public.** - ---- +Thoughts for a specific tag. **Public.** ### `GET /search` +Full-text search over thoughts and users (PostgreSQL trigram). **Public.** -Full-text search across thoughts and users. - -**Public** (optional auth for personalized results). +Query params: `q`, `page`, `per_page`. --- -## API Key Endpoints +## Notifications + +### `GET /notifications` +List notifications for the authenticated user. **JWT required.** + +### `GET /notifications/unread-count` +Count of unread notifications. **JWT required.** + +### `POST /notifications/{id}/read` +Mark a notification read. **JWT required.** + +### `POST /notifications/read-all` +Mark all notifications read. **JWT required.** + +--- + +## API Keys ### `GET /api-keys` - -List all API keys for the authenticated user. - -**Required:** JWT. - ---- +List own keys. **JWT required.** ### `POST /api-keys` +Create a key. **JWT required.** Raw key returned **once** — store immediately. -Create a new API key. - -**Required:** JWT. - -The raw key is returned **once** at creation time — store it securely. +### `DELETE /api-keys/{id}` +Revoke a key. **JWT required.** --- -### `DELETE /api-keys/{id}` +## Federation Management -Revoke an API key. +### `GET /federation/pending-followers` +List remote actors with pending follow requests. **JWT required.** -**Required:** JWT. +### `POST /federation/accept-follower` +Accept a remote follow request. **JWT required.** + +### `POST /federation/reject-follower` +Reject a remote follow request. **JWT required.** + +### `DELETE /federation/remote-follower` +Remove an accepted remote follower. **JWT required.** + +### `GET /federation/remote-following` +List remote actors this user follows. **JWT required.** + +### `POST /federation/follow-remote` +Follow a remote actor by `@user@instance` handle. **JWT required.** + +### `POST /federation/unfollow-remote` +Unfollow a remote actor. **JWT required.** + +### `GET /remote-actors` +Look up a remote actor by handle. **JWT required.** + +--- + +## ActivityPub Endpoints + +These are consumed by other Fediverse servers, not the frontend. + +| Endpoint | Description | +|---|---| +| `GET /.well-known/webfinger` | WebFinger discovery | +| `GET /.well-known/nodeinfo` | NodeInfo pointer | +| `GET /nodeinfo/2.1` | NodeInfo stats | +| `GET /users/{username}` (AP Accept) | Actor JSON | +| `GET /users/{username}/outbox` | Paginated outbox | +| `GET /users/{username}/followers` | Followers collection | +| `GET /users/{username}/following` | Following collection | +| `POST /users/{username}/inbox` | Shared inbox | --- ## Data Models -### User (Public) - +### User (public) ```json { "username": "frutiger", @@ -255,37 +240,30 @@ Revoke an API key. "avatarUrl": "https://...", "headerUrl": "https://...", "customCss": "body { background: blue; }", - "topFriends": ["username1", "username2"], "joinedAt": "2024-01-01T12:00:00Z" } ``` ### Thought - ```json { - "id": "uuid-v4-string", + "id": "uuid", "authorUsername": "frutiger", - "content": "This is my first thought! #welcome", + "content": "Hello world! #welcome", "tags": ["welcome"], "visibility": "public", "replyTo": null, + "likeCount": 3, + "boostCount": 1, + "likedByMe": false, + "boostedByMe": false, "createdAt": "2024-01-01T12:01:00Z" } ``` -`visibility` values: `public`, `followers`, `private`. -`replyTo`: UUID of the parent thought if this is a reply. - ### Pagination -Paginated endpoints accept `page` and `per_page` query params and return: - +All paginated endpoints accept `page` and `per_page` and return: ```json -{ - "data": [...], - "page": 1, - "per_page": 20, - "total": 142 -} +{ "data": [...], "page": 1, "per_page": 20, "total": 142 } ```