Sheets API 🟡 BETA

Spreadsheet creation, editing, formatting, formulas, charts, collaboration, and real-time synchronization


Base URL

/api/sheet

Authentication

All endpoints require a valid session token via Authorization: Bearer <token> header.

⚠️ Not enforced yet. The handlers currently resolve every request to a single hardcoded user identity, so any client can read or overwrite any document by id, and no per-document permission is checked. Real identity, tenancy scoping and a four-role ACL (owner / editor / commenter / viewer) are tracked in generalbots#789. Do not expose these endpoints to untrusted clients until it lands. See Sheet Parity Plan.

⚠️ Concurrency. Every mutating endpoint currently loads the whole document, mutates it, and writes it back with no version check. Two clients editing different cells will lose one edit silently. Optimistic concurrency with a version field and 409 Conflict responses is part of the same issue.


Spreadsheet Operations

List Spreadsheets

GET /api/sheet/list

Returns all spreadsheets accessible to the authenticated user.

ParameterTypeRequiredDescription
folderstringNoFilter by folder path
searchstringNoSearch by title
sortstringNoSort: name, created_at, updated_at (default: updated_at)
pageintegerNoPage number (default: 1)
limitintegerNoResults per page (default: 20)

Response:

{
  "spreadsheets": [
    {
      "id": "sheet_001",
      "title": "Relatório de Vendas Q2",
      "folder": "/reports",
      "created_by": "user_001",
      "created_at": "2026-06-01T10:00:00Z",
      "updated_at": "2026-06-04T10:00:00Z",
      "sheet_count": 3,
      "collaborators": 5,
      "size_bytes": 245760
    }
  ],
  "total": 28
}

Search Spreadsheets

GET /api/sheet/search

Full-text search across spreadsheet content and metadata.

ParameterTypeRequiredDescription
qstringYesSearch query
scopestringNotitle, content, all (default: all)
limitintegerNoMax results (default: 10)

Response:

{
  "results": [
    {
      "id": "sheet_001",
      "title": "Relatório de Vendas Q2",
      "match_type": "title",
      "match_snippet": "...Relatório de **Vendas** Q2...",
      "updated_at": "2026-06-04T10:00:00Z"
    },
    {
      "id": "sheet_005",
      "title": "Forecast 2026",
      "match_type": "content",
      "match_snippet": "...receita de **vendas** no Q2 foi de R$ 2.5M...",
      "updated_at": "2026-06-03T15:00:00Z"
    }
  ],
  "total": 2
}

Load Spreadsheet

GET /api/sheet/load

Loads a spreadsheet with all sheet data.

ParameterTypeRequiredDescription
idstringYesSpreadsheet identifier
sheetstringNoSpecific sheet name (default: first sheet)
rangestringNoCell range (e.g., A1:Z100)
formatstringNojson, csv (default: json)

Response:

{
  "id": "sheet_001",
  "title": "Relatório de Vendas Q2",
  "sheets": [
    {
      "name": "Resumo",
      "id": "sheet_tab_001",
      "rows": 50,
      "columns": 15,
      "data": [
        ["Produto", "Qtd Vendida", "Receita", "Margem"],
        ["Bot Enterprise", "45", "R$ 135.000", "68%"],
        ["Bot Starter", "120", "R$ 36.000", "72%"],
        ["Bot Pro", "78", "R$ 156.000", "65%"]
      ],
      "freeze_position": "A2"
    }
  ],
  "active_sheet": "Resumo",
  "last_editor": "Maria Santos",
  "updated_at": "2026-06-04T10:00:00Z"
}

Load from Drive

POST /api/sheet/load-from-drive

Loads a spreadsheet directly from a Drive (MinIO) bucket.

ParameterTypeRequiredDescription
bot_namestringYesBot name containing the sheet
file_pathstringYesPath within .gbdrive
formatstringNoExpected format: xlsx, csv, json

Response:

{
  "id": "sheet_drive_001",
  "title": "dados_vendas.xlsx",
  "source": "drive",
  "bot_name": "salesbot",
  "sheets": [
    {
      "name": "Vendas",
      "rows": 500,
      "columns": 12
    }
  ],
  "loaded_at": "2026-06-04T10:00:00Z"
}

Save Spreadsheet

POST /api/sheet/save

Saves spreadsheet changes back to Drive.

ParameterTypeRequiredDescription
idstringNoSpreadsheet ID (omit for new)
titlestringNoUpdated title
sheetsobject[]NoUpdated sheet data
folderstringNoTarget folder in .gbdrive
formatstringNoSave format: xlsx, csv, json

Response:

{
  "id": "sheet_001",
  "saved": true,
  "path": "reports/vendas_q2.xlsx",
  "size_bytes": 250880,
  "saved_at": "2026-06-04T10:15:00Z"
}

Delete Spreadsheet

POST /api/sheet/delete

Deletes a spreadsheet.

ParameterTypeRequiredDescription
idstringYesSpreadsheet identifier

Response:

{
  "deleted": true,
  "id": "sheet_001",
  "title": "Relatório de Vendas Q2"
}

New Spreadsheet

GET /api/sheet/new

Creates a new empty spreadsheet.

ParameterTypeRequiredDescription
titlestringNoSpreadsheet title (default: “Untitled”)
templatestringNoTemplate ID to clone
sheetsstring[]NoInitial sheet names

Response:

{
  "id": "sheet_002",
  "title": "Nova Planilha",
  "sheets": [
    { "name": "Sheet1", "id": "sheet_tab_002" }
  ],
  "created_at": "2026-06-04T10:00:00Z"
}

Cell Operations

Update Cell

POST /api/sheet/cell

Updates a single cell value.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name (default: first sheet)
cellstringYesCell reference (e.g., A1)
valueanyYesCell value
formulastringNoCell formula

Response:

{
  "sheet_id": "sheet_001",
  "cell": "C2",
  "value": "=B2*D2",
  "computed_value": 91800,
  "updated_at": "2026-06-04T10:00:00Z"
}

Format Cells

POST /api/sheet/format

Applies formatting to a range of cells.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringYesCell range (e.g., A1:D10)
boldbooleanNoBold text
italicbooleanNoItalic text
font_sizeintegerNoFont size in px
font_colorstringNoFont color (hex)
bg_colorstringNoBackground color (hex)
alignstringNoleft, center, right
borderstringNoBorder style
number_formatstringNoNumber format: currency, percent, date, number

Response:

{
  "sheet_id": "sheet_001",
  "range": "A1:D1",
  "format_applied": {
    "bold": true,
    "bg_color": "#1E40AF",
    "font_color": "#FFFFFF",
    "align": "center"
  },
  "cells_formatted": 4
}

Set Formula

POST /api/sheet/formula

Sets a formula in a cell.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
cellstringYesCell reference
formulastringYesSpreadsheet formula

Response:

{
  "sheet_id": "sheet_001",
  "cell": "E10",
  "formula": "=SUM(E2:E9)",
  "computed_value": 450000,
  "updated_at": "2026-06-04T10:00:00Z"
}

Validate Cell

POST /api/sheet/validate-cell

Validates a cell value against data validation rules.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
cellstringYesCell reference
valueanyYesValue to validate

Response:

{
  "valid": true,
  "cell": "B5",
  "value": "ativo",
  "rule": {
    "type": "list",
    "options": ["ativo", "inativo", "pendente"]
  }
}

Merge & Freeze

Merge Cells

POST /api/sheet/merge

Merges a range of cells.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringYesCell range to merge (e.g., A1:C1)
typestringNoMerge type: all, rows, columns (default: all)

Response:

{
  "sheet_id": "sheet_001",
  "range": "A1:C1",
  "merged": true,
  "merge_type": "all"
}

Unmerge Cells

POST /api/sheet/unmerge

Unmerges a previously merged cell range.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringYesRange to unmerge

Response:

{
  "sheet_id": "sheet_001",
  "range": "A1:C1",
  "unmerged": true
}

Freeze Panes

POST /api/sheet/freeze

Freezes rows and/or columns.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rowsintegerNoNumber of rows to freeze
columnsintegerNoNumber of columns to freeze

Response:

{
  "sheet_id": "sheet_001",
  "frozen_rows": 1,
  "frozen_columns": 0
}

Sort & Filter

Sort Data

POST /api/sheet/sort

Sorts a range by one or more columns.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringYesRange to sort
sort_byobject[]YesSort columns with order
sort_by[].columnstringYesColumn letter (e.g., B)
sort_by[].orderstringNoasc or desc (default: asc)

Response:

{
  "sheet_id": "sheet_001",
  "range": "A2:D100",
  "sorted": true,
  "sort_by": [
    { "column": "B", "order": "desc" },
    { "column": "A", "order": "asc" }
  ],
  "rows_sorted": 99
}

Apply Filter

POST /api/sheet/filter

Applies a filter to a data range.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringYesHeader range (e.g., A1:D1)
columnstringYesColumn to filter
operatorstringYesequals, contains, gt, lt, between, in
valueanyYesFilter value
value2anyNoSecond value for between

Response:

{
  "sheet_id": "sheet_001",
  "column": "C",
  "operator": "gt",
  "value": 50000,
  "visible_rows": 12,
  "hidden_rows": 87,
  "filtered_at": "2026-06-04T10:00:00Z"
}

Clear Filter

POST /api/sheet/filter/clear

Removes all active filters from a sheet.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name

Response:

{
  "sheet_id": "sheet_001",
  "filters_cleared": 3,
  "all_rows_visible": true
}

Charts & Visualization

Create Chart

POST /api/sheet/chart

Creates a chart from spreadsheet data.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
data_rangestringYesData range for chart
typestringYesbar, line, pie, scatter, area, column
titlestringNoChart title
x_axisstringNoX-axis label
y_axisstringNoY-axis label
positionobjectNoPosition { row, column }

Response:

{
  "chart_id": "chart_001",
  "type": "bar",
  "title": "Vendas por Produto",
  "data_range": "A1:B5",
  "position": { "row": 7, "column": 1 },
  "created_at": "2026-06-04T10:00:00Z"
}

Delete Chart

POST /api/sheet/chart/delete

Removes a chart from the spreadsheet.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
chart_idstringYesChart identifier

Response:

{
  "chart_id": "chart_001",
  "deleted": true
}

Data Validation

Conditional Formatting

POST /api/sheet/conditional-format

Applies conditional formatting rules to a range.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringYesCell range
rulesobject[]YesFormatting rules
rules[].conditionstringYesgreater_than, less_than, equals, contains, between
rules[].valueanyYesCondition value
rules[].formatobjectYesFormat to apply: { bg_color, font_color, bold }

Response:

{
  "sheet_id": "sheet_001",
  "range": "C2:C100",
  "rules_applied": 2,
  "cells_formatted": 45
}

Data Validation Rule

POST /api/sheet/data-validation

Sets a data validation rule on a cell range.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringYesCell range
typestringYeslist, number, date, text, checkbox
optionsanyValidation options (depends on type)
options.valuesstring[]For list: allowed values
options.minnumberFor number: minimum
options.maxnumberFor number: maximum
options.allow_blankbooleanAllow empty cells

Response:

{
  "sheet_id": "sheet_001",
  "range": "D2:D50",
  "rule_type": "list",
  "rule": {
    "values": ["Ativo", "Inativo", "Pendente"],
    "allow_blank": false
  },
  "applied_to": 49
}

Notes & Comments

Add Note

POST /api/sheet/note

Adds a note/comment to a cell.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
cellstringYesCell reference
contentstringYesNote content

Response:

{
  "note_id": "note_001",
  "cell": "C5",
  "content": "Receita do mês anterior precisa ser verificada",
  "author": "Maria Santos",
  "created_at": "2026-06-04T10:00:00Z"
}

Add Comment

POST /api/sheet/comment

Adds a threaded comment to a cell.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
cellstringYesCell reference
contentstringYesComment content
mentionsstring[]NoUser IDs to mention

Response:

{
  "comment_id": "comment_001",
  "cell": "E10",
  "content": "@Maria Santos este total está correto?",
  "author": "João Silva",
  "mentions": ["user_001"],
  "created_at": "2026-06-04T10:00:00Z",
  "resolved": false
}

Reply to Comment

POST /api/sheet/comment/reply

Replies to an existing comment thread.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
comment_idstringYesParent comment identifier
contentstringYesReply content

Response:

{
  "reply_id": "reply_001",
  "comment_id": "comment_001",
  "content": "Sim, confirmei com o financeiro",
  "author": "Maria Santos",
  "created_at": "2026-06-04T10:05:00Z"
}

Resolve Comment

POST /api/sheet/comment/resolve

Marks a comment thread as resolved.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
comment_idstringYesComment identifier

Response:

{
  "comment_id": "comment_001",
  "resolved": true,
  "resolved_by": "João Silva",
  "resolved_at": "2026-06-04T10:10:00Z"
}

Delete Comment

POST /api/sheet/comment/delete

Deletes a comment and all its replies.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
comment_idstringYesComment identifier

Response:

{
  "comment_id": "comment_001",
  "deleted": true,
  "replies_deleted": 3
}

List Comments

POST /api/sheet/comments

Returns all comments in a spreadsheet.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
resolvedbooleanNoFilter by resolved status

Response:

{
  "comments": [
    {
      "comment_id": "comment_001",
      "cell": "E10",
      "content": "@Maria Santos este total está correto?",
      "author": { "id": "user_002", "name": "João Silva" },
      "created_at": "2026-06-04T10:00:00Z",
      "resolved": false,
      "replies": [
        {
          "reply_id": "reply_001",
          "content": "Sim, confirmei com o financeiro",
          "author": { "id": "user_001", "name": "Maria Santos" },
          "created_at": "2026-06-04T10:05:00Z"
        }
      ]
    }
  ],
  "total": 5,
  "unresolved": 2
}

Cell Protection

Protect Sheet

POST /api/sheet/protect

Protects a sheet or range from editing.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringNoSpecific range to protect (omit for full sheet)
descriptionstringNoProtection reason
allowed_usersstring[]NoUser IDs allowed to edit

Response:

{
  "sheet_id": "sheet_001",
  "range": "A1:Z1000",
  "protected": true,
  "description": "Cabeçalho não pode ser alterado",
  "allowed_users": ["user_001"]
}

Unprotect Sheet

POST /api/sheet/unprotect

Removes protection from a sheet or range.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name

Response:

{
  "sheet_id": "sheet_001",
  "unprotected": true
}

Lock Cells

POST /api/sheet/lock-cells

Locks specific cells while keeping the rest editable.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangesstring[]YesCell ranges to lock
allowed_usersstring[]NoUsers allowed to edit locked cells

Response:

{
  "sheet_id": "sheet_001",
  "locked_ranges": ["A1:D1", "A10:D10"],
  "locked_cells": 8,
  "allowed_users": ["user_001", "user_002"]
}

Import & Export

Import Data

POST /api/sheet/import

Imports data from various formats into a spreadsheet.

ParameterTypeRequiredDescription
sheet_idstringNoTarget spreadsheet (omit to create new)
sourcestringYescsv, json, xlsx, drive
dataanyYesRaw data or file content
file_pathstringFor drive: path in .gbdrive
sheet_tabstringNoTarget sheet tab name
start_cellstringNoStarting cell (default: A1)
has_headerbooleanYesFirst row is header

Response:

{
  "sheet_id": "sheet_001",
  "imported": true,
  "source": "csv",
  "rows_imported": 500,
  "columns_imported": 12,
  "start_cell": "A1",
  "duration_ms": 2340
}

Export Spreadsheet

POST /api/sheet/export

Exports a spreadsheet to various formats.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
formatstringYesxlsx, csv, json, pdf
sheet_tabstringNoSpecific sheet (default: all)
rangestringNoSpecific range

Response:

{
  "export_id": "export_001",
  "format": "xlsx",
  "download_url": "https://storage.example.com/exports/relatorio_vendas.xlsx",
  "size_bytes": 256000,
  "expires_at": "2026-06-05T10:00:00Z"
}

Collaboration

Share Spreadsheet

POST /api/sheet/share

Shares a spreadsheet with other users.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
user_idstringYesUser to share with
permissionstringYesview, comment, edit
notifybooleanNoSend notification (default: true)

Response:

{
  "sheet_id": "sheet_001",
  "shared_with": "user_003",
  "permission": "edit",
  "shared_at": "2026-06-04T10:00:00Z"
}

Get Collaborators

GET /api/sheet/:id/collaborators

Returns all collaborators on a spreadsheet.

ParameterTypeRequiredDescription
idpathYesSpreadsheet identifier

Response:

{
  "collaborators": [
    {
      "user_id": "user_001",
      "name": "Maria Santos",
      "email": "maria@example.com",
      "permission": "edit",
      "last_active_at": "2026-06-04T10:00:00Z",
      "is_online": true
    },
    {
      "user_id": "user_002",
      "name": "João Silva",
      "email": "joao@example.com",
      "permission": "view",
      "last_active_at": "2026-06-03T15:00:00Z",
      "is_online": false
    }
  ],
  "total": 5
}

AI Integration

AI Assist

POST /api/sheet/ai

Uses AI to analyze or transform spreadsheet data.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
sheet_tabstringNoSheet tab name
rangestringNoData range to analyze
promptstringYesNatural language instruction
operationstringNoanalyze, transform, generate_formula, suggest

Response:

{
  "sheet_id": "sheet_001",
  "prompt": "Analise a tendência de vendas por produto",
  "operation": "analyze",
  "result": {
    "analysis": "Bot Enterprise apresenta crescimento de 15% QoQ, enquanto Bot Starter manteve estável. Bot Pro cresceu 22%, indicando oportunidade de upsell.",
    "suggestions": [
      "Focar esforços de venda em Bot Pro (maior crescimento)",
      "Revisar pricing de Bot Starter para estimular crescimento",
      "Criar campanha de upsell para clientes Bot Starter → Bot Pro"
    ],
    "formulas_generated": [
      {
        "cell": "E2",
        "formula": "=IF(D2>100000, \"Alto\", IF(D2>50000, \"Médio\", \"Baixo\"))",
        "description": "Classificação de performance"
      }
    ]
  },
  "generated_at": "2026-06-04T10:00:00Z"
}

WebSocket Real-Time

Collaborative Editing

GET /ws/sheet/:sheet_id

Establishes a WebSocket connection for real-time collaborative editing.

⚠️ The current wire protocol addresses a cell as a single integer, row * 26 + col, with 26 hardcoded on both ends. Any grid wider than 26 columns therefore delivers every remote edit to the wrong cell, and two clients configured differently corrupt each other’s data. Conflict handling is last-write-wins with no sequence numbers, no reconnect recovery and no rendered presence. The replacement protocol — A1 addressing, server-authoritative sequencing with operation transformation, and oplog-based recovery — is tracked in generalbots#791. The message shapes below are the target protocol, not the current one.

ParameterTypeRequiredDescription
sheet_idpathYesSpreadsheet identifier
tokenqueryYesAuthentication token

WebSocket Messages (Server → Client):

{
  "event": "cell_updated",
  "data": {
    "user": { "id": "user_001", "name": "Maria Santos" },
    "cell": "A1",
    "value": "Produto",
    "color": "#3B82F6"
  }
}
{
  "event": "cursor_moved",
  "data": {
    "user_id": "user_001",
    "cell": "C5",
    "color": "#3B82F6"
  }
}
{
  "event": "selection_changed",
  "data": {
    "user_id": "user_002",
    "range": "A1:D10",
    "color": "#10B981"
  }
}
{
  "event": "user_joined",
  "data": {
    "user_id": "user_003",
    "name": "Carlos Lima",
    "color": "#F59E0B"
  }
}

WebSocket Messages (Client → Server):

{
  "event": "edit",
  "data": {
    "cell": "B2",
    "value": "Nova receita",
    "sheet_tab": "Resumo"
  }
}
{
  "event": "cursor",
  "data": {
    "cell": "C5"
  }
}

POST /api/sheet/external-link

Creates a shareable external link for spreadsheet access.

ParameterTypeRequiredDescription
sheet_idstringYesSpreadsheet identifier
permissionstringYesview, comment
expires_in_daysintegerNoLink expiration (default: 30)
passwordstringNoPassword protection

Response:

{
  "link_id": "link_001",
  "url": "https://sheets.example.com/shared/abc123def456",
  "permission": "view",
  "expires_at": "2026-07-04T10:00:00Z",
  "has_password": true,
  "created_at": "2026-06-04T10:00:00Z"
}

GET /api/sheet/external-link

Returns all external links for a spreadsheet.

ParameterTypeRequiredDescription
sheet_idqueryYesSpreadsheet identifier

Response:

{
  "links": [
    {
      "link_id": "link_001",
      "permission": "view",
      "access_count": 45,
      "last_accessed_at": "2026-06-04T09:30:00Z",
      "expires_at": "2026-07-04T10:00:00Z",
      "active": true
    }
  ]
}

DELETE /api/sheet/external-link/:id

Revokes an external link.

ParameterTypeRequiredDescription
idpathYesLink identifier

Response:

{
  "link_id": "link_001",
  "deleted": true,
  "revoked_access_count": 45
}

Get Spreadsheet by ID

GET /api/sheet/:id

Returns metadata for a specific spreadsheet.

ParameterTypeRequiredDescription
idpathYesSpreadsheet identifier

Response:

{
  "id": "sheet_001",
  "title": "Relatório de Vendas Q2",
  "folder": "/reports",
  "created_by": { "id": "user_001", "name": "Maria Santos" },
  "sheets": [
    { "name": "Resumo", "rows": 50, "columns": 15 },
    { "name": "Detalhes", "rows": 500, "columns": 12 },
    { "name": "Gráficos", "rows": 30, "columns": 10 }
  ],
  "permissions": {
    "owner": "user_001",
    "shared_with": 5,
    "external_links": 2
  },
  "created_at": "2026-06-01T10:00:00Z",
  "updated_at": "2026-06-04T10:00:00Z"
}

Endpoint status

Endpoints that accept and persist a request but whose effect is not yet visible or enforced. Each is reachable and returns success; the gap is downstream.

EndpointStatusNote
POST /api/sheet/formatPartialStyle is stored and applied to the active cell only; number format codes are stored but not rendered
POST /api/sheet/formulaPartialA formula must be a single function call; =SUM(A1:A3)+1, =A1&B1, =A1^2 and nested calls return #ERROR!. String literals are upper-cased
POST /api/sheet/cellPartialRecalculation of dependents silently stops after 1000 cells
POST /api/sheet/mergeStored, not renderedThe grid does not draw merges
POST /api/sheet/freezeStored, not rendered
POST /api/sheet/filterStored, not appliedNo rows are hidden
POST /api/sheet/sortPartialValues move; formulas referencing them are not rewritten
POST /api/sheet/chartStored, not renderedSeries data is snapshotted rather than bound to a range
POST /api/sheet/conditional-formatStored, not applied
POST /api/sheet/data-validationStored, not enforcedPOST /api/sheet/validate-cell works but the editor never calls it
POST /api/sheet/comment*Stored, not renderedThreads are complete server-side; the grid draws no marker
POST /api/sheet/protectStored, not enforced
POST /api/sheet/exportPartialCSV/TSV/JSON/HTML/Markdown work but emit unformatted values; ODS emits content XML rather than a complete package; PDF returns HTML bytes
POST /api/sheet/importPartial.xlsx import drops defined names, validation, conditional formatting, charts, images, pivot tables, tables, autofilter, hidden rows, hyperlinks, rich text runs, protection and print setup
POST /api/sheet/sharePartialNo real ACL is written; see #789
GET /api/sheet/listPartialFully deserialises every document to build the list

Full detail and the plan to close each gap: Sheet Parity Plan.


See Also