Create wiki page 'API Reference'
291
API-Reference.md
Normal file
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
|
||||||
|
}
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user