Create wiki page 'API Reference'

2026-05-15 15:00:15 +00:00
parent a9135c253a
commit c14cc4d8b4

291
API-Reference.md Normal file

@@ -0,0 +1,291 @@
# API Reference
**Base URL:** `/api/v1`
**Data format:** JSON
**Interactive docs:** `/api/swagger` (served by the backend at runtime)
## Authentication
| Method | Header | When |
|---|---|---|
| JWT | `Authorization: Bearer <token>` | Web client (short-lived) |
| API Key | `Authorization: ApiKey <key>` | Third-party apps (long-lived) |
Generate API keys from the Settings → API Keys page.
---
## Auth Endpoints
### `POST /auth/register`
Creates a new user account.
**Public** — no auth required.
```json
{
"username": "frutiger",
"email": "aero@example.com",
"password": "strongpassword123"
}
```
| Status | Meaning |
|---|---|
| 201 | Created — returns new User object (password omitted) |
| 400 | Bad Request — invalid input |
| 409 | Conflict — username or email already exists |
---
### `POST /auth/login`
Authenticates a user and returns a JWT.
**Public** — no auth required.
```json
{
"username": "frutiger",
"password": "strongpassword123"
}
```
**Response:**
```json
{
"token": "eyJhbGci..."
}
```
| Status | Meaning |
|---|---|
| 200 | OK — returns JWT |
| 400 | Bad Request |
| 401 | Unauthorized |
---
## User & Profile Endpoints
### `GET /users/{username}`
Retrieves the public profile of a user.
**Public.**
| Status | Meaning |
|---|---|
| 200 | OK — returns public User object |
| 404 | Not Found |
---
### `GET /users/me`
Retrieves the full profile of the authenticated user (includes private fields like email).
**Required:** JWT.
---
### `PUT /users/me`
Updates the authenticated user's profile.
**Required:** JWT.
```json
{
"displayName": "Frutiger Aero Fan",
"bio": "Est. 2004",
"avatarUrl": "https://...",
"headerUrl": "https://...",
"customCss": "body { background: blue; }",
"topFriends": ["username1", "username2"]
}
```
- `topFriends`: up to 8 usernames displayed on your profile
- `customCss`: sanitized on the server (malicious patterns stripped)
---
### `GET /users/{username}/thoughts`
All thoughts for a specific user, paginated.
**Public.**
---
## Thoughts Endpoints
### `POST /thoughts`
Creates a new thought.
**Required:** JWT or API Key.
```json
{
"content": "This is my first thought! #welcome"
}
```
| Status | Meaning |
|---|---|
| 201 | Created — returns new Thought object |
| 400 | Bad Request (e.g. content > 128 chars) |
Hashtags in `content` are parsed automatically.
---
### `DELETE /thoughts/{id}`
Deletes a thought. Caller must be the author.
**Required:** JWT or API Key.
| Status | Meaning |
|---|---|
| 204 | No Content |
| 403 | Forbidden |
| 404 | Not Found |
---
## Social Endpoints
### `POST /users/{username}/follow`
Follow a user.
**Required:** JWT.
| Status | Meaning |
|---|---|
| 204 | No Content |
| 404 | Not Found |
| 409 | Conflict — already following |
---
### `DELETE /users/{username}/follow`
Unfollow a user.
**Required:** JWT.
---
### `GET /feed`
The authenticated user's main feed — thoughts from all followed users in reverse-chronological order, paginated.
**Required:** JWT.
---
## Discovery Endpoints
### `GET /tags/popular`
List of currently trending tags.
**Public.**
---
### `GET /tags/{tagName}`
All thoughts with a specific tag, paginated, chronological.
**Public.**
---
### `GET /search`
Full-text search across thoughts and users.
**Public** (optional auth for personalized results).
---
## API Key Endpoints
### `GET /api-keys`
List all API keys for the authenticated user.
**Required:** JWT.
---
### `POST /api-keys`
Create a new API key.
**Required:** JWT.
The raw key is returned **once** at creation time — store it securely.
---
### `DELETE /api-keys/{id}`
Revoke an API key.
**Required:** JWT.
---
## Data Models
### User (Public)
```json
{
"username": "frutiger",
"displayName": "Frutiger Aero Fan",
"bio": "Est. 2004",
"avatarUrl": "https://...",
"headerUrl": "https://...",
"customCss": "body { background: blue; }",
"topFriends": ["username1", "username2"],
"joinedAt": "2024-01-01T12:00:00Z"
}
```
### Thought
```json
{
"id": "uuid-v4-string",
"authorUsername": "frutiger",
"content": "This is my first thought! #welcome",
"tags": ["welcome"],
"visibility": "public",
"replyTo": null,
"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:
```json
{
"data": [...],
"page": 1,
"per_page": 20,
"total": 142
}
```