Getting Started
Solo Data API
Manage user-scoped private data collections for pages with Solo App storage. Records are private to each user.
Records are private to each user - users can only access their own records. Collection names must be lowercase alphanumeric with underscores (e.g., todos, notes).
Endpoints
/api/pages/:id/solo-data/:collection
List user's records in a collection
/api/pages/:id/solo-data/:collection/count
Count records (with optional groupBy)
/api/pages/:id/solo-data/:collection
Create a new record
/api/pages/:id/solo-data/:collection/:recordId
Get a single record
/api/pages/:id/solo-data/:collection/:recordId
Update a record
/api/pages/:id/solo-data/:collection/:recordId
Delete a record
GET /api/pages/:id/solo-data/:collection
List records in a collection for the authenticated user. Only returns records owned by the user. Requires solo-data:read scope.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
where | JSON string | Filter by data fields, e.g., {"completed":true} |
orderBy | string | Sort field: created_at or updated_at |
order | string | asc or desc (default) |
limit | number | Max records to return (default 50, max 100) |
offset | number | Number of records to skip for pagination |
before | number | Return records with ID less than this value (cursor pagination) |
after | number | Return records with ID greater than this value (cursor pagination) |
Example
curl -H "Authorization: Bearer vm_your_token_here" \ "https://visimade.com/api/pages/123/solo-data/todos?limit=10"
Response
{
"records": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"collection": "todos",
"data": { "title": "Buy groceries", "completed": false },
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
],
"total": 15, "limit": 10, "offset": 0, "hasMore": true
}Cursor-Based Pagination
Use before and after instead of offset for stable pagination when records may be added or removed between requests. Pass a record ID as the cursor.
# Get the 20 most recent records curl -H "Authorization: Bearer ..." \ "https://visimade.com/api/pages/123/solo-data/todos?limit=20" # Load older records (use the smallest ID from previous results) curl -H "Authorization: Bearer ..." \ "https://visimade.com/api/pages/123/solo-data/todos?limit=20&before=456" # Poll for new records since your last fetch curl -H "Authorization: Bearer ..." \ "https://visimade.com/api/pages/123/solo-data/todos?after=500&order=asc"
The response includes hasMore: true/false to indicate if more records exist beyond the current page. When using cursors, offset is ignored.
GET /api/pages/:id/solo-data/:collection/count
Count records in a collection, optionally grouped by a data field. Requires solo-data:read scope. Only counts the authenticated user's records.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
where | JSON string | Filter by data fields |
groupBy | string | Group counts by this data field name |
values | string | Comma-separated list of values to limit groupBy results |
// Simple count
curl -H "Authorization: Bearer vm_your_token_here" \
"https://visimade.com/api/pages/123/solo-data/todos/count"
// { "count": 42 }
// Grouped count
curl -H "Authorization: Bearer vm_your_token_here" \
"https://visimade.com/api/pages/123/solo-data/todos/count?groupBy=category"
// { "counts": { "work": 5, "personal": 12 } }POST /api/pages/:id/solo-data/:collection
Create a new record in a collection. Requires solo-data:write scope.
Example
curl -X POST \
-H "Authorization: Bearer vm_your_token_here" \
-H "Content-Type: application/json" \
-d '{"data": {"title": "New todo", "completed": false}}' \
https://visimade.com/api/pages/123/solo-data/todosPATCH /api/pages/:id/solo-data/:collection/:recordId
Update an existing record. Data is merged with existing values. Requires solo-data:write scope.
Example
curl -X PATCH \
-H "Authorization: Bearer vm_your_token_here" \
-H "Content-Type: application/json" \
-d '{"data": {"completed": true}}' \
https://visimade.com/api/pages/123/solo-data/todos/550e8400-e29b-41d4-a716-446655440000DELETE /api/pages/:id/solo-data/:collection/:recordId
Delete a record. Requires solo-data:write scope.
curl -X DELETE \ -H "Authorization: Bearer vm_your_token_here" \ https://visimade.com/api/pages/123/solo-data/todos/550e8400-e29b-41d4-a716-446655440000
Batch Operations
Execute up to 100 create, update, and delete operations in a single request. The entire batch runs in one database transaction (all-or-nothing) and counts as a single rate limit hit. Users can only batch their own records.
/api/pages/:id/solo-data/:collection/batch
Execute batch operations on your own records
Request Body
{
"operations": [
{ "op": "create", "data": { "score": 100 } },
{ "op": "update", "id": "uuid-1", "data": { "score": 200 } },
{ "op": "delete", "id": "uuid-2" }
]
}Response
{
"results": [
{ "op": "create", "success": true, "id": "uuid-new", "data": { "score": 100 } },
{ "op": "update", "success": true, "id": "uuid-1" },
{ "op": "delete", "success": true, "id": "uuid-2" }
]
}Update = Shallow Merge (same as PATCH)
The update operation merges the provided data with the existing record's data. Only the fields you include are overwritten — fields you omit are preserved. For example, if a record has {"score": 100, "level": 5} and you send{"data": {"score": 200}}, the result is {"score": 200, "level": 5}. However, if you send a field with null, it will be set to null. This is a shallow merge — nested objects are fully replaced, not deep-merged.
Rules: Maximum 100 operations per batch. All operations run atomically. Schema validation is applied to each create/update. Requires solo-data:write scope.
On this page
- Endpoints
- GET - List Records
- GET - Count Records
- POST - Create Record
- PATCH - Update Record
- DELETE - Delete Record
- Batch Operations