> For the complete documentation index, see [llms.txt](https://help.csvbox.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.csvbox.io/advanced-installation/sheet-api.md).

# Sheet API

## Create Sheet

> Creates a new sheet importer.

```json
{"openapi":"3.0.0","info":{"title":"CSVBox Sheets API Documentation","version":"1.2.0"},"tags":[{"name":"Sheets","description":"Sheets"}],"servers":[{"url":"https://api.csvbox.io/","description":"CSVBox Sheets API Server"}],"security":[{"ApiKeyAuth":[],"ApiSecretKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"x-csvbox-api-key","in":"header"}},"parameters":{"AcceptHeader":{"name":"Accept","in":"header","description":"Must be application/json","required":true,"schema":{"type":"string"}},"ContentTypeHeader":{"name":"Content-Type","in":"header","description":"Content type must be application/json","required":true,"schema":{"type":"string"}}},"schemas":{"CreateSheetRequest":{"required":["title"],"properties":{"title":{"type":"string"},"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"destinations":{"type":"array","items":{"$ref":"#/components/schemas/Destinations"}},"sheet_columns":{"type":"array","items":{"$ref":"#/components/schemas/SheetColumn"}},"steps":{"$ref":"#/components/schemas/Steps"},"security_settings":{"$ref":"#/components/schemas/SecuritySettings"},"virtual_columns":{"description":"POST: every item listed is created. Omitting the key creates nothing.","type":"array","items":{"$ref":"#/components/schemas/VirtualColumn"},"maxItems":20},"validation_functions":{"description":"POST: every item listed is created. Omitting the key creates nothing. Two functions are shown: `check_email` needs nothing beyond the built-ins, while `check_date` declares `dayjs` — remove that dependency and its code is rejected with js_disallowed_global. That entry omits the optional `integrity` field so this body can be sent unmodified; in your own sheet add `\"integrity\": \"sha384-<digest published by the CDN>\"` beside the `url`, and add further scripts as further comma-separated objects in the same array (5 max).","type":"array","items":{"$ref":"#/components/schemas/ValidationFunction"},"maxItems":10},"data_transforms":{"description":"POST: every item listed is created. Omitting the key creates nothing.","type":"array","items":{"$ref":"#/components/schemas/DataTransform"},"maxItems":10}},"type":"object"},"Webhook":{"properties":{"import_complete":{"$ref":"#/components/schemas/WebhookImportComplete"}},"type":"object"},"WebhookImportComplete":{"properties":{"url":{"type":"string","format":"url"},"send_copy":{"description":"Send a copy of imported data to client","type":"boolean"},"custom_headers":{"type":"array","items":{"$ref":"#/components/schemas/Header"}}},"type":"object"},"Header":{"required":["key","value"],"properties":{"key":{"description":"---------------------------------------------------------\nHEADER OBJECT\n---------------------------------------------------------","type":"string"},"value":{"type":"string"}},"type":"object"},"Destinations":{"properties":{"type":{"type":"string","enum":["webhook","testapi","none"]},"isActive":{"type":"boolean"},"settings":{"properties":{"method":{"type":"string","enum":["POST","PATCH"]},"url":{"type":"string","format":"url"},"post_data_format":{"type":"string","enum":["JSON","FORM_DATA","XML"]},"rows_per_chunk":{"type":"integer"},"request_type":{"type":"string","enum":["parallel","sequential"]},"server_side_validation":{"type":"boolean"},"allow_resubmit":{"type":"string","enum":["all_rows","error_rows_only"]},"custom_headers":{"type":"array","items":{"$ref":"#/components/schemas/Header"}}},"type":"object"}},"type":"object"},"SheetColumn":{"required":["column_name"],"properties":{"column_name":{"type":"string"},"display_label":{"type":"string"},"info_hint":{"type":"string"},"matching_keywords":{"type":"string"},"type":{"type":"string","enum":["text","number","email","date","time","boolean","regex","ip","url","credit_card","phone_number","currency","list","dependent_list","dynamic_list","dependent_dynamic_list","multiselect_list","multiselect_dynamic_list"]},"default_value":{"type":"string"},"required":{"type":"boolean"},"read_only":{"type":"boolean"},"position":{"type":"integer","minimum":1},"validators":{"description":"Validators depend on the column type. See examples below for each type.","properties":{"min_length":{"description":"[text] Minimum character length","type":"integer"},"max_length":{"description":"[text] Maximum character length","type":"integer"},"min_value":{"description":"[number] Minimum numeric value","type":"number"},"max_value":{"description":"[number] Maximum numeric value","type":"number"},"format":{"description":"[date] Date format e.g. YYYY-MM-DD | [time] Time format e.g. HH:mm:ss","type":"string"},"expression":{"description":"[regex] Regular expression pattern","type":"string"},"error_message":{"description":"[regex] Custom error message","type":"string"},"version":{"description":"[ip] IP version","type":"string","enum":["ipv4","ipv6"]},"country_code":{"description":"[phone_number] Country code e.g. IN, US","type":"string"},"symbol":{"description":"[currency] Currency symbol","type":"string"},"require_symbol":{"description":"[currency] Whether symbol is required","type":"boolean"},"values":{"description":"[list] Array of ListItem objects (with dependents) | [multiselect_list] Array of strings","oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/ListItem"}},{"type":"array","items":{"type":"string"}}]},"case_sensitive":{"description":"[list, multiselect_list] Case-sensitive matching","type":"boolean"},"primary_column":{"description":"[dependent_list, dependent_dynamic_list] The column_name of the parent list column","type":"string"},"source_url":{"description":"[dynamic_list, multiselect_dynamic_list] URL to fetch list options from","type":"string"},"request_method":{"description":"[dynamic_list, multiselect_dynamic_list] HTTP method","type":"string","enum":["GET","POST"]},"request_headers":{"description":"[dynamic_list, multiselect_dynamic_list] Custom request headers","type":"array","items":{"$ref":"#/components/schemas/Header"}},"custom_user_attributes":{"description":"[dynamic_list] Include custom user attributes in request","type":"boolean"},"other_values":{"description":"[dynamic_list, multiselect_list, multiselect_dynamic_list] Allow values outside predefined list","type":"boolean"},"delimiter":{"description":"[multiselect_list, multiselect_dynamic_list] Delimiter for multiple values","type":"string"}},"type":"object"}},"type":"object"},"ListItem":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"},"dependents":{"type":"array","items":{"$ref":"#/components/schemas/ListItemChild"}}},"type":"object"},"ListItemChild":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"},"dependents":{"type":"array","items":{"$ref":"#/components/schemas/ListItemDependent"}}},"type":"object"},"ListItemDependent":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"}},"type":"object"},"Steps":{"properties":{"file_upload":{"properties":{"types":{"type":"array","items":{"type":"string"}},"title":{"type":"string"},"help":{"type":"string"},"sample_file_url":{"type":"string"},"size_mb":{"type":"integer"},"validation_msg":{"type":"string"},"copy_paste":{"type":"boolean"},"copy_delimiter":{"type":"string"},"show_upload":{"type":"boolean"},"worksheet_select":{"type":"boolean"},"description_option":{"type":"boolean"},"lang":{"type":"string"},"excel_date_format":{"type":"string"},"excel_date_custom":{"type":"string"},"hide_cancel":{"type":"boolean"},"split":{"description":"Split large files into multiple imports","type":"boolean"},"split_rows":{"description":"Rows per import when splitting (min 1)","type":"integer"},"split_confirm":{"description":"User confirmation required after each import: no=0, yes=1, no_if_no_errors=2","type":"string","enum":["no","yes","no_if_no_errors"]},"extract_types":{"description":"Allowed document extraction types (mapped to .pdf/.doc/images)","type":"array","items":{"type":"string","enum":["pdf","docs","images"]}},"page_limit":{"description":"Max pages allowed for extraction (null = no limit)","type":"integer","nullable":true}},"type":"object"},"select_header":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"default_row":{"type":"string"},"encoding_option":{"type":"boolean"},"encoding":{"type":"string"},"row_column_switch":{"type":"boolean"}},"type":"object"},"map_columns":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"mapping_mode":{"type":"string"},"bulk_cols_dd":{"type":"boolean"},"accept_unmapped":{"type":"boolean"},"accept_unmapped_select":{"type":"boolean"},"allow_zero_template":{"type":"boolean"},"ignore_cols":{"type":"boolean"},"ignore_cols_default":{"type":"boolean"},"user_keywords":{"type":"boolean"}},"type":"object"},"verify_data":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"row_display_mode":{"type":"string"},"export_option":{"type":"boolean"},"search_option":{"type":"boolean"},"ai_transform":{"type":"boolean"},"allow_new_rows":{"type":"boolean"},"rows_display":{"type":"integer"},"allow_invalid":{"type":"boolean"},"invalid_confirmation":{"type":"boolean"},"max_rows":{"type":"integer"},"allow_upload_if_max":{"type":"boolean"},"max_rows_msg":{"type":"string"},"min_rows":{"type":"integer"},"min_rows_msg":{"type":"string"}},"type":"object"},"results":{"properties":{"close_mode":{"type":"string"},"redirect_url":{"type":"string"},"success_type":{"type":"string"},"success_text":{"type":"string"},"success_method":{"type":"string"},"success_url":{"type":"string"},"failed_type":{"type":"string"},"failed_text":{"type":"string"},"failed_method":{"type":"string"},"failed_url":{"type":"string"},"show_resubmit":{"type":"boolean"},"show_error_text":{"type":"boolean"}},"type":"object"}},"type":"object"},"SecuritySettings":{"properties":{"region":{"type":"string","enum":["us","eu"]},"domains":{"type":"array","items":{"type":"string"}},"import_url_upload":{"type":"boolean"},"s3_upload":{"type":"boolean"}},"type":"object"},"VirtualColumn":{"description":"A computed column. Max 20 per sheet. `column_name` must not collide with a real sheet column.","required":["column_name"],"properties":{"column_name":{"type":"string","maxLength":190},"js_code":{"description":"Function body receiving a single `csvbox` argument and returning the computed value. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"description":"Defaults to true on API create — unlike the web UI, whose post-save toggle starts off.","type":"boolean","default":true},"dependencies":{"description":"Supported here as on every collection. Empty in this example because the snippet above needs only `csvbox` and built-ins — see the `check_date` validation function for a worked dependency. To use one here, send `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`; `globals` and `integrity` are optional, and further scripts are further objects in the same array. See the JsDependency schema for the host allowlist and per-field rules.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. When true the item is deleted and every other field on it is ignored, including `js_code`.","type":"boolean"}},"type":"object"},"JsDependency":{"description":"A third-party script an item's `js_code` may use. The API never accepts raw HTML — send the URL and the server renders the <script src> tag. Migrating from the web UI: `js_dependency` markup is not a writable field. Full shape, all three fields, on any of the three collections: `\"dependencies\": [{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`. Only `url` is required; `globals` is what makes the library's name callable from `js_code`, and `integrity` is optional. Up to 5 dependencies per item — send them as separate objects in the array, comma-separated, one per script. The server renders each as `<script src=\"…\" integrity=\"…\" crossorigin=\"anonymous\"></script>`, in the order sent, so a library that must load before another goes first.","required":["url"],"properties":{"url":{"description":"HTTPS only. Host must be exactly cdn.jsdelivr.net, unpkg.com or cdnjs.cloudflare.com (no subdomains). Path must end in .js or .mjs. No query string, fragment, userinfo or port.","type":"string","format":"url","maxLength":512},"globals":{"description":"Names this script defines. Each is added to the allowed-identifier list for this item only — code referencing an undeclared global is rejected with js_disallowed_global. May not shadow a built-in or `csvbox`. Loading the script is not enough on its own: the code gate checks this list, so a name absent from it is refused whether or not the CDN would have defined it at runtime. Up to 5 names, each matching /^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/.","type":"array","items":{"type":"string"},"maxItems":5},"integrity":{"description":"Optional Subresource Integrity digest: sha256-, sha384- or sha512- followed by base64. When sent it is rendered as the tag's integrity attribute, so the browser refuses the script if the file does not hash to it. Take the digest from the CDN's own copy button (jsDelivr and cdnjs both publish one) — a digest that does not match the exact file at that URL stops the library loading, and the failure shows up in the importer at runtime, not as a 422 here. Pin an exact version in the URL when you use it: a floating version resolves to a different file later and invalidates the digest.","type":"string"}},"type":"object"},"ValidationFunction":{"description":"A custom validation rule. Max 10 per sheet.","required":["function_name"],"properties":{"function_name":{"type":"string","maxLength":190},"scope":{"description":"`column` runs over whole columns via csvbox.column[...]; `row` runs per row via csvbox.row[...]. A column-scoped item must name at least one entry across `columns` and `dynamic_columns`. On a PATCH updating an existing item, `scope`, `columns` and `dynamic_columns` preserve as a GROUP: send none of the three and the stored scoping is kept; send any one and all three are taken from the request, so `columns` alone also clears `dynamic_columns`.","type":"string","default":"column","enum":["column","row"]},"columns":{"description":"Sheet columns this function reads. Validated against the sheet as it stands AFTER this request, so one call may add a column and a function that uses it. A scope preserved by a PATCH that sent none of the three scope fields is written back as stored and is not re-checked.","type":"array","items":{"type":"string"}},"dynamic_columns":{"description":"Columns that only exist at import time and so cannot be checked against the sheet definition.","type":"array","items":{"type":"string"}},"js_code":{"description":"Function body receiving `csvbox` and returning an array of errors — empty means valid. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"type":"boolean","default":true},"dependencies":{"description":"Scripts this item's `js_code` may use. The `check_date` example below is the worked case: `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"]}]`, plus an optional `integrity` digest per entry. Remove it and the same code is rejected with js_disallowed_global, which is the whole purpose of `globals`. Up to 5 entries, comma-separated in the array, loaded in the order sent.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. See VirtualColumn._delete.","type":"boolean"}},"type":"object"},"DataTransform":{"description":"A transform that rewrites values in place. Max 10 per sheet.","required":["transform_name"],"properties":{"transform_name":{"type":"string","maxLength":190},"scope":{"type":"string","default":"column","enum":["column","row"]},"run_at":{"description":"When the transform runs relative to validation.","type":"string","enum":["before_validation","after_validation"]},"columns":{"type":"array","items":{"type":"string"}},"dynamic_columns":{"type":"array","items":{"type":"string"}},"js_code":{"description":"Function body receiving `csvbox`, mutating it and returning it. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"type":"boolean","default":true},"dependencies":{"description":"Supported here as on every collection. Empty in this example because the snippet above needs only `csvbox` and built-ins — see the `check_date` validation function for a worked dependency. To use one here, send `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`; `globals` and `integrity` are optional, and further scripts are further objects in the same array. See the JsDependency schema for the host allowlist and per-field rules.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. See VirtualColumn._delete.","type":"boolean"}},"type":"object"},"SheetSuccessResponse":{"properties":{"status":{"type":"string"},"data":{"properties":{"sheet_license_key":{"type":"string"},"title":{"type":"string"},"virtual_columns":{"description":"Per-item outcome, present only when the request sent this collection. Additive — existing clients reading sheet_license_key and title are unaffected.","type":"array","items":{"properties":{"column_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}},"validation_functions":{"description":"Per-item outcome, present only when the request sent this collection. `unchanged` means the item was submitted but matched what was already stored, so no write happened.","type":"array","items":{"properties":{"function_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}},"data_transforms":{"description":"Per-item outcome, present only when the request sent this collection.","type":"array","items":{"properties":{"transform_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}}},"type":"object"}},"type":"object"},"ErrorResponse":{"properties":{"status":{"type":"string"},"errors":{"description":"Keys are dotted paths into the request body (for example `virtual_columns.0.js_code`), each mapping to a list of problems found at that path. Every failing item is reported in one response, so a caller pushing ten functions learns about all ten in a single round trip. Requests rejected by the JavaScript gate always use this form, and point into that item's own js_code: `line` is 1-based, `column` is 0-based. `identifier`, `line` and `column` are present only when the violation has one. Codes: js_code_too_long, js_forbidden_sequence, js_syntax_error, js_disallowed_global, js_forbidden_construct, js_duplicate_name, js_name_conflicts_column, js_unknown_column, js_too_many_items, js_budget_exceeded, js_name_ambiguous, js_missing_name, js_unknown_field, js_invalid_field, js_invalid_item, dependency_url_invalid, dependency_host_not_allowed, column_name_ambiguous.","type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"identifier":{"type":"string"},"line":{"type":"integer"},"column":{"type":"integer"}}}}}},"type":"object"}}},"paths":{"/1.1/sheet":{"post":{"tags":["Sheets"],"summary":"Create Sheet","description":"Creates a new sheet importer.","operationId":"createSheet","parameters":[{"$ref":"#/components/parameters/AcceptHeader"},{"$ref":"#/components/parameters/ContentTypeHeader"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSheetRequest"}}}},"responses":{"201":{"description":"Sheet Created Successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SheetSuccessResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Update Sheet

> Fully updates an existing sheet. All provided fields will overwrite existing values.

```json
{"openapi":"3.0.0","info":{"title":"CSVBox Sheets API Documentation","version":"1.2.0"},"tags":[{"name":"Sheets","description":"Sheets"}],"servers":[{"url":"https://api.csvbox.io/","description":"CSVBox Sheets API Server"}],"security":[{"ApiKeyAuth":[],"ApiSecretKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"x-csvbox-api-key","in":"header"}},"parameters":{"AcceptHeader":{"name":"Accept","in":"header","description":"Must be application/json","required":true,"schema":{"type":"string"}},"ContentTypeHeader":{"name":"Content-Type","in":"header","description":"Content type must be application/json","required":true,"schema":{"type":"string"}}},"schemas":{"PutSheetRequest":{"properties":{"title":{"type":"string"},"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"destinations":{"type":"array","items":{"$ref":"#/components/schemas/Destinations"}},"sheet_columns":{"type":"array","items":{"$ref":"#/components/schemas/SheetColumn"}},"steps":{"$ref":"#/components/schemas/Steps"},"security_settings":{"$ref":"#/components/schemas/SecuritySettings"},"virtual_columns":{"description":"PUT is AUTHORITATIVE for a collection it sends: items listed are created or updated in place, and any existing item this array does not name is DELETED. Sending [] deletes every virtual column on the sheet. Omitting the key entirely leaves the collection untouched. Use `_delete` under PATCH instead if you want targeted removal.","type":"array","items":{"$ref":"#/components/schemas/VirtualColumn"},"maxItems":20},"validation_functions":{"description":"PUT is AUTHORITATIVE: unlisted existing items are DELETED, [] empties the collection, an omitted key leaves it untouched. Two functions are shown: `check_email` needs nothing beyond the built-ins, while `check_date` declares `dayjs` — remove that dependency and its code is rejected with js_disallowed_global. That entry omits the optional `integrity` field so this body can be sent unmodified; in your own sheet add `\"integrity\": \"sha384-<digest published by the CDN>\"` beside the `url`, and add further scripts as further comma-separated objects in the same array (5 max).","type":"array","items":{"$ref":"#/components/schemas/ValidationFunction"},"maxItems":10},"data_transforms":{"description":"PUT is AUTHORITATIVE: unlisted existing items are DELETED, [] empties the collection, an omitted key leaves it untouched.","type":"array","items":{"$ref":"#/components/schemas/DataTransform"},"maxItems":10}},"type":"object"},"Webhook":{"properties":{"import_complete":{"$ref":"#/components/schemas/WebhookImportComplete"}},"type":"object"},"WebhookImportComplete":{"properties":{"url":{"type":"string","format":"url"},"send_copy":{"description":"Send a copy of imported data to client","type":"boolean"},"custom_headers":{"type":"array","items":{"$ref":"#/components/schemas/Header"}}},"type":"object"},"Header":{"required":["key","value"],"properties":{"key":{"description":"---------------------------------------------------------\nHEADER OBJECT\n---------------------------------------------------------","type":"string"},"value":{"type":"string"}},"type":"object"},"Destinations":{"properties":{"type":{"type":"string","enum":["webhook","testapi","none"]},"isActive":{"type":"boolean"},"settings":{"properties":{"method":{"type":"string","enum":["POST","PATCH"]},"url":{"type":"string","format":"url"},"post_data_format":{"type":"string","enum":["JSON","FORM_DATA","XML"]},"rows_per_chunk":{"type":"integer"},"request_type":{"type":"string","enum":["parallel","sequential"]},"server_side_validation":{"type":"boolean"},"allow_resubmit":{"type":"string","enum":["all_rows","error_rows_only"]},"custom_headers":{"type":"array","items":{"$ref":"#/components/schemas/Header"}}},"type":"object"}},"type":"object"},"SheetColumn":{"required":["column_name"],"properties":{"column_name":{"type":"string"},"display_label":{"type":"string"},"info_hint":{"type":"string"},"matching_keywords":{"type":"string"},"type":{"type":"string","enum":["text","number","email","date","time","boolean","regex","ip","url","credit_card","phone_number","currency","list","dependent_list","dynamic_list","dependent_dynamic_list","multiselect_list","multiselect_dynamic_list"]},"default_value":{"type":"string"},"required":{"type":"boolean"},"read_only":{"type":"boolean"},"position":{"type":"integer","minimum":1},"validators":{"description":"Validators depend on the column type. See examples below for each type.","properties":{"min_length":{"description":"[text] Minimum character length","type":"integer"},"max_length":{"description":"[text] Maximum character length","type":"integer"},"min_value":{"description":"[number] Minimum numeric value","type":"number"},"max_value":{"description":"[number] Maximum numeric value","type":"number"},"format":{"description":"[date] Date format e.g. YYYY-MM-DD | [time] Time format e.g. HH:mm:ss","type":"string"},"expression":{"description":"[regex] Regular expression pattern","type":"string"},"error_message":{"description":"[regex] Custom error message","type":"string"},"version":{"description":"[ip] IP version","type":"string","enum":["ipv4","ipv6"]},"country_code":{"description":"[phone_number] Country code e.g. IN, US","type":"string"},"symbol":{"description":"[currency] Currency symbol","type":"string"},"require_symbol":{"description":"[currency] Whether symbol is required","type":"boolean"},"values":{"description":"[list] Array of ListItem objects (with dependents) | [multiselect_list] Array of strings","oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/ListItem"}},{"type":"array","items":{"type":"string"}}]},"case_sensitive":{"description":"[list, multiselect_list] Case-sensitive matching","type":"boolean"},"primary_column":{"description":"[dependent_list, dependent_dynamic_list] The column_name of the parent list column","type":"string"},"source_url":{"description":"[dynamic_list, multiselect_dynamic_list] URL to fetch list options from","type":"string"},"request_method":{"description":"[dynamic_list, multiselect_dynamic_list] HTTP method","type":"string","enum":["GET","POST"]},"request_headers":{"description":"[dynamic_list, multiselect_dynamic_list] Custom request headers","type":"array","items":{"$ref":"#/components/schemas/Header"}},"custom_user_attributes":{"description":"[dynamic_list] Include custom user attributes in request","type":"boolean"},"other_values":{"description":"[dynamic_list, multiselect_list, multiselect_dynamic_list] Allow values outside predefined list","type":"boolean"},"delimiter":{"description":"[multiselect_list, multiselect_dynamic_list] Delimiter for multiple values","type":"string"}},"type":"object"}},"type":"object"},"ListItem":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"},"dependents":{"type":"array","items":{"$ref":"#/components/schemas/ListItemChild"}}},"type":"object"},"ListItemChild":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"},"dependents":{"type":"array","items":{"$ref":"#/components/schemas/ListItemDependent"}}},"type":"object"},"ListItemDependent":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"}},"type":"object"},"Steps":{"properties":{"file_upload":{"properties":{"types":{"type":"array","items":{"type":"string"}},"title":{"type":"string"},"help":{"type":"string"},"sample_file_url":{"type":"string"},"size_mb":{"type":"integer"},"validation_msg":{"type":"string"},"copy_paste":{"type":"boolean"},"copy_delimiter":{"type":"string"},"show_upload":{"type":"boolean"},"worksheet_select":{"type":"boolean"},"description_option":{"type":"boolean"},"lang":{"type":"string"},"excel_date_format":{"type":"string"},"excel_date_custom":{"type":"string"},"hide_cancel":{"type":"boolean"},"split":{"description":"Split large files into multiple imports","type":"boolean"},"split_rows":{"description":"Rows per import when splitting (min 1)","type":"integer"},"split_confirm":{"description":"User confirmation required after each import: no=0, yes=1, no_if_no_errors=2","type":"string","enum":["no","yes","no_if_no_errors"]},"extract_types":{"description":"Allowed document extraction types (mapped to .pdf/.doc/images)","type":"array","items":{"type":"string","enum":["pdf","docs","images"]}},"page_limit":{"description":"Max pages allowed for extraction (null = no limit)","type":"integer","nullable":true}},"type":"object"},"select_header":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"default_row":{"type":"string"},"encoding_option":{"type":"boolean"},"encoding":{"type":"string"},"row_column_switch":{"type":"boolean"}},"type":"object"},"map_columns":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"mapping_mode":{"type":"string"},"bulk_cols_dd":{"type":"boolean"},"accept_unmapped":{"type":"boolean"},"accept_unmapped_select":{"type":"boolean"},"allow_zero_template":{"type":"boolean"},"ignore_cols":{"type":"boolean"},"ignore_cols_default":{"type":"boolean"},"user_keywords":{"type":"boolean"}},"type":"object"},"verify_data":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"row_display_mode":{"type":"string"},"export_option":{"type":"boolean"},"search_option":{"type":"boolean"},"ai_transform":{"type":"boolean"},"allow_new_rows":{"type":"boolean"},"rows_display":{"type":"integer"},"allow_invalid":{"type":"boolean"},"invalid_confirmation":{"type":"boolean"},"max_rows":{"type":"integer"},"allow_upload_if_max":{"type":"boolean"},"max_rows_msg":{"type":"string"},"min_rows":{"type":"integer"},"min_rows_msg":{"type":"string"}},"type":"object"},"results":{"properties":{"close_mode":{"type":"string"},"redirect_url":{"type":"string"},"success_type":{"type":"string"},"success_text":{"type":"string"},"success_method":{"type":"string"},"success_url":{"type":"string"},"failed_type":{"type":"string"},"failed_text":{"type":"string"},"failed_method":{"type":"string"},"failed_url":{"type":"string"},"show_resubmit":{"type":"boolean"},"show_error_text":{"type":"boolean"}},"type":"object"}},"type":"object"},"SecuritySettings":{"properties":{"region":{"type":"string","enum":["us","eu"]},"domains":{"type":"array","items":{"type":"string"}},"import_url_upload":{"type":"boolean"},"s3_upload":{"type":"boolean"}},"type":"object"},"VirtualColumn":{"description":"A computed column. Max 20 per sheet. `column_name` must not collide with a real sheet column.","required":["column_name"],"properties":{"column_name":{"type":"string","maxLength":190},"js_code":{"description":"Function body receiving a single `csvbox` argument and returning the computed value. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"description":"Defaults to true on API create — unlike the web UI, whose post-save toggle starts off.","type":"boolean","default":true},"dependencies":{"description":"Supported here as on every collection. Empty in this example because the snippet above needs only `csvbox` and built-ins — see the `check_date` validation function for a worked dependency. To use one here, send `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`; `globals` and `integrity` are optional, and further scripts are further objects in the same array. See the JsDependency schema for the host allowlist and per-field rules.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. When true the item is deleted and every other field on it is ignored, including `js_code`.","type":"boolean"}},"type":"object"},"JsDependency":{"description":"A third-party script an item's `js_code` may use. The API never accepts raw HTML — send the URL and the server renders the <script src> tag. Migrating from the web UI: `js_dependency` markup is not a writable field. Full shape, all three fields, on any of the three collections: `\"dependencies\": [{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`. Only `url` is required; `globals` is what makes the library's name callable from `js_code`, and `integrity` is optional. Up to 5 dependencies per item — send them as separate objects in the array, comma-separated, one per script. The server renders each as `<script src=\"…\" integrity=\"…\" crossorigin=\"anonymous\"></script>`, in the order sent, so a library that must load before another goes first.","required":["url"],"properties":{"url":{"description":"HTTPS only. Host must be exactly cdn.jsdelivr.net, unpkg.com or cdnjs.cloudflare.com (no subdomains). Path must end in .js or .mjs. No query string, fragment, userinfo or port.","type":"string","format":"url","maxLength":512},"globals":{"description":"Names this script defines. Each is added to the allowed-identifier list for this item only — code referencing an undeclared global is rejected with js_disallowed_global. May not shadow a built-in or `csvbox`. Loading the script is not enough on its own: the code gate checks this list, so a name absent from it is refused whether or not the CDN would have defined it at runtime. Up to 5 names, each matching /^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/.","type":"array","items":{"type":"string"},"maxItems":5},"integrity":{"description":"Optional Subresource Integrity digest: sha256-, sha384- or sha512- followed by base64. When sent it is rendered as the tag's integrity attribute, so the browser refuses the script if the file does not hash to it. Take the digest from the CDN's own copy button (jsDelivr and cdnjs both publish one) — a digest that does not match the exact file at that URL stops the library loading, and the failure shows up in the importer at runtime, not as a 422 here. Pin an exact version in the URL when you use it: a floating version resolves to a different file later and invalidates the digest.","type":"string"}},"type":"object"},"ValidationFunction":{"description":"A custom validation rule. Max 10 per sheet.","required":["function_name"],"properties":{"function_name":{"type":"string","maxLength":190},"scope":{"description":"`column` runs over whole columns via csvbox.column[...]; `row` runs per row via csvbox.row[...]. A column-scoped item must name at least one entry across `columns` and `dynamic_columns`. On a PATCH updating an existing item, `scope`, `columns` and `dynamic_columns` preserve as a GROUP: send none of the three and the stored scoping is kept; send any one and all three are taken from the request, so `columns` alone also clears `dynamic_columns`.","type":"string","default":"column","enum":["column","row"]},"columns":{"description":"Sheet columns this function reads. Validated against the sheet as it stands AFTER this request, so one call may add a column and a function that uses it. A scope preserved by a PATCH that sent none of the three scope fields is written back as stored and is not re-checked.","type":"array","items":{"type":"string"}},"dynamic_columns":{"description":"Columns that only exist at import time and so cannot be checked against the sheet definition.","type":"array","items":{"type":"string"}},"js_code":{"description":"Function body receiving `csvbox` and returning an array of errors — empty means valid. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"type":"boolean","default":true},"dependencies":{"description":"Scripts this item's `js_code` may use. The `check_date` example below is the worked case: `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"]}]`, plus an optional `integrity` digest per entry. Remove it and the same code is rejected with js_disallowed_global, which is the whole purpose of `globals`. Up to 5 entries, comma-separated in the array, loaded in the order sent.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. See VirtualColumn._delete.","type":"boolean"}},"type":"object"},"DataTransform":{"description":"A transform that rewrites values in place. Max 10 per sheet.","required":["transform_name"],"properties":{"transform_name":{"type":"string","maxLength":190},"scope":{"type":"string","default":"column","enum":["column","row"]},"run_at":{"description":"When the transform runs relative to validation.","type":"string","enum":["before_validation","after_validation"]},"columns":{"type":"array","items":{"type":"string"}},"dynamic_columns":{"type":"array","items":{"type":"string"}},"js_code":{"description":"Function body receiving `csvbox`, mutating it and returning it. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"type":"boolean","default":true},"dependencies":{"description":"Supported here as on every collection. Empty in this example because the snippet above needs only `csvbox` and built-ins — see the `check_date` validation function for a worked dependency. To use one here, send `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`; `globals` and `integrity` are optional, and further scripts are further objects in the same array. See the JsDependency schema for the host allowlist and per-field rules.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. See VirtualColumn._delete.","type":"boolean"}},"type":"object"},"SheetSuccessResponse":{"properties":{"status":{"type":"string"},"data":{"properties":{"sheet_license_key":{"type":"string"},"title":{"type":"string"},"virtual_columns":{"description":"Per-item outcome, present only when the request sent this collection. Additive — existing clients reading sheet_license_key and title are unaffected.","type":"array","items":{"properties":{"column_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}},"validation_functions":{"description":"Per-item outcome, present only when the request sent this collection. `unchanged` means the item was submitted but matched what was already stored, so no write happened.","type":"array","items":{"properties":{"function_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}},"data_transforms":{"description":"Per-item outcome, present only when the request sent this collection.","type":"array","items":{"properties":{"transform_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}}},"type":"object"}},"type":"object"},"ErrorResponse":{"properties":{"status":{"type":"string"},"errors":{"description":"Keys are dotted paths into the request body (for example `virtual_columns.0.js_code`), each mapping to a list of problems found at that path. Every failing item is reported in one response, so a caller pushing ten functions learns about all ten in a single round trip. Requests rejected by the JavaScript gate always use this form, and point into that item's own js_code: `line` is 1-based, `column` is 0-based. `identifier`, `line` and `column` are present only when the violation has one. Codes: js_code_too_long, js_forbidden_sequence, js_syntax_error, js_disallowed_global, js_forbidden_construct, js_duplicate_name, js_name_conflicts_column, js_unknown_column, js_too_many_items, js_budget_exceeded, js_name_ambiguous, js_missing_name, js_unknown_field, js_invalid_field, js_invalid_item, dependency_url_invalid, dependency_host_not_allowed, column_name_ambiguous.","type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"identifier":{"type":"string"},"line":{"type":"integer"},"column":{"type":"integer"}}}}}},"type":"object"}}},"paths":{"/1.1/sheet/{sheet_license_key}":{"put":{"tags":["Sheets"],"summary":"Update Sheet","description":"Fully updates an existing sheet. All provided fields will overwrite existing values.","operationId":"updateSheet","parameters":[{"name":"sheet_license_key","in":"path","description":"Sheet License Key","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptHeader"},{"$ref":"#/components/parameters/ContentTypeHeader"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PutSheetRequest"}}}},"responses":{"200":{"description":"Sheet Updated Successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SheetSuccessResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Sheet Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Partially Update Sheet

> Partially updates an existing sheet. Only provided fields will be updated. Fields not included will remain unchanged.

```json
{"openapi":"3.0.0","info":{"title":"CSVBox Sheets API Documentation","version":"1.2.0"},"tags":[{"name":"Sheets","description":"Sheets"}],"servers":[{"url":"https://api.csvbox.io/","description":"CSVBox Sheets API Server"}],"security":[{"ApiKeyAuth":[],"ApiSecretKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","name":"x-csvbox-api-key","in":"header"}},"parameters":{"AcceptHeader":{"name":"Accept","in":"header","description":"Must be application/json","required":true,"schema":{"type":"string"}},"ContentTypeHeader":{"name":"Content-Type","in":"header","description":"Content type must be application/json","required":true,"schema":{"type":"string"}}},"schemas":{"PatchSheetRequest":{"properties":{"title":{"type":"string"},"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"destinations":{"type":"array","items":{"$ref":"#/components/schemas/Destinations"}},"sheet_columns":{"type":"array","items":{"$ref":"#/components/schemas/SheetColumn"}},"steps":{"$ref":"#/components/schemas/Steps"},"security_settings":{"$ref":"#/components/schemas/SecuritySettings"},"virtual_columns":{"description":"PATCH MERGES: only the items you list are touched. Existing items you do not name are left alone — nothing is deleted implicitly. Sending [] is a no-op, not a clear. To remove one item send {\"column_name\": \"old_one\", \"_delete\": true}; every other field on a _delete item is ignored, so js_code is not required. It merges at FIELD level too: on an item that already exists every field you omit keeps its stored value, so {\"function_name\": \"check_email\", \"active\": false} disables that function without re-sending its code, columns or dependencies.","type":"array","items":{"$ref":"#/components/schemas/VirtualColumn"},"maxItems":20},"validation_functions":{"description":"PATCH MERGES: unlisted items are untouched, [] is a no-op. Delete one with {\"function_name\": \"old_one\", \"_delete\": true}. Two functions are shown: `check_email` needs nothing beyond the built-ins, while `check_date` declares `dayjs` — remove that dependency and its code is rejected with js_disallowed_global. That entry omits the optional `integrity` field so this body can be sent unmodified; in your own sheet add `\"integrity\": \"sha384-<digest published by the CDN>\"` beside the `url`, and add further scripts as further comma-separated objects in the same array (5 max).","type":"array","items":{"$ref":"#/components/schemas/ValidationFunction"},"maxItems":10},"data_transforms":{"description":"PATCH MERGES: unlisted items are untouched, [] is a no-op. Delete one with {\"transform_name\": \"old_one\", \"_delete\": true}.","type":"array","items":{"$ref":"#/components/schemas/DataTransform"},"maxItems":10}},"type":"object"},"Webhook":{"properties":{"import_complete":{"$ref":"#/components/schemas/WebhookImportComplete"}},"type":"object"},"WebhookImportComplete":{"properties":{"url":{"type":"string","format":"url"},"send_copy":{"description":"Send a copy of imported data to client","type":"boolean"},"custom_headers":{"type":"array","items":{"$ref":"#/components/schemas/Header"}}},"type":"object"},"Header":{"required":["key","value"],"properties":{"key":{"description":"---------------------------------------------------------\nHEADER OBJECT\n---------------------------------------------------------","type":"string"},"value":{"type":"string"}},"type":"object"},"Destinations":{"properties":{"type":{"type":"string","enum":["webhook","testapi","none"]},"isActive":{"type":"boolean"},"settings":{"properties":{"method":{"type":"string","enum":["POST","PATCH"]},"url":{"type":"string","format":"url"},"post_data_format":{"type":"string","enum":["JSON","FORM_DATA","XML"]},"rows_per_chunk":{"type":"integer"},"request_type":{"type":"string","enum":["parallel","sequential"]},"server_side_validation":{"type":"boolean"},"allow_resubmit":{"type":"string","enum":["all_rows","error_rows_only"]},"custom_headers":{"type":"array","items":{"$ref":"#/components/schemas/Header"}}},"type":"object"}},"type":"object"},"SheetColumn":{"required":["column_name"],"properties":{"column_name":{"type":"string"},"display_label":{"type":"string"},"info_hint":{"type":"string"},"matching_keywords":{"type":"string"},"type":{"type":"string","enum":["text","number","email","date","time","boolean","regex","ip","url","credit_card","phone_number","currency","list","dependent_list","dynamic_list","dependent_dynamic_list","multiselect_list","multiselect_dynamic_list"]},"default_value":{"type":"string"},"required":{"type":"boolean"},"read_only":{"type":"boolean"},"position":{"type":"integer","minimum":1},"validators":{"description":"Validators depend on the column type. See examples below for each type.","properties":{"min_length":{"description":"[text] Minimum character length","type":"integer"},"max_length":{"description":"[text] Maximum character length","type":"integer"},"min_value":{"description":"[number] Minimum numeric value","type":"number"},"max_value":{"description":"[number] Maximum numeric value","type":"number"},"format":{"description":"[date] Date format e.g. YYYY-MM-DD | [time] Time format e.g. HH:mm:ss","type":"string"},"expression":{"description":"[regex] Regular expression pattern","type":"string"},"error_message":{"description":"[regex] Custom error message","type":"string"},"version":{"description":"[ip] IP version","type":"string","enum":["ipv4","ipv6"]},"country_code":{"description":"[phone_number] Country code e.g. IN, US","type":"string"},"symbol":{"description":"[currency] Currency symbol","type":"string"},"require_symbol":{"description":"[currency] Whether symbol is required","type":"boolean"},"values":{"description":"[list] Array of ListItem objects (with dependents) | [multiselect_list] Array of strings","oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/ListItem"}},{"type":"array","items":{"type":"string"}}]},"case_sensitive":{"description":"[list, multiselect_list] Case-sensitive matching","type":"boolean"},"primary_column":{"description":"[dependent_list, dependent_dynamic_list] The column_name of the parent list column","type":"string"},"source_url":{"description":"[dynamic_list, multiselect_dynamic_list] URL to fetch list options from","type":"string"},"request_method":{"description":"[dynamic_list, multiselect_dynamic_list] HTTP method","type":"string","enum":["GET","POST"]},"request_headers":{"description":"[dynamic_list, multiselect_dynamic_list] Custom request headers","type":"array","items":{"$ref":"#/components/schemas/Header"}},"custom_user_attributes":{"description":"[dynamic_list] Include custom user attributes in request","type":"boolean"},"other_values":{"description":"[dynamic_list, multiselect_list, multiselect_dynamic_list] Allow values outside predefined list","type":"boolean"},"delimiter":{"description":"[multiselect_list, multiselect_dynamic_list] Delimiter for multiple values","type":"string"}},"type":"object"}},"type":"object"},"ListItem":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"},"dependents":{"type":"array","items":{"$ref":"#/components/schemas/ListItemChild"}}},"type":"object"},"ListItemChild":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"},"dependents":{"type":"array","items":{"$ref":"#/components/schemas/ListItemDependent"}}},"type":"object"},"ListItemDependent":{"properties":{"value":{"type":"string"},"display_label":{"type":"string"}},"type":"object"},"Steps":{"properties":{"file_upload":{"properties":{"types":{"type":"array","items":{"type":"string"}},"title":{"type":"string"},"help":{"type":"string"},"sample_file_url":{"type":"string"},"size_mb":{"type":"integer"},"validation_msg":{"type":"string"},"copy_paste":{"type":"boolean"},"copy_delimiter":{"type":"string"},"show_upload":{"type":"boolean"},"worksheet_select":{"type":"boolean"},"description_option":{"type":"boolean"},"lang":{"type":"string"},"excel_date_format":{"type":"string"},"excel_date_custom":{"type":"string"},"hide_cancel":{"type":"boolean"},"split":{"description":"Split large files into multiple imports","type":"boolean"},"split_rows":{"description":"Rows per import when splitting (min 1)","type":"integer"},"split_confirm":{"description":"User confirmation required after each import: no=0, yes=1, no_if_no_errors=2","type":"string","enum":["no","yes","no_if_no_errors"]},"extract_types":{"description":"Allowed document extraction types (mapped to .pdf/.doc/images)","type":"array","items":{"type":"string","enum":["pdf","docs","images"]}},"page_limit":{"description":"Max pages allowed for extraction (null = no limit)","type":"integer","nullable":true}},"type":"object"},"select_header":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"default_row":{"type":"string"},"encoding_option":{"type":"boolean"},"encoding":{"type":"string"},"row_column_switch":{"type":"boolean"}},"type":"object"},"map_columns":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"mapping_mode":{"type":"string"},"bulk_cols_dd":{"type":"boolean"},"accept_unmapped":{"type":"boolean"},"accept_unmapped_select":{"type":"boolean"},"allow_zero_template":{"type":"boolean"},"ignore_cols":{"type":"boolean"},"ignore_cols_default":{"type":"boolean"},"user_keywords":{"type":"boolean"}},"type":"object"},"verify_data":{"properties":{"skip":{"type":"boolean"},"help":{"type":"string"},"row_display_mode":{"type":"string"},"export_option":{"type":"boolean"},"search_option":{"type":"boolean"},"ai_transform":{"type":"boolean"},"allow_new_rows":{"type":"boolean"},"rows_display":{"type":"integer"},"allow_invalid":{"type":"boolean"},"invalid_confirmation":{"type":"boolean"},"max_rows":{"type":"integer"},"allow_upload_if_max":{"type":"boolean"},"max_rows_msg":{"type":"string"},"min_rows":{"type":"integer"},"min_rows_msg":{"type":"string"}},"type":"object"},"results":{"properties":{"close_mode":{"type":"string"},"redirect_url":{"type":"string"},"success_type":{"type":"string"},"success_text":{"type":"string"},"success_method":{"type":"string"},"success_url":{"type":"string"},"failed_type":{"type":"string"},"failed_text":{"type":"string"},"failed_method":{"type":"string"},"failed_url":{"type":"string"},"show_resubmit":{"type":"boolean"},"show_error_text":{"type":"boolean"}},"type":"object"}},"type":"object"},"SecuritySettings":{"properties":{"region":{"type":"string","enum":["us","eu"]},"domains":{"type":"array","items":{"type":"string"}},"import_url_upload":{"type":"boolean"},"s3_upload":{"type":"boolean"}},"type":"object"},"VirtualColumn":{"description":"A computed column. Max 20 per sheet. `column_name` must not collide with a real sheet column.","required":["column_name"],"properties":{"column_name":{"type":"string","maxLength":190},"js_code":{"description":"Function body receiving a single `csvbox` argument and returning the computed value. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"description":"Defaults to true on API create — unlike the web UI, whose post-save toggle starts off.","type":"boolean","default":true},"dependencies":{"description":"Supported here as on every collection. Empty in this example because the snippet above needs only `csvbox` and built-ins — see the `check_date` validation function for a worked dependency. To use one here, send `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`; `globals` and `integrity` are optional, and further scripts are further objects in the same array. See the JsDependency schema for the host allowlist and per-field rules.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. When true the item is deleted and every other field on it is ignored, including `js_code`.","type":"boolean"}},"type":"object"},"JsDependency":{"description":"A third-party script an item's `js_code` may use. The API never accepts raw HTML — send the URL and the server renders the <script src> tag. Migrating from the web UI: `js_dependency` markup is not a writable field. Full shape, all three fields, on any of the three collections: `\"dependencies\": [{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`. Only `url` is required; `globals` is what makes the library's name callable from `js_code`, and `integrity` is optional. Up to 5 dependencies per item — send them as separate objects in the array, comma-separated, one per script. The server renders each as `<script src=\"…\" integrity=\"…\" crossorigin=\"anonymous\"></script>`, in the order sent, so a library that must load before another goes first.","required":["url"],"properties":{"url":{"description":"HTTPS only. Host must be exactly cdn.jsdelivr.net, unpkg.com or cdnjs.cloudflare.com (no subdomains). Path must end in .js or .mjs. No query string, fragment, userinfo or port.","type":"string","format":"url","maxLength":512},"globals":{"description":"Names this script defines. Each is added to the allowed-identifier list for this item only — code referencing an undeclared global is rejected with js_disallowed_global. May not shadow a built-in or `csvbox`. Loading the script is not enough on its own: the code gate checks this list, so a name absent from it is refused whether or not the CDN would have defined it at runtime. Up to 5 names, each matching /^[A-Za-z_$][A-Za-z0-9_$]{0,63}$/.","type":"array","items":{"type":"string"},"maxItems":5},"integrity":{"description":"Optional Subresource Integrity digest: sha256-, sha384- or sha512- followed by base64. When sent it is rendered as the tag's integrity attribute, so the browser refuses the script if the file does not hash to it. Take the digest from the CDN's own copy button (jsDelivr and cdnjs both publish one) — a digest that does not match the exact file at that URL stops the library loading, and the failure shows up in the importer at runtime, not as a 422 here. Pin an exact version in the URL when you use it: a floating version resolves to a different file later and invalidates the digest.","type":"string"}},"type":"object"},"ValidationFunction":{"description":"A custom validation rule. Max 10 per sheet.","required":["function_name"],"properties":{"function_name":{"type":"string","maxLength":190},"scope":{"description":"`column` runs over whole columns via csvbox.column[...]; `row` runs per row via csvbox.row[...]. A column-scoped item must name at least one entry across `columns` and `dynamic_columns`. On a PATCH updating an existing item, `scope`, `columns` and `dynamic_columns` preserve as a GROUP: send none of the three and the stored scoping is kept; send any one and all three are taken from the request, so `columns` alone also clears `dynamic_columns`.","type":"string","default":"column","enum":["column","row"]},"columns":{"description":"Sheet columns this function reads. Validated against the sheet as it stands AFTER this request, so one call may add a column and a function that uses it. A scope preserved by a PATCH that sent none of the three scope fields is written back as stored and is not re-checked.","type":"array","items":{"type":"string"}},"dynamic_columns":{"description":"Columns that only exist at import time and so cannot be checked against the sheet definition.","type":"array","items":{"type":"string"}},"js_code":{"description":"Function body receiving `csvbox` and returning an array of errors — empty means valid. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"type":"boolean","default":true},"dependencies":{"description":"Scripts this item's `js_code` may use. The `check_date` example below is the worked case: `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"]}]`, plus an optional `integrity` digest per entry. Remove it and the same code is rejected with js_disallowed_global, which is the whole purpose of `globals`. Up to 5 entries, comma-separated in the array, loaded in the order sent.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. See VirtualColumn._delete.","type":"boolean"}},"type":"object"},"DataTransform":{"description":"A transform that rewrites values in place. Max 10 per sheet.","required":["transform_name"],"properties":{"transform_name":{"type":"string","maxLength":190},"scope":{"type":"string","default":"column","enum":["column","row"]},"run_at":{"description":"When the transform runs relative to validation.","type":"string","enum":["before_validation","after_validation"]},"columns":{"type":"array","items":{"type":"string"}},"dynamic_columns":{"type":"array","items":{"type":"string"}},"js_code":{"description":"Function body receiving `csvbox`, mutating it and returning it. Required unless `_delete` is true, or a PATCH is updating an item that already exists — an omitted `js_code` then keeps the stored snippet. Sending an empty string, null or whitespace is refused with js_syntax_error: preservation is triggered by absence, not emptiness.","type":"string","maxLength":32768},"active":{"type":"boolean","default":true},"dependencies":{"description":"Supported here as on every collection. Empty in this example because the snippet above needs only `csvbox` and built-ins — see the `check_date` validation function for a worked dependency. To use one here, send `[{\"url\": \"https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js\", \"globals\": [\"dayjs\"], \"integrity\": \"sha384-…\"}]`; `globals` and `integrity` are optional, and further scripts are further objects in the same array. See the JsDependency schema for the host allowlist and per-field rules.","type":"array","items":{"$ref":"#/components/schemas/JsDependency"},"maxItems":5},"_delete":{"description":"PATCH only. See VirtualColumn._delete.","type":"boolean"}},"type":"object"},"SheetSuccessResponse":{"properties":{"status":{"type":"string"},"data":{"properties":{"sheet_license_key":{"type":"string"},"title":{"type":"string"},"virtual_columns":{"description":"Per-item outcome, present only when the request sent this collection. Additive — existing clients reading sheet_license_key and title are unaffected.","type":"array","items":{"properties":{"column_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}},"validation_functions":{"description":"Per-item outcome, present only when the request sent this collection. `unchanged` means the item was submitted but matched what was already stored, so no write happened.","type":"array","items":{"properties":{"function_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}},"data_transforms":{"description":"Per-item outcome, present only when the request sent this collection.","type":"array","items":{"properties":{"transform_name":{"type":"string"},"result":{"type":"string","enum":["created","updated","unchanged","deleted"]}},"type":"object"}}},"type":"object"}},"type":"object"},"ErrorResponse":{"properties":{"status":{"type":"string"},"errors":{"description":"Keys are dotted paths into the request body (for example `virtual_columns.0.js_code`), each mapping to a list of problems found at that path. Every failing item is reported in one response, so a caller pushing ten functions learns about all ten in a single round trip. Requests rejected by the JavaScript gate always use this form, and point into that item's own js_code: `line` is 1-based, `column` is 0-based. `identifier`, `line` and `column` are present only when the violation has one. Codes: js_code_too_long, js_forbidden_sequence, js_syntax_error, js_disallowed_global, js_forbidden_construct, js_duplicate_name, js_name_conflicts_column, js_unknown_column, js_too_many_items, js_budget_exceeded, js_name_ambiguous, js_missing_name, js_unknown_field, js_invalid_field, js_invalid_item, dependency_url_invalid, dependency_host_not_allowed, column_name_ambiguous.","type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"identifier":{"type":"string"},"line":{"type":"integer"},"column":{"type":"integer"}}}}}},"type":"object"}}},"paths":{"/1.1/sheet/{sheet_license_key}":{"patch":{"tags":["Sheets"],"summary":"Partially Update Sheet","description":"Partially updates an existing sheet. Only provided fields will be updated. Fields not included will remain unchanged.","operationId":"patchSheet","parameters":[{"name":"sheet_license_key","in":"path","description":"Sheet License Key","required":true,"schema":{"type":"string"}},{"$ref":"#/components/parameters/AcceptHeader"},{"$ref":"#/components/parameters/ContentTypeHeader"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchSheetRequest"}}}},"responses":{"200":{"description":"Sheet Partially Updated Successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SheetSuccessResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Sheet Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```
