REST API examples for nextmin-node
This page demonstrates how to call the REST API exposed by nextmin-node.
Assumptions:
- Base URL: http://localhost:8081/rest
- All requests must include the x-api-key header (value from your DB → Settings.apiKey)
- Authenticated routes also require Authorization: Bearer YOUR_JWT
Headers
- x-api-key: your_api_key_here
- Content-Type: application/json for JSON bodies
- Authorization: Bearer YOUR_JWT for authenticated endpoints
Example header block used below:
x-api-key: YOUR_API_KEY
Authorization: Bearer YOUR_JWT
Content-Type: application/json
Tip: You can obtain the API key by starting the server once, then reading the Settings collection/table → apiKey field.
Schemas
List public schema definitions the server is using:
curl -H "x-api-key: $API_KEY" \
http://localhost:8081/rest/_schemas
Response shape (example):
{
"success": true,
"data": [
{ "modelName": "Users", "attributes": { "email": { "type": "String" } } },
{ "modelName": "Posts", "attributes": { "title": { "type": "String" } } }
]
}
Auth endpoints
Base path: /auth/users
Register
curl -X POST http://localhost:8081/rest/auth/users/register \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"username": "alice",
"password": "supersecret123"
}'
Response:
{
"success": true,
"message": "Registration successful.",
"data": { "token": "<JWT>", "user": { "id": "...", "email": "alice@example.com", "username": "alice", "status": "active" } }
}
Login (email or username)
curl -X POST http://localhost:8081/rest/auth/users/login \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "alice@example.com",
"password": "supersecret123"
}'
Success returns { token, user }
. The token expires in 7 days.
Current user (me)
curl http://localhost:8081/rest/auth/users/me \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT"
Change password
curl -X POST http://localhost:8081/rest/auth/users/change-password \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{ "oldPassword": "supersecret123", "newPassword": "newsecret456" }'
Forgot password
curl -X POST http://localhost:8081/rest/auth/users/forgot-password \
-H "x-api-key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{ "email": "alice@example.com" }'
Returns a generic success message without revealing user existence.
Generic CRUD per model
Model base path: /:model (lowercase). The routes are auto-generated from your JSON schemas and policy‑enforced.
Common responses include { success, message, data, pagination? }
.
Create (POST /:model)
curl -X POST http://localhost:8081/rest/posts \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{ "title": "Hello", "content": "World" }'
- Validates required fields and unique constraints.
- For users model, password is automatically hashed on create.
List (GET /:model)
Query parameters supported by the list endpoint:
- page: number (default 0)
- limit: number (default 10)
- Search helpers:
- q: the search term/value
- searchKey: field name to search in (single)
- searchKeys: CSV of fields to search in (multi)
- searchMode: and|or (defaults to or)
- Date range:
- dateFrom: ISO or parseable date
- dateTo: ISO or parseable date
- dateKey: which date field to use (defaults to createdAt, then updatedAt)
- Sorting (multi-field):
- sort: CSV of field names, e.g. name,createdAt
- sortType: CSV of directions (asc|desc), matched by position
Example:
curl "http://localhost:8081/rest/posts?limit=20&page=0&sort=createdAt&sortType=desc&q=hello&searchKeys=title,content" \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT"
Response:
{
"success": true,
"message": "Data fetched for Posts",
"data": [ { "id": "...", "title": "Hello" } ],
"pagination": { "totalRows": 1, "page": 0, "limit": 20 },
"sort": { "createdAt": -1 }
}
Field‑specific filters are also supported by passing query params matching attribute types. Examples:
- String: name=Alice (regex, case‑insensitive)
- Number: age=30 (or CSV for $in)
- Boolean: active=true
- ObjectId/ref: user=6523… or user=ID1,ID2
- Date: createdAt=2024-12-31
Read one (GET /:model/:id)
curl http://localhost:8081/rest/posts/ID123 \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT"
Update (PATCH /:model/:id)
curl -X PATCH http://localhost:8081/rest/posts/ID123 \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-d '{ "title": "Updated" }'
- Only validates required fields if you send the field with an empty value (so omitted fields remain unchanged).
Delete (DELETE /:model/:id)
curl -X DELETE http://localhost:8081/rest/posts/ID123 \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT"
Relationship queries
These help you load referenced documents without relying on autopopulate.
Forward: items referenced by a container document
GET /find/:container/:refField/:id
- container: model holding the reference field
- refField: the field on container that references the target model
- id: the container record id
curl "http://localhost:8081/rest/find/orders/items/ORDER_ID?limit=50&page=1&fields=name,price&sort=-createdAt" \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT"
Supports query params:
- limit (max 100), page (1‑based), fields (CSV projection), sort (e.g., -createdAt,+name)
Reverse: items that point to a given id
GET /find/reverse/:target/:byField/:id
- target: the target model to read
- byField: the reference field on target that points to another model
- id: the id to match (contained within byField or equal to it)
curl "http://localhost:8081/rest/find/reverse/items/order/ORDER_ID?limit=20&page=1&fields=name,price&sort=-createdAt" \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT"
Files (if file storage adapter is configured)
Upload files (multipart)
POST /files
curl -X POST http://localhost:8081/rest/files \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT" \
-F "file=@/path/to/photo.jpg" \
-F "file=@/path/to/another.png"
Response includes provider, bucket, key, url, contentType, size, etc.
Delete a file by key
DELETE /files/:key(*)
curl -X DELETE "http://localhost:8081/rest/files/uploads/2025/09/23/abcd1234.jpg" \
-H "x-api-key: $API_KEY" \
-H "Authorization: Bearer $JWT"
JavaScript fetch examples
const BASE = 'http://localhost:8081/rest';
const API_KEY = process.env.NEXT_PUBLIC_NEXTMIN_API_KEY!; // or NEXTMIN_API_KEY server-side
async function login(email: string, password: string) {
const res = await fetch(`${BASE}/auth/users/login`, {
method: 'POST',
headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password })
});
const json = await res.json();
if (!res.ok) throw new Error(json?.message || 'Login failed');
return json.data.token as string;
}
async function listPosts(jwt: string) {
const res = await fetch(`${BASE}/posts?limit=20&page=0&sort=createdAt&sortType=desc`, {
headers: { 'x-api-key': API_KEY, Authorization: `Bearer ${jwt}` },
});
const json = await res.json();
if (!res.ok) throw new Error(json?.message || 'Fetch failed');
return json.data;
}
Notes on authorization and policies
- Every request must pass a valid x-api-key or it returns 401.
- Most routes also enforce JWT auth; auth-free reads depend on your schema access config.
- Read responses are masked according to your schema’s readMask/sensitiveMask and the requester’s role.
- Create/Update/Delete are restricted by role/owner rules declared in your JSON schema (access section).
Default admin credentials (after setup)
After first setup you may sign in with:
- Email: super@example.com
- Username: superadmin
- Password: supersecurepassword
Change the password immediately after first login.
Error handling
- 400: Validation or bad request (e.g., missing required fields, duplicates)
- 401: Missing/invalid API key or JWT
- 403: Forbidden by policy
- 404: Not found
- 405: Method not allowed for that model
- 410: Model removed (hot‑reloaded schema)