API Documentation

Everything you need to create tables, add data, and interact with VisiBase programmatically.

Quick start

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

Tables

GET/api/tables

List 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": "..."
    }
  ]
}
POST/api/tables

Create a new table with columns.

Request body

FieldTypeRequiredDescription
namestringYesTable name
columnsarrayYesAt least one column definition

Column definition

FieldTypeRequiredDescription
namestringYesColumn name
kindstringNoColumn 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": [...] } }
GET/api/tables/{tableId}

Get a table's schema. The tableId can be the table UUID or its slug.

DELETE/api/tables/{tableId}

Delete a table and all its data. Returns 204.

Columns

Add, update, or remove columns on an existing table.

POST/api/tables/{tableId}/columns

Add a column to an existing table.

Request body

FieldTypeRequiredDescription
namestringYesColumn name
kindstringNo"text" (default), "number", "boolean", "date", "json"

Response (201) — returns the full updated table schema

{ "table": { "id": "...", "columns": [...] } }
PATCH/.../columns/{columnId}

Rename a column or update its configuration.

FieldTypeRequiredDescription
namestringNoNew column name
DELETE/.../columns/{columnId}

Delete a column. Returns the updated table schema.

Rows

GET/api/tables/{tableId}/rows

List rows with pagination.

Query parameters

FieldTypeRequiredDescription
limitnumberNoMax rows to return (default 100, max 500)
offsetnumberNoNumber 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.

POST/api/tables/{tableId}/rows

Create 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 } }
PATCH/.../rows/{rowId}

Update specific fields on a row. Only the provided values are changed.

{ "values": { "Rating": 4.8 } }
DELETE/.../rows/{rowId}

Delete a row. Returns 204.

Real-time updates

Subscribe to table changes to update your UI in real time.

GET/.../tables/{tableId}/events

Server-Sent Events stream. Emits table_changed events whenever rows or columns are modified.

event: connected
data: {}

event: table_changed
data: {}
GET/.../tables/{tableId}/version

Returns 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" }

Viewing data

In the browser

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.

In the terminal

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:3000

Open 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.

Full example

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}

Column kinds

KindDescriptionExample value
textUTF-8 string (default)"Hello world"
numberInteger or floating point4.5
booleanTrue or falsetrue
dateISO 8601 date string"2024-01-15"
jsonArbitrary JSON value{"key": "value"}

Errors

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