A Deno-powered backend service for Plants vs. Zombies: MODDED. [Read-only GitHub mirror] docs.pvzm.net
express typescript expressjs plant deno jspvz pvzm game online backend plants-vs-zombies zombie javascript plants modded vs plantsvszombies openapi pvz noads
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

move api docs to gitbook

Clay 42ef2859 2d677f38

+1 -232
+1 -232
README.md
··· 55 55 56 56 ## API Documentation 57 57 58 - ### Base URL 59 - 60 - All API endpoints are prefixed with `/api`. 61 - 62 - ### MessagePack 63 - 64 - The server automatically supports MessagePack encoding/decoding via middleware. 65 - 66 - - To receive MessagePack responses, set `Accept: application/msgpack`. 67 - - To send MessagePack requests, set `Content-Type: application.msgpack`. 68 - 69 - ### Authentication 70 - 71 - Public API endpoints do not require authentication, but some behavior is based on client IP address (e.g. favorites). 72 - Admin endpoints under `/api/admin/*` are protected when `USE_GITHUB_AUTH=true` (GitHub OAuth session). When GitHub auth is enabled, `PUT` and `DELETE` on `/api/admin/levels/:id` can alternatively be authorized via a one-time token using `?token=...`. 73 - 74 - ### Endpoints 75 - 76 - #### Level Management 77 - 78 - ##### Create a Level 79 - 80 - - **URL:** `/api/levels` 81 - - **Method:** `POST` 82 - - **Content Types:** 83 - - `application/octet-stream` 84 - - **URL Params:** None 85 - - **Query Params:** (for octet-stream) 86 - - `author`: Author name 87 - - `turnstileResponse`: Captcha verification token (if enabled) 88 - - **Notes:** Only IZL3 is supported (v2 is deprecated). 89 - - **Request Body:** Raw binary level data (`.izl3`), sent as the request body. 90 - - **Success Response:** 91 - - **Code:** 201 92 - - **Content:** 93 - 94 - ```json 95 - { 96 - "id": 123, 97 - "name": "Level Name", 98 - "author": "Author Name", 99 - "created_at": 1714680000, 100 - "sun": 100, 101 - "is_water": true, 102 - "version": 3 103 - } 104 - ``` 105 - 106 - Note: `is_water` is stored as `0/1` in the database and is returned as `0/1` in list/detail endpoints. 107 - 108 - - **Error Responses:** 109 - - **Code:** 400 110 - - **Content:** `{ "error": "Missing required fields" }` 111 - - **Code:** 400 112 - - **Content:** `{ "error": "Content contains inappropriate language or content" }` 113 - - **Code:** 400 114 - - **Content:** `{ "error": "Captcha verification required" }` 115 - - **Code:** 400 116 - - **Content:** `{ "error": "Invalid captcha" }` 117 - - **Code:** 500 118 - - **Content:** `{ "error": "Failed to upload level" }` 119 - 120 - ##### List Levels 121 - 122 - - **URL:** `/api/levels` 123 - - **Method:** `GET` 124 - - **URL Params:** None 125 - - **Query Params:** 126 - - `page`: Page number (default: 1) 127 - - `limit`: Results per page (default: 10) 128 - - `author`: Filter by author name (partial match) 129 - - `is_water`: Filter by water levels ("true"/"false") 130 - - `version`: Filter by level version (currently always `3`; reserved for future versions) 131 - - `sort`: Sorting mode. Default is by play count (`plays`). Use `recent` to sort by creation time (`created_at`) and `favorites` to sort by favorite count. 132 - - `reversed_order`: Reverse the sort order (`true` or `1`). By default, sorting is descending. 133 - - `token`: One-time token. If provided and valid, the response is filtered to the single level associated with that token (and pagination becomes `page=1`, `limit=1`). If the token is invalid, the endpoint returns `401`. 134 - - **Success Response:** 135 - - **Code:** 200 136 - - **Content:** 137 - 138 - ```json 139 - { 140 - "levels": [ 141 - { 142 - "id": 123, 143 - "name": "Level Name", 144 - "author": "Author Name", 145 - "created_at": 1714680000, 146 - "sun": 100, 147 - "is_water": 1, 148 - "favorites": 5, 149 - "plays": 10, 150 - "difficulty": 7, 151 - "thumbnail": [[0, 10, 10, 40, 40, 1]], 152 - "version": 3 153 - } 154 - ], 155 - "pagination": { 156 - "total": 50, 157 - "page": 1, 158 - "limit": 10, 159 - "pages": 5 160 - } 161 - } 162 - ``` 163 - 164 - - **Error Response:** 165 - - **Code:** 401 166 - - **Content:** `{ "error": "Invalid token" }` 167 - - **Code:** 500 168 - - **Content:** `{ "error": "Failed to list levels" }` 169 - 170 - ##### Get Level Details 171 - 172 - - **URL:** `/api/levels/:id` 173 - - **Method:** `GET` 174 - - **URL Params:** 175 - - `id`: Level ID 176 - - **Success Response:** 177 - - **Code:** 200 178 - - **Content:** 179 - 180 - ```json 181 - { 182 - "id": 123, 183 - "name": "Level Name", 184 - "author": "Author Name", 185 - "created_at": 1714680000, 186 - "sun": 100, 187 - "is_water": 1, 188 - "favorites": 5, 189 - "plays": 10, 190 - "difficulty": 7, 191 - "thumbnail": null, 192 - "version": 3 193 - } 194 - ``` 195 - 196 - - **Error Responses:** 197 - - **Code:** 400 198 - - **Content:** `{ "error": "Invalid level ID" }` 199 - - **Code:** 404 200 - - **Content:** `{ "error": "Level not found" }` 201 - - **Code:** 500 202 - - **Content:** `{ "error": "Failed to get level" }` 203 - 204 - ##### Download Level 205 - 206 - - **URL:** `/api/levels/:id/download` 207 - - **Method:** `GET` 208 - - **URL Params:** 209 - - `id`: Level ID 210 - - **Success Response:** 211 - - **Code:** 200 212 - - **Content:** Binary file download with `.izl3` extension 213 - - **Error Responses:** 214 - - **Code:** 400 215 - - **Content:** `{ "error": "Invalid level ID" }` 216 - - **Code:** 404 217 - - **Content:** `{ "error": "Level not found" }` or `{ "error": "Level file not found" }` 218 - - **Code:** 500 219 - - **Content:** `{ "error": "Failed to download level" }` 220 - 221 - #### Favorites 222 - 223 - ##### Favorite a Level 224 - 225 - - **URL:** `/api/levels/:id/favorite` 226 - - **Method:** `POST` 227 - - **URL Params:** 228 - - `id`: Level ID 229 - - **Request Body:** None (this endpoint always toggles favorite on/off) 230 - - **Success Response:** 231 - - **Code:** 200 232 - - **Content:** `{ "success": true, "level": { "id": 123, "favorites": 5, ... } }` 233 - - **Error Responses:** 234 - - **Code:** 400 235 - - **Content:** `{ "error": "Invalid level ID" }` 236 - - **Code:** 404 237 - - **Content:** `{ "error": "Level not found" }` 238 - - **Code:** 500 239 - - **Content:** `{ "error": "Failed to favorite level" }` 240 - Note: Captcha verification is not required for favoriting. 241 - 242 - #### Reporting 243 - 244 - ##### Report a Level 245 - 246 - - **URL:** `/api/levels/:id/report` 247 - - **Method:** `POST` 248 - - **URL Params:** 249 - - `id`: Level ID 250 - - **Request Body:** 251 - 252 - ```json 253 - { 254 - "reason": "Brief description of the issue" 255 - } 256 - ``` 257 - 258 - - **Behavior:** 259 - - If `USE_REPORTING=false`, this endpoint returns 404. 260 - - If `DISCORD_REPORT_WEBHOOK_URL` is configured, the server sends the report to the Discord webhook (and attaches the level file if available). 261 - - If no webhook is configured, the server still accepts the report and returns success. 262 - - **Success Response:** 263 - - **Code:** 200 264 - - **Content:** `{ "success": true }` 265 - - **Error Responses:** 266 - - **Code:** 400 267 - - **Content:** `{ "error": "Invalid input" }` 268 - - **Code:** 404 269 - - **Content:** `{ "error": "Level not found" }` 270 - - **Code:** 500 271 - - **Content:** `{ "error": "Failed to report level" }` 272 - 273 - #### Configuration 274 - 275 - ##### Get Frontend Configuration 276 - 277 - - **URL:** `/api/config` 278 - - **Method:** `GET` 279 - - **Success Response:** 280 - - **Code:** 200 281 - - **Content:** 282 - 283 - ```json 284 - { 285 - "turnstileEnabled": true, 286 - "turnstileSiteKey": "0x0000000000000000000000", 287 - "moderationEnabled": true 288 - } 289 - ``` 58 + Full API documentation is available at [docs.pvzm.net/api](https://docs.pvzm.net/api). 290 59 291 60 ## Environment Variables 292 61