API Reference
Complete REST API reference for ObjectStack — all endpoints, request/response schemas, and service availability.
API Reference
ObjectStack exposes a fully typed REST API. All endpoints use JSON request/response bodies. The API is service-driven — routes are only available when the corresponding plugin is installed. Use the Discovery endpoint to determine what services are available at runtime.
Base URL: Configurable, defaults to /api/v1. All paths below are relative to the base URL.
Discovery
The discovery endpoint is the entry point for all clients. It returns the API version, available routes, service capabilities, and per-service status.
GET /api/v1
Returns the full discovery manifest.
Response:
{
"name": "ObjectOS",
"version": "1.0.0",
"environment": "development",
"routes": {
"data": "/api/v1/data",
"metadata": "/api/v1/meta",
"analytics": "/api/v1/analytics",
"auth": null,
"workflow": null
},
"features": {
"graphql": false,
"search": false,
"websockets": false,
"files": false,
"analytics": true,
"ai": false,
"workflow": false,
"notifications": false,
"i18n": false
},
"services": {
"metadata": {
"enabled": true,
"status": "degraded",
"route": "/api/v1/meta",
"provider": "kernel",
"message": "In-memory registry; DB persistence pending"
},
"data": { "enabled": true, "status": "available", "route": "/api/v1/data", "provider": "kernel" },
"analytics": { "enabled": true, "status": "available", "route": "/api/v1/analytics" },
"auth": { "enabled": false, "status": "unavailable", "message": "Install an auth plugin to enable" }
},
"locale": {
"default": "en",
"supported": ["en", "zh-CN"],
"timezone": "UTC"
}
}GET /.well-known/objectstack
Alias for the discovery endpoint used by auto-discovery in the client SDK.
Service Status Values: available (fully operational), degraded (partial functionality), unavailable (not installed), stub (placeholder that throws errors)
Metadata
Retrieve and manage object schemas, metadata types, and UI views. Always available — provided by the kernel.
GET /meta
List all registered metadata types.
Response: { types: ["object", "view", "plugin", ...] }
GET /meta/:type
List all items of a metadata type.
| Parameter | Location | Description |
|---|---|---|
type | path | Metadata type name (e.g. object, view) |
Response: { type: "object", items: [{ name: "account", ... }, ...] }
GET /meta/:type/:name
Get a specific metadata item with optional ETag caching.
| Parameter | Location | Description |
|---|---|---|
type | path | Metadata type name |
name | path | Item name (snake_case) |
If-None-Match | header | ETag for conditional request |
Response: { type: "object", name: "account", item: { ... } }
304 if ETag matches (not modified).
PUT /meta/:type/:name
Create or update a metadata item.
Body: { type: "object", name: "account", item: { ... } }
Response: { success: true }
GET /ui/view/:object/:type
Get an auto-generated UI view for an object.
| Parameter | Location | Description |
|---|---|---|
object | path | Object name (snake_case) |
type | path | list or form |
Response: Full ViewSchema definition with columns/fields derived from the object schema.
Data Operations
CRUD operations on any object. Always available — provided by the kernel.
GET /data/:object
Query records with filtering, sorting, selection, and pagination.
| Parameter | Location | Description |
|---|---|---|
object | path | Object name |
$select | query | Comma-separated field names |
$filter | query | Filter expression (OData-style or JSON) |
$orderby | query | Sort expression (e.g. -created_at) |
$top | query | Limit (default: 20) |
$skip | query | Offset |
Response:
{
"object": "account",
"records": [{ "id": "1", "name": "Acme Corp", ... }],
"total": 42,
"hasMore": true
}GET /data/:object/:id
Get a single record by ID.
Response: { object: "account", id: "1", record: { ... } }
POST /data/:object
Create a new record.
Body: { name: "Acme Corp", industry: "Technology" }
Response: { object: "account", id: "1", record: { ... } }
PATCH /data/:object/:id
Update an existing record (partial update).
Body: { industry: "Healthcare" }
Response: { object: "account", id: "1", record: { ... } }
DELETE /data/:object/:id
Delete a record.
Response: { object: "account", id: "1", success: true }
Batch Operations
Efficient bulk operations. Always available.
POST /data/:object/batch
Execute a batch operation (create / update / upsert / delete) on multiple records.
Body:
{
"operation": "update",
"records": [
{ "id": "1", "data": { "status": "active" } },
{ "id": "2", "data": { "status": "active" } }
],
"options": {
"atomic": true,
"returnRecords": true,
"continueOnError": false,
"validateOnly": false
}
}Response: BatchUpdateResponse with succeeded, failed, errors, and optionally records.
POST /data/:object/createMany
Batch create multiple records.
Body: { records: [{ name: "A" }, { name: "B" }] }
Response: { object: "account", records: [...], count: 2 }
POST /data/:object/updateMany
Batch update multiple records.
Body:
{
"records": [
{ "id": "1", "data": { "status": "active" } },
{ "id": "2", "data": { "status": "closed" } }
],
"options": { "atomic": false }
}POST /data/:object/deleteMany
Batch delete records by ID list.
Body: { ids: ["1", "2", "3"] }
Analytics
Semantic BI queries using a cube-style API. Available when the analytics service is enabled.
POST /analytics/query
Execute an analytics query.
Body:
{
"cube": "account",
"measures": ["revenue.sum", "count"],
"dimensions": ["industry"],
"filters": [{ "member": "status", "operator": "equals", "values": ["active"] }],
"limit": 100
}Response:
{
"data": [
{ "industry": "Technology", "revenue.sum": 150000, "count": 5 },
{ "industry": "Healthcare", "revenue.sum": 80000, "count": 3 }
],
"annotation": {
"measures": { "revenue.sum": { "title": "Revenue Sum", "type": "number" } },
"dimensions": { "industry": { "title": "Industry", "type": "string" } }
}
}GET /analytics/meta
Get auto-generated cube metadata for all objects.
Response: Array of cube definitions with measures, dimensions, and time dimensions.
POST /analytics/sql
Execute a raw SQL analytics query (if supported by driver).
Package Management
Manage installed plugins/packages.
GET /packages
List installed packages.
POST /packages
Install a package from manifest.
Body: { manifest: { name: "plugin-auth", version: "1.0.0", ... } }
GET /packages/:id
Get package details.
DELETE /packages/:id
Uninstall a package.
PATCH /packages/:id/enable
Enable a disabled package.
PATCH /packages/:id/disable
Disable a package without uninstalling.
Authentication (Plugin Required)
These endpoints are only available when an auth plugin is installed. Check discovery.services.auth.enabled first.
POST /auth/login
Authenticate and receive a session token.
Body: { username: "admin", password: "secret" }
Response: { token: "jwt...", expiresAt: "...", user: { ... } }
Plugin-Provided Service Endpoints
The following endpoints become available when the corresponding plugin is installed and registered with the kernel. Use the discovery services map to check availability.
Workflow (/workflow) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| GET | /workflow/:object/config | Get workflow configuration |
| GET | /workflow/:object/:recordId/state | Get record's workflow state |
| POST | /workflow/:object/:recordId/transition | Execute state transition |
| POST | /workflow/:object/:recordId/approve | Approve workflow step |
| POST | /workflow/:object/:recordId/reject | Reject workflow step |
Automation (/automation) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| POST | /automation/trigger | Trigger an automation flow |
Views (/ui) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| GET | /ui/views?object=:object | List views for an object |
| GET | /ui/views/:viewId | Get a view definition |
| POST | /ui/views | Create a new view |
| PATCH | /ui/views/:viewId | Update a view |
| DELETE | /ui/views/:viewId | Delete a view |
Realtime (/realtime) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| POST | /realtime/connect | Establish WebSocket/SSE connection |
| POST | /realtime/disconnect | Close connection |
| POST | /realtime/subscribe | Subscribe to channel |
| POST | /realtime/unsubscribe | Unsubscribe |
| POST | /realtime/presence | Set presence |
| GET | /realtime/presence/:channel | Get channel presence |
Notifications (/notifications) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| GET | /notifications | List notifications |
| POST | /notifications/read | Mark as read |
| POST | /notifications/read-all | Mark all as read |
| POST | /notifications/devices | Register device |
| DELETE | /notifications/devices/:id | Unregister device |
| GET | /notifications/preferences | Get preferences |
| PATCH | /notifications/preferences | Update preferences |
AI (/ai) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| POST | /ai/nlq | Natural language → query |
| POST | /ai/chat | AI chat conversation |
| POST | /ai/suggest | Get value suggestions |
| POST | /ai/insights | Get data insights |
i18n (/i18n) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| GET | /i18n/locales | List available locales |
| GET | /i18n/translations?locale=:locale | Get translation bundle |
| GET | /i18n/labels/:object?locale=:locale | Get field labels |
GraphQL (/graphql) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| POST | /graphql | Execute GraphQL query/mutation |
File Storage (/storage) — Plugin Required
| Method | Endpoint | Description |
|---|---|---|
| POST | /storage/upload | Upload a file |
| GET | /storage/:id | Download a file |
| DELETE | /storage/:id | Delete a file |
Error Handling
All error responses follow a standardized format:
{
"error": {
"code": "resource_not_found",
"message": "Record not found: account/123",
"httpStatus": 404,
"category": "request",
"retryable": false,
"details": {}
}
}Error Codes
| Code | HTTP | Category | Retryable | Description |
|---|---|---|---|---|
validation_error | 400 | validation | No | Input validation failed |
invalid_query | 400 | validation | No | Malformed query |
unauthenticated | 401 | auth | No | Authentication required |
permission_denied | 403 | auth | No | Insufficient permissions |
resource_not_found | 404 | request | No | Resource does not exist |
conflict | 409 | request | No | Resource conflict (e.g. duplicate) |
rate_limit_exceeded | 429 | rate_limit | Yes | Too many requests |
internal_error | 500 | server | Yes | Server error |
service_unavailable | 503 | server | Yes | Service temporarily unavailable |
Protocol Types (Zod)
All request/response schemas are defined as Zod schemas in @objectstack/spec/api and can be used for both runtime validation and TypeScript type inference.
import {
FindDataRequestSchema,
FindDataResponseSchema,
type FindDataRequest,
type FindDataResponse,
} from '@objectstack/spec/api';
// Runtime validation
const request = FindDataRequestSchema.parse({ object: 'account', query: { ... } });
// TypeScript type
const response: FindDataResponse = await protocol.findData(request);See the Protocol Reference for the complete list of 57 protocol methods and their Zod schemas.