REST API Documentation
Complete reference for GEO Wiki Pro REST API endpoints, including authentication, document management, categories, tags, media upload, and all endpoints
# REST API Documentation
> Complete reference manual for GEO Wiki Pro backend REST API
---
## Overview
GEO Wiki Pro provides RESTful-style HTTP APIs, all under the `/api/v1/` path. Public endpoints require no authentication, while admin endpoints require JWT authentication and admin role.
### Basic Information
| Item | Description |
|------|-------------|
| Base URL | `https://your-domain.com/api/v1` |
| Authentication | JWT (httpOnly cookie) |
| CSRF Protection | Double-submit cookie HMAC |
| Content Type | `application/json` |
| Rate Limiting | Global 300 requests/minute, auth endpoints 10 requests/minute |
### Response Format
**Success Response:**
```json
{
"success": true,
"data": { ... }
}
```
**Paginated Response:**
```json
{
"success": true,
"data": [ ... ],
"pagination": {
"page": 1,
"limit": 20,
"total": 42,
"totalPages": 3
}
}
```
**Error Response:**
```json
{
"success": false,
"message": "Not found"
}
```
---
## Public Endpoints
The following endpoints require no authentication and are accessible by anyone.
### Get Document List
```
GET /api/v1/docs
```
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `lang` | string | No | Language code (zh/en/jp), default zh |
| `category` | string | No | Category slug filter |
| `page` | number | No | Page number, default 1 |
| `limit` | number | No | Items per page, default 20 |
**Example:**
```bash
curl "https://geowiki.pro/api/v1/docs?lang=en&category=can-motion&page=1&limit=10"
```
**Response:**
```json
{
"success": true,
"data": [
{
"slug": "can-bus-protocol",
"title": "CAN Bus Protocol",
"category": "can-motion",
"tags": ["can-bus", "protocol"],
"author": "admin",
"sort": 1,
"description": "CAN bus communication protocol overview",
"updated_at": "2026-05-20T10:30:00Z"
}
],
"pagination": {
"page": 1,
"limit": 10,
"total": 25,
"totalPages": 3
}
}
```
### Get Single Document
```
GET /api/v1/docs/:slug
```
**Path Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `slug` | string | Document slug |
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `lang` | string | No | Language code, default zh |
**Example:**
```bash
curl "https://geowiki.pro/api/v1/docs/can-bus-protocol?lang=en"
```
**Response:**
```json
{
"success": true,
"data": {
"slug": "can-bus-protocol",
"title": "CAN Bus Protocol",
"category": "can-motion",
"tags": ["can-bus", "protocol"],
"author": "admin",
"sort": 1,
"description": "CAN bus communication protocol overview",
"content": "# CAN Bus Protocol\n\nThe Controller Area Network (CAN)...",
"updated_at": "2026-05-20T10:30:00Z"
}
}
```
::: note
For non-default language requests, the system performs cascading merge: first reads Chinese documents as the base, then overlays target language documents for matching slugs. Therefore, even if a document only has a Chinese version, English requests can still return content.
:::
### Document Search
```
GET /api/v1/docs/search
```
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `q` | string | Yes | Search keyword |
| `lang` | string | No | Language code |
| `category` | string | No | Category slug |
| `page` | number | No | Page number |
| `limit` | number | No | Items per page |
**Example:**
```bash
curl "https://geowiki.pro/api/v1/docs/search?q=can+bus&lang=en&category=can-motion"
```
**Response:**
```json
{
"success": true,
"data": [
{
"slug": "can-bus-protocol",
"title": "CAN Bus Protocol",
"description": "CAN bus communication protocol overview",
"score": 0.95
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 5,
"totalPages": 1
}
}
```
### Get Category List
```
GET /api/v1/categories
```
**Response:**
```json
{
"success": true,
"data": [
{
"slug": "can-motion",
"name": "CAN 运动控制",
"name_en": "CAN Motion Control",
"description": "CAN 总线运动控制产品文档"
}
]
}
```
### Get Tag List
```
GET /api/v1/tags
```
**Response:**
```json
{
"success": true,
"data": [
{
"slug": "can-bus",
"name": "CAN 总线",
"name_en": "CAN Bus"
}
]
}
```
### Get Site Configuration
```
GET /api/v1/config
```
**Response:**
```json
{
"success": true,
"data": {
"hero_title": "GEO Wiki Pro",
"hero_subtitle": "Technical Documentation Platform",
"featured_slugs": ["quick-start", "faq"],
"logo_url": "/media/logo.png",
"favicon_url": "/media/favicon.ico"
}
}
```
### Get Combined Metadata
```
GET /api/v1/meta
```
Returns combined data of categories, tags, and notifications.
**Response:**
```json
{
"success": true,
"data": {
"categories": [ ... ],
"tags": [ ... ],
"notice": "Important announcement text"
}
}
```
### AI Crawler Feed
```
GET /api/v1/llms.txt
```
Returns text content optimized for AI crawlers.
### Sitemap
```
GET /api/v1/geo/sitemap.xml
```
Returns XML format sitemap.
### Submit Feedback
```
POST /api/v1/feedback
```
**Request Body:**
```json
{
"slug": "can-bus-protocol",
"content": "Great documentation!",
"rating": 5
}
```
**Response:**
```json
{
"success": true,
"data": {
"id": "fb_123456"
}
}
```
---
## Authentication Endpoints
### User Login
```
POST /api/v1/auth/login
```
**Request Body:**
```json
{
"username": "admin",
"password": "your-password"
}
```
**Response:**
```json
{
"success": true,
"data": {
"user": {
"username": "admin",
"role": "admin"
},
"mustChangePassword": false
}
}
```
::: warning
On first login, `mustChangePassword` is `true`, and you must call the change password endpoint before accessing admin functions.
:::
### User Logout
```
POST /api/v1/auth/logout
```
### Get Current User Info
```
GET /api/v1/auth/me
```
**Response:**
```json
{
"success": true,
"data": {
"username": "admin",
"role": "admin",
"passwordChanged": true
}
}
```
### Change Password
```
POST /api/v1/auth/change-password
```
**Request Body:**
```json
{
"oldPassword": "current-password",
"newPassword": "new-password"
}
```
### Register New User
```
POST /api/v1/auth/register
```
::: warning
This endpoint is only available to administrators.
:::
**Request Body:**
```json
{
"username": "newuser",
"password": "user-password",
"role": "editor"
}
```
---
## Admin Endpoints
All admin endpoints require JWT authentication and admin/editor role.
### Document Management
#### Create Document
```
POST /api/v1/admin/docs
```
**Request Body:**
```json
{
"slug": "my-new-doc",
"title": "My New Document",
"category": "support",
"tags": ["guide", "tutorial"],
"author": "admin",
"sort": 5,
"description": "A helpful guide",
"content": "# My New Document\n\nContent here...",
"lang": "en"
}
```
::: tip
If slug is not provided, the system automatically generates it from the title. Slug uniqueness is checked during creation.
:::
#### Update Document
```
PUT /api/v1/admin/docs/:slug
```
Updating a document automatically syncs shared fields (category, tags, author, sort) to other language versions.
#### Delete Document
```
DELETE /api/v1/admin/docs/:slug
```
#### Document Reorder
```
PUT /api/v1/admin/docs/reorder
```
**Request Body:**
```json
{
"slugs": ["doc-1", "doc-2", "doc-3"],
"category": "can-motion",
"lang": "zh"
}
```
::: note
This endpoint must be defined before `PUT /api/v1/admin/docs/:slug`, otherwise Express will match `reorder` as a slug parameter.
:::
### Category Management
#### Get Category List
```
GET /api/v1/admin/categories
```
#### Create Category
```
POST /api/v1/admin/categories
```
**Request Body:**
```json
{
"slug": "new-category",
"name": "新分类",
"name_en": "New Category",
"description": "Category description"
}
```
#### Update Category
```
PUT /api/v1/admin/categories/:slug
```
#### Delete Category
```
DELETE /api/v1/admin/categories/:slug
```
### Tag Management
#### Get Tag List
```
GET /api/v1/admin/tags
```
#### Create Tag
```
POST /api/v1/admin/tags
```
**Request Body:**
```json
{
"slug": "new-tag",
"name": "新标签",
"name_en": "New Tag"
}
```
#### Delete Tag
```
DELETE /api/v1/admin/tags/:slug
```
### Feedback Management
#### Get Feedback List
```
GET /api/v1/admin/feedback
```
#### Delete Feedback
```
DELETE /api/v1/admin/feedback/:id
```
### Media Management
#### Get Media List
```
GET /api/v1/admin/media
```
#### Delete Media File
```
DELETE /api/v1/admin/media/:filename
```
### Upload File
```
POST /api/v1/media/upload
```
**Request:** `multipart/form-data`
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `file` | file | Yes | File to upload |
::: warning
File uploads are checked for real type via magic bytes. Filenames are encoded with `encodeURIComponent`.
:::
**Example:**
```bash
curl -X POST "https://geowiki.pro/api/v1/media/upload" \
-H "Cookie: jwt=your-token" \
-F "[email protected]"
```
### Site Configuration Management
#### Get Full Configuration
```
GET /api/v1/admin/config
```
#### Update Configuration
```
PUT /api/v1/admin/config
```
**Request Body:**
```json
{
"hero_title": "My Wiki",
"hero_subtitle": "Technical Documentation",
"featured_slugs": ["quick-start", "faq"],
"logo_url": "/media/logo.png",
"favicon_url": "/media/favicon.ico",
"customHeadHtml": "<meta name=\"theme-color\" content=\"#3b82f6\">"
}
```
::: note
The `customHeadHtml` field automatically filters `<script>`, `<iframe>`, and `on*` event attributes to prevent XSS attacks.
:::
### Draft Management
#### Publish Draft
```
POST /api/v1/admin/drafts/:slug/publish
```
#### Reject Draft
```
DELETE /api/v1/admin/drafts/:slug
```
### User Management
#### Get User List
```
GET /api/v1/admin/users
```
#### Create User
```
POST /api/v1/admin/users
```
#### Delete User
```
DELETE /api/v1/admin/users/:username
```
### Statistics
```
GET /api/v1/admin/stats
```
Returns dashboard data including document counts, category statistics, tag usage, etc.
### Guestbook Management
#### Get Guestbook List
```
GET /api/v1/admin/guestbook
```
#### Create Guestbook Entry
```
POST /api/v1/admin/guestbook
```
#### Update Guestbook Entry
```
PUT /api/v1/admin/guestbook/:id
```
#### Delete Guestbook Entry
```
DELETE /api/v1/admin/guestbook/:id
```
### GEO Analytics
#### Get GEO Overview
```
GET /api/v1/admin/geo/overview
```
#### Rebuild GEO Files
```
POST /api/v1/admin/geo/rebuild
```
Triggers regeneration of `llms.txt` and `sitemap.xml`.
---
## HTTP Status Codes
| HTTP Status Code | Description |
|-----------------|-------------|
| 200 | Success |
| 201 | Created successfully |
| 400 | Invalid request parameters |
| 401 | Unauthenticated or token expired |
| 403 | No permission |
| 404 | Resource not found |
| 409 | Resource conflict (e.g., duplicate slug) |
| 429 | Too many requests (rate limited) |
| 500 | Internal server error |
---
## Security Mechanisms
| Mechanism | Description |
|-----------|-------------|
| JWT Authentication | httpOnly cookie, 2-hour expiration |
| CSRF Protection | Double-submit cookie HMAC verification |
| Rate Limiting | Global 300 requests/minute, auth endpoints 10 requests/minute |
| CSP | Helmet nonce-based Content Security Policy |
| File Upload | Magic bytes type detection |
| Slug Validation | Regex matching + length limits + deduplication checks |
---
*Last updated: 2026-06-06 | Version: v3.0.2*