Sheets
Sheets are workbooks containing one or more tabs. Each tab has its own grid of cells. Cell references use A1 notation (e.g., A1, B3, AA10).
Concepts
- A sheet (workbook) is the top-level container. It has a title, belongs to a user/server, and contains one or more tabs.
- A tab is an individual spreadsheet within the workbook. Each tab has a name (e.g., "Sheet 1", "Revenue"), a grid size, and its own cell data.
- Cells use A1 notation as keys and cell objects as values. A cell object has a
value(string or number) and an optionalformatobject. - Formulas start with
=(e.g.,=SUM(A1:A10),=B2*1.1). Cross-tab references use the format=TabName!A1.
Cell Object
| Field | Type | Description |
|---|---|---|
value | string or number | The cell's content. Prefix with = for formulas. |
format | object | Optional formatting (see below) |
Format options:
| Field | Type | Example |
|---|---|---|
bold | boolean | true |
italic | boolean | true |
underline | boolean | true |
color | string | "#ff0000" |
bgColor | string | "#f0f0f0" |
borderColor | string | "#000000" |
fontSize | number | 14 |
fontFamily | string | "Arial" |
align | string | "left", "center", "right" |
wrapText | boolean | true |
numberFormat | string | "general", "number", "currency", "percentage", "date", "time" |
decimals | number | 2 |
currencySymbol | string | "$" |
currencyCode | string | "USD" |
dateFormat | string | "MM/DD/YYYY" |
decimalSeparator | string | "." |
thousandSeparator | string | "," |
List Sheets
GET /v1/sheetsReturns workbooks with tab metadata (names, positions, grid sizes) but not cell data. Use the get endpoint for full cell data.
Query parameters:
| Param | Default | Description |
|---|---|---|
limit | 50 | Results per page (max 100) |
offset | 0 | Pagination offset |
sort | updated_at | Sort field: created_at, updated_at, last_edited_at, title |
order | desc | Sort order: asc or desc |
server_id | (all) | Filter by server: omit for all, personal for personal files, or a server ID |
Response shape:
{
"success": true,
"data": [
{
"id": "xK9mQ2vB7n",
"title": "Sales Report",
"tabs": [
{ "id": "abc123", "name": "Sheet 1", "position": 0, "rows": 100, "columns": 26, "color": null },
{ "id": "def456", "name": "Summary", "position": 1, "rows": 100, "columns": 26, "color": "#4f46e5" }
],
"server_id": null,
"created_at": "2026-02-26T...",
"updated_at": "2026-02-26T..."
}
],
"pagination": { "total": 1, "limit": 50, "offset": 0 }
}Get Sheet
GET /v1/sheets/:idReturns the workbook with all tabs including cell data in A1 notation.
curl https://api.mila.gg/v1/sheets/xK9mQ2vB7n \
-H "Authorization: Bearer mila_sk_your_key_here"Response shape:
{
"success": true,
"data": {
"id": "xK9mQ2vB7n",
"title": "Sales Report",
"tabs": [
{
"id": "abc123",
"name": "Sheet 1",
"position": 0,
"rows": 100,
"columns": 26,
"color": null,
"cells": {
"A1": { "value": "Product" },
"B1": { "value": "Revenue" },
"A2": { "value": "Widget" },
"B2": { "value": 15000 }
}
}
],
"server_id": null,
"created_at": "2026-02-26T...",
"updated_at": "2026-02-26T..."
}
}Create Sheet
POST /v1/sheetsCreates a new workbook with one initial tab. Optionally provide cells for the first tab.
Body:
{
"title": "Q3 Budget",
"cells": {
"A1": { "value": "Category", "format": { "bold": true } },
"B1": { "value": "Amount", "format": { "bold": true, "align": "right" } },
"A2": { "value": "Engineering" },
"B2": { "value": 50000, "format": { "numberFormat": "currency", "currencySymbol": "$" } }
},
"tab_name": "Budget",
"rows": 100,
"columns": 26,
"server_id": null
}| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Workbook title |
cells | object | No | Cell data for the initial tab (A1 notation keys, cell objects as values) |
tab_name | string | No | Name of the initial tab (default: "Sheet 1") |
rows | number | No | Number of rows for the initial tab (default: 100) |
columns | number | No | Number of columns for the initial tab (default: 26) |
server_id | string or null | No | Server to create in (null = personal files) |
Example -- create a formatted workbook in a server:
curl -X POST https://api.mila.gg/v1/sheets \
-H "Authorization: Bearer mila_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"title": "Q3 Budget",
"server_id": "xK9mP2wQ",
"tab_name": "Budget",
"cells": {
"A1": { "value": "Category", "format": { "bold": true, "bgColor": "#e2e8f0" } },
"B1": { "value": "Amount", "format": { "bold": true, "bgColor": "#e2e8f0", "align": "right" } },
"A2": { "value": "Engineering" },
"B2": { "value": 50000, "format": { "numberFormat": "currency", "currencySymbol": "$", "decimals": 2 } },
"A3": { "value": "Marketing" },
"B3": { "value": 25000, "format": { "numberFormat": "currency", "currencySymbol": "$", "decimals": 2 } },
"A4": { "value": "Total", "format": { "bold": true } },
"B4": { "value": "=SUM(B2:B3)", "format": { "bold": true, "numberFormat": "currency", "currencySymbol": "$", "decimals": 2 } }
}
}'Update Sheet
PUT /v1/sheets/:idUpdates workbook-level properties only (title). To update cell data, use the tab endpoints below.
Body:
{
"title": "Updated Workbook Title"
}Delete Sheet
DELETE /v1/sheets/:idDeletes the workbook and all of its tabs.
Get Tab
GET /v1/sheets/:id/tabs/:tabIdReturns a single tab with its cell data in A1 notation.
curl https://api.mila.gg/v1/sheets/xK9mQ2vB7n/tabs/abc123 \
-H "Authorization: Bearer mila_sk_your_key_here"Response:
{
"success": true,
"data": {
"id": "abc123",
"name": "Sheet 1",
"position": 0,
"rows": 100,
"columns": 26,
"color": null,
"cells": {
"A1": { "value": "Product" },
"B1": { "value": "Revenue" },
"A2": { "value": "Widget" },
"B2": { "value": 15000 }
}
}
}Create Tab
POST /v1/sheets/:id/tabsAdd a new tab to an existing workbook.
Body:
{
"name": "Summary",
"cells": {
"A1": { "value": "Total Revenue" },
"B1": { "value": "=Sheet 1!B5" }
},
"rows": 100,
"columns": 26
}| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Tab name (default: auto-generated, e.g., "Sheet 2") |
cells | object | No | Initial cell data (A1 notation) |
rows | number | No | Number of rows (default: 100) |
columns | number | No | Number of columns (default: 26) |
Update Tab
PUT /v1/sheets/:id/tabs/:tabIdUpdate a tab's name, color, grid size, or cells. When cells is provided, the new cells are merged with existing data -- existing cells not mentioned in the request are left unchanged.
Body (all fields optional):
{
"name": "Renamed Tab",
"color": "#4f46e5",
"cells": {
"A1": { "value": "Updated Value" },
"C3": { "value": 42, "format": { "bold": true } }
}
}| Field | Type | Description |
|---|---|---|
name | string | Tab name |
color | string or null | Tab color as hex string (e.g., "#4f46e5"), or null to clear |
cells | object | Cells to merge (A1 notation). Set a cell's value to null to clear it. |
rows | number | Number of rows |
columns | number | Number of columns |
Clearing a cell:
To delete a cell, set its value to null:
{
"cells": {
"B2": null
}
}Example -- update specific cells without affecting others:
curl -X PUT https://api.mila.gg/v1/sheets/xK9mQ2vB7n/tabs/abc123 \
-H "Authorization: Bearer mila_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"cells": {
"B2": { "value": 18000 },
"B3": { "value": 30000 },
"C1": { "value": "Notes", "format": { "bold": true } },
"C2": { "value": "Increased from Q2" }
}
}'The response includes the full updated tab with all cells.
Delete Tab
DELETE /v1/sheets/:id/tabs/:tabIdDelete a tab from the workbook. You cannot delete the last tab -- every workbook must have at least one tab.
curl -X DELETE https://api.mila.gg/v1/sheets/xK9mQ2vB7n/tabs/def456 \
-H "Authorization: Bearer mila_sk_your_key_here"Append Rows
POST /v1/sheets/:id/tabs/:tabId/rowsAppend one or more rows of data to the end of a tab. Rows are placed after the last occupied row. This is useful for logging data, appending records, or building a spreadsheet incrementally without needing to know the current row count.
Single row -- array form (fills columns A, B, C, ...):
{
"values": ["Widget", 100, "$9.99"]
}Single row -- object form (specify columns by letter):
{
"values": { "A": "Widget", "C": 100, "E": "$9.99" }
}Multiple rows -- array form:
{
"rows": [
["Widget", 100, "$9.99"],
["Gadget", 50, "$19.99"],
["Doohickey", 200, "$4.99"]
]
}Multiple rows -- object form:
{
"rows": [
{ "A": "Widget", "B": 100, "C": "$9.99" },
{ "A": "Gadget", "B": 50, "C": "$19.99" }
]
}| Field | Type | Required | Description |
|---|---|---|---|
values | array or object | One of values or rows | A single row. Array fills columns sequentially; object uses column letters as keys. |
rows | array | One of values or rows | Multiple rows. Each element is an array or object as described above. |
Response:
{
"success": true,
"data": {
"start_row": 5,
"rows_added": 3,
"cells": {
"A5": { "value": "Widget" },
"B5": { "value": 100 },
"C5": { "value": "$9.99" },
"A6": { "value": "Gadget" },
"B6": { "value": 50 },
"C6": { "value": "$19.99" },
"A7": { "value": "Doohickey" },
"B7": { "value": 200 },
"C7": { "value": "$4.99" }
}
}
}The start_row is 1-based (matching A1 notation). The cells object shows exactly which cells were written.
Example -- append a row to a tab:
curl -X POST https://api.mila.gg/v1/sheets/xK9mQ2vB7n/tabs/abc123/rows \
-H "Authorization: Bearer mila_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"values": ["New Product", 75, "$12.50"]
}'Example -- log multiple entries:
curl -X POST https://api.mila.gg/v1/sheets/xK9mQ2vB7n/tabs/abc123/rows \
-H "Authorization: Bearer mila_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"rows": [
{ "A": "2026-02-26", "B": "Deploy v2.1", "C": "success" },
{ "A": "2026-02-26", "B": "Run migrations", "C": "success" },
{ "A": "2026-02-26", "B": "Clear cache", "C": "pending" }
]
}'