| ```markdown | |
| # Internet Engineering Blog API — Complete Specification | |
| **Base URL:** `http://localhost:9092/api` | |
| **Version:** 2.0 | |
| **Data format:** JSON (all requests & responses) | |
| **Encoding:** UTF‑8 | |
| --- | |
| ## Table of Contents | |
| 1. [Authentication & General Notes](#authentication--general-notes) | |
| 2. [Common Response Structures](#common-response-structures) | |
| 3. [Authentication Endpoints](#authentication-endpoints) | |
| 4. [Articles](#articles) | |
| 5. [Comments](#comments) | |
| 6. [Likes](#likes) | |
| 7. [Tags](#tags) | |
| 8. [Users](#users) | |
| 9. [Bookmarks](#bookmarks) | |
| 10. [Profile](#profile) | |
| 11. [Notifications](#notifications) | |
| 12. [Citations](#citations) | |
| 13. [User Analytics](#user-analytics) | |
| 14. [Admin Panel](#admin-panel) | |
| 15. [Messaging – One‑to‑One](#messaging--onetoone) | |
| 16. [Messaging – Groups](#messaging--groups) | |
| 17. [Media Uploads](#media-uploads) | |
| 18. [Reactions](#reactions) | |
| 19. [Polls](#polls) | |
| 20. [Typing Indicators](#typing-indicators) | |
| 21. [Pinned Messages](#pinned-messages) | |
| 22. [Search](#search) | |
| 23. [User Search (Mentions)](#user-search-mentions) | |
| 24. [Muting Groups](#muting-groups) | |
| 25. [Rate Limiting & Error Codes](#rate-limiting--error-codes) | |
| --- | |
| ## Authentication & General Notes | |
| ### Authentication Methods | |
| The API supports both **cookie‑based** sessions and **Bearer token** headers. | |
| - **Cookies** – set automatically after login; the client should send credentials with every request (`credentials: 'include'`). | |
| - **Bearer token** – obtained via `POST /login` and sent in the `Authorization` header. | |
| - **CSRF Protection** – state‑changing requests (POST, PUT, DELETE) must include a custom header: | |
| `X-CSRF-Token: <csrf_token>` | |
| The token is returned in the login response and can be read from the (non‑HttpOnly) cookie or from the JSON body. | |
| ### Rate Limiting | |
| Public endpoints are limited to 60 requests per minute per IP. | |
| Authenticated endpoints are limited to 120 requests per minute per user. | |
| Messaging endpoints have stricter limits – see the [Rate Limiting](#rate-limiting--error-codes) section. | |
| --- | |
| ## Common Response Structures | |
| **Success:** 200/201 with the expected payload. | |
| 204 No Content for successful DELETE or actions with no return body. | |
| **Client Errors:** | |
| `400 Bad Request` – validation error | |
| `401 Unauthorized` – missing / expired token or session | |
| `403 Forbidden` – insufficient permissions | |
| `404 Not Found` – resource not found | |
| `409 Conflict` – duplicate resource | |
| `429 Too Many Requests` – rate limit exceeded | |
| **Server Error:** | |
| `500 Internal Server Error` | |
| All error bodies for new messaging endpoints follow the envelope form (with `"ok":false`). | |
| Older endpoints (articles, comments, etc.) retain the legacy format: | |
| ```json | |
| { | |
| "error": "Human‑readable message", | |
| "details": [ "Optional" ] | |
| } | |
| ``` | |
| For new endpoints, errors also include a numeric `error_code` and an optional `description`: | |
| ```json | |
| { | |
| "ok": false, | |
| "error_code": 400, | |
| "description": "Validation error" | |
| } | |
| ``` | |
| --- | |
| ## Messaging – One‑to‑One | |
| ### Conversations | |
| #### `GET /api/conversations` | |
| Return the list of one‑on‑one conversations for the authenticated user. | |
| **Auth** – required (cookie or Bearer). | |
| **Query parameters** | |
| | Param | Type | Default | Description | | |
| |---------|---------|---------|------------------------------| | |
| | `limit` | integer | 50 | Max conversations returned | | |
| | `after` | integer | – | Cursor: return conversations with last message id > after (for pagination) | | |
| **Success** – `200 OK` | |
| ```json | |
| { | |
| "ok": true, | |
| "result": [ | |
| { | |
| "with": "username", | |
| "lastMessage": "Hello!", | |
| "lastTime": "2025-04-10T14:23:00", | |
| "unread": 2 | |
| } | |
| ] | |
| } | |
| ``` | |
| **Errors** | |
| - `401` if not authenticated. | |
| #### `DELETE /api/conversations/{username}` | |
| Delete the entire conversation with the specified user. | |
| **Auth** – required. | |
| **Success** – `200 OK` (`{"ok":true,"result":true}`) | |
| --- | |
| ### Messages | |
| #### `GET /api/conversations/{username}/messages` | |
| Fetch messages between the current user and another user. Supports cursor‑based pagination. | |
| **Auth** – required. | |
| **Query parameters** | |
| | Param | Type | Default | Description | | |
| |----------|---------|---------|-------------------------------------------------| | |
| | `limit` | integer | 50 | Max messages to return | | |
| | `after` | integer | – | Return messages with id > after (newer) | | |
| | `before` | integer | – | Return messages with id < before (older) | | |
| **Success** – `200 OK` | |
| ```json | |
| { | |
| "ok": true, | |
| "result": [ | |
| { | |
| "id": 123, | |
| "from": "ali_tehrani", | |
| "to": "m_bagheri", | |
| "body": "Hello!", | |
| "sentAt": "2025-04-10T14:22:00", | |
| "read": true | |
| } | |
| ] | |
| } | |
| ``` | |
| #### `POST /api/conversations/{username}/messages` | |
| Send a message to a user. | |
| **Auth** – required. | |
| **Request body** | |
| ```json | |
| { | |
| "body": "string, required, max 5000 chars" | |
| } | |
| ``` | |
| **Success** – `201 Created` – returns the created message object. | |
| **Errors** | |
| - `400` if body missing or too long. | |
| - `404` if target user does not exist. | |
| #### `POST /api/conversations/{username}/read` | |
| Mark all messages from the specified user as read. | |
| **Auth** – required. | |
| **Success** – `200 OK` (`{"ok":true,"result":true}`) | |
| #### `POST /api/conversations/{username}/typing` | |
| Notify that the current user is typing. Typing status expires after 5 seconds. | |
| **Auth** – required. | |
| **Body** – empty. | |
| **Success** – `200 OK` | |
| #### `GET /api/conversations/{username}/typing` | |
| Check if the specified user is currently typing. | |
| **Auth** – required. | |
| **Success** – `200 OK` | |
| ```json | |
| { | |
| "ok": true, | |
| "result": { "typing": true } | |
| } | |
| ``` | |
| #### `GET /api/conversations/{username}/read-status` | |
| Get the last read message ID for both participants. | |
| **Auth** – required. | |
| **Success** – `200 OK` | |
| ```json | |
| { | |
| "ok": true, | |
| "result": { | |
| "lastReadMessageId": 120 | |
| } | |
| } | |
| ``` | |
| --- | |
| ## Messaging – Groups | |
| ### Group Management | |
| #### `GET /api/groups` | |
| List all groups the current user is a member of. | |
| **Auth** – required. | |
| **Success** – `200 OK` – array of group objects. | |
| #### `POST /api/groups` | |
| Create a new group. The creator automatically becomes an admin and member. | |
| **Auth** – required. | |
| **Request body** | |
| ```json | |
| { | |
| "name": "string, required, max 100 chars", | |
| "description": "optional, max 500 chars", | |
| "members": [1, 2, 3] // array of user IDs (optional) | |
| } | |
| ``` | |
| **Success** – `201 Created` – returns the created group object. | |
| #### `GET /api/groups/{groupId}` | |
| Get group information. | |
| **Auth** – required. | |
| **Success** – `200 OK` – group object. | |
| #### `PUT /api/groups/{groupId}` | |
| Update group settings (name, description, slow mode, avatar). | |
| **Auth** – admin only. | |
| **Request body** (all optional) | |
| ```json | |
| { | |
| "name": "string", | |
| "description": "string", | |
| "slowMode": true, | |
| "slowModeSeconds": 30, | |
| "avatarUrl": "string" | |
| } | |
| ``` | |
| **Success** – `200 OK` | |
| #### `DELETE /api/groups/{groupId}` | |
| Delete a group. **Auth** – admin only. | |
| **Success** – `200 OK` | |
| ### Membership | |
| #### `GET /api/groups/{groupId}/members` | |
| Return a list of members with their admin status. | |
| **Auth** – group member. | |
| **Success** – `200 OK` | |
| ```json | |
| { | |
| "ok": true, | |
| "result": [ | |
| { "userId": 1, "isAdmin": true }, | |
| { "userId": 2, "isAdmin": false } | |
| ] | |
| } | |
| ``` | |
| #### `POST /api/groups/{groupId}/members` | |
| Add one or more members to the group. **Auth** – admin only. | |
| **Request body** | |
| ```json | |
| { | |
| "members": [ 4, 5 ] | |
| } | |
| ``` | |
| **Success** – `200 OK` | |
| #### `DELETE /api/groups/{groupId}/members/{memberId}` | |
| Remove a member (or kick). **Auth** – admin only. | |
| **Success** – `200 OK` | |
| #### `POST /api/groups/{groupId}/members/{memberId}/promote` | |
| Promote a member to admin. **Auth** – admin only. | |
| **Success** – `200 OK` | |
| #### `POST /api/groups/{groupId}/members/{memberId}/demote` | |
| Demote an admin back to member. **Auth** – admin only. | |
| **Success** – `200 OK` | |
| #### `POST /api/groups/{groupId}/leave` | |
| Leave the group. **Auth** – required. | |
| **Success** – `200 OK` | |
| ### Group Messages | |
| #### `GET /api/groups/{groupId}/messages` | |
| Fetch messages in a group with cursor‑based pagination. | |
| **Auth** – member of the group. | |
| **Query parameters** | |
| | Param | Type | Default | Description | | |
| |----------|---------|---------|-------------------------------------------------| | |
| | `limit` | integer | 50 | Max messages | | |
| | `after` | integer | – | Return messages with id > after (newer) | | |
| | `before` | integer | – | Return messages with id < before (older) | | |
| **Success** – `200 OK` – array of group message objects (enriched with reactions, media, poll info). | |
| #### `POST /api/groups/{groupId}/messages` | |
| Send a message to a group. | |
| **Auth** – member of the group. | |
| **Request body** (all optional except body) | |
| ```json | |
| { | |
| "body": "string, required", | |
| "replyTo": 123, // message ID being replied to | |
| "mentions": [ 1, 2 ], // user IDs to mention | |
| "media": [ 99, 100 ], // uploaded media IDs | |
| "pollId": 10, // poll ID (if the message is a poll) | |
| "keyboard": "{...}" // inline keyboard JSON | |
| } | |
| ``` | |
| **Success** – `201 Created` – returns the created message. | |
| **Errors** | |
| - `400` if body missing. | |
| - `403` if not a group member. | |
| - `429` if slow mode is active. | |
| #### `DELETE /api/groups/{groupId}/messages/{messageId}` | |
| Delete a message. **Auth** – sender or group admin. | |
| **Success** – `200 OK` | |
| #### `PUT /api/groups/{groupId}/messages/{messageId}` | |
| Edit a message. **Auth** – sender. | |
| **Request body** `{"body": "new text"}` | |
| **Success** – `200 OK` | |
| #### `POST /api/groups/{groupId}/messages/{messageId}/forward` | |
| Forward a message to another group (or the same). | |
| **Auth** – group member. | |
| **Request body** `{"toGroupId": 456}` | |
| **Success** – `201 Created` – returns the new forwarded message. | |
| #### `POST /api/groups/{groupId}/messages/bulk-delete` | |
| Delete a list of messages. **Auth** – group admin. | |
| **Request body** `{"messageIds": [1,2,3]}` | |
| **Success** – `200 OK` with `{"deleted": 3}` | |
| #### `POST /api/groups/{groupId}/read` | |
| Mark the group as read (sets last read timestamp). | |
| **Auth** – member. | |
| **Success** – `200 OK` | |
| #### `GET /api/groups/{groupId}/read-status` | |
| Return the last read timestamp for each member. | |
| **Auth** – member. | |
| **Success** – array of `{ userId, lastRead }` | |
| --- | |
| ## Media Uploads | |
| #### `POST /api/media/upload` | |
| Upload a file (image, video, audio, document) as a Base64 data‑URL. | |
| Maximum file size: **10 MB**. | |
| **Auth** – required. | |
| **Request body** | |
| ```json | |
| { | |
| "file": "data:image/png;base64,iVBOR...", | |
| "fileName": "optional.png" | |
| } | |
| ``` | |
| **Success** – `201 Created` | |
| ```json | |
| { | |
| "ok": true, | |
| "result": { | |
| "mediaId": 1, | |
| "url": "/uploads/media/...", | |
| "thumbnail": "base64..." // only for images | |
| } | |
| } | |
| ``` | |
| **Errors** | |
| - `400` if file is missing or invalid. | |
| - `413` if file too large. | |
| #### `GET /api/media/{mediaId}` | |
| Retrieve a media file’s metadata. | |
| **Auth** – required. | |
| **Success** – media object. | |
| --- | |
| ## Reactions | |
| #### `POST /api/messages/{messageId}/reactions` | |
| Toggle a reaction on a message (both one‑on‑one and group). | |
| If the user already reacted with the same emoji, it is removed. | |
| Otherwise, the reaction is added. | |
| **Auth** – required. | |
| **Request body** `{"emoji": "❤️"}` | |
| **Success** – `200 OK` | |
| **Note**: The client should optimistically update the UI. | |
| #### `GET /api/messages/{messageId}/reactions` | |
| Get all reactions for a message. | |
| **Auth** – required. | |
| **Success** – array of `{ userId, emoji }` | |
| --- | |
| ## Polls | |
| #### `POST /api/groups/{groupId}/polls` | |
| Create a new poll in a group. | |
| **Auth** – group member. | |
| **Request body** | |
| ```json | |
| { | |
| "question": "string, required", | |
| "options": ["Option 1", "Option 2"], // 2‑10 options | |
| "multipleAnswers": false, // allow multiple choice | |
| "shuffleOptions": false, // randomise options order | |
| "closeDate": 1712345678000 // optional, epoch millis | |
| } | |
| ``` | |
| **Success** – `201 Created` – poll object. | |
| **Errors** | |
| - `400` if fewer than 2 or more than 10 options. | |
| #### `GET /api/polls/{pollId}` | |
| Get poll details (including current results). | |
| **Auth** – required (any member of the group). | |
| #### `POST /api/polls/{pollId}/vote` | |
| Vote on a poll. | |
| **Auth** – required (must be a group member). | |
| **Request body** | |
| For single‑choice polls: `{"optionId": 1}` | |
| For multiple‑choice polls: `{"optionIds": [1, 3]}` | |
| **Success** – `200 OK` | |
| **Errors** – `400` if poll is closed or invalid option, `409` if already voted (for single‑choice). | |
| #### `POST /api/polls/{pollId}/close` | |
| Close a poll. **Auth** – poll creator or group admin. | |
| **Success** – `200 OK` | |
| #### `POST /api/polls/{pollId}/reopen` | |
| Reopen a closed poll. **Auth** – poll creator or group admin. | |
| **Success** – `200 OK` | |
| #### `DELETE /api/polls/{pollId}` | |
| Delete a poll. **Auth** – poll creator or group admin. | |
| **Success** – `200 OK` | |
| --- | |
| ## Typing Indicators | |
| #### `POST /api/conversations/{username}/typing` | |
| Already described in One‑to‑One section. | |
| #### `GET /api/conversations/{username}/typing` | |
| Already described in One‑to‑One section. | |
| #### `POST /api/groups/{groupId}/typing` | |
| Notify that the user is typing in a group. Typing status expires after 5 seconds. | |
| **Auth** – required. | |
| **Success** – `204 No Content` | |
| #### `GET /api/groups/{groupId}/typing` | |
| Return a list of user IDs currently typing in the group. | |
| **Auth** – group member. | |
| **Success** – `200 OK` | |
| ```json | |
| { | |
| "ok": true, | |
| "result": [ 1, 2 ] | |
| } | |
| ``` | |
| --- | |
| ## Pinned Messages | |
| #### `POST /api/groups/{groupId}/pin/{messageId}` | |
| Pin a message. It will appear at the top of the pinned list. | |
| **Auth** – group admin. | |
| **Success** – `200 OK` | |
| #### `DELETE /api/groups/{groupId}/pin/{messageId}` | |
| Unpin a message. **Auth** – group admin. | |
| **Success** – `200 OK` | |
| #### `GET /api/groups/{groupId}/pins` | |
| List all pinned message IDs. **Auth** – group member. | |
| **Success** – array of message IDs. | |
| --- | |
| ## Search | |
| #### `GET /api/conversations/search` | |
| Search one‑on‑one messages for the authenticated user. | |
| **Auth** – required. | |
| **Query parameters** | |
| `q` (required), `limit` (optional, default 50) | |
| **Success** – `200 OK` – array of matching messages. | |
| #### `GET /api/groups/{groupId}/search` | |
| Search messages inside a group. | |
| **Auth** – group member. | |
| **Query parameters** | |
| `q` (required), `limit` (optional, default 50) | |
| **Success** – `200 OK` – array of matching group messages. | |
| --- | |
| ## User Search (Mentions) | |
| #### `GET /api/users/search` | |
| Search for users by username (for mentions / starting conversations). | |
| **Auth** – required. | |
| **Query parameter** `q` (required, minimum 2 characters) | |
| **Success** – `200 OK` | |
| ```json | |
| { | |
| "ok": true, | |
| "result": [ | |
| { "id": 1, "username": "ali_tehrani", "fullName": "Ali Tehrani", "avatarUrl": "..." } | |
| ] | |
| } | |
| ``` | |
| --- | |
| ## Muting Groups | |
| #### `POST /api/groups/{groupId}/mute` | |
| Mute notifications for a group. | |
| **Auth** – required (any member). | |
| **Success** – `200 OK` | |
| #### `DELETE /api/groups/{groupId}/mute` | |
| Unmute notifications. | |
| **Auth** – required. | |
| **Success** – `200 OK` | |
| --- | |
| ## Rate Limiting & Error Codes | |
| | Error Code | Meaning | | |
| |------------|---------| | |
| | 400 | Bad Request – missing or invalid parameters | | |
| | 401 | Unauthorized – authentication required | | |
| | 403 | Forbidden – not enough permissions | | |
| | 404 | Not Found – resource doesn’t exist | | |
| | 409 | Conflict – duplicate or conflicting state | | |
| | 429 | Too Many Requests – rate limit exceeded | | |
| **Rate limit headers** | |
| All responses include the headers `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset` (epoch seconds) to inform the client of the current status. | |
| --- | |
| **End of API specification** | |
| ``` |
Xet Storage Details
- Size:
- 16.1 kB
- Xet hash:
- 507c48503c0150eeeb4d3ae2647944301362e79c886120869a075c63d56653ed
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.