> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.staple.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.staple.ai/_mcp/server.

# Save Document Data

POST https://api.staple.io/v2/documents/save
Content-Type: application/json

Save sidebar field values and complex table rows on a document without completing it. The document keeps its status, and no export, webhook or completion side effect runs. Use it to store edits made outside the Staple UI, for example from a review tool of your own.

##### HOW TO ADDRESS DATA

* Sidebar fields are addressed by `fieldUuid`. Get the ids from `POST /v2/search/documents/model/fields` (`field_id`) or from the document JSON returned by `GET /v1/documents/:docId` (`field_id` on each field).
* Tables are addressed by `tableTypeId` or `tableName`, plus a 0-based `pageNumber`. Get the table type and header ids from `POST /v2/search/documents/model/tables`. `tableName` is the model's table name returned there (for example `Tax Table`); the name a document shows for its own table is accepted too.
* Rows are addressed by `lineItemId` or 0-based `rowIndex` on that page. Cells are keyed by header id or header name: the model's `headerName` (for example `Tax Code`), or the column name the document shows.
* A name that matches more than one table type or header is rejected with 400. Use the id instead.

##### HOW ROWS ARE APPLIED

* On an existing row only the cells you send change. Cells you leave out keep their value.
* Only the rows you send change. Rows you do not mention are kept as they are.
* Rows without `lineItemId` or `rowIndex` are added at the end of the page. A new row needs at least one cell.
* To clear a value, send it as an empty string.
* `removeRows` deletes rows on that page, each by `lineItemId` or `rowIndex` (the position before this save). A row cannot be patched and removed in the same request.
* Rows on other pages are untouched.
* `removeColumns` (header id or name) removes those columns from every page of the table type, the same as removing a column in the editor.

##### VALIDATION AND VERSIONING

* Every changed value is validated against the data type of its field or header. If any value is invalid the whole request is refused with 422 and `errors.invalidValues`, and nothing is saved.
* Send `expectedDataVersion` with the `dataVersion` you received from `GET /v1/documents/:docId`. If someone changed the document since then the request is refused with 409 and `errors.currentDataVersion`. Reload the document, or resend with the current version to overwrite.
* Locked fields and exported documents cannot be changed (403).
* Limited to 6 calls per 30 seconds per user.

##### REQUEST HEADERS

| Attribute     | Type             | Option   | Description           |
| ------------- | ---------------- | -------- | --------------------- |
| x-api-key     | String           | Required | An unique string      |
| Authorization | String           | Required | The bearer token      |
| Content-Type  | application/json | Required | The original resource |

##### REQUEST PAYLOAD

```
{
    "documentId": Int | required,
    "qid": Int | required | the queue the document is in,
    "expectedDataVersion": String | optional | dataVersion from GET /v1/documents/:docId,
    "fields": Array | optional | [{ "fieldUuid": String, "value": String }],
    "tables": Array | optional | [{
        "tableTypeId" | "tableName": String,
        "pageNumber": Int (0-based),
        "rows": [{ "lineItemId"? | "rowIndex"?, "cells": { header_id_or_name: String } }] | optional,
        "removeRows": [{ "lineItemId" | "rowIndex" }] | optional,
        "removeColumns": [ header_id_or_name ] | optional
    }]
}
```

At least one of `fields` or `tables` is required. Each table entry needs at least one of `rows`, `removeRows`, `removeColumns`.

##### RESPONSE BODY

| Attribute   | Type   | Description                                                                                                                                           |
| ----------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| message     | String | Confirmation message                                                                                                                                  |
| documentId  | Int    | The document id                                                                                                                                       |
| qid         | Int    | The queue id                                                                                                                                          |
| dataVersion | String | New version token to send as `expectedDataVersion` on the next save                                                                                   |
| fields      | Array  | Saved fields: `fieldUuid`, `value` (stored, canonical form), `originalValue`                                                                          |
| tables      | Array  | Per page: `tableTypeId`, `pageNumber`, `tableName` (the model's table name), `rowCount`, `addedLineItemIds`, `removedLineItemIds`, `removedColumnIds` |

##### ERRORS

| Status | Meaning                                                                                                              |
| ------ | -------------------------------------------------------------------------------------------------------------------- |
| 400    | Malformed body, ambiguous name, row listed twice, row from another page, empty new row, row both patched and removed |
| 403    | Locked field, exported document, or no access to the queue                                                           |
| 404    | Document, field, table, page, row or column not found                                                                |
| 409    | Document changed since you loaded it (`errors.currentDataVersion`)                                                   |
| 422    | Values invalid for their data type (`errors.invalidValues`)                                                          |
| 503    | Validation service unavailable, nothing saved                                                                        |

Reference: https://docs.staple.ai/api-reference/v2/documents/save-document-data

## Authentication

- `x-api-key` header (required) — API key issued by Staple.
- `Authorization` header (bearer token, required) — JWT obtained from the login endpoint.

## Request

### Body (application/json)

This endpoint expects an object.

- `documentId` (integer, optional)
- `qid` (integer, optional)
- `expectedDataVersion` (string, optional)
- `fields` (list of V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaFieldsItems, optional)
- `tables` (list of V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaTablesItems, optional)

## Response

### 200

OK

## Types

### V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaFieldsItems

- `fieldUuid` (string, optional)
- `value` (string, optional)

### V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaTablesItems

- `tableTypeId` (string, optional)
- `pageNumber` (integer, optional)
- `rows` (list of V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaTablesItemsRowsItems, optional)
- `removeRows` (list of V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaTablesItemsRemoveRowsItems, optional)

### V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaTablesItemsRowsItems

- `lineItemId` (string, optional)
- `cells` (V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaTablesItemsRowsItemsCells, optional)

### V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaTablesItemsRemoveRowsItems

- `lineItemId` (string, optional)
- `rowIndex` (integer, optional)

### V2DocumentsSavePostRequestBodyContentApplicationJsonSchemaTablesItemsRowsItemsCells

- `8b76bc3d-25f7-4080-a9e2-f395e4e48018` (string, optional)

## Examples

### Save Document Data

**Request**

```json
undefined
```

**Response**

```json
{
  "dataVersion": "2026-09-23T10:39:16.330Z",
  "documentId": 248161,
  "fields": [
    {
      "fieldUuid": "0ff92b5f-de92-4ae1-90c0-bb2a86730340",
      "originalValue": "INV-2026-0041",
      "value": "INV-2026-0042"
    }
  ],
  "message": "Updated successfully.",
  "qid": 4701,
  "tables": [
    {
      "addedLineItemIds": [
        "c1d2e3f4-0a1b-4c2d-8e3f-4a5b6c7d8e9f"
      ],
      "pageNumber": 0,
      "removedColumnIds": [],
      "removedLineItemIds": [
        "00811ea5-f90c-453c-8d5d-7a40812133d1"
      ],
      "rowCount": 3,
      "tableName": "INVOICE COMPLEX TABLE",
      "tableTypeId": "64163822-5aac-46e1-86a4-24cb74c69f5e"
    }
  ]
}
```

**SDK Code**

```python Save Document Data
import requests

url = "https://api.staple.io/v2/documents/save"

headers = {"x-api-key": "<apiKey>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Save Document Data
const url = 'https://api.staple.io/v2/documents/save';
const options = {method: 'POST', headers: {'x-api-key': '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Save Document Data
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.staple.io/v2/documents/save"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("x-api-key", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Save Document Data
require 'uri'
require 'net/http'

url = URI("https://api.staple.io/v2/documents/save")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'

response = http.request(request)
puts response.read_body
```

```java Save Document Data
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.staple.io/v2/documents/save")
  .header("x-api-key", "<apiKey>")
  .asString();
```

```php Save Document Data
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.staple.io/v2/documents/save', [
  'headers' => [
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Save Document Data
using RestSharp;

var client = new RestClient("https://api.staple.io/v2/documents/save");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift Save Document Data
import Foundation

let headers = ["x-api-key": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.staple.io/v2/documents/save")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Save by table name, header name and row index

**Request**

```json
undefined
```

**Response**

```json
{
  "dataVersion": "2026-09-23T10:39:17.461Z",
  "documentId": 248161,
  "fields": [],
  "message": "Updated successfully.",
  "qid": 4701,
  "tables": [
    {
      "addedLineItemIds": [],
      "pageNumber": 0,
      "removedColumnIds": [],
      "removedLineItemIds": [],
      "rowCount": 3,
      "tableName": "INVOICE COMPLEX TABLE",
      "tableTypeId": "64163822-5aac-46e1-86a4-24cb74c69f5e"
    }
  ]
}
```

**SDK Code**

```python Save by table name, header name and row index
import requests

url = "https://api.staple.io/v2/documents/save"

headers = {"x-api-key": "<apiKey>"}

response = requests.post(url, headers=headers)

print(response.json())
```

```javascript Save by table name, header name and row index
const url = 'https://api.staple.io/v2/documents/save';
const options = {method: 'POST', headers: {'x-api-key': '<apiKey>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Save by table name, header name and row index
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.staple.io/v2/documents/save"

	req, _ := http.NewRequest("POST", url, nil)

	req.Header.Add("x-api-key", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Save by table name, header name and row index
require 'uri'
require 'net/http'

url = URI("https://api.staple.io/v2/documents/save")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'

response = http.request(request)
puts response.read_body
```

```java Save by table name, header name and row index
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.staple.io/v2/documents/save")
  .header("x-api-key", "<apiKey>")
  .asString();
```

```php Save by table name, header name and row index
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.staple.io/v2/documents/save', [
  'headers' => [
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Save by table name, header name and row index
using RestSharp;

var client = new RestClient("https://api.staple.io/v2/documents/save");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

```swift Save by table name, header name and row index
import Foundation

let headers = ["x-api-key": "<apiKey>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.staple.io/v2/documents/save")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Documents_saveDocumentData_example

**Request**

```json
{
  "documentId": 248161,
  "qid": 4701,
  "expectedDataVersion": "2026-09-17T16:25:56.465Z",
  "fields": [
    {
      "fieldUuid": "0ff92b5f-de92-4ae1-90c0-bb2a86730340",
      "value": "INV-2026-0042"
    }
  ],
  "tables": [
    {
      "tableTypeId": "64163822-5aac-46e1-86a4-24cb74c69f5e",
      "pageNumber": 0,
      "rows": [
        {
          "lineItemId": "b7855902-03a5-4115-a6b5-af479dfffd80",
          "cells": {
            "8b76bc3d-25f7-4080-a9e2-f395e4e48018": "ITM-1007"
          }
        },
        {
          "lineItemId": "af9a4ae3-e2fa-497c-95ba-6421a6bd85cf",
          "cells": {}
        },
        {
          "cells": {
            "Item Code": "ITM-1010",
            "Quantity": "1"
          }
        }
      ]
    }
  ]
}
```

**Response**

```json
{
  "dataVersion": "2026-09-23T10:39:16.330Z",
  "documentId": 248161,
  "fields": [
    {
      "fieldUuid": "0ff92b5f-de92-4ae1-90c0-bb2a86730340",
      "originalValue": "INV-2026-0041",
      "value": "INV-2026-0042"
    }
  ],
  "message": "Updated successfully.",
  "qid": 4701,
  "tables": [
    {
      "addedLineItemIds": [
        "c1d2e3f4-0a1b-4c2d-8e3f-4a5b6c7d8e9f"
      ],
      "pageNumber": 0,
      "removedColumnIds": [],
      "removedLineItemIds": [
        "00811ea5-f90c-453c-8d5d-7a40812133d1"
      ],
      "rowCount": 3,
      "tableName": "INVOICE COMPLEX TABLE",
      "tableTypeId": "64163822-5aac-46e1-86a4-24cb74c69f5e"
    }
  ]
}
```

**SDK Code**

```python Documents_saveDocumentData_example
import requests

url = "https://api.staple.io/v2/documents/save"

payload = {
    "documentId": 248161,
    "qid": 4701,
    "expectedDataVersion": "2026-09-17T16:25:56.465Z",
    "fields": [
        {
            "fieldUuid": "0ff92b5f-de92-4ae1-90c0-bb2a86730340",
            "value": "INV-2026-0042"
        }
    ],
    "tables": [
        {
            "tableTypeId": "64163822-5aac-46e1-86a4-24cb74c69f5e",
            "pageNumber": 0,
            "rows": [{
                    "lineItemId": "b7855902-03a5-4115-a6b5-af479dfffd80",
                    "cells": { "8b76bc3d-25f7-4080-a9e2-f395e4e48018": "ITM-1007" }
                }, {
                    "lineItemId": "af9a4ae3-e2fa-497c-95ba-6421a6bd85cf",
                    "cells": {}
                }, { "cells": {
                        "Item Code": "ITM-1010",
                        "Quantity": "1"
                    } }]
        }
    ]
}
headers = {
    "x-api-key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Documents_saveDocumentData_example
const url = 'https://api.staple.io/v2/documents/save';
const options = {
  method: 'POST',
  headers: {'x-api-key': '<apiKey>', 'Content-Type': 'application/json'},
  body: '{"documentId":248161,"qid":4701,"expectedDataVersion":"2026-09-17T16:25:56.465Z","fields":[{"fieldUuid":"0ff92b5f-de92-4ae1-90c0-bb2a86730340","value":"INV-2026-0042"}],"tables":[{"tableTypeId":"64163822-5aac-46e1-86a4-24cb74c69f5e","pageNumber":0,"rows":[{"lineItemId":"b7855902-03a5-4115-a6b5-af479dfffd80","cells":{"8b76bc3d-25f7-4080-a9e2-f395e4e48018":"ITM-1007"}},{"lineItemId":"af9a4ae3-e2fa-497c-95ba-6421a6bd85cf","cells":{}},{"cells":{"Item Code":"ITM-1010","Quantity":"1"}}]}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Documents_saveDocumentData_example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.staple.io/v2/documents/save"

	payload := strings.NewReader("{\n  \"documentId\": 248161,\n  \"qid\": 4701,\n  \"expectedDataVersion\": \"2026-09-17T16:25:56.465Z\",\n  \"fields\": [\n    {\n      \"fieldUuid\": \"0ff92b5f-de92-4ae1-90c0-bb2a86730340\",\n      \"value\": \"INV-2026-0042\"\n    }\n  ],\n  \"tables\": [\n    {\n      \"tableTypeId\": \"64163822-5aac-46e1-86a4-24cb74c69f5e\",\n      \"pageNumber\": 0,\n      \"rows\": [\n        {\n          \"lineItemId\": \"b7855902-03a5-4115-a6b5-af479dfffd80\",\n          \"cells\": {\n            \"8b76bc3d-25f7-4080-a9e2-f395e4e48018\": \"ITM-1007\"\n          }\n        },\n        {\n          \"lineItemId\": \"af9a4ae3-e2fa-497c-95ba-6421a6bd85cf\",\n          \"cells\": {}\n        },\n        {\n          \"cells\": {\n            \"Item Code\": \"ITM-1010\",\n            \"Quantity\": \"1\"\n          }\n        }\n      ]\n    }\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("x-api-key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Documents_saveDocumentData_example
require 'uri'
require 'net/http'

url = URI("https://api.staple.io/v2/documents/save")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<apiKey>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"documentId\": 248161,\n  \"qid\": 4701,\n  \"expectedDataVersion\": \"2026-09-17T16:25:56.465Z\",\n  \"fields\": [\n    {\n      \"fieldUuid\": \"0ff92b5f-de92-4ae1-90c0-bb2a86730340\",\n      \"value\": \"INV-2026-0042\"\n    }\n  ],\n  \"tables\": [\n    {\n      \"tableTypeId\": \"64163822-5aac-46e1-86a4-24cb74c69f5e\",\n      \"pageNumber\": 0,\n      \"rows\": [\n        {\n          \"lineItemId\": \"b7855902-03a5-4115-a6b5-af479dfffd80\",\n          \"cells\": {\n            \"8b76bc3d-25f7-4080-a9e2-f395e4e48018\": \"ITM-1007\"\n          }\n        },\n        {\n          \"lineItemId\": \"af9a4ae3-e2fa-497c-95ba-6421a6bd85cf\",\n          \"cells\": {}\n        },\n        {\n          \"cells\": {\n            \"Item Code\": \"ITM-1010\",\n            \"Quantity\": \"1\"\n          }\n        }\n      ]\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java Documents_saveDocumentData_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.staple.io/v2/documents/save")
  .header("x-api-key", "<apiKey>")
  .header("Content-Type", "application/json")
  .body("{\n  \"documentId\": 248161,\n  \"qid\": 4701,\n  \"expectedDataVersion\": \"2026-09-17T16:25:56.465Z\",\n  \"fields\": [\n    {\n      \"fieldUuid\": \"0ff92b5f-de92-4ae1-90c0-bb2a86730340\",\n      \"value\": \"INV-2026-0042\"\n    }\n  ],\n  \"tables\": [\n    {\n      \"tableTypeId\": \"64163822-5aac-46e1-86a4-24cb74c69f5e\",\n      \"pageNumber\": 0,\n      \"rows\": [\n        {\n          \"lineItemId\": \"b7855902-03a5-4115-a6b5-af479dfffd80\",\n          \"cells\": {\n            \"8b76bc3d-25f7-4080-a9e2-f395e4e48018\": \"ITM-1007\"\n          }\n        },\n        {\n          \"lineItemId\": \"af9a4ae3-e2fa-497c-95ba-6421a6bd85cf\",\n          \"cells\": {}\n        },\n        {\n          \"cells\": {\n            \"Item Code\": \"ITM-1010\",\n            \"Quantity\": \"1\"\n          }\n        }\n      ]\n    }\n  ]\n}")
  .asString();
```

```php Documents_saveDocumentData_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.staple.io/v2/documents/save', [
  'body' => '{
  "documentId": 248161,
  "qid": 4701,
  "expectedDataVersion": "2026-09-17T16:25:56.465Z",
  "fields": [
    {
      "fieldUuid": "0ff92b5f-de92-4ae1-90c0-bb2a86730340",
      "value": "INV-2026-0042"
    }
  ],
  "tables": [
    {
      "tableTypeId": "64163822-5aac-46e1-86a4-24cb74c69f5e",
      "pageNumber": 0,
      "rows": [
        {
          "lineItemId": "b7855902-03a5-4115-a6b5-af479dfffd80",
          "cells": {
            "8b76bc3d-25f7-4080-a9e2-f395e4e48018": "ITM-1007"
          }
        },
        {
          "lineItemId": "af9a4ae3-e2fa-497c-95ba-6421a6bd85cf",
          "cells": {}
        },
        {
          "cells": {
            "Item Code": "ITM-1010",
            "Quantity": "1"
          }
        }
      ]
    }
  ]
}',
  'headers' => [
    'Content-Type' => 'application/json',
    'x-api-key' => '<apiKey>',
  ],
]);

echo $response->getBody();
```

```csharp Documents_saveDocumentData_example
using RestSharp;

var client = new RestClient("https://api.staple.io/v2/documents/save");
var request = new RestRequest(Method.POST);
request.AddHeader("x-api-key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"documentId\": 248161,\n  \"qid\": 4701,\n  \"expectedDataVersion\": \"2026-09-17T16:25:56.465Z\",\n  \"fields\": [\n    {\n      \"fieldUuid\": \"0ff92b5f-de92-4ae1-90c0-bb2a86730340\",\n      \"value\": \"INV-2026-0042\"\n    }\n  ],\n  \"tables\": [\n    {\n      \"tableTypeId\": \"64163822-5aac-46e1-86a4-24cb74c69f5e\",\n      \"pageNumber\": 0,\n      \"rows\": [\n        {\n          \"lineItemId\": \"b7855902-03a5-4115-a6b5-af479dfffd80\",\n          \"cells\": {\n            \"8b76bc3d-25f7-4080-a9e2-f395e4e48018\": \"ITM-1007\"\n          }\n        },\n        {\n          \"lineItemId\": \"af9a4ae3-e2fa-497c-95ba-6421a6bd85cf\",\n          \"cells\": {}\n        },\n        {\n          \"cells\": {\n            \"Item Code\": \"ITM-1010\",\n            \"Quantity\": \"1\"\n          }\n        }\n      ]\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Documents_saveDocumentData_example
import Foundation

let headers = [
  "x-api-key": "<apiKey>",
  "Content-Type": "application/json"
]
let parameters = [
  "documentId": 248161,
  "qid": 4701,
  "expectedDataVersion": "2026-09-17T16:25:56.465Z",
  "fields": [
    [
      "fieldUuid": "0ff92b5f-de92-4ae1-90c0-bb2a86730340",
      "value": "INV-2026-0042"
    ]
  ],
  "tables": [
    [
      "tableTypeId": "64163822-5aac-46e1-86a4-24cb74c69f5e",
      "pageNumber": 0,
      "rows": [[
          "lineItemId": "b7855902-03a5-4115-a6b5-af479dfffd80",
          "cells": ["8b76bc3d-25f7-4080-a9e2-f395e4e48018": "ITM-1007"]
        ], [
          "lineItemId": "af9a4ae3-e2fa-497c-95ba-6421a6bd85cf",
          "cells": []
        ], ["cells": [
            "Item Code": "ITM-1010",
            "Quantity": "1"
          ]]]
    ]
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.staple.io/v2/documents/save")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```