API Documentation
Every REST endpoint exposed by the playground — use Testver to test the API. Try requests live in the embedded Swagger UI below.
1 · Use it in Testver
One-click import:
- Click ⬇ Download spec above
- In Testver:
Import → OpenAPIthe downloaded file - All endpoints land in a new collection ready to send
2 · Use it in code
No SDK needed — plain HTTP works:
// Node / fetch const r = await fetch( 'http://testplay.testver.com/api/products'); const data = await r.json();
3 · Reset state between tests
Always start fresh:
curl -X POST \
http://testplay.testver.com/api/reset \
-H "Content-Type: application/json" \
-d '{"size":"medium"}'
Quick reference
Base URL:http://testplay.testver.com · click any row to see request/response details
| Method | Endpoint | Description | Tag | |||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| GET | /api/health |
Health check | Health & State | |||||||||||||||||||||||||||||
|
Response (200)
{
"ok": true,
"time": "2025-01-01T00:00:00.000Z"
}
Try with curl
curl -X GET 'http://testplay.testver.com/api/health' |
||||||||||||||||||||||||||||||||
| POST | /api/reset |
Reset & reseed (small/medium/large) | Health & State | |||||||||||||||||||||||||||||
|
Request body (application/json)
{
"size": "medium"
}
Response (200)
{
"ok": true,
"message": "State reset",
"size": "medium"
}
Try with curl
curl -X POST 'http://testplay.testver.com/api/reset' \
-H 'Content-Type: application/json' \
-d '{"size":"medium"}'
|
||||||||||||||||||||||||||||||||
| GET | /api/users |
List all users | Users | |||||||||||||||||||||||||||||
|
Response (200)
[
{
"id": 1,
"username": "admin",
"email": "admin@testverqa.io",
"role": "admin",
"status": "active"
}
]
Try with curl
curl -X GET 'http://testplay.testver.com/api/users' |
||||||||||||||||||||||||||||||||
| GET | /api/users/:id |
Get user by id | Users | |||||||||||||||||||||||||||||
|
Parameters
Response (200)
{
"id": 1,
"username": "admin",
"email": "admin@testverqa.io",
"role": "admin",
"status": "active"
}
Try with curl
curl -X GET 'http://testplay.testver.com/api/users/1' |
||||||||||||||||||||||||||||||||
| GET | /api/products |
List products (first 50) | Products | |||||||||||||||||||||||||||||
|
Response (200)
[
{
"id": 1,
"name": "Incredible Wooden Ball",
"sku": "SKU-00001",
"price": 1978,
"categoryName": "Clothing",
"stock": 175,
"rating": 2.2
}
]
Try with curl
curl -X GET 'http://testplay.testver.com/api/products' |
||||||||||||||||||||||||||||||||
| GET | /api/products/:id |
Get product by id | Products | |||||||||||||||||||||||||||||
|
Parameters
Response (200)
{
"id": 1,
"name": "Incredible Wooden Ball",
"sku": "SKU-00001",
"price": 1978
}
Try with curl
curl -X GET 'http://testplay.testver.com/api/products/1' |
||||||||||||||||||||||||||||||||
| GET | /api/orders |
List orders (first 50) | Orders | |||||||||||||||||||||||||||||
|
Response (200)
[
{
"id": 1,
"orderNumber": "ORD-000001",
"userName": "Alice Johnson",
"total": 234.56,
"status": "shipped"
}
]
Try with curl
curl -X GET 'http://testplay.testver.com/api/orders' |
||||||||||||||||||||||||||||||||
| GET | /api/categories |
List product categories | Categories | |||||||||||||||||||||||||||||
|
Response (200)
[
{
"id": 1,
"name": "Electronics",
"parentId": null,
"icon": "laptop"
}
]
Try with curl
curl -X GET 'http://testplay.testver.com/api/categories' |
||||||||||||||||||||||||||||||||
| GET | /api/notifications |
List notifications | Notifications | |||||||||||||||||||||||||||||
|
Response (200)
[
{
"id": 1,
"type": "success",
"title": "Order placed",
"message": "Your order has shipped.",
"read": false
}
]
Try with curl
curl -X GET 'http://testplay.testver.com/api/notifications' |
||||||||||||||||||||||||||||||||
| GET | /ajax/get |
Plain GET | AJAX | |||||||||||||||||||||||||||||
|
Response (200)
{
"method": "GET",
"when": "2025-01-01T00:00:00.000Z",
"random": 742
}
Try with curl
curl -X GET 'http://testplay.testver.com/ajax/get' |
||||||||||||||||||||||||||||||||
| POST | /ajax/post |
POST that echoes the body | AJAX | |||||||||||||||||||||||||||||
|
Request body (application/json)
Any JSON object — it is echoed back inside {
"from": "my-test",
"anything": 42
}
Response (200)
{
"method": "POST",
"received": {
"from": "my-test",
"anything": 42
}
}
Try with curl
curl -X POST 'http://testplay.testver.com/ajax/post' \
-H 'Content-Type: application/json' \
-d '{"from":"my-test","anything":42}'
|
||||||||||||||||||||||||||||||||
| PUT | /ajax/put |
PUT that echoes the body | AJAX | |||||||||||||||||||||||||||||
|
Request body (application/json)
Any JSON object — echoed back inside {
"update": "value"
}
Response (200)
{
"method": "PUT",
"received": {
"update": "value"
}
}
Try with curl
curl -X PUT 'http://testplay.testver.com/ajax/put' \
-H 'Content-Type: application/json' \
-d '{"update":"value"}'
|
||||||||||||||||||||||||||||||||
| DELETE | /ajax/delete |
DELETE | AJAX | |||||||||||||||||||||||||||||
|
Response (200)
{
"method": "DELETE",
"when": "2025-01-01T00:00:00.000Z"
}
Try with curl
curl -X DELETE 'http://testplay.testver.com/ajax/delete' |
||||||||||||||||||||||||||||||||
| GET | /ajax/slow |
4-second delayed response | AJAX | |||||||||||||||||||||||||||||
|
Response (200)
{
"ok": true,
"after": "4 seconds"
}
Try with curl
curl -X GET 'http://testplay.testver.com/ajax/slow' |
||||||||||||||||||||||||||||||||
| GET | /ajax/fail/:code |
Forced HTTP error (400/401/404/500/503) | AJAX | |||||||||||||||||||||||||||||
|
Parameters
Response (200)
{
"error": "Forced HTTP 500"
}
Try with curl
curl -X GET 'http://testplay.testver.com/ajax/fail/1' |
||||||||||||||||||||||||||||||||
| GET | /ajax/sse |
Server-Sent Events stream | AJAX | |||||||||||||||||||||||||||||
|
Response (200)
text/event-stream — emits Try with curl
curl -X GET 'http://testplay.testver.com/ajax/sse' |
||||||||||||||||||||||||||||||||
| GET | /tables/data |
Server-side paginated data | Tables | |||||||||||||||||||||||||||||
|
Parameters
Response (200)
{
"rows": [],
"total": 500,
"page": 1,
"limit": 10,
"totalPages": 50,
"categories": [
"Books",
"Clothing",
"Electronics"
]
}
Try with curl
curl -X GET 'http://testplay.testver.com/tables/data' |
||||||||||||||||||||||||||||||||
| PUT | /tables/data/:id |
Update product row | Tables | |||||||||||||||||||||||||||||
|
Parameters
Request body (application/json)
Any subset of product fields — they are merged into the existing row. {
"name": "Updated name",
"price": 99.99,
"stock": 50
}
Response (200)
{
"ok": true,
"product": {
"id": 1,
"name": "Updated name",
"price": 99.99,
"stock": 50
}
}
Try with curl
curl -X PUT 'http://testplay.testver.com/tables/data/1' \
-H 'Content-Type: application/json' \
-d '{"name":"Updated name","price":99.99,"stock":50}'
|
||||||||||||||||||||||||||||||||
| DELETE | /tables/data/:id |
Delete product row | Tables | |||||||||||||||||||||||||||||
|
Parameters
Response (200)
{
"ok": true
}
Try with curl
curl -X DELETE 'http://testplay.testver.com/tables/data/1' |
||||||||||||||||||||||||||||||||
| GET | /forms/cascade |
Cascading dropdown data | Forms | |||||||||||||||||||||||||||||
|
Parameters
Response (200)
[ "Karnataka", "Maharashtra", "Delhi" ] Try with curl
curl -X GET 'http://testplay.testver.com/forms/cascade' |
||||||||||||||||||||||||||||||||
| POST | /files/upload |
Upload file(s) — multipart/form-data | Files | |||||||||||||||||||||||||||||
|
Request body
multipart/form-data with one or more files in the Response (200)
{
"ok": true,
"uploaded": [
{
"id": 1,
"originalName": "photo.jpg",
"size": 12345,
"mime": "image/jpeg",
"path": "/uploads/abc123",
"uploadedAt": "2025-01-01T00:00:00.000Z"
}
]
}
Try with curl
curl -X POST 'http://testplay.testver.com/files/upload' |
||||||||||||||||||||||||||||||||
| DELETE | /files/upload/:id |
Delete an uploaded file | Files | |||||||||||||||||||||||||||||
|
Parameters
Response (200)
{
"ok": true
}
Try with curl
curl -X DELETE 'http://testplay.testver.com/files/upload/1' |
||||||||||||||||||||||||||||||||
| GET | /files/download/:type |
Download sample csv / json / txt / html | Files | |||||||||||||||||||||||||||||
|
Parameters
Response (200)
Binary file with Try with curl
curl -X GET 'http://testplay.testver.com/files/download/1' |
||||||||||||||||||||||||||||||||
| POST | /shop/cart/add |
Add item to cart | Shop | |||||||||||||||||||||||||||||
|
Request body (application/json)
{
"productId": 1,
"quantity": 2
}
Response (200)
{
"ok": true,
"cart": {
"subtotal": 3956,
"discount": 0,
"shipping": 9.99,
"tax": 316.48,
"total": 4282.47,
"count": 2
}
}
Try with curl
curl -X POST 'http://testplay.testver.com/shop/cart/add' \
-H 'Content-Type: application/json' \
-d '{"productId":1,"quantity":2}'
|
||||||||||||||||||||||||||||||||
| POST | /shop/cart/update |
Update item quantity | Shop | |||||||||||||||||||||||||||||
|
Request body (application/json)
Both fields required. {
"productId": 1,
"quantity": 5
}
Response (200)
{
"ok": true,
"cart": {
"subtotal": 9890,
"discount": 0,
"shipping": 9.99,
"tax": 791.2,
"total": 10691.19,
"count": 5
}
}
Try with curl
curl -X POST 'http://testplay.testver.com/shop/cart/update' \
-H 'Content-Type: application/json' \
-d '{"productId":1,"quantity":5}'
|
||||||||||||||||||||||||||||||||
| POST | /shop/cart/remove |
Remove item from cart | Shop | |||||||||||||||||||||||||||||
|
Request body (application/json)
{
"productId": 1
}
Response (200)
{
"ok": true,
"cart": {
"subtotal": 0,
"discount": 0,
"shipping": 0,
"tax": 0,
"total": 0,
"count": 0
}
}
Try with curl
curl -X POST 'http://testplay.testver.com/shop/cart/remove' \
-H 'Content-Type: application/json' \
-d '{"productId":1}'
|
||||||||||||||||||||||||||||||||
| POST | /shop/cart/coupon |
Apply coupon (SAVE10, WELCOME20, EXPIRED, MAXEDOUT) | Shop | |||||||||||||||||||||||||||||
|
Request body (application/json)
Try {
"code": "SAVE10"
}
Response (200)
{
"ok": true,
"code": "SAVE10",
"discountPct": 10,
"cart": {
"subtotal": 100,
"discount": 10,
"total": 100
}
}
Try with curl
curl -X POST 'http://testplay.testver.com/shop/cart/coupon' \
-H 'Content-Type: application/json' \
-d '{"code":"SAVE10"}'
|
||||||||||||||||||||||||||||||||