Spreadsheet endpoints
All endpoints use the base URL https://app.visigrid.app/api/connector and
require bearer authentication. Examples use synthetic
data. Replace {pid} with the pid UUID returned by the list endpoint.
List spreadsheets
Section titled “List spreadsheets”GET /sheets · Scope: read · Response: 200
Returns an array of accessible spreadsheets, including shared workbooks.
There is no pagination envelope. An empty result is [].
[ { "id": 42, "pid": "00000000-0000-4000-8000-000000000042", "name": "Leads", "revision": 3, "folder_id": null, "role": "owner", "can_manage_sharing": true, "created_at": "2026-10-08T12:00:00Z", "updated_at": "2026-10-08T12:05:00Z" }]role is owner, editor, or viewer. Use pid in URLs. Integrations
that write should offer only workbooks with an owner or editor role.
can_manage_sharing describes the account’s permission; these REST endpoints
do not expose sharing management.
Create a spreadsheet
Section titled “Create a spreadsheet”POST /sheets · Scope: create · Response: 201
| Field | Required | Description |
|---|---|---|
name |
Yes | Workbook name, 1–255 characters after trimming whitespace. |
document |
Yes | Complete workbook JSON object. Use the v2 format below for cell operations. |
{ "name": "Leads", "document": { "format": "visigrid-json", "version": 2, "sheets": [ { "name": "Sheet1", "cells": [ { "row": 0, "col": 0, "value": "Email" }, { "row": 0, "col": 1, "value": "Name" } ] } ] }}Returns a spreadsheet object with the same fields as a list entry, an owner
role, and revision 0. Creation through this endpoint puts the workbook in
the account’s root; folder_id, if supplied, is ignored.
Document cells use zero-based row and col, so (0, 0) is A1. Each
worksheet needs a nonempty name unique within the workbook, ignoring case.
For an empty workbook, use a single worksheet with "cells": [].
Creation stores the supplied document; it does not recalculate formulas. Use Write cells to calculate formula edits.
Get workbook structure
Section titled “Get workbook structure”GET /sheets/{pid}/workbook · Scope: read · Response: 200
Lists worksheet tabs without returning all their cells.
{ "sheet_id": "00000000-0000-4000-8000-000000000042", "name": "Leads", "revision": 0, "sheets": [ { "index": 0, "name": "Sheet1", "cell_count": 2, "used_range": "A1:B1", "frozen_rows": 0, "frozen_cols": 0, "has_charts": false, "has_conditional_formatting": false } ]}Use index as sheet_index for range reads and cell writes. Indexes are
zero-based and may change when tabs are reordered. used_range is null
for a worksheet without stored cells. Stored formatting-only cells can count
toward cell_count and used_range; neither field identifies a table’s last
data row.
Read a range
Section titled “Read a range”GET /sheets/{pid}/range?range=A1:B20&sheet_index=0 · Scope: read · Response: 200
| Query parameter | Required | Description |
|---|---|---|
range |
Yes | One cell (A1) or an A1 rectangle (A1:B20), at most 5,000 positions. |
sheet_index |
No | Nonnegative worksheet index; defaults to 0. |
Use sheet_index to select the worksheet; do not prefix the range with a
worksheet name. Unknown or repeated query parameters are rejected.
curl --fail-with-body --get \ -H "Authorization: Bearer $VISIGRID_API_TOKEN" \ --data-urlencode 'range=A1:B20' \ --data-urlencode 'sheet_index=0' \ "https://app.visigrid.app/api/connector/sheets/$VISIGRID_SHEET_ID/range"Example response:
{ "sheet_id": "00000000-0000-4000-8000-000000000042", "revision": 0, "sheet": "Sheet1", "sheet_index": 0, "range": "A1:B20", "cells": [ { "ref": "A1", "row": 0, "col": 0, "value": "Email" }, { "ref": "B1", "row": 0, "col": 1, "value": "Name" } ]}The cell list is sparse, ordered by row then column. Unstored blank cells
are omitted; stored cells may contain null values or formatting only.
Cells can also include formula and format. A single-cell range is
normalized to a rectangle such as A1:A1.
Get a snapshot
Section titled “Get a snapshot”GET /sheets/{pid}/snapshot · Scope: read · Response: 200
Returns the full stored workbook document together with its revision.
{ "sheet_id": "00000000-0000-4000-8000-000000000042", "revision": 0, "document": { "format": "visigrid-json", "version": 2, "sheets": [ { "name": "Sheet1", "cells": [ { "row": 0, "col": 0, "value": "Email" }, { "row": 0, "col": 1, "value": "Name" } ] } ] }}Use this endpoint when an operation depends on data across the whole workbook, or when preparing a complete document save. Preserve fields you do not modify, including formatting, charts, and other workbook metadata.
Write cells
Section titled “Write cells”POST /sheets/{pid}/cells · Scope: write · Response: 200
| Field | Required | Description |
|---|---|---|
expected_revision |
Yes | Nonnegative integer revision from the preceding read. |
sheet_index |
No | Zero-based worksheet index; defaults to 0. |
edits |
Yes | Array of 1–1,000 edits with distinct cell references. |
Each edit contains ref and exactly one of value or formula:
| Edit | Meaning |
|---|---|
{"ref":"A2","value":"person@example.com"} |
Write literal text. |
{"ref":"B2","value":12} |
Write a number. Booleans are also supported. |
{"ref":"C2","formula":"=B2*2"} |
Write and evaluate a formula. |
{"ref":"D2","value":null} |
Clear the value and any formula, preserving formatting. |
A string in value is always literal, even if it starts with =. Arrays
and objects are not cell values. A literal replaces any existing formula;
the response reports the formulas replaced this way.
This example assumes the preceding read returned revision 0. Substitute
the revision you actually read before sending a request.
curl --fail-with-body \ -H "Authorization: Bearer $VISIGRID_API_TOKEN" \ -H 'Content-Type: application/json' \ --data '{"expected_revision":0,"sheet_index":0,"edits":[{"ref":"A2","value":"person@example.com"},{"ref":"B2","value":"Taylor"}]}' \ "https://app.visigrid.app/api/connector/sheets/$VISIGRID_SHEET_ID/cells"Example response:
{ "sheet_id": "00000000-0000-4000-8000-000000000042", "revision": 1, "replaced_formulas": [], "cells": [ { "ref": "A2", "row": 1, "col": 0, "value": "person@example.com" }, { "ref": "B2", "row": 1, "col": 1, "value": "Taylor" } ]}cells contains read-back cells when available and may be empty after a
successful live write. Read the range if you need the resulting values.
replaced_formulas entries contain ref and the previous formula.
Formula edits are recalculated through VisiGrid’s engine.
Save a complete snapshot
Section titled “Save a complete snapshot”POST /sheets/{pid}/save · Scope: write · Response: 200
Replaces the entire document, subject to the same revision check as cell writes. Use cell writes for ordinary data updates. Omitting existing content from a complete save removes that content.
{ "expected_revision": 0, "document": { "format": "visigrid-json", "version": 2, "sheets": [ { "name": "Sheet1", "cells": [ { "row": 0, "col": 0, "value": "Updated heading" } ] } ] }}Both fields are required. document must be a JSON object. Returns the
updated spreadsheet object with the same fields as a list entry.
This endpoint stores the supplied document without recalculating formulas.
Use a snapshot read as your starting point and preserve all other fields.
See errors and limits before implementing retries or batch writes.