Everything you need to create tables, add data, and interact with VisiBase programmatically.
No authentication required. All endpoints accept and return JSON.
1. Create a table with columns
POST /api/tables
Content-Type: application/json
{
"name": "Gyms in SF",
"columns": [
{ "name": "Name" },
{ "name": "Address" },
{ "name": "Rating", "kind": "number" },
{ "name": "Website" }
]
}2. Add rows
POST /api/tables/{tableId}/rows
Content-Type: application/json
{
"values": {
"Name": "Gold's Gym",
"Address": "1001 Brannan St",
"Rating": 4.5,
"Website": "https://goldsgym.com"
}
}Value keys can be the column name, slug, or ID.
3. View the table
Browser: Open /base/{tableId} — e.g. /base/tbl_xyz789
Terminal: npx visibase-cli view tbl_xyz789
/api/tablesList all tables.
Response
{
"tables": [
{
"id": "tbl_xyz",
"name": "Gyms in SF",
"slug": "gyms-in-sf",
"columns": [
{ "id": "col_1", "name": "Name", "slug": "name", "kind": "text", "ordinal": 0 },
{ "id": "col_2", "name": "Rating", "slug": "rating", "kind": "number", "ordinal": 1 }
],
"createdAt": "...",
"updatedAt": "..."
}
]
}/api/tablesCreate a new table with columns.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Table name |
columns | array | Yes | At least one column definition |
Column definition
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Column name |
kind | string | No | Column type: "text" (default), "number", "boolean", "date", "json" |
Example
{
"name": "Gyms in SF",
"columns": [
{ "name": "Name" },
{ "name": "Address" },
{ "name": "Rating", "kind": "number" },
{ "name": "Website" }
]
}Response (201)
{ "table": { "id": "tbl_xyz", "name": "Gyms in SF", "slug": "gyms-in-sf", "columns": [...] } }/api/tables/{tableId}Get a table's schema. The tableId can be the table UUID or its slug.
/api/tables/{tableId}Delete a table and all its data. Returns 204.
Add, update, or remove columns on an existing table.
/api/tables/{tableId}/columnsAdd a column to an existing table.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Column name |
kind | string | No | "text" (default), "number", "boolean", "date", "json" |
Response (201) — returns the full updated table schema
{ "table": { "id": "...", "columns": [...] } }/.../columns/{columnId}Rename a column or update its configuration.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | New column name |
/.../columns/{columnId}Delete a column. Returns the updated table schema.
/api/tables/{tableId}/rowsList rows with pagination.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
limit | number | No | Max rows to return (default 100, max 500) |
offset | number | No | Number of rows to skip (default 0) |
Response
{
"rows": [
{
"id": "row_123",
"values": {
"col_1": "Gold's Gym",
"col_2": "1001 Brannan St",
"col_3": 4.5
},
"createdAt": "...",
"updatedAt": "...",
"version": 1
}
]
}Note: values are keyed by column ID in responses.
/api/tables/{tableId}/rowsCreate a new row.
Request body
{
"values": {
"Name": "Gold's Gym",
"Address": "1001 Brannan St",
"Rating": 4.5
}
}Value keys can be the column name, slug, or ID. All are accepted.
Response (201)
{ "row": { "id": "row_123", "values": { ... }, "version": 1 } }/.../rows/{rowId}Update specific fields on a row. Only the provided values are changed.
{ "values": { "Rating": 4.8 } }/.../rows/{rowId}Delete a row. Returns 204.
Subscribe to table changes to update your UI in real time.
/.../tables/{tableId}/eventsServer-Sent Events stream. Emits table_changed events whenever rows or columns are modified.
event: connected
data: {}
event: table_changed
data: {}/.../tables/{tableId}/versionReturns an opaque version string. Poll this endpoint to detect changes when SSE is unavailable.
{ "version": "2024-01-15T10:30:00Z:42:2024-01-15T10:29:55Z" }Every table has a shareable URL based on its ID:
/base/{tableId}Example: /base/tbl_xyz789
The browser UI is a full spreadsheet with real-time updates, cell editing, column management, and AI features.
Use the VisiBase CLI for a terminal-based spreadsheet viewer with vim-like navigation:
Setup
# Point CLI to your server
npx visibase-cli config -s http://localhost:3000Open the TUI viewer
npx visibase-cli view {tableId}Navigate with h/j/k/l, edit with i, add rows with o, delete with dd. Press r to reload, q to quit.
A complete workflow: create a table, add data, and view it.
# 1. Create a table
curl -s -X POST http://localhost:3000/api/tables \
-H "Content-Type: application/json" \
-d '{
"name": "Gyms in SF",
"columns": [
{ "name": "Name" },
{ "name": "Address" },
{ "name": "Rating", "kind": "number" },
{ "name": "Phone" },
{ "name": "Website" }
]
}' | jq .
# Response: { "table": { "id": "tbl_...", "slug": "gyms-in-sf", ... } }
# 2. Insert rows (use the table ID from step 1)
curl -s -X POST http://localhost:3000/api/tables/{tableId}/rows \
-H "Content-Type: application/json" \
-d '{"values": {"Name": "Fitness SF", "Address": "1001 Brannan St", "Rating": 4.3}}'
curl -s -X POST http://localhost:3000/api/tables/{tableId}/rows \
-H "Content-Type: application/json" \
-d '{"values": {"Name": "Equinox", "Address": "747 Market St", "Rating": 4.6}}'
# 3. Open in browser:
# http://localhost:3000/base/{tableId}
# 4. Open in terminal:
# npx visibase-cli config -s http://localhost:3000
# npx visibase-cli view {tableId}| Kind | Description | Example value |
|---|---|---|
text | UTF-8 string (default) | "Hello world" |
number | Integer or floating point | 4.5 |
boolean | True or false | true |
date | ISO 8601 date string | "2024-01-15" |
json | Arbitrary JSON value | {"key": "value"} |
All error responses follow the same format:
{
"error": "Table not found.",
"details": null
}Common status codes: 400 (bad request), 404 (not found), 500 (server error).
Machine-readable version available at /llms.txt