Legacy Spreadsheets API Migration Guide#
This guide helps developers transition from the legacy Spreadsheets API to the 2026-01-01 Spreadsheets API. The new API provides improved functionality and simplified endpoint paths.
High-Level Changes#
Endpoint Paths: All endpoints have been updated to new paths
Revision: The
revisionfield used to be an integer. It is now an opaque string. This string can be used with the$revisionquery parameter when getting a Spreadsheet or Sheet to retrieve a specific version.Scopes: OAuth scopes have been revised to match patterns going forward
Migration: Creating a Spreadsheet#
2022-01-01 Endpoint#
POST /spreadsheets/v1/spreadsheets
2026-01-01 Endpoint#
POST /files
Key Changes#
Path: Changed from
/spreadsheets/v1/spreadsheetsto/filesFile Kind: When creating a spreadsheet, you must specify
"kind": "Spreadsheet"in the request bodyResponse Structure: The response now returns a unified
Fileobject instead of aSpreadsheetBodyobject
Request Example#
2022-01-01 Request#
POST /spreadsheets/v1/spreadsheets
Content-Type: application/json
Authorization: Bearer {token}
{
"name": "Quarterly Report"
}
2026-01-01 Request#
POST /files
Content-Type: application/json
Authorization: Bearer {token}
{
"name": "Quarterly Report",
"kind": "Spreadsheet"
}
Response Example#
2022-01-01 Response#
{
"data": {
"name": "Quarterly Report"
},
"revision": 1
}
2026-01-01 Response#
{
"id": "124efa2a142f472ba1ceab34ed18915f",
"name": "Quarterly Report",
"kind": "Spreadsheet",
"container": "",
"created": {
"dateTime": "2019-10-28T15:03:27Z"
},
"modified": {
"dateTime": "2019-10-28T15:03:27Z"
},
"type": "Spreadsheet",
"template": false
}
HTTP Status#
2022-01-01: 201 Created
2026-01-01: 201 Created
Required Scopes#
2022-01-01:
data_tables|w2026-01-01:
file:write
Migration: Deleting a Spreadsheet#
2022-01-01 Endpoint#
DELETE /spreadsheets/v1/spreadsheets/{spreadsheetId}
2026-01-01 Endpoint#
POST /files/{fileId}/trash
Key Changes#
HTTP Method: Changed from
DELETEtoPOSTPath: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}to/files/{fileId}/trashRequest Body: The new endpoint requires a request body with trash options
Request Example#
2022-01-01 Request#
DELETE /spreadsheets/v1/spreadsheets/abc123def456
Authorization: Bearer {token}
2026-01-01 Request#
POST /files/76515a4224224565ba1fae5e69ceaafd/trash
Content-Type: application/json
Authorization: Bearer {token}
{}
Response Example#
2022-01-01 Response#
{
"message":"Delete successful",
"request_id":"68a4f1e5-5936-407f-8f3b-086df4338d92"
}
2026-01-01 Response#
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://api.app.wdesk.com/operations/9b7dd722-cb79-4330-83da-f6c9633fc875
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 202 Accepted (asynchronous operation)
Required Scopes#
2022-01-01:
data_tables|w2026-01-01:
file:write
Important Notes#
The new endpoint is asynchronous. Check the operation ID in the response to track the deletion status.
Files moved to trash can be recovered from the trash within a grace period.
Migration: Getting a Spreadsheet by ID#
2022-01-01 Endpoint#
GET /spreadsheets/v1/spreadsheets/{spreadsheetId}
2026-01-01 Endpoint#
GET /spreadsheets/{spreadsheetId}
Key Changes#
Path: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}to/spreadsheets/{spreadsheetId}Response Structure: The response now returns a unified
Spreadsheetobject instead of a wrapped response withdataandrevisionpropertiesQuery Parameters: The
revisionparameter is no longer available
Request Example#
2022-01-01 Request#
GET /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd
Authorization: Bearer {token}
2026-01-01 Request#
GET /spreadsheets/76515a4224224565ba1fae5e69ceaafd
Authorization: Bearer {token}
Response Example#
2022-01-01 Response#
{
"data": {
"created": "2026-01-07T22:00:58.67Z",
"id": "76515a4224224565ba1fae5e69ceaafd",
"last_modified": "2026-01-07T22:00:58.732362Z",
"locked": false,
"name": "Quarterly Report",
},
"request_id": "dddd9f93-d63d-45ce-9210-25622fbb0d47",
"revision": 1707951
}
2026-01-01 Response#
{
"id": "124efa2a142f472ba1ceab34ed18915f",
"name": "Year-end review",
"created": {
"dateTime": "2018-10-21T15:03:27Z"
},
"modified": {
"dateTime": "2018-10-21T15:03:27Z"
},
"template": false
}
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 200 OK
Required Scopes#
2022-01-01:
data_tables|r(read access to data tables)2026-01-01:
file:read(read access to files)
Migration Tips#
Update response parsing: Change from extracting
data.propertyto directly accessingpropertyon the response object.
Migration: Updating a Spreadsheet#
2022-01-01 Endpoint#
PUT /spreadsheets/v1/spreadsheets/{spreadsheetId}
2026-01-01 Endpoint#
PATCH /files/{fileId}
Key Changes#
HTTP Method: Changed from
PUTtoPATCHfor partial updatesPath: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}to/files/{fileId}Request Body Format: Changed from direct property object to JSON Patch (RFC 6902) format
Response Structure: The response now returns a unified
Fileobject instead of anEmptyResponse
Request Example#
2022-01-01 Request#
PUT /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd
Content-Type: application/json
Authorization: Bearer {token}
{
"name": "Updated Spreadsheet Name"
}
2026-01-01 Request#
PATCH /files/76515a4224224565ba1fae5e69ceaafd
Content-Type: application/json
Authorization: Bearer {token}
[
{
"op": "replace",
"path": "/name",
"value": "Updated Spreadsheet Name"
}
]
Response Example#
2022-01-01 Response#
{
"message": "No content returned."
}
2026-01-01 Response#
{
"id": "124efa2a142f472ba1ceab34ed18915f",
"name": "Updated Spreadsheet Name",
"kind": "Spreadsheet",
"container": "",
"created": {
"dateTime": "2019-10-28T15:03:27Z"
},
"modified": {
"dateTime": "2026-01-07T15:30:45Z"
},
"type": "Spreadsheet",
"template": false
}
Supported PATCH Operations#
The 2026-01-01 endpoint supports the following JSON Patch operations:
/name: Update the file name using thereplaceoperation/container: Update the container (folder) using thereplaceoperation
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 200 OK
Required Scopes#
2022-01-01:
data_tables|w2026-01-01:
file:write
Important Notes#
The 2026-01-01 endpoint only supports one operation per request
Updates are applied asynchronously and may not be immediately reflected in subsequent requests
The response includes the updated
Fileobject with current timestamps
Migration Tips#
Switch to JSON Patch format: Convert direct property updates to JSON Patch operations
Handle multiple updates: If you need to update multiple properties, make separate PATCH requests for each
Process response: Update your code to handle the
Fileobject response instead of an empty response
Migration: Publish links in a spreadsheet#
2022-01-01 Endpoint#
POST /spreadsheets/v1/spreadsheets/{spreadsheetId}/publish
2026-01-01 Endpoint#
POST /spreadsheets/{spreadsheetId}/links/publication
Key Changes#
HTTP Method: Remains
POSTfor both endpointsPath: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}/publishto/spreadsheets/{spreadsheetId}/links/publicationRequest Body Structure: Changed from
PublishBodywith optionalallboolean property toLinksPublicationOptionswith requiredpublishTypeenum propertyRequest Body Property: The
allboolean property (defaultfalse) is replaced bypublishTypeenum with values"ownLinks"or"allLinks"Response Status: Changed from
200 OKto202 Accepted(asynchronous operation)Response Structure: Changed from
EmptyResponsewith message to a long-running operation withLocationheader for pollingRevision Handling: The new endpoint explicitly publishes content at the latest spreadsheet revision
Request Example#
2022-01-01 Request (Publish Own Links)#
POST /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/publish
Content-Type: application/json
Authorization: Bearer {token}
{
"all": false
}
2022-01-01 Request (Publish All Links as Owner)#
POST /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/publish
Content-Type: application/json
Authorization: Bearer {token}
{
"all": true
}
2026-01-01 Request (Publish Own Links)#
POST /spreadsheets/76515a4224224565ba1fae5e69ceaafd/links/publication
Content-Type: application/json
Authorization: Bearer {token}
{
"publishType": "ownLinks"
}
2026-01-01 Request (Publish All Links as Owner)#
POST /spreadsheets/76515a4224224565ba1fae5e69ceaafd/links/publication
Content-Type: application/json
Authorization: Bearer {token}
{
"publishType": "allLinks"
}
Response Example#
2022-01-01 Response#
{
"message": "No content returned.",
"request_id": "a1b2c3d4-e5f6-4789-0123-456789abcdef"
}
2026-01-01 Response#
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://api.app.wdesk.com/operations/9b7dd722-cb79-4330-83da-f6c9633fc875
Retry-After: 5
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 202 Accepted (asynchronous operation)
Required Scopes#
2022-01-01:
data_tables|w2026-01-01:
file:write
Important Notes#
In the 2026-01-01 API, both operations require the
file:writescope, but publishing all links still requires document ownership.The 2026-01-01 endpoint is asynchronous. Use the
Locationheader to poll for operation completion.Both endpoints are rate-limited and may experience rates as low as 20 requests per minute at the workspace level. When encountering a 429 status, examine the
Retry-Afterheader and retry after that many seconds.The new endpoint explicitly publishes content at the latest spreadsheet revision.
Migration Tips#
Update request body structure: Replace
"all": falsewith"publishType": "ownLinks"and"all": truewith"publishType": "allLinks"Make publishType required: Unlike the optional
allproperty in the old API,publishTypeis required in the new APIHandle asynchronous operation: Implement polling logic using the
Locationheader in the response to track operation completionUse Retry-After header: Respect the
Retry-Afterheader value (in seconds) when polling for results or retrying after rate limitsUpdate status code handling: Change success handler to expect
202 Acceptedinstead of200 OK
Migration: Retrieving Sheets in a Spreadsheet#
2022-01-01 Endpoint#
GET /spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets
2026-01-01 Endpoint#
GET /spreadsheets/{spreadsheetId}/sheets
Key Changes#
Path: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}/sheetsto/spreadsheets/{spreadsheetId}/sheetsResponse Structure: Changed from wrapped response with
dataandrevisionproperties to aSheetsListResultobjectSheet Object Structure: The new endpoint returns sheets with simplified structure including
id,name,parent,index,children, anddatasetpropertiesPagination: The new endpoint supports pagination via
@nextLinkfor large result setsRevision: Use the
$revisionquery parameter to retrieve sheets at a specific revision
Request Example#
2022-01-01 Request#
GET /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets
Authorization: Bearer {token}
2026-01-01 Request#
GET /spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets
Authorization: Bearer {token}
Response Example#
2022-01-01 Response#
{
"data": [
{
"id": "k78a604b74564afa76b5ba96755123456",
"name": "Q1 Results",
"parent_id": "",
"index": 0,
"child_ids": [],
"locked": false,
"input_mode": false,
"restricted": false
},
{
"id": "d10a604b74564afa86b5ba96755845652",
"name": "Q2 Results",
"parent_id": "",
"index": 1,
"child_ids": [],
"locked": false,
"input_mode": false,
"restricted": false
}
],
"revision": 1707951
}
2026-01-01 Response#
{
"data": [
{
"id": "242a56d3cc0742c8abad0820bd318b23",
"name": "Q1",
"parent": null,
"index": 0,
"children": [],
"dataset": null,
"customFields": {}
"revision": "2c6438ab454f2d35",
"table": {
"revision": "2c6438ab454f2d35",
"table": "WAwoICAsJfFtQSC4oT29AwFaRUY8Sg99wgBW3nodhoGQmSqagANsKJBW3"
}
},
{
"id": "132b55d1cd0543c1aaae0924bc328a24",
"name": "Q2",
"parent": null,
"index": 1,
"children": [],
"dataset": null,
"customFields": {},
"revision": "2c6438ab454f2d35",
"table": {
"revision": "2c6438ab454f2d35",
"table": "WAwoICAsJfFtQSC4oT29AwFaRUY8Sg99wgBW3nodhoGQmSqagANsKJCOg"
}
}
],
"@nextLink": "<opaque_url>"
}
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 200 OK
Required Scopes#
2022-01-01:
data_tables|r(read access to data tables)2026-01-01:
file:read(read access to files)
Migration Tips#
Handle pagination: Implement pagination support by checking for the
@nextLinkproperty in the response and following the link for additional resultsUse new sheet properties: Update your code to work with the new sheet object structure that includes
parent,index,children, anddatasetpropertiesLocks: Note that properties like
lockedandinput_modeare reflected by thelockproperty on the sheet. This field can be set tolockif the sheet is locked orinputModeif the sheet is in input mode.
Migration: Creating a Sheet in a Spreadsheet#
2022-01-01 Endpoint#
POST /spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets
2026-01-01 Endpoint#
POST /spreadsheets/{spreadsheetId}/sheets
Key Changes#
Path: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}/sheetsto/spreadsheets/{spreadsheetId}/sheetsRequest Body: Simplified request structure with optional properties
Required Fields: In the 2022-01-01 API,
name,parent_id, andindexwere all required. In the 2026-01-01 API, onlynameis required;parentandindexare optionalResponse Structure: Changed from wrapped response with
data,revision, andrequest_idproperties to a directSheetobjectSheet Object Structure: The new endpoint returns sheets with simplified structure using
parent(object) instead ofparent_id(string), andchildreninstead ofchild_idsDefault Behavior: If
indexis not specified, the sheet is created in the top-most position. If the name is not unique, a number is appended automatically
Request Example#
2022-01-01 Request#
POST /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets
Content-Type: application/json
Authorization: Bearer {token}
{
"name": "Q3 Results",
"parent_id": "",
"index": 2
}
2026-01-01 Request#
POST /spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets
Content-Type: application/json
Authorization: Bearer {token}
{
"name": "Q3",
"index": 2
}
Response Example#
2022-01-01 Response#
{
"data": {
"id": "k78a604b74564afa76b5ba96755123456",
"name": "Q3 Results",
"parent_id": "",
"index": 2,
"child_ids": [],
"locked": false,
"input_mode": false,
"restricted": false
},
"revision": 1707952,
"request_id": "a1b2c3d4-e5f6-4789-0123-456789abcdef"
}
2026-01-01 Response#
{
"id": "281c26d8ca0145c2cabe1714dc318c26",
"name": "Q3",
"parent": null,
"index": 2,
"children": [],
"dataset": null
}
HTTP Status#
2022-01-01: 201 Created
2026-01-01: 201 Created
Required Scopes#
2022-01-01:
data_tables|w(write access to data tables)2026-01-01:
file:write(write access to files)
Migration Tips#
Simplify request body: Remove the
parent_idparameter if creating a top-level sheet (the default behavior)Use -1 for end positioning: To position a sheet at the end of its siblings without knowing the count, use
index: -1in both APIsUpdate response parsing: Change from extracting
data.propertyto directly accessingpropertyon the response objectHandle automatic naming: The new API automatically appends numbers to duplicate sheet names, so you don’t need to implement your own uniqueness logic
Parent object instead of ID: The response now includes a
parentobject (ornullfor top-level sheets) instead of aparent_idstring
Migration: Deleting a Sheet from a Spreadsheet#
2022-01-01 Endpoint#
DELETE /spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}
2026-01-01 Endpoint#
DELETE /spreadsheets/{spreadsheetId}/sheets/{sheetId}
Key Changes#
Path: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}to/spreadsheets/{spreadsheetId}/sheets/{sheetId}Response Structure: Changed from a response with
messageandrequest_idproperties to no content (empty response body)HTTP Status: Changed from
200 OKto204 No ContentRecursive Deletion: Both APIs delete a sheet and all of its child sheets recursively
Request Example#
2022-01-01 Request#
DELETE /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/k78a604b74564afa76b5ba96755123456
Authorization: Bearer {token}
2026-01-01 Request#
DELETE /spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/281c26d8ca0145c2cabe1714dc318c26
Authorization: Bearer {token}
Response Example#
2022-01-01 Response#
{
"message": "No content returned.",
"request_id": "a1b2c3d4-e5f6-4789-0123-456789abcdef"
}
2026-01-01 Response#
HTTP/1.1 204 No Content
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 204 No Content
Required Scopes#
2022-01-01:
data_tables|w(write access to data tables)2026-01-01:
file:write(write access to files)
Important Notes#
Both endpoints permanently delete the specified sheet and all of its child sheets (recursively)
The 2026-01-01 endpoint returns an empty response body with a
204 No Contentstatus, following REST best practices for successful DELETE operationsOnce deleted, sheets cannot be recovered, so ensure you have proper confirmation workflows in your application
Migration Tips#
Update status code handling: Change your success handler to expect
204 No Contentinstead of200 OKHandle empty response: Update your code to handle an empty response body rather than parsing JSON content
Remove request_id tracking: The new endpoint doesn’t return a
request_idin the response; use theX-Request-IDheader if you need to track requests for debuggingConfirm before deletion: Implement proper confirmation dialogs in your application, as the deletion is permanent and includes all child sheets
Migration: Getting a Sheet by ID#
2022-01-01 Endpoint#
GET /spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}
2026-01-01 Endpoint#
GET /spreadsheets/{spreadsheetId}/sheets/{sheetId}
Key Changes#
Path: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}to/spreadsheets/{spreadsheetId}/sheets/{sheetId}Response Structure: Changed from wrapped response with
data,revision, andrequest_idproperties to a directSheetobjectSheet Object Structure: The new endpoint returns sheets with simplified structure using
parent(object/null) instead ofparent_id(string), andchildren(array) instead ofchild_ids(array of strings)Lock Properties: The
locked,input_mode, andrestrictedproperties from the 2022-01-01 API are no longer present. Lock status can be checked via thelockproperty.Revision: Use the
$revisionquery parameter to retrieve the sheet at a specific revision.
Request Example#
2022-01-01 Request#
GET /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/k78a604b74564afa76b5ba96755123456
Authorization: Bearer {token}
2026-01-01 Request#
GET /spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/242a56d3cc0742c8abad0820bd318b23
Authorization: Bearer {token}
Response Example#
2022-01-01 Response#
{
"data": {
"id": "k78a604b74564afa76b5ba96755123456",
"name": "Q1 Results",
"parent_id": "",
"index": 0,
"child_ids": [
"h65a604b74564afa86b5ba96755845652"
],
"locked": false,
"input_mode": false,
"restricted": false
},
"revision": 1707951,
"request_id": "a1b2c3d4-e5f6-4789-0123-456789abcdef"
}
2026-01-01 Response#
{
"id": "242a56d3cc0742c8abad0820bd318b23",
"name": "Q1",
"parent": null,
"index": 0,
"children": [
{
"id": "132b55d1cd0543c1aaae0924bc328a24",
"name": "Q1 Subtotals"
}
],
"dataset": null
}
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 200 OK
Required Scopes#
2022-01-01:
data_tables|r(read access to data tables)2026-01-01:
file:read(read access to files)
Migration Tips#
Update response parsing: Change from extracting
data.propertyto directly accessingpropertyon the response objectHandle parent structure: Update code that checks
parent_idto check forparentobject (will benullfor top-level sheets)Process children array: Instead of just IDs in
child_ids, the new endpoint returns partialSheetobjects in thechildrenarray with bothidandnamepropertiesHandle lock status: If you need to check lock status, note that
locked,input_mode, andrestrictedproperties are replaced by alockproperty in the new API (check the Sheets List migration section for details)
Migration: Updating a Sheet in a Spreadsheet#
2022-01-01 Endpoint#
PUT /spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}
2026-01-01 Endpoint#
PATCH /spreadsheets/{spreadsheetId}/sheets/{sheetId}
Key Changes#
HTTP Method: Changed from
PUTtoPATCHfor partial updatesPath: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}to/spreadsheets/{spreadsheetId}/sheets/{sheetId}Request Body Format: Changed from direct property object to JSON Patch (RFC 6902) format
Response Status: Changed from
200 OKto202 Accepted(asynchronous operation)Response Structure: The new endpoint is a long-running operation that returns a
Locationheader for polling resultsAdditional Capabilities: The new endpoint supports updating the
lockproperty to control sheet locking
Request Example#
2022-01-01 Request (Rename Only)#
PUT /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/k78a604b74564afa76b5ba96755123456
Content-Type: application/json
Authorization: Bearer {token}
{
"name": "Q1 Final"
}
2022-01-01 Request (Move and Rename)#
PUT /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/k78a604b74564afa76b5ba96755123456
Content-Type: application/json
Authorization: Bearer {token}
{
"name": "Q1 Final",
"parent_id": "d10a604b74564afa86b5ba96755845652",
"index": 0
}
2026-01-01 Request (Rename Only)#
PATCH /spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/242a56d3cc0742c8abad0820bd318b23
Content-Type: application/json
Authorization: Bearer {token}
[
{
"op": "replace",
"path": "/name",
"value": "Q1 Final"
}
]
2026-01-01 Request (Move and Rename)#
PATCH /spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/242a56d3cc0742c8abad0820bd318b23
Content-Type: application/json
Authorization: Bearer {token}
[
{
"op": "replace",
"path": "/name",
"value": "Q1 Final"
},
{
"op": "replace",
"path": "/parent",
"value": {
"id": "132b55d1cd0543c1aaae0924bc328a24"
}
},
{
"op": "replace",
"path": "/index",
"value": 0
}
]
2026-01-01 Request (Lock a Sheet)#
PATCH /spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/242a56d3cc0742c8abad0820bd318b23
Content-Type: application/json
Authorization: Bearer {token}
[
{
"op": "replace",
"path": "/lock",
"value": "lock"
}
]
Response Example#
2022-01-01 Response#
{
"message": "No content returned.",
"request_id": "a1b2c3d4-e5f6-4789-0123-456789abcdef"
}
2026-01-01 Response#
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://api.app.wdesk.com/operations/9b7dd722-cb79-4330-83da-f6c9633fc875
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 202 Accepted (asynchronous operation)
Required Scopes#
2022-01-01:
data_tables|w(write access to data tables)2026-01-01:
file:write(write access to files)
Supported PATCH Operations#
The 2026-01-01 endpoint supports the following JSON Patch operations:
/name: Update the sheet name using thereplaceoperation/index: Update the sheet’s position among siblings using thereplaceoperation/parent: Update the sheet’s parent using thereplaceoperation (requires an object with anidproperty)/lock: Update the sheet’s lock status using thereplaceoperation (values:"lock"for locked,"inputMode"for input mode, ornullfor unlocked)
Important Notes#
In the 2022-01-01 API, if
nameis set tonullor not included, the sheet will not be renamed. If bothparent_idandindexare set tonullor not included, the sheet will not be moved.The 2026-01-01 endpoint is asynchronous. Check the
Locationheader in the response to poll for operation completion.When moving a sheet to a new parent, you can optionally specify an
indexto control its position among the new siblings.Use
index: -1to position a sheet at the end of its siblings without knowing the total count.The new endpoint allows multiple properties to be updated in a single request using multiple JSON Patch operations.
Migration Tips#
Switch to JSON Patch format: Convert direct property updates to JSON Patch operations with
op,path, andvaluefieldsHandle parent object: When updating the parent, use an object with an
idproperty instead of a simple string IDImplement operation polling: Since the operation is asynchronous, implement polling logic using the
Locationheader to track completionBatch multiple updates: Take advantage of the ability to update multiple properties in a single request by including multiple JSON Patch operations
Handle lock operations: Use the new
/lockpath to programmatically lock or unlock sheets
Migration: Getting Table Cell Content with Rich Formatting#
2022-01-01 Endpoint#
GET /spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}/data/{region}
2026-01-01 Endpoint#
GET /content/tables/{tableId}/cells
Key Changes#
Path: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}/data/{region}to/content/tables/{tableId}/cellsIdentifiers: Changed from using
spreadsheetIdandsheetIdto usingtableId(the sheet’s underlying table identifier)Range Specification: Changed from A1-style notation (
regionpath parameter) to numeric row/column query parameters (startRow,stopRow,startColumn,stopColumn)Response Content: The new endpoint returns rich formatting information including cell properties, borders, colors, alignment, and rich text content, while the old endpoint only returned cell values
Response Structure: Changed from
RangeDataResponsetoTableCellsResultwith detailed cell properties and formattingPagination: Changed from
page/per_page/next_urlto$next/$maxcellsperpage/@nextLinkValue Format: The new endpoint returns both
value(with rich formatting) andrawValue(plain text) for each cellRevision Access: Both endpoints support the
$revisionquery parameter to retrieve cells at a specific revision
Request Example#
2022-01-01 Request (A1:C5 range)#
GET /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/k78a604b74564afa76b5ba96755123456/data/A1%3AC5
Authorization: Bearer {token}
2022-01-01 Request (With pagination)#
GET /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/k78a604b74564afa76b5ba96755123456/data/A1%3AC5?per_page=1000
Authorization: Bearer {token}
2026-01-01 Request (Rows 0-4, Columns 0-2)#
GET /content/tables/WAwoICAsJfFtQSC4oT29AwFaRUY8Sg99wgBW3nodhoGQmSqagANsKJBW3/cells?startRow=0&stopRow=4&startColumn=0&stopColumn=2
Authorization: Bearer {token}
2026-01-01 Request (With pagination)#
GET /content/tables/WAwoICAsJfFtQSC4oT29AwFaRUY8Sg99wgBW3nodhoGQmSqagANsKJBW3/cells?startRow=0&stopRow=4&startColumn=0&stopColumn=2&$maxcellsperpage=1000
Authorization: Bearer {token}
Response Example#
2022-01-01 Response#
{
"data": {
"range": "A1:C3",
"values": [
["First", "Second", "Third"],
["1", "2", ""],
["3", "4", "5"]
]
},
"revision": 1707951,
"request_id": "d6a6ce3f-f120-4104-9587-a5a2dc45626c"
}
2026-01-01 Response#
{
"data": [
{
"cells": [
{
"properties": {
"borders": {
"bottom": {
"color": {
"red": 128,
"green": 128,
"blue": 128
},
"style": "single",
"weight": 1
},
"left": {
"color": {
"red": 128,
"green": 128,
"blue": 128
},
"style": "single",
"weight": 1
},
"right": {
"color": {
"red": 128,
"green": 128,
"blue": 128
},
"style": "single",
"weight": 1
},
"top": {
"color": {
"red": 128,
"green": 128,
"blue": 128
},
"style": "single",
"weight": 1
}
},
"fillColor": {
"red": 136,
"green": 204,
"blue": 255
},
"horizontalAlignment": "left",
"indent": 10,
"verticalAlignment": "middle"
},
"rawValue": "Hello World",
"value": {
"richText": {
"paragraphs": [
{
"elements": [
{
"textSpan": {
"format": {},
"length": 5,
"offset": 0,
"text": "Hello",
"type": "text"
},
"type": "textSpan"
}
],
"format": {
"bold": true,
"font": "Arial",
"size": 24
},
"index": 3
}
]
},
"type": "richText"
}
}
]
}
],
"range": {
"startColumn": 0,
"startRow": 0,
"stopColumn": 0,
"stopRow": 0
},
"revision": "24601abc"
}
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 200 OK
Required Scopes#
2022-01-01:
data_tables|r(read access to data tables)2026-01-01:
file:read(read access to files)
Important Notes#
The new endpoint requires the
tableId, which can be obtained from the Sheet object’stable.tableproperty when retrieving sheetsThe 2022-01-01 endpoint uses A1-style notation (e.g.,
A1:C5) while the 2026-01-01 endpoint uses zero-based numeric indices for rows and columnsThe new endpoint returns comprehensive formatting information including borders, colors, alignment, indentation, and rich text formatting
Both
value(with formatting) andrawValue(plain text) are provided for each cell in the new endpointRange parameters in the 2026-01-01 endpoint are all optional. Omitting a parameter makes the range unbounded in that direction
Pagination uses
@nextLinkin the 2026-01-01 endpoint for retrieving subsequent pagesThe
$maxcellsperpagedefault and maximum is 50,000 cells in both APIs
Migration Tips#
Obtain the tableId: Before calling the new endpoint, retrieve the sheet and extract the
table.tableproperty to get the tableIdConvert A1 notation to numeric indices: Convert A1-style ranges (e.g.,
A1:C5) to zero-based row/column indices:Column A = 0, B = 1, C = 2, etc.
Row 1 = 0, Row 2 = 1, Row 3 = 2, etc.
Example:
A1:C5becomesstartRow=0&stopRow=4&startColumn=0&stopColumn=2
Parse rich formatting: Update your code to handle the new response structure with cell properties and rich text formatting
Use rawValue for simple text: If you only need plain text values (like in the old API), use the
rawValuepropertyHandle pagination: Use
@nextLinkfor pagination instead of constructing URLs with page numbersUpdate response parsing: The
dataproperty is now an array of objects containingcellsarrays, rather than a simple 2D array of valuesHandle revision as string: The revision is now an opaque string instead of an integer
Migration: Editing Table Cells with Rich Formatting#
2022-01-01 Endpoint#
PUT /spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}/data/{region}
2026-01-01 Endpoint#
POST /content/tables/{tableId}/cells/edit
Key Changes#
HTTP Method: Changed from
PUTtoPOSTPath: Changed from
/spreadsheets/v1/spreadsheets/{spreadsheetId}/sheets/{sheetId}/data/{region}to/content/tables/{tableId}/cells/editIdentifiers: Changed from using
spreadsheetIdandsheetIdto usingtableId(the sheet’s underlying table identifier)Range Specification: Changed from A1-style notation (
regionpath parameter) to numeric row/column properties in the request body (startRow,stopRow,startColumn,stopColumn)Request Body Structure: Changed from simple 2D array of values to batch edit format supporting multiple edit operations with rich formatting capabilities
Edit Capabilities: The new endpoint supports comprehensive cell editing including text, formatting, styles, borders, properties, and locking
Response Status: Changed from
200 OKto202 Accepted(asynchronous operation)Response Structure: Changed from
EmptyResponsewith message to a long-running operation withLocationheader for pollingLocked Cell Handling: The new endpoint includes a
lockedCellEditModeproperty to control how edits are handled for locked cellsRevision Support: Both endpoints support revision-based editing, but the 2026-01-01 API uses an opaque string revision instead of integer
Request Example#
2022-01-01 Request (Simple Text Update)#
PUT /spreadsheets/v1/spreadsheets/76515a4224224565ba1fae5e69ceaafd/sheets/k78a604b74564afa76b5ba96755123456/data/A1%3AC3
Content-Type: application/json
Authorization: Bearer {token}
{
"values": [
["First", "Second", "Third"],
["1", "2", ""],
["3", "4", "5"]
]
}
2026-01-01 Request (Simple Text Update)#
POST /content/tables/WAwoICAsJfFtQSC4oT29AwFaRUY8Sg99wgBW3nodhoGQmSqagANsKJBW3/cells/edit
Content-Type: application/json
Authorization: Bearer {token}
{
"data": [
{
"type": "setCellsText",
"setCellsText": {
"range": {
"startRow": 0,
"stopRow": 2,
"startColumn": 0,
"stopColumn": 2
},
"text": [
["First", "Second", "Third"],
["1", "2", ""],
["3", "4", "5"]
]
}
}
]
}
2026-01-01 Request (Multiple Edit Operations)#
POST /content/tables/WAwoICAsJfFtQSC4oT29AwFaRUY8Sg99wgBW3nodhoGQmSqagANsKJBW3/cells/edit
Content-Type: application/json
Authorization: Bearer {token}
{
"data": [
{
"type": "setCellsText",
"setCellsText": {
"range": {
"startRow": 0,
"stopRow": 2,
"startColumn": 0,
"stopColumn": 2
},
"text": [
["First", "Second", "Third"],
["1", "2", ""],
["3", "4", "5"]
]
}
},
{
"type": "formatCells",
"formatCells": {
"ranges": [
{
"startRow": 0,
"stopRow": 0,
"startColumn": 0,
"stopColumn": 2
}
],
"bold": true,
"size": 14
}
}
],
"lockedCellEditMode": "strict"
}
Response Example#
2022-01-01 Response#
{
"message": "No content returned.",
"request_id": "a1b2c3d4-e5f6-4789-0123-456789abcdef"
}
2026-01-01 Response#
HTTP/1.1 202 Accepted
Content-Type: application/json
Location: https://api.app.wdesk.com/operations/9b7dd722-cb79-4330-83da-f6c9633fc875
Retry-After: 5
HTTP Status#
2022-01-01: 200 OK
2026-01-01: 202 Accepted (asynchronous operation)
Required Scopes#
2022-01-01:
data_tables|w(write access to data tables)2026-01-01:
file:write(write access to files)
Supported Edit Types#
The 2026-01-01 endpoint supports the following edit types (up to 100 edits per request):
setCellsText: Write plain text to cells, preserving cell properties and some formattingrichCellBatchEdit: Write rich text with formatting to cellsclearCellsText: Clear text content from cellsformatCells: Apply text formatting (bold, italic, underline, font, size, color, etc.)clearCellsFormat: Clear text formatting from cellssetCellsStyle: Apply cell styles (number format, alignment, etc.)setCellsProperties: Set cell properties (background color, horizontal/vertical alignment, indent, etc.)clearCellsProperties: Clear cell propertiessetCellsBorders: Apply borders to cellsclearCellsBorders: Clear borders from cellssetCellsLock: Lock or unlock cellssetInputCells: Configure cells for input mode
Important Notes#
The new endpoint requires the
tableId, which can be obtained from the Sheet object’stable.tableproperty when retrieving sheetsThe 2022-01-01 endpoint uses A1-style notation (e.g.,
A1:C3) while the 2026-01-01 endpoint uses zero-based numeric indices for rows and columns in the request bodyThe new endpoint is asynchronous. Use the
Locationheader to poll for operation completionIn the 2026-01-01 API, you can batch multiple edit operations (up to 100) in a single request for better performance
The
lockedCellEditModeproperty controls behavior for locked cells:strict(default) will fail if any locked cells are in the edit range, whiletrimwill skip locked cellsThe provided text/edits may not be larger than the specified range. Any
nullor missing elements will not modify the corresponding cellBoth endpoints support revision-based editing to target a specific table version
Migration Tips#
Obtain the tableId: Before calling the new endpoint, retrieve the sheet and extract the
table.tableproperty to get the tableIdConvert A1 notation to numeric indices: Convert A1-style ranges (e.g.,
A1:C3) to zero-based row/column indices:Column A = 0, B = 1, C = 2, etc.
Row 1 = 0, Row 2 = 1, Row 3 = 2, etc.
Example:
A1:C3becomesstartRow: 0, stopRow: 2, startColumn: 0, stopColumn: 2
Wrap simple text updates: Wrap your 2D array of values in the
setCellsTextedit format with thedataarray and appropriatetypefieldLeverage batch edits: Take advantage of the ability to combine multiple operations (text updates, formatting, styling) in a single request
Handle asynchronous operation: Implement polling logic using the
Locationheader in the response to track operation completionUse Retry-After header: Respect the
Retry-Afterheader value (in seconds) when polling for results or retrying after rate limitsUpdate status code handling: Change success handler to expect
202 Acceptedinstead of200 OKHandle locked cells: Set
lockedCellEditModetotrimif you want to skip locked cells instead of failing the entire operationHandle revision as string: The revision is now an opaque string instead of an integer
Consider edit capabilities: The new endpoint provides extensive formatting and styling capabilities beyond simple text updates