Data Sets
A Data Set is a table of reference data that template controls read from — a Dropdown offering your suppliers, a Sub-Tasks list built from your sites. It is made of fields (the columns), records (the rows) and views (saved filters, sorts and hidden columns). A template control is linked to a view rather than to the whole Data Set, so that it can offer a filtered slice of the table.
The routes on this page manage the workspace's own Data Sets and read the ten system Data Sets CheckFlow provides to every workspace. How a template control is linked to a Data Set is part of the template document — see Template Documents. How a linked control is answered on a checklist is covered in Task Fields and Files.
Every write on this page accepts an Idempotency-Key header (see Idempotency) and every request is charged to the standard rate limit budget.
"Field" on this page means a column of a Data Set. It is unrelated to the fields of a checklist task, which are the task's input controls. A missing Data Set column is reported as DATA_SET_FIELD_NOT_FOUND, never as FIELD_NOT_FOUND.
Endpoints
| Method | Path | Description | MCP tool |
|---|---|---|---|
GET | /v3/data-sets | List Data Sets | list_data_sets |
POST | /v3/data-sets | Create a Data Set | create_data_set |
POST | /v3/data-sets/import | Create a Data Set from CSV | create_data_set_from_csv |
GET | /v3/data-sets/{dataSetKey} | Get a Data Set | get_data_set |
PATCH | /v3/data-sets/{dataSetKey} | Update a Data Set | update_data_set |
DELETE | /v3/data-sets/{dataSetKey} | Delete a Data Set | delete_data_set |
GET | /v3/data-sets/{dataSetKey}/connections | List a Data Set's Connections | list_data_set_connections |
GET | /v3/data-sets/{dataSetKey}/export | Export a Data Set as CSV | export_data_set_csv |
POST | /v3/data-sets/{dataSetKey}/import | Replace Records from CSV | replace_data_set_records_from_csv |
GET | /v3/data-sets/{dataSetKey}/fields | List Fields | — |
POST | /v3/data-sets/{dataSetKey}/fields | Add a Field | create_data_set_field |
PATCH | /v3/data-sets/{dataSetKey}/fields/{fieldKey} | Update a Field | update_data_set_field |
DELETE | /v3/data-sets/{dataSetKey}/fields/{fieldKey} | Delete a Field | delete_data_set_field |
GET | /v3/data-sets/{dataSetKey}/records | List Records | list_data_set_records |
POST | /v3/data-sets/{dataSetKey}/records | Add a Record | create_data_set_record |
GET | /v3/data-sets/{dataSetKey}/records/{recordKey} | Get a Record | get_data_set_record |
PATCH | /v3/data-sets/{dataSetKey}/records/{recordKey} | Update a Record | update_data_set_record |
DELETE | /v3/data-sets/{dataSetKey}/records/{recordKey} | Delete a Record | — |
POST | /v3/data-sets/{dataSetKey}/records/bulk | Add or Replace Records in Bulk | create_data_set_records |
DELETE | /v3/data-sets/{dataSetKey}/records/bulk | Delete Records in Bulk | delete_data_set_records |
GET | /v3/data-sets/{dataSetKey}/views | List Views | — |
POST | /v3/data-sets/{dataSetKey}/views | Create a View | create_data_set_view |
GET | /v3/data-sets/{dataSetKey}/views/{viewKey} | Get a View | — |
PATCH | /v3/data-sets/{dataSetKey}/views/{viewKey} | Update a View | update_data_set_view |
DELETE | /v3/data-sets/{dataSetKey}/views/{viewKey} | Delete a View | delete_data_set_view |
The MCP server has no separate tools for the fields list, the views list or a single view, because get_data_set already returns every field and view in full. A single record is deleted with delete_data_set_records and one key — the REST route does exactly the same thing. See Data Set Tools.
Addressing a Data Set
dataSetKey is either the Data Set's key (a GUID) or, for a system Data Set, its slug such as system-countries. Both reach the same object. A value that matches nothing — a GUID from another workspace, a misspelt slug — is a 404 with DATA_SET_NOT_FOUND, never a 400, because only a lookup can say whether a slug names something.
Fields, records and views answer to their GUID key only. A value that is not a GUID is a 400 VALIDATION_ERROR naming the parameter (fieldKey, recordKey, viewKey or the view query parameter). A well-formed key that names nothing in this Data Set is a 404 with its own code — DATA_SET_FIELD_NOT_FOUND, DATA_SET_RECORD_NOT_FOUND or DATA_SET_VIEW_NOT_FOUND — so you can tell which of two keys was wrong. A record or view that belongs to a different Data Set from the one in the path is a 404 too.
Permissions
The Data Set routes apply the Library permissions the app uses. What a key may do depends on who it acts as:
- An Administrator can read, change and delete every Data Set in the workspace.
- The workspace can do everything an Administrator can, deleting included. None of these routes is about a person, so a key that acts as the workspace works on all of them.
- A Member needs the permissions below.
| Operation | What a Member needs |
|---|---|
| List Data Sets | One of Library.Creator, Library.Viewer, Template.Creator or Template.Viewer. The list holds only the Data Sets the Member could read one at a time. |
| Read a Data Set — get it, list its fields, records and views, get a record or view, list its connections, export it as CSV | One of the same four permissions, and View or Edit on the Library folder the Data Set is filed in. |
| Create a Data Set, directly or from CSV | Library.Creator. |
| Change a Data Set — rename it, change its description, add, change or delete fields, records (singly, in bulk or from CSV) and views | Library.Creator, and Edit on the Library folder the Data Set is filed in. Edit on the folder without Library.Creator is not enough. |
| Delete a Data Set | Cannot. Deleting a Data Set is limited to Administrators, whatever the folder allows. |
A folder that denies the Member, or that gives them no permission at all, refuses them. A Data Set in no folder — Unfiled, or never filed, as every Data Set the v2 API created is — has no folder to check, so no folder grant is needed: one of the four permissions above is enough to read it, and Library.Creator to change it. The same goes for reading the system Data Sets. A Member with none of the four permissions cannot read any Data Set, the list included.
A refusal is 403 FORBIDDEN, and its message names the missing permission or says that the Data Set's folder is the reason. The workspace check comes first: another workspace's Data Set is a 404 DATA_SET_NOT_FOUND, never a 403.
Writes to a system Data Set are refused for everybody, Administrators and the workspace included, with 403 FORBIDDEN — see System Data Sets.
A Data Set created through the API (directly or from CSV) is credited to the member the key acts as, or to the workspace's anonymous member for a key that acts as the workspace. It is filed in the Library as Unfiled, as the app files a Data Set created without a folder. Move it to a folder in the app to put it under that folder's permissions.
System Data Sets
Every workspace can read ten built-in system Data Sets. They have "source": "system", are the same in every workspace and region, and can be addressed by slug:
| Slug | Name | Fields |
|---|---|---|
system-countries | Countries | Name, ISO2 Code, ISO3 Code, Dial Code |
system-currencies | Currencies | Name, Code, Symbol |
system-months-of-year | Months of Year | Name, Short Name, Number |
system-days-of-week | Days of Week | Name, Short Name, Number |
system-us-states | US States | Name, Abbreviation |
system-timezones | Timezones | Name, UTC Offset, Region |
system-language-codes | Language Codes | Name, ISO 639-1 Code |
system-priority-levels | Priority Levels | Label, Value |
system-yes-no-na | Yes / No / N/A | Label, Value |
system-quarters-of-year | Quarters of Year | Name, Short Name, Number |
Every system Data Set has an All Records view. Currencies also has a Major Currencies view, which filters the Code field to twenty common currency codes.
Their keys, field keys, view keys and record keys are fixed: they are the same in every workspace, and a record's key is derived from its first cell (the country name, for example), so it does not change when CheckFlow adds rows to a list.
What you can and cannot do with a system Data Set:
| Operation | Allowed |
|---|---|
| List, get, list fields, list and get views | Yes |
| List and get records, including through a view | Yes |
| List connections | Yes |
| Export as CSV | Yes |
| Rename, change the description, delete | No — 403 FORBIDDEN |
| Add, change or delete fields | No — 403 FORBIDDEN |
| Add, change or delete records, in bulk or singly, or replace them from CSV | No — 403 FORBIDDEN |
| Create, change or delete views | No — 403 FORBIDDEN |
On a system Data Set, url, createdDateTime and updatedDateTime are absent — the ten are built by CheckFlow and have no page of their own in the app. System Data Sets do not count towards the workspace's limit of 100.
A write to a system Data Set is checked after the request body. A body that is invalid in its own right — a cell naming a column the Data Set does not have, say — is answered 400 before the 403.
Limits
| Limit | Value | When exceeded |
|---|---|---|
| Data Sets per workspace (system Data Sets not counted) | 100 | 400 on create or CSV import |
| Fields per Data Set | 50 | 400 on create, add field or CSV import |
| Records per Data Set | 10,000 | 400 on add record, bulk create or CSV import |
| Views per Data Set | 20 | 400 on create view |
| Cell text in one record | 5 KB (5,120 bytes of UTF-8, all cells together) | 400 on any record write |
| Records in one bulk create or bulk delete | 1,000 | 400 naming records or recordKeys |
| CSV text in one import or export | 5 MB (5,242,880 bytes of UTF-8) | 400 |
| Data Set, field and view names | 200 characters | 400 |
A limit is enforced when a request would cross it; nothing is written. Names are trimmed before they are stored. Field names must be unique within a Data Set, compared without regard to case.
The Data Set Object
GET /v3/data-sets/{dataSetKey}, create, update and both CSV imports return the full object. GET /v3/data-sets returns each Data Set without fields and views.
| Field | Type | Description |
|---|---|---|
key | string (GUID) | The Data Set's key. |
slug | string | The slug a system Data Set also answers to, such as system-countries. Absent for the workspace's own Data Sets. |
name | string | The Data Set's name. |
description | string | Absent when there is none. |
source | string | organisation for a Data Set the workspace made, system for a system Data Set. |
fieldCount | integer | How many fields it has. |
recordCount | integer | How many records it holds. |
url | string | Where to open it in the app. Absent for a system Data Set. |
createdDateTime | string (date-time) | When it was created. Absent for a system Data Set. |
updatedDateTime | string (date-time) | When it was last updated. Absent for a system Data Set. |
fields | array of Field | Its fields, in field order. Full object only. |
views | array of View | Its views, the default view first and the rest in the order they were created. Full object only. |
{
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Suppliers",
"description": "Approved suppliers for invoice review",
"source": "organisation",
"fieldCount": 5,
"recordCount": 3,
"url": "https://app.checkflow.io/DataSet/Index?key=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-03-04T09:15:22Z",
"updatedDateTime": "2026-06-18T14:02:47Z",
"fields": [
{ "key": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "name": "Supplier", "type": "text", "description": "Trading name", "position": 0 },
{ "key": "b72d9e14-5f3a-4b6c-8d20-1e9f4a7c3b68", "name": "Contact", "type": "email", "position": 1 },
{ "key": "c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74", "name": "Payment Terms", "type": "number", "description": "Days", "position": 2 },
{ "key": "d4f86a29-7b3c-4e1f-b852-5a9c0e3d7f16", "name": "Contract Renews", "type": "date", "position": 3 },
{ "key": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "name": "Active", "type": "boolean", "position": 4 }
],
"views": [
{
"key": "6b2e4d8f-1a3c-4e5b-8d7f-0c9a2e4b6d13",
"name": "All Records",
"isDefault": true,
"filters": [],
"sorts": [],
"hiddenFieldKeys": [],
"hiddenFieldNames": []
},
{
"key": "7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24",
"name": "Active Suppliers",
"isDefault": false,
"filters": [
{ "fieldKey": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "fieldName": "Active", "operator": "eq", "value": "true" }
],
"sorts": [
{ "fieldKey": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "fieldName": "Supplier", "direction": "asc", "position": 0 }
],
"hiddenFieldKeys": ["c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74"],
"hiddenFieldNames": ["Payment Terms"]
}
]
}
The url uses your workspace's own address, so it may be a custom subdomain or eu.checkflow.io rather than app.checkflow.io.
The Field Object
A field is one column. See Fields for how field types behave in the app.
| Field | Type | Description |
|---|---|---|
key | string (GUID) | The field's key. |
name | string | Its name, unique within the Data Set regardless of case. Records are keyed by this name. |
type | string | text, number, date, email, url or boolean. See Record Values. |
description | string | Absent when there is none. |
position | integer | Where the field sits, counting from zero. Set when the field is created; nothing changes it. |
Fields are always listed by position, then by name, then by key. Positions are not renumbered when a field is deleted, so they can have gaps. There is no way to reorder fields, in the API or in the app.
The View Object
A view is a saved way of looking at the records: which of them, in what order and with which fields hidden. See Views.
| Field | Type | Description |
|---|---|---|
key | string (GUID) | The view's key. This is what a template control links to, and what ?view= takes. |
name | string | The view's name. |
isDefault | boolean | true for the All Records view every Data Set is created with. Exactly one view is the default, and it cannot be renamed, deleted or replaced as the default. |
filters | array of Filter | The conditions a record must meet. Empty for none. |
sorts | array of Sort | The sort levels, in the order they apply. Empty for the Data Set's own order. |
hiddenFieldKeys | array of string | The keys of the fields this view hides. |
hiddenFieldNames | array of string | The names of those fields, index for index. An entry is null when the view names a field that has since been deleted. |
A filter or sort in a response has this shape:
| Field | Type | Description |
|---|---|---|
fieldKey | string (GUID) | The field it applies to. |
fieldName | string | That field's name. Absent when the field has since been deleted. |
operator | string | Filters only. One of the filter operators. |
value | string | Filters only. What the field is compared against. Absent for is_empty and is_not_empty. |
direction | string | Sorts only. asc or desc. |
position | integer | Sorts only. The order the sort levels apply in, counting from zero. |
Deleting a field does not change any view. A filter, sort or hidden field that names a deleted field shows with no fieldName (or a null in hiddenFieldNames), has no effect on which records the view returns, and is dropped the next time the view is updated.
The Record Object
A record is one row. Its values are keyed by field name, not by field key, so a record reads as it would in a spreadsheet.
| Field | Type | Description |
|---|---|---|
key | string (GUID) | The record's key. |
position | integer | Where the record sits in the Data Set, counting from zero. Set when the record is created and never changed. Positions are not renumbered when records are deleted, so they can have gaps — they are an order, not a count. When you read through a view, this is still the record's position in the Data Set, not its place in the view. |
values | object | One entry per field of the Data Set, in field order, keyed by field name. Every value is a string, or null for an empty cell. |
{
"key": "8d4a6f0b-3c5e-4a7d-b9f1-2e1c4a6d8f35",
"position": 0,
"values": {
"Supplier": "Acme Office Supplies Ltd",
"Contact": "accounts@acme-office.example",
"Payment Terms": "30",
"Contract Renews": "2026-11-30",
"Active": "true"
}
}
Every field appears in values, including empty ones and fields a view hides, so every record of a Data Set has the same keys as GET /v3/data-sets/{dataSetKey}/fields reports. Unlike other properties in the API, an empty cell is sent as null rather than left out.
Record Values
When you write a record, each entry in values names a field by its name (matched without regard to case) or by its key. An entry that is neither is refused with 400, naming the cell — values.Suplier — and nothing is written. Naming the same field twice, once by name and once by key, is also a 400.
Each value is a JSON string, number or boolean. An array or object is refused, because a cell holds one value. null, an empty string and a string of only spaces all mean an empty cell. Values are trimmed. Every value is stored as text and read back as a string, whatever the field's type:
| Type | Accepts | Stored and read back as |
|---|---|---|
text | Anything. | As sent. |
number | A number, as a JSON number or a string, written with . as the decimal point — for example 30, -2.5 or "1,250.00". | As sent — 30 reads back as "30", and nothing is reformatted. |
date | A date or date-time. yyyy-MM-dd, yyyy-MM-ddTHH:mm:ss and yyyy-MM-ddTHH:mm:ssZ are always accepted; other formats are read with US conventions, so 03/01/2026 is 1 March. Use yyyy-MM-dd. | As sent. |
email | An address with exactly one @, something before it, a . after it (the first . after the @ must not come straight after it) and no spaces. | As sent. |
url | An absolute http or https URL. | As sent. |
boolean | true or false as JSON booleans, or the strings true, false, yes, no, 1 or 0 in any case. | "true" or "false". |
A value the field's type does not accept is a 400 naming the cell, with a message such as 'n/a' is not a valid number value for field 'Payment Terms'. Because a record write returns the record as stored, the response is not always what you sent: a boolean written as "yes" reads back as "true".
The Connection Object
A connection is one template control that reads from the Data Set. It is what stands between a Data Set and deleting it.
| Field | Type | Description |
|---|---|---|
templateKey | string (GUID) | The template the control is in. |
templateName | string | That template's name. |
templateVersion | integer | The template version the control is in — always the latest version. |
templateUrl | string | Where to open that template in the app. |
controlKey | string (GUID) | The control's key within that version. |
controlLabel | string | The control's label. |
controlType | string | dropDown, multiChoice, subTasks or table. |
viewKey | string (GUID) | The view the control reads. |
viewName | string | That view's name. Absent when the control points at a view that has since been deleted. |
Filters and Sorts
A view's filters decide which records it returns and its sorts decide their order. You write them when you create or update a view. Records are only ever filtered and sorted through a saved view — List Records has no filter or sort parameters of its own.
Writing a Filter
{ "field": "Payment Terms", "operator": "lte", "value": "30" }
| Field | Type | Required | Description |
|---|---|---|---|
field | string | Yes | The field, by name (matched without regard to case) or by key. |
operator | string | Yes | One of the operators below. |
value | string | For all but is_empty and is_not_empty | What to compare against, always as a string. is_empty and is_not_empty refuse a value, even an empty one. |
A view's filters are combined with AND — a record must meet every one. There is no OR. You can filter the same field twice, which is how you write a range.
| Operator | Matches a record when the cell… |
|---|---|
eq | equals value. |
neq | does not equal value. |
contains | contains value. |
not_contains | does not contain value. |
starts_with | starts with value. |
ends_with | ends with value. |
gt | is greater than value. |
gte | is greater than or equal to value. |
lt | is less than value. |
lte | is less than or equal to value. |
is_empty | is empty. |
is_not_empty | is not empty. |
in | equals one of the items in value, a comma-separated list such as "GBP,EUR,USD". Items are trimmed. |
How values are compared:
- Text comparisons ignore case. An empty cell compares as an empty string, so
neqandnot_containsmatch empty cells. gt,gte,ltandltecompare numerically on anumberfield and chronologically on adatefield when both the cell andvaluecan be read that way. Otherwise — on other field types, or when either side cannot be read as a number or date — they compare as text, ignoring case.- On a
booleanfield the filter's value is normalised the way a record's is, so"yes"and"1"matchtrue. Forin, each item is normalised separately.
Writing a Sort
{ "field": "Contract Renews", "direction": "desc" }
| Field | Type | Required | Description |
|---|---|---|---|
field | string | Yes | The field, by name or by key. A field may appear in sorts only once. |
direction | string | No | asc (the default) or desc. Anything else is refused rather than read as asc. |
Sorts apply in the order you write them; the array is the order, and there is no position to send. A number field sorts numerically and a date field chronologically, with empty and unreadable cells after every other value when ascending (and before them when descending). Other fields sort as text. Records that tie keep the Data Set's own order, and a view with no sorts returns records in the Data Set's own order.
Hidden Fields
hiddenFields is an array of field names or keys that the view leaves out of the grid and out of a CSV export. Naming a field twice is harmless. A view must show at least one field, so hiding every field is refused.
Hiding a field is a display instruction, not a security boundary: List Records still returns hidden fields through the view.
CSV Format
Both CSV imports take the file as text in a JSON string, csv, rather than as a file upload, so the same call works from a script and from an MCP tool. Export returns the file the same way. These rules apply to both imports:
- The first line names the columns. Every column must have a name; names are trimmed, must be unique without regard to case and must be 200 characters or fewer. At most 50 columns.
- Quoting follows RFC 4180: a value containing a comma, a double quote or a line break is wrapped in double quotes, and a double quote inside it is doubled. A quote that is never closed is refused.
- Lines may end in CRLF, LF or CR. A leading byte-order mark is ignored.
- Every line after the first is a record. A line whose cells are all blank is skipped and not counted. At most 10,000 records.
- A line with more cells than the header is refused, and the message lists the line numbers (up to 20). A line with fewer cells is padded with empty cells.
- Each record may hold at most 5 KB of cell text.
- Values are trimmed; a blank cell is an empty cell.
- A value that starts with an apostrophe followed by
=,+,-or@has the apostrophe removed. This reverses the formula protection export adds, so an exported file imports unchanged. - The whole text may be at most 5 MB, measured in UTF-8 bytes.
A file that breaks one of these rules is refused with 400 VALIDATION_ERROR and a message describing the problem, such as Column names in the first row must be unique. Nothing is written.
Column Type Detection
When an import creates a field, its type is detected from the non-empty values in that column, trying each type in this order:
| Every non-empty value is… | Type |
|---|---|
a date written exactly yyyy-MM-dd | date |
| a number | number |
true, false, yes, no, 1 or 0 | boolean |
| an email address | email |
an absolute http or https URL | url |
| anything else, or the column is empty | text |
Because numbers are tried before booleans, a column of 1 and 0 becomes a number field. There is no way to choose types when importing; change a field's type afterwards with Update a Field, which succeeds as long as every existing value suits the new type.
Webhook Events
Record changes raise these webhook events:
| Event | Raised by |
|---|---|
data_set.record.created | Add a Record. |
data_set.record.updated | Update a Record, when at least one cell actually changed. |
data_set.record.deleted | Delete a Record, and Delete Records in Bulk once per record. |
Add or Replace Records in Bulk and both CSV imports raise no events, including for records a replace removes. Use the single-record routes if something downstream relies on these events.
List Data Sets
Returns every Data Set the key can read: the workspace's own, followed by the ten system Data Sets. For a key that acts as a Member, the workspace's own are only those the Member could read — see Permissions. Each item is a Data Set object without fields and views — use Get a Data Set for those.
GET /v3/data-sets
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
includeSystem | query | boolean | No | false leaves the system Data Sets out. Default true. Any value other than true or false is a 400. |
The list is not paged: the whole list comes back in one response, with hasMore always false and total equal to the number of items. The workspace's own Data Sets come first, by name; the system Data Sets follow in a fixed order.
Example
GET https://api.checkflow.io/v3/data-sets
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Suppliers",
"description": "Approved suppliers for invoice review",
"source": "organisation",
"fieldCount": 5,
"recordCount": 3,
"url": "https://app.checkflow.io/DataSet/Index?key=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-03-04T09:15:22Z",
"updatedDateTime": "2026-06-18T14:02:47Z"
},
{
"key": "2c7e9a41-5d3b-4f8e-a162-9b0d4e7f3a58",
"slug": "system-priority-levels",
"name": "Priority Levels",
"description": "Standard priority levels",
"source": "system",
"fieldCount": 2,
"recordCount": 4
}
],
"hasMore": false,
"total": 2
}
The example is shortened; a real response lists all ten system Data Sets.
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The Data Sets. |
400 Bad Request | VALIDATION_ERROR | includeSystem is neither true nor false (field: includeSystem). |
403 Forbidden | FORBIDDEN | The key acts as a Member with none of Library.Creator, Library.Viewer, Template.Creator and Template.Viewer. |
Create a Data Set
Creates a Data Set with the fields you name. An All Records view is created with it. To create a Data Set and fill it from a spreadsheet in one call, use Create a Data Set from CSV instead.
POST /v3/data-sets
Parameters
This endpoint takes no parameters.
Request Body
{
"name": "Suppliers",
"description": "Approved suppliers for invoice review",
"fields": [
{ "name": "Supplier", "type": "text", "description": "Trading name" },
{ "name": "Contact", "type": "email" },
{ "name": "Payment Terms", "type": "number", "description": "Days" },
{ "name": "Contract Renews", "type": "date" },
{ "name": "Active", "type": "boolean" }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters. |
description | string | No | A description of the Data Set. |
fields | array | No | The fields to create, in order. Leave it out, or send [], and the Data Set is created with one text field called Name. At most 50. |
fields[].name | string | Yes | Up to 200 characters, unique within the Data Set regardless of case. |
fields[].type | string | No | text, number, date, email, url or boolean. Default text. |
fields[].description | string | No | A description of the field. |
Example
POST https://api.checkflow.io/v3/data-sets
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"name": "Suppliers",
"description": "Approved suppliers for invoice review",
"fields": [
{ "name": "Supplier", "type": "text", "description": "Trading name" },
{ "name": "Contact", "type": "email" },
{ "name": "Payment Terms", "type": "number", "description": "Days" },
{ "name": "Contract Renews", "type": "date" },
{ "name": "Active", "type": "boolean" }
]
}
HTTP/1.1 201 Created
{
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Suppliers",
"description": "Approved suppliers for invoice review",
"source": "organisation",
"fieldCount": 5,
"recordCount": 0,
"url": "https://app.checkflow.io/DataSet/Index?key=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-03-04T09:15:22Z",
"updatedDateTime": "2026-03-04T09:15:22Z",
"fields": [
{ "key": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "name": "Supplier", "type": "text", "description": "Trading name", "position": 0 },
{ "key": "b72d9e14-5f3a-4b6c-8d20-1e9f4a7c3b68", "name": "Contact", "type": "email", "position": 1 },
{ "key": "c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74", "name": "Payment Terms", "type": "number", "description": "Days", "position": 2 },
{ "key": "d4f86a29-7b3c-4e1f-b852-5a9c0e3d7f16", "name": "Contract Renews", "type": "date", "position": 3 },
{ "key": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "name": "Active", "type": "boolean", "position": 4 }
],
"views": [
{
"key": "6b2e4d8f-1a3c-4e5b-8d7f-0c9a2e4b6d13",
"name": "All Records",
"isDefault": true,
"filters": [],
"sorts": [],
"hiddenFieldKeys": [],
"hiddenFieldNames": []
}
]
}
Responses
| Status | Code | When |
|---|---|---|
201 Created | — | The Data Set, with its fields and its All Records view. |
400 Bad Request | VALIDATION_ERROR | name or a field name is missing or over 200 characters; two fields share a name; more than 50 fields; the workspace already has 100 Data Sets; or a field type is not one of the six (field: fields). |
403 Forbidden | FORBIDDEN | The key acts as a Member without Library.Creator. |
Create a Data Set from CSV
Creates a Data Set from CSV text: the first line becomes the fields, every later line a record. Field types are detected from the values. To load an existing Data Set, use Replace Records from CSV.
POST /v3/data-sets/import
Parameters
This endpoint takes no parameters.
Request Body
{
"name": "Suppliers",
"description": "Imported from the finance system",
"csv": "Supplier,Contact,Payment Terms,Active\nAcme Office Supplies Ltd,accounts@acme-office.example,30,true\n\"Harbour Print Co, Leeds\",,14,false\n"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters. There is no file name to fall back on. |
description | string | No | A description of the Data Set. |
csv | string | Yes | The file's text, following the CSV format. |
Example
POST https://api.checkflow.io/v3/data-sets/import
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"name": "Suppliers",
"description": "Imported from the finance system",
"csv": "Supplier,Contact,Payment Terms,Active\nAcme Office Supplies Ltd,accounts@acme-office.example,30,true\n\"Harbour Print Co, Leeds\",,14,false\n"
}
HTTP/1.1 201 Created
{
"dataSet": {
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Suppliers",
"description": "Imported from the finance system",
"source": "organisation",
"fieldCount": 4,
"recordCount": 2,
"url": "https://app.checkflow.io/DataSet/Index?key=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-03-04T09:15:22Z",
"updatedDateTime": "2026-03-04T09:15:22Z",
"fields": [
{ "key": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "name": "Supplier", "type": "text", "position": 0 },
{ "key": "b72d9e14-5f3a-4b6c-8d20-1e9f4a7c3b68", "name": "Contact", "type": "email", "position": 1 },
{ "key": "c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74", "name": "Payment Terms", "type": "number", "position": 2 },
{ "key": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "name": "Active", "type": "boolean", "position": 3 }
],
"views": [
{
"key": "6b2e4d8f-1a3c-4e5b-8d7f-0c9a2e4b6d13",
"name": "All Records",
"isDefault": true,
"filters": [],
"sorts": [],
"hiddenFieldKeys": [],
"hiddenFieldNames": []
}
]
},
"recordsImported": 2,
"fieldsAdded": ["Supplier", "Contact", "Payment Terms", "Active"]
}
| Field | Type | Description |
|---|---|---|
dataSet | Data Set | The new Data Set, with its fields and views. |
recordsImported | integer | How many records the file created. Skipped blank lines are not counted. |
fieldsAdded | array of string | The fields created, in column order — here, every column. |
Responses
| Status | Code | When |
|---|---|---|
201 Created | — | The Data Set was created and filled. |
400 Bad Request | VALIDATION_ERROR | csv is missing, blank or over 5 MB (field: csv); the file breaks a CSV format rule; name is missing or over 200 characters; or the workspace already has 100 Data Sets. |
403 Forbidden | FORBIDDEN | The key acts as a Member without Library.Creator. |
Get a Data Set
Returns one Data Set with its fields and views, but not its records — use List Records for those. Read this before writing records (for the field names) or linking a template control (for the view keys).
GET /v3/data-sets/{dataSetKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key, or a system Data Set's slug. |
Example
GET https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
The body is a Data Set object, as in the example there.
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The Data Set, with its fields and views. |
403 Forbidden | FORBIDDEN | The key acts as a Member without a Library or Template permission, or without View or Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No Data Set of this workspace, and no system Data Set, has that key or slug. |
Update a Data Set
Renames a Data Set or changes its description. Fields, records and views have routes of their own.
PATCH /v3/data-sets/{dataSetKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
Request Body
This is a partial update (see Partial Updates with PATCH): a property you leave out is unchanged.
{
"name": "Approved Suppliers",
"description": null
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | The new name, up to 200 characters. Sending null or a blank name is refused. |
description | string | No | The new description. null clears it. |
A body that names neither property is refused rather than treated as a no-op.
Example
PATCH https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"name": "Approved Suppliers",
"description": null
}
HTTP/1.1 200 OK
{
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Approved Suppliers",
"source": "organisation",
"fieldCount": 5,
"recordCount": 3,
"url": "https://app.checkflow.io/DataSet/Index?key=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-03-04T09:15:22Z",
"updatedDateTime": "2026-09-27T10:41:05Z",
"fields": [
{ "key": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "name": "Supplier", "type": "text", "description": "Trading name", "position": 0 }
],
"views": [
{
"key": "6b2e4d8f-1a3c-4e5b-8d7f-0c9a2e4b6d13",
"name": "All Records",
"isDefault": true,
"filters": [],
"sorts": [],
"hiddenFieldKeys": [],
"hiddenFieldNames": []
}
]
}
The example's fields and views are shortened; the response carries all of them.
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The Data Set as it now reads. |
400 Bad Request | VALIDATION_ERROR | The body names neither property; name is null or blank (field: name); or name is over 200 characters. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Delete a Data Set
Deletes a Data Set with its fields, records and views. A Data Set that template controls read from is refused with 409 unless you send force=true.
DELETE /v3/data-sets/{dataSetKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
force | query | boolean | No | true deletes the links from template controls along with the Data Set, instead of refusing. Default false. Any value other than true or false is a 400. |
Example
DELETE https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14
X-API-KEY: your-api-key-here
When no template control reads from the Data Set:
HTTP/1.1 204 No Content
When one does, and force was not sent:
HTTP/1.1 409 Conflict
{
"error": {
"code": "CONFLICT",
"message": "This Data Set is read by controls in 1 template: Invoice Review. Read its connections for the controls themselves, or send force=true to delete the links with it.",
"requestId": "b3d1f7a2-4c6e-4a8b-9d0f-1e2c3a4b5d6e"
}
}
Responses
| Status | Code | When |
|---|---|---|
204 No Content | — | The Data Set was deleted. |
400 Bad Request | VALIDATION_ERROR | force is neither true nor false (field: force). |
403 Forbidden | FORBIDDEN | It is a system Data Set, or the key acts as a Member. Deleting a Data Set is limited to Administrators. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
409 Conflict | CONFLICT | Template controls read from the Data Set and force was not true. The message names up to five templates, then a count of the rest. |
Notes
- The
409is based on the latest version of each template, as List a Data Set's Connections is. Call that first to see which controls would be affected. - The API has no way to restore a deleted Data Set.
force=true removes the Data Set links from every version of every template, not only the latest versions the 409 named. The affected controls are left with nothing to offer.
List a Data Set's Connections
Returns the template controls that read from a Data Set — one Connection per control. Use it before deleting a Data Set, a field or a view to see what would be affected.
GET /v3/data-sets/{dataSetKey}/connections
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key, or a system Data Set's slug. |
Only the latest version of each template is reported. An older version's link still works for checklists created from it, but it cannot be edited. A template appears once for each control in it that reads the Data Set. The list is not paged: hasMore is always false and total is the number of items.
Example
GET https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/connections
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"templateKey": "4a7c9e2b-6d8f-4a1c-b3e5-7f9d1b3c5e68",
"templateName": "Invoice Review",
"templateVersion": 3,
"templateUrl": "https://app.checkflow.io/Template/Index?templateKey=4a7c9e2b-6d8f-4a1c-b3e5-7f9d1b3c5e68",
"controlKey": "5b8d0f3c-7e9a-4b2d-8c4f-6a0e2c4d6f79",
"controlLabel": "Supplier",
"controlType": "dropDown",
"viewKey": "7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24",
"viewName": "Active Suppliers"
}
],
"hasMore": false,
"total": 1
}
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The controls reading the Data Set. An empty list means nothing reads it. |
403 Forbidden | FORBIDDEN | The key acts as a Member without a Library or Template permission, or without View or Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Export a Data Set as CSV
Returns a Data Set's records as CSV text, taken through a view. System Data Sets can be exported too.
GET /v3/data-sets/{dataSetKey}/export
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key, or a system Data Set's slug. |
view | query | string (GUID) | No | The view to export through. Default: the Data Set's default view. |
The view's filters and sorts decide which records are in the file and in what order, and a field the view hides is not a column of the file.
Example
GET https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/export?view=7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"fileName": "suppliers-active-suppliers-2026-09-27.csv",
"contentType": "text/csv",
"viewKey": "7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24",
"viewName": "Active Suppliers",
"columns": ["Supplier", "Contact", "Contract Renews", "Active"],
"rowCount": 2,
"csv": "Supplier,Contact,Contract Renews,Active\r\nAcme Office Supplies Ltd,accounts@acme-office.example,2026-11-30,true\r\nNorthwind Logistics,billing@northwind.example,2027-02-28,true\r\n"
}
| Field | Type | Description |
|---|---|---|
fileName | string | The name the app gives the same export: the Data Set's name, the view's name and today's UTC date, lower case with spaces replaced by hyphens. |
contentType | string | Always text/csv. |
viewKey | string (GUID) | The view the records were taken through. |
viewName | string | That view's name. |
columns | array of string | The file's columns, in order. |
rowCount | integer | How many records the file holds, not counting the header line. |
csv | string | The file's text, header line first, with no byte-order mark. |
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The CSV text. |
400 Bad Request | VALIDATION_ERROR | view is not a GUID (field: view); the view hides every field (field: view); or the file would be over the 5 MB an import accepts. |
403 Forbidden | FORBIDDEN | The key acts as a Member without a Library or Template permission, or without View or Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_VIEW_NOT_FOUND | The Data Set has no view with that key. |
Notes
- Columns are in field order. Boolean values are written as
trueorfalse. - A value that begins with
=,+,-or@— ignoring leading spaces and tabs — is written with an apostrophe in front, so a spreadsheet does not run it as a formula. This includes negative numbers:-2.5is exported as'-2.5. Both CSV imports remove the apostrophe again. - An export larger than 5 MB is refused rather than cut short, so anything this route exports can be imported again. To export a larger Data Set, export through a view that hides fields or filters records, or read it with List Records.
Replace Records from CSV
Replaces every record in a Data Set with the records in CSV text. The Data Set keeps its key, name, description and views. To add records rather than replace them, use Add or Replace Records in Bulk.
POST /v3/data-sets/{dataSetKey}/import
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
Request Body
{
"csv": "Supplier,Payment Terms,Active,Region\nAcme Office Supplies Ltd,30,yes,North\nNorthwind Logistics,45,yes,South\n"
}
| Field | Type | Required | Description |
|---|---|---|---|
csv | string | Yes | The file's text, following the CSV format. |
How the file's columns meet the Data Set's fields:
- A column is matched to a field by name, without regard to case. Its values must suit that field's type, as record values must.
- A column with no matching field creates a new field, with its type detected from the values.
fieldsAddedlists these — check it to catch a misspelt header, which otherwise quietly becomes a new field. - A field no column names is kept, and is empty in every new record.
Example
POST https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/import
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"csv": "Supplier,Payment Terms,Active,Region\nAcme Office Supplies Ltd,30,yes,North\nNorthwind Logistics,45,yes,South\n"
}
HTTP/1.1 200 OK
{
"dataSet": {
"key": "3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"name": "Suppliers",
"description": "Approved suppliers for invoice review",
"source": "organisation",
"fieldCount": 6,
"recordCount": 2,
"url": "https://app.checkflow.io/DataSet/Index?key=3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14",
"createdDateTime": "2026-03-04T09:15:22Z",
"updatedDateTime": "2026-09-27T10:52:31Z",
"fields": [
{ "key": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "name": "Supplier", "type": "text", "description": "Trading name", "position": 0 },
{ "key": "b72d9e14-5f3a-4b6c-8d20-1e9f4a7c3b68", "name": "Contact", "type": "email", "position": 1 },
{ "key": "c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74", "name": "Payment Terms", "type": "number", "description": "Days", "position": 2 },
{ "key": "d4f86a29-7b3c-4e1f-b852-5a9c0e3d7f16", "name": "Contract Renews", "type": "date", "position": 3 },
{ "key": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "name": "Active", "type": "boolean", "position": 4 },
{ "key": "f6b08c4b-9d5e-4a31-8d74-8c2e3a5f9b38", "name": "Region", "type": "text", "position": 5 }
],
"views": [
{
"key": "6b2e4d8f-1a3c-4e5b-8d7f-0c9a2e4b6d13",
"name": "All Records",
"isDefault": true,
"filters": [],
"sorts": [],
"hiddenFieldKeys": [],
"hiddenFieldNames": []
}
]
},
"recordsImported": 2,
"fieldsAdded": ["Region"]
}
The response has the same shape as Create a Data Set from CSV's. fieldsAdded lists only the fields this import created.
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The records were replaced. |
400 Bad Request | VALIDATION_ERROR | csv is missing, blank or over 5 MB (field: csv); the file breaks a CSV format rule; a value does not suit its field's type; or new columns would take the Data Set over 50 fields. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Notes
- Removing the old records and writing the new ones is a single transaction: if writing the records fails, the old records are left as they were.
- No webhook events are raised, for the records removed or the records added.
List Fields
Returns a Data Set's fields. Get a Data Set returns the same fields alongside the views; use this route when the fields are all you need.
GET /v3/data-sets/{dataSetKey}/fields
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key, or a system Data Set's slug. |
The list is not paged — a Data Set has at most 50 fields. hasMore is always false and total is the number of items. Fields are ordered by position, then name, then key.
Example
GET https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/fields
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{ "key": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "name": "Supplier", "type": "text", "description": "Trading name", "position": 0 },
{ "key": "b72d9e14-5f3a-4b6c-8d20-1e9f4a7c3b68", "name": "Contact", "type": "email", "position": 1 },
{ "key": "c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74", "name": "Payment Terms", "type": "number", "description": "Days", "position": 2 },
{ "key": "d4f86a29-7b3c-4e1f-b852-5a9c0e3d7f16", "name": "Contract Renews", "type": "date", "position": 3 },
{ "key": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "name": "Active", "type": "boolean", "position": 4 }
],
"hasMore": false,
"total": 5
}
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The fields. |
403 Forbidden | FORBIDDEN | The key acts as a Member without a Library or Template permission, or without View or Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Add a Field
Adds a field after the existing ones. Every existing record gets an empty cell in it.
POST /v3/data-sets/{dataSetKey}/fields
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
Request Body
{
"name": "Region",
"type": "text",
"description": "Sales region the supplier serves"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters, unique within the Data Set regardless of case. |
type | string | No | text, number, date, email, url or boolean. Default text. |
description | string | No | A description of the field. |
There is no position: a new field always goes last.
Example
POST https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/fields
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"name": "Region",
"type": "text",
"description": "Sales region the supplier serves"
}
HTTP/1.1 201 Created
{
"key": "f6b08c4b-9d5e-4a31-8d74-8c2e3a5f9b38",
"name": "Region",
"type": "text",
"description": "Sales region the supplier serves",
"position": 5
}
Responses
| Status | Code | When |
|---|---|---|
201 Created | — | The new Field. |
400 Bad Request | VALIDATION_ERROR | name is missing, over 200 characters or already used by another field; the Data Set already has 50 fields; or type is not one of the six (field: type). |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Update a Field
Renames a field, changes its type or changes its description. A field's position cannot be changed.
PATCH /v3/data-sets/{dataSetKey}/fields/{fieldKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
fieldKey | path | string (GUID) | Yes | The field's key. |
Request Body
This is a partial update (see Partial Updates with PATCH): a property you leave out is unchanged.
{
"type": "number"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | The new name, up to 200 characters and unique within the Data Set. null or blank is refused. |
type | string | No | text, number, date, email, url or boolean. null or blank is refused. |
description | string | No | The new description. null clears it. |
A body that names none of the three is refused rather than treated as a no-op.
Example
PATCH https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/fields/f6b08c4b-9d5e-4a31-8d74-8c2e3a5f9b38
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"name": "Sales Region",
"description": null
}
HTTP/1.1 200 OK
{
"key": "f6b08c4b-9d5e-4a31-8d74-8c2e3a5f9b38",
"name": "Sales Region",
"type": "text",
"position": 5
}
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The Field as it now reads. |
400 Bad Request | VALIDATION_ERROR | The body names no property; name or type is null or blank (field: name or type); type is not one of the six (field: type); fieldKey is not a GUID (field: fieldKey); name is over 200 characters or used by another field; or a record holds a value the new type does not accept. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_FIELD_NOT_FOUND | The Data Set has no field with that key. |
Notes
- Changing the type is refused while any record holds a value the new type does not accept — a
textfield holdingn/acannot becomenumber. The message names the type but not the record; find it with List Records. Empty cells suit every type, so a field nobody has filled in can be retyped freely. - Existing values are not rewritten when the type changes. A
textfield holdingyesthat becomesbooleankeeps the storedyes.
Delete a Field
Removes a field and every value in it from every record.
DELETE /v3/data-sets/{dataSetKey}/fields/{fieldKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
fieldKey | path | string (GUID) | Yes | The field's key. |
Example
DELETE https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/fields/f6b08c4b-9d5e-4a31-8d74-8c2e3a5f9b38
X-API-KEY: your-api-key-here
HTTP/1.1 204 No Content
Responses
| Status | Code | When |
|---|---|---|
204 No Content | — | The field and its values were deleted. |
400 Bad Request | VALIDATION_ERROR | fieldKey is not a GUID (field: fieldKey), or it is the Data Set's last field — delete the Data Set instead. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_FIELD_NOT_FOUND | The Data Set has no field with that key. |
409 Conflict | CONFLICT | A template control uses the field as its display field or in a Table column mapping. There is no force. |
Notes
- List a Data Set's Connections lists the controls that read the Data Set, but does not say which of them use a particular field. The check applies to the latest version of each template.
- Views that name the field are not changed; see The View Object.
Deleting a field permanently removes its value from every record. It cannot be undone.
List Records
Returns a page of a Data Set's records, optionally through a saved view.
GET /v3/data-sets/{dataSetKey}/records
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key, or a system Data Set's slug. |
view | query | string (GUID) | No | A view to read through. Its filters and sorts decide which records are returned and in what order. Without it, every record in the Data Set's own order. |
pageSize | query | integer | No | Records per page, 1 to 100. Default 50. A value outside that range, or not a number, is read as 50. |
after | query | string | No | The nextCursor from the previous page. |
There is no sort parameter and no filter parameters — a Data Set's records are sorted and filtered by saved views (see Filters and Sorts). Create a view if you need a different order or subset. Fields the view hides are still returned in values.
Pagination follows Pagination. A cursor is valid only with the same view and pageSize it was issued under; changing either mid-walk is a 400 on after. total is the number of records the view matched, not the number on this page.
Example
GET https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/records?pageSize=2
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"key": "8d4a6f0b-3c5e-4a7d-b9f1-2e1c4a6d8f35",
"position": 0,
"values": {
"Supplier": "Acme Office Supplies Ltd",
"Contact": "accounts@acme-office.example",
"Payment Terms": "30",
"Contract Renews": "2026-11-30",
"Active": "true"
}
},
{
"key": "9e5b7a1c-4d6f-4b8e-8a02-3f2d5b7e9a46",
"position": 1,
"values": {
"Supplier": "Harbour Print Co",
"Contact": null,
"Payment Terms": "14",
"Contract Renews": null,
"Active": "false"
}
}
],
"nextCursor": "eyJ2IjoxLCJzIjoicG9zaXRpb24iLCJvIjoyfQ",
"hasMore": true,
"total": 3
}
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | A page of Records. |
400 Bad Request | VALIDATION_ERROR | view is not a GUID (field: view), or after is not a valid cursor or was issued for a different view or pageSize (field: after). |
403 Forbidden | FORBIDDEN | The key acts as a Member without a Library or Template permission, or without View or Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_VIEW_NOT_FOUND | The Data Set has no view with that key. |
Add a Record
Adds one record after the existing ones. To add many records, use Add or Replace Records in Bulk — but note that only this route raises the data_set.record.created webhook event.
POST /v3/data-sets/{dataSetKey}/records
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
Request Body
{
"values": {
"Supplier": "Northwind Logistics",
"Contact": "billing@northwind.example",
"Payment Terms": 45,
"Contract Renews": "2027-02-28",
"Active": "yes"
}
}
| Field | Type | Required | Description |
|---|---|---|---|
values | object | No | The cells, keyed by field name or field key, following Record Values. A field you leave out is empty. Leave values out altogether, or send {}, for a blank record. |
Example
POST https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/records
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"values": {
"Supplier": "Northwind Logistics",
"Contact": "billing@northwind.example",
"Payment Terms": 45,
"Contract Renews": "2027-02-28",
"Active": "yes"
}
}
HTTP/1.1 201 Created
{
"key": "0f6c8b2d-5e7a-4c9f-9b13-4a3e6c8f0b57",
"position": 2,
"values": {
"Supplier": "Northwind Logistics",
"Contact": "billing@northwind.example",
"Payment Terms": "45",
"Contract Renews": "2027-02-28",
"Active": "true"
}
}
Responses
| Status | Code | When |
|---|---|---|
201 Created | — | The Record as stored, with the position it was given. |
400 Bad Request | VALIDATION_ERROR | A cell names no field of this Data Set, names a field twice, holds an array or object, or holds a value its field's type does not accept (field: values.<name>); the record is over 5 KB; or the Data Set already holds 10,000 records. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Notes
Raises the data_set.record.created webhook event.
Get a Record
Returns one record.
GET /v3/data-sets/{dataSetKey}/records/{recordKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key, or a system Data Set's slug. |
recordKey | path | string (GUID) | Yes | The record's key. It must be a record of this Data Set. |
Example
GET https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/records/8d4a6f0b-3c5e-4a7d-b9f1-2e1c4a6d8f35
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"key": "8d4a6f0b-3c5e-4a7d-b9f1-2e1c4a6d8f35",
"position": 0,
"values": {
"Supplier": "Acme Office Supplies Ltd",
"Contact": "accounts@acme-office.example",
"Payment Terms": "30",
"Contract Renews": "2026-11-30",
"Active": "true"
}
}
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The Record. |
400 Bad Request | VALIDATION_ERROR | recordKey is not a GUID (field: recordKey). |
403 Forbidden | FORBIDDEN | The key acts as a Member without a Library or Template permission, or without View or Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_RECORD_NOT_FOUND | The Data Set has no record with that key. |
Update a Record
Changes some of a record's cells. Only the cells you send change.
PATCH /v3/data-sets/{dataSetKey}/records/{recordKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
recordKey | path | string (GUID) | Yes | The record's key. It must be a record of this Data Set. |
Request Body
This is a partial update, cell by cell: a cell you leave out keeps its value, and a cell sent as null (or an empty string) is emptied.
{
"values": {
"Payment Terms": 60,
"Contact": null
}
}
| Field | Type | Required | Description |
|---|---|---|---|
values | object | Yes | The cells to change, keyed by field name or field key, following Record Values. Must name at least one cell. |
A record's position cannot be changed.
Example
PATCH https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/records/8d4a6f0b-3c5e-4a7d-b9f1-2e1c4a6d8f35
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"values": {
"Payment Terms": 60,
"Contact": null
}
}
HTTP/1.1 200 OK
{
"key": "8d4a6f0b-3c5e-4a7d-b9f1-2e1c4a6d8f35",
"position": 0,
"values": {
"Supplier": "Acme Office Supplies Ltd",
"Contact": null,
"Payment Terms": "60",
"Contract Renews": "2026-11-30",
"Active": "true"
}
}
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The Record as it now reads. |
400 Bad Request | VALIDATION_ERROR | values is missing or empty (field: values); recordKey is not a GUID (field: recordKey); a cell names no field, names a field twice, holds an array or object, or holds a value its field's type does not accept (field: values.<name>); or the record would be over 5 KB. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_RECORD_NOT_FOUND | The Data Set has no record with that key. |
Notes
Raises the data_set.record.updated webhook event when at least one cell's stored value changed.
Delete a Record
Deletes one record. The records after it keep their positions.
DELETE /v3/data-sets/{dataSetKey}/records/{recordKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
recordKey | path | string (GUID) | Yes | The record's key. It must be a record of this Data Set. |
Example
DELETE https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/records/9e5b7a1c-4d6f-4b8e-8a02-3f2d5b7e9a46
X-API-KEY: your-api-key-here
HTTP/1.1 204 No Content
Responses
| Status | Code | When |
|---|---|---|
204 No Content | — | The record was deleted. |
400 Bad Request | VALIDATION_ERROR | recordKey is not a GUID (field: recordKey). |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_RECORD_NOT_FOUND | The Data Set has no record with that key. |
Notes
Raises the data_set.record.deleted webhook event. Checklist answers already chosen from the record are snapshots and are not changed — see Using Data Sets in Checklists.
Deleting a record is permanent. It cannot be undone.
Add or Replace Records in Bulk
Writes up to 1,000 records in one call, either after the existing records or in place of them. This is the way to load or sync a Data Set from a source other than a CSV file.
POST /v3/data-sets/{dataSetKey}/records/bulk
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
Request Body
{
"mode": "append",
"records": [
{ "values": { "Supplier": "Kestrel Cleaning Services", "Payment Terms": 30, "Active": true } },
{ "values": { "Supplier": "Meridian IT Ltd", "Contact": "ap@meridian-it.example", "Active": false } }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | No | append (the default) adds the records after the existing ones. replace makes them the Data Set's only records. Any other value is refused. |
records | array | Yes | 1 to 1,000 records. |
records[].values | object | No | The record's cells, exactly as for Add a Record. Leave it out, or send {}, for a blank record. |
Every record is checked before any is written. A problem in any record refuses the whole call, and the error's field names the record and cell, such as records[41].values.Suplier.
Example
POST https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/records/bulk
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"mode": "append",
"records": [
{ "values": { "Supplier": "Kestrel Cleaning Services", "Payment Terms": 30, "Active": true } },
{ "values": { "Supplier": "Meridian IT Ltd", "Contact": "ap@meridian-it.example", "Active": false } }
]
}
HTTP/1.1 201 Created
{
"mode": "append",
"created": 2,
"recordCount": 5,
"records": [
{
"key": "1a7d9c3e-6f8b-4d0a-8c24-5b4f7d9a1c68",
"position": 3,
"values": {
"Supplier": "Kestrel Cleaning Services",
"Contact": null,
"Payment Terms": "30",
"Contract Renews": null,
"Active": "true"
}
},
{
"key": "2b8e0d4f-7a9c-4e1b-9d35-6c5a8e0b2d79",
"position": 4,
"values": {
"Supplier": "Meridian IT Ltd",
"Contact": "ap@meridian-it.example",
"Payment Terms": null,
"Contract Renews": null,
"Active": "false"
}
}
]
}
| Field | Type | Description |
|---|---|---|
mode | string | append or replace, as applied — so you can see which you got if you left it out. |
created | integer | How many records this call wrote. |
recordCount | integer | How many records the Data Set now holds: the same as created after a replace, the new total after an append. |
records | array of Record | The records written, in the order you sent them, as stored and with their real positions. |
Responses
| Status | Code | When |
|---|---|---|
201 Created | — | The records were written. |
400 Bad Request | VALIDATION_ERROR | mode is neither append nor replace (field: mode); records is missing, empty or has more than 1,000 entries (field: records); a cell names no field, names a field twice, holds an array or object, or holds a value its field's type does not accept (field: records[n].values.<name>); a record is over 5 KB; or the Data Set would hold more than 10,000 records. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Notes
- A
replaceis one transaction: if it fails part way through, the Data Set keeps its old records rather than being left empty. An emptyrecordslist is refused, so areplacecannot empty a Data Set by accident — use Delete Records in Bulk for that. - No webhook events are raised, for the records written or the records a
replaceremoves.
Delete Records in Bulk
Deletes up to 1,000 records in one call. The record keys go in the request body.
DELETE /v3/data-sets/{dataSetKey}/records/bulk
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
Request Body
{
"recordKeys": [
"1a7d9c3e-6f8b-4d0a-8c24-5b4f7d9a1c68",
"2b8e0d4f-7a9c-4e1b-9d35-6c5a8e0b2d79"
]
}
| Field | Type | Required | Description |
|---|---|---|---|
recordKeys | array of string (GUID) | Yes | 1 to 1,000 record keys, each of a record in this Data Set. A key sent twice is deleted once. |
All or nothing: every key is checked before anything is deleted, and one key that names no record of this Data Set refuses the whole call.
Example
DELETE https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/records/bulk
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"recordKeys": [
"1a7d9c3e-6f8b-4d0a-8c24-5b4f7d9a1c68",
"2b8e0d4f-7a9c-4e1b-9d35-6c5a8e0b2d79"
]
}
HTTP/1.1 204 No Content
Responses
| Status | Code | When |
|---|---|---|
204 No Content | — | Every record named was deleted. |
400 Bad Request | VALIDATION_ERROR | recordKeys is missing, empty or has more than 1,000 entries (field: recordKeys), or an entry is not a GUID (field: recordKeys[n]). |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_RECORD_NOT_FOUND | A key names no record of this Data Set. Nothing was deleted. |
Notes
Raises one data_set.record.deleted webhook event per record. The records after the deleted ones keep their positions.
Deleting records is permanent. It cannot be undone.
List Views
Returns a Data Set's views. Get a Data Set returns the same views alongside the fields.
GET /v3/data-sets/{dataSetKey}/views
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key, or a system Data Set's slug. |
The list is not paged — a Data Set has at most 20 views. hasMore is always false and total is the number of items. The default view comes first; the rest follow in the order they were created.
Example
GET https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/views
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
{
"items": [
{
"key": "6b2e4d8f-1a3c-4e5b-8d7f-0c9a2e4b6d13",
"name": "All Records",
"isDefault": true,
"filters": [],
"sorts": [],
"hiddenFieldKeys": [],
"hiddenFieldNames": []
},
{
"key": "7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24",
"name": "Active Suppliers",
"isDefault": false,
"filters": [
{ "fieldKey": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "fieldName": "Active", "operator": "eq", "value": "true" }
],
"sorts": [
{ "fieldKey": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "fieldName": "Supplier", "direction": "asc", "position": 0 }
],
"hiddenFieldKeys": ["c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74"],
"hiddenFieldNames": ["Payment Terms"]
}
],
"hasMore": false,
"total": 2
}
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The Views. |
403 Forbidden | FORBIDDEN | The key acts as a Member without a Library or Template permission, or without View or Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Create a View
Saves a new view. Only name is required: a view with no filters, sorts or hidden fields shows every record in the Data Set's own order.
POST /v3/data-sets/{dataSetKey}/views
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
Request Body
{
"name": "Active Suppliers",
"filters": [
{ "field": "Active", "operator": "eq", "value": "true" }
],
"sorts": [
{ "field": "Supplier" }
],
"hiddenFields": ["Payment Terms"]
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters. |
filters | array | No | The filters. All must match. |
sorts | array | No | The sort levels, in order. |
hiddenFields | array of string | No | Fields to hide, by name or key. At least one field must stay visible. |
There is no isDefault: the All Records view is always the default.
Example
POST https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/views
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"name": "Active Suppliers",
"filters": [
{ "field": "Active", "operator": "eq", "value": "true" }
],
"sorts": [
{ "field": "Supplier" }
],
"hiddenFields": ["Payment Terms"]
}
HTTP/1.1 201 Created
{
"key": "7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24",
"name": "Active Suppliers",
"isDefault": false,
"filters": [
{ "fieldKey": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "fieldName": "Active", "operator": "eq", "value": "true" }
],
"sorts": [
{ "fieldKey": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "fieldName": "Supplier", "direction": "asc", "position": 0 }
],
"hiddenFieldKeys": ["c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74"],
"hiddenFieldNames": ["Payment Terms"]
}
Responses
| Status | Code | When |
|---|---|---|
201 Created | — | The new View. |
400 Bad Request | VALIDATION_ERROR | See the table below; also name missing or over 200 characters, or the Data Set already has 20 views. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
Clause errors name the clause in field:
| Problem | field |
|---|---|
A filter entry is null | filters[n] |
| A filter's field is missing or names no field of this Data Set | filters[n].field |
| A filter's operator is missing or unknown | filters[n].operator |
value missing for an operator that needs one, or sent with is_empty or is_not_empty | filters[n].value |
A sort entry is null | sorts[n] |
| A sort's field is missing, unknown or already sorted on | sorts[n].field |
A sort's direction is neither asc nor desc | sorts[n].direction |
| A hidden field is missing or names no field of this Data Set | hiddenFields[n] |
| Every field is hidden | hiddenFields |
Get a View
Returns one view's configuration. For the records it matches, call List Records with view set to its key.
GET /v3/data-sets/{dataSetKey}/views/{viewKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key, or a system Data Set's slug. |
viewKey | path | string (GUID) | Yes | The view's key. It must be a view of this Data Set. |
Example
GET https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/views/7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24
X-API-KEY: your-api-key-here
HTTP/1.1 200 OK
The body is a View object, as in the Create a View example.
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The View. |
400 Bad Request | VALIDATION_ERROR | viewKey is not a GUID (field: viewKey). |
403 Forbidden | FORBIDDEN | The key acts as a Member without a Library or Template permission, or without View or Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_VIEW_NOT_FOUND | The Data Set has no view with that key. |
Update a View
Changes a view's name, filters, sorts or hidden fields.
PATCH /v3/data-sets/{dataSetKey}/views/{viewKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
viewKey | path | string (GUID) | Yes | The view's key. It must be a view of this Data Set. |
Request Body
This is a partial update (see Partial Updates with PATCH): a property you leave out is unchanged. Each of filters, sorts and hiddenFields is replaced as a whole when you send it — send [] to clear it.
{
"filters": [
{ "field": "Active", "operator": "eq", "value": "true" },
{ "field": "Payment Terms", "operator": "lte", "value": "30" }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | The new name, up to 200 characters. null or blank is refused. The All Records view cannot be renamed. |
filters | array | No | Replaces the view's filters. |
sorts | array | No | Replaces the view's sort levels. |
hiddenFields | array of string | No | Replaces the view's hidden fields. |
A body that names none of the four is refused rather than treated as a no-op. The All Records view can be filtered, sorted and have fields hidden like any other.
Example
PATCH https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/views/7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24
X-API-KEY: your-api-key-here
Content-Type: application/json
{
"filters": [
{ "field": "Active", "operator": "eq", "value": "true" },
{ "field": "Payment Terms", "operator": "lte", "value": "30" }
]
}
HTTP/1.1 200 OK
{
"key": "7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24",
"name": "Active Suppliers",
"isDefault": false,
"filters": [
{ "fieldKey": "e5a97b3a-8c4d-4f20-9c63-7b1d2f4e8a27", "fieldName": "Active", "operator": "eq", "value": "true" },
{ "fieldKey": "c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74", "fieldName": "Payment Terms", "operator": "lte", "value": "30" }
],
"sorts": [
{ "fieldKey": "a1c4e7f0-2b5d-4c8e-9f13-6d0a3b7e2c51", "fieldName": "Supplier", "direction": "asc", "position": 0 }
],
"hiddenFieldKeys": ["c9e3f158-6a2b-4d7e-a041-3f8b2d6e9c74"],
"hiddenFieldNames": ["Payment Terms"]
}
Responses
| Status | Code | When |
|---|---|---|
200 OK | — | The View as it now reads. |
400 Bad Request | VALIDATION_ERROR | The body names no property; name is null or blank (field: name); name is over 200 characters; the All Records view would be renamed; viewKey is not a GUID (field: viewKey); or a clause is invalid, as listed under Create a View. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_VIEW_NOT_FOUND | The Data Set has no view with that key. |
Notes
A list you do not send is kept, except that any filter, sort or hidden field in it naming a deleted field is dropped. Those entries have had no effect since the field was deleted.
Delete a View
Deletes a view. The records it showed are not affected.
DELETE /v3/data-sets/{dataSetKey}/views/{viewKey}
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dataSetKey | path | string | Yes | The Data Set's key. |
viewKey | path | string (GUID) | Yes | The view's key. It must be a view of this Data Set. |
Example
DELETE https://api.checkflow.io/v3/data-sets/3f2b8c1e-7a4d-4e5b-9c61-2d8f0a7b6e14/views/7c3f5e9a-2b4d-4f6c-9e8a-1d0b3f5c7e24
X-API-KEY: your-api-key-here
HTTP/1.1 204 No Content
Responses
| Status | Code | When |
|---|---|---|
204 No Content | — | The view was deleted. |
400 Bad Request | VALIDATION_ERROR | viewKey is not a GUID (field: viewKey), or it is the All Records view, which cannot be deleted. |
403 Forbidden | FORBIDDEN | It is a system Data Set; or the key acts as a Member without Library.Creator, or without Edit on the Data Set's Library folder. See Permissions. |
404 Not Found | DATA_SET_NOT_FOUND | No such Data Set. |
404 Not Found | DATA_SET_VIEW_NOT_FOUND | The Data Set has no view with that key. |
A view that template controls read from is deleted anyway. The controls are left pointing at a view that no longer exists, and the template cannot be saved in the designer until each is linked to another view or disconnected. Check List a Data Set's Connections first.
Related Pages
- Data Sets Overview — what Data Sets are and how templates use them.
- Data Set Tools — the same operations as MCP tools for AI assistants.
- Template Documents — linking a control to a Data Set view in a template.
- Import and Export — CSV import and export in the app.
- Webhooks — subscribing to the
data_set.recordevents.