Skip to main content

Data Set Tools

These tools let an AI client work with your workspace's Data Sets: the reference tables a template's Dropdown, Multi-Choice, Sub-Tasks or Table field can read its options from. A Data Set is made of fields (its columns), records (its rows) and saved views, and a template field is linked to a view rather than to the Data Set as a whole. The tools mirror the Data Sets REST routes.

Every tool that takes dataSetKey accepts a Data Set's key or, for one of the ten built-in System Data Sets, its slug — system-countries reaches the same Data Set as its key, in every workspace. Because a slug is a perfectly good name, a value that names nothing is refused with DATA_SET_NOT_FOUND rather than as malformed. The built-in Data Sets can be read and exported but not written to; a write to one is refused with FORBIDDEN.

Record cells are addressed by field name — {"Supplier": "Northwind Ltd"} — or by field key. A name or key that matches no field of the Data Set is refused, naming the cell, rather than silently dropped.

How to Read This Page​

Every tool acts on the workspace your API key belongs to, as the member (or the workspace) the key acts as. There is no workspace argument. See Connecting.

  • The Read/Write column in the summary table says whether a tool can change anything.
  • Annotations are the hints a tool publishes to your client: readOnlyHint, destructiveHint and idempotentHint. A hint a tool does not declare is left out of its definition, and the MCP specification tells a client to assume the cautious default in that case — that the tool may write, may be destructive and is not idempotent. See Tool Annotations.
  • idempotencyKey appears on the write tools that accept it. It is optional and at most 255 characters. If a call times out or its answer is lost, send it again with the same key and the same arguments: the first call's answer comes back, marked checkflow.io/idempotentReplay in the result's _meta, instead of the work happening twice. The same key with different arguments is refused with CONFLICT, and so is a retry while the first call is still running. See Idempotency.
  • Refusals come back as an ordinary tool result with isError set. structuredContent carries the v3 error body — code, message, requestId and field — and the text block summarises it. See Errors and How It Works.
  • A tool that returns nothing, such as a delete, answers with a result that is not flagged isError and carries no data.

Four REST routes have no tool: listing fields, listing views and reading one view are covered by get_data_set, which returns every field and view in full, and deleting a single record is delete_data_set_records with one key.

Tool Summary​

ToolWhat it doesRead/Write
list_data_setsLists the workspace's Data Sets and the built-in onesRead
get_data_setReturns one Data Set with its fields and viewsRead
create_data_setCreates a Data SetWrite
update_data_setRenames or re-describes a Data SetWrite
delete_data_setDeletes a Data SetWrite
list_data_set_connectionsLists the template fields that read from a Data SetRead
create_data_set_fieldAdds a fieldWrite
update_data_set_fieldRenames, retypes or re-describes a fieldWrite
delete_data_set_fieldDeletes a field and every value in itWrite
list_data_set_recordsLists records, optionally through a viewRead
get_data_set_recordReturns one recordRead
create_data_set_recordAdds one record and fires a webhookWrite
update_data_set_recordChanges cells of one recordWrite
create_data_set_recordsAppends or replaces up to 1,000 recordsWrite
delete_data_set_recordsDeletes up to 1,000 records by keyWrite
create_data_set_viewCreates a saved viewWrite
update_data_set_viewChanges a saved viewWrite
delete_data_set_viewDeletes a saved viewWrite
create_data_set_from_csvCreates a Data Set from CSV textWrite
replace_data_set_records_from_csvReplaces every record from CSV textWrite
export_data_set_csvReturns a Data Set's records as CSV textRead

list_data_sets​

Lists the workspace's Data Sets, with the ten built-in ones appended. The description tells the model to start here before writing a template that offers a choice, because a drop-down is linked to a Data Set view rather than to a list of words. All of them come back at once — a workspace holds at most 100.

Each row's source is organisation for a Data Set your workspace made, which it can change, or system for a built-in one, which cannot be written to and also answers to its slug. Rows carry fieldCount and recordCount but no fields; get_data_set has those.

NameTypeRequiredDescription
includeSystembooleanNoInclude the built-in Data Sets. Default true. Send false for only the ones your workspace made.
  • Returns: the standard list envelope (see Pagination) holding Data Set objects.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/data-sets.
  • Example prompt: "What Data Sets do we have in CheckFlow?"

get_data_set​

Returns one Data Set with its fields and its saved views — everything needed to read or write its records or link a template field to it. It does not include records; a Data Set holds up to 10,000 and list_data_set_records pages through them. A view whose filter or sort reports no fieldName points at a field that has been deleted: that clause has had no effect since, and the next write to the view drops it.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set's key, or a built-in Data Set's slug such as system-countries.
  • Returns: a Data Set object with fields and views.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/data-sets/{dataSetKey}.
  • Example prompt: "What fields and views does the Suppliers Data Set have?"

create_data_set​

Creates a Data Set. The description tells the model to name the fields in the same call if it knows them: a Data Set created with none is given a single text field called Name, which stays behind when the real fields are added. A workspace holds at most 100 Data Sets and a Data Set at most 50 fields. If the records are already in a CSV file, create_data_set_from_csv does the whole job in one call.

NameTypeRequiredDescription
namestringYesThe Data Set's name. Unique within the workspace.
descriptionstringNoWhat it is for.
fieldsarray of objectsNoThe fields to start with, each name, type and description. type is text, number, date, email, url or boolean, and text when left out. Fields are added in the order given; there is no position, and nothing reorders them later.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: the new Data Set object with its fields and views.
  • Annotations: destructiveHint false.
  • REST equivalent: POST /v3/data-sets.
  • Example prompt: "Create a Data Set called Suppliers with fields Supplier, Country, Contact Email and Active."

update_data_set​

Renames or re-describes a Data Set. Only these two can change here — fields, records and views have their own tools. Sending neither is refused rather than answered with an unchanged Data Set. A built-in Data Set is refused with FORBIDDEN.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
namestringNoThe new name. Cannot be cleared; leave it out to keep the current name.
descriptionstringNoThe new description. Send an empty string to clear it.
  • Returns: the Data Set object with its fields and views.
  • Annotations: idempotentHint true.
  • REST equivalent: PATCH /v3/data-sets/{dataSetKey}.
  • Example prompt: "Rename the Suppliers Data Set to Approved Suppliers."

delete_data_set​

Deletes a Data Set. It is refused while any template field still reads from it, and the refusal names the templates, because a drop-down whose Data Set has gone offers nothing and says nothing about why. list_data_set_connections lists the fields themselves. force deletes the links too, clearing them from every version of every template — while the refusal only names the latest version of each, so a forced delete can touch templates the refusal did not mention.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
forcebooleanNoDelete it even though template fields read from it, breaking their links. Default false.
  • Returns: nothing.
  • Annotations: destructiveHint true, idempotentHint true.
  • REST equivalent: DELETE /v3/data-sets/{dataSetKey} (with ?force=true).
  • Example prompt: "Delete the old Suppliers Data Set if nothing uses it."
danger

A deleted Data Set, and its records, cannot be recovered. With force, every template field that read from it loses its link.

list_data_set_connections​

Lists every template field linked to one of this Data Set's views, with the template, the version, the field's key and its label. It is what stands between a Data Set and deleting it, and a partial answer to "what breaks if I remove this field" — partial because it reports the view each template field uses, not which Data Set field it shows or how a Table field maps its columns. A connection with no viewName is a template field pointing at a view that has been deleted; the template designer refuses to save until somebody repoints it. See Linking a Data Set to a Control.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
  • Returns: the standard list envelope holding Connection objects, each with templateKey, templateName, templateVersion, templateUrl, controlKey, controlLabel, controlType, viewKey and viewName.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/data-sets/{dataSetKey}/connections.
  • Example prompt: "Which templates use the Suppliers Data Set?"

create_data_set_field​

Adds a field after the ones already there. There is no position argument, because nothing in CheckFlow renumbers fields. A Data Set holds at most 50 fields, and a name another field already has, ignoring case, is refused, because names are how record cells are addressed.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug. A built-in one is refused with FORBIDDEN.
namestringYesThe field's name, at most 200 characters.
typestringNotext, number, date, email, url or boolean. Default text. Every value written into the field afterwards is checked against it; widening the type later is allowed, narrowing it is refused while any record holds a value the new type would not take.
descriptionstringNoWhat the field is for.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: the new Field object, with key, name, type, description and position.
  • Annotations: destructiveHint false.
  • REST equivalent: POST /v3/data-sets/{dataSetKey}/fields.
  • Example prompt: "Add a Payment Terms field to the Suppliers Data Set."

update_data_set_field​

Renames, retypes or re-describes a field. Send only what is changing; sending none of the three is refused. Retyping can fail on the data: every record is read first, and a text field holding n/a cannot become a number field while that record is there. The refusal names the type but not the record — list_data_set_records is how to find it. Renaming is safe for the records, which are stored against the field's key, but a caller writing cells by name must use the new name afterwards.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
fieldKeystringYesThe field's key, from get_data_set.
namestringNoThe new name. Cannot be cleared.
typestringNoThe new type: text, number, date, email, url or boolean. Cannot be cleared.
descriptionstringNoThe new description. Send an empty string to clear it.
  • Returns: the field as it now stands.
  • Annotations: idempotentHint true.
  • REST equivalent: PATCH /v3/data-sets/{dataSetKey}/fields/{fieldKey}.
  • Example prompt: "Change the Credit Limit field in Suppliers to a number."

delete_data_set_field​

Deletes a field and every value in it. The field's key is stripped out of every record before the field itself goes, so the data is gone and nothing keeps a copy. There is no force. It is refused in two cases: a field a template reads from (a conflict), and the last remaining field (invalid, because a Data Set with no fields can hold nothing). The conflict cannot name the template field; list_data_set_connections narrows it to this Data Set's connections.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
fieldKeystringYesThe field's key, from get_data_set.
  • Returns: nothing.
  • Annotations: destructiveHint true, idempotentHint true.
  • REST equivalent: DELETE /v3/data-sets/{dataSetKey}/fields/{fieldKey}.
  • Example prompt: "Remove the Fax Number field from the Suppliers Data Set."
danger

Deleting a field permanently removes its value from every record.

list_data_set_records​

Returns a page of records. Cells come back keyed by field name, with every field present and null for an empty cell, so every record has the same keys. There are no sort or filter arguments: a Data Set orders and filters through a saved view, so view is the sort, the filter and the column selection at once. A record's position is its place in the Data Set even when a view has reordered the page.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
viewstringNoA view's key, from get_data_set. Its filters, sorts and hidden fields apply. Omit for every record in the Data Set's own order. Cells the view hides are still returned.
afterstringNoThe nextCursor from the previous page. Send the same view and pageSize with it; changing either mid-walk is refused.
pageSizeintegerNoRecords per page, 1 to 100. Default 50. A value outside the range is not refused; the default of 50 is used instead.
  • Returns: the standard list envelope holding Record objects, each with key, position and values.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/data-sets/{dataSetKey}/records.
  • Example prompt: "List the active suppliers in the Suppliers Data Set."

get_data_set_record​

Returns one record by key. It is for a record whose key is already in hand — from a write or a webhook — rather than for finding one: there is no search over records, and a record is found by its contents by listing through a view that filters on them. A key belonging to another Data Set's record is refused with DATA_SET_RECORD_NOT_FOUND.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
recordKeystringYesThe record's key, from list_data_set_records.
  • Returns: the record, with key, position and values.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/data-sets/{dataSetKey}/records/{recordKey}.
  • Example prompt: "Show me the Suppliers record from that webhook."

create_data_set_record​

Adds one record and fires the data_set.record.created webhook for it. The description points the model to create_data_set_records for more than one record, but that tool fires no webhooks at all — the real difference between the two. Cells may be left out entirely; a blank record is allowed. A Data Set holds at most 10,000 records.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug. A built-in one is refused with FORBIDDEN.
valuesobjectNoThe record's cells, keyed by field name or key, for example {"Supplier": "Northwind Ltd", "Credit Limit": 5000, "Active": true}. Values are strings, numbers or booleans and are stored as text; a list or an object is refused. null and the empty string are both an empty cell. Every value is checked against its field's type.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: the new record.
  • Annotations: destructiveHint false.
  • REST equivalent: POST /v3/data-sets/{dataSetKey}/records.
  • Example prompt: "Add Northwind Ltd, United Kingdom, to the Suppliers Data Set."

update_data_set_record​

Changes cells of one record. It merges rather than replaces: name only the cells that change and the rest are kept. Send a cell as null to empty it. An empty values is refused. The answer is read back from storage, so a boolean written as yes comes back as true — the model is told to read it rather than assume.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
recordKeystringYesThe record's key, from list_data_set_records.
valuesobjectYesThe cells to change, keyed by field name or key. A cell left out is left alone; a cell sent as null is emptied. The same value rules as create_data_set_record.
  • Returns: the record as stored.
  • Annotations: idempotentHint true.
  • REST equivalent: PATCH /v3/data-sets/{dataSetKey}/records/{recordKey}.
  • Example prompt: "Mark Northwind Ltd as inactive in Suppliers."

create_data_set_records​

Writes up to 1,000 records in one call, appending them or replacing the whole Data Set. It is all or nothing: every record is checked against the fields before any is written, so one bad cell refuses the call and says where — for example records[41].values.Supplier. No webhooks fire for these records. A replace runs in one transaction, so a failure part-way leaves the Data Set as it was. The 10,000-record limit applies to the total, not to the call.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug. A built-in one is refused with FORBIDDEN.
recordsarray of objectsYesThe records, each { "values": { … } } with cells keyed as create_data_set_record takes them. A record with no values is a blank record. At most 1,000.
modestringNoappend to add after the existing records, or replace to make these the whole contents. Default append. Anything else is refused.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: an object with mode, created, recordCount and records.
  • Annotations: destructiveHint true.
  • REST equivalent: POST /v3/data-sets/{dataSetKey}/records/bulk.
  • Example prompt: "Replace everything in the Suppliers Data Set with these 40 suppliers."

delete_data_set_records​

Deletes records by key — one, or up to 1,000. There is no separate single-record tool. It is all or nothing: every key is checked against this Data Set's records first, and a key matching none of them refuses the whole call, so a partial delete cannot pass for a complete one. A key sent twice is deleted once. One data_set.record.deleted webhook fires per key.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug. A built-in one is refused with FORBIDDEN.
recordKeysarray of stringsYesThe records to delete, from list_data_set_records. At least one, at most 1,000.
  • Returns: nothing.
  • Annotations: destructiveHint true, idempotentHint true.
  • REST equivalent: DELETE /v3/data-sets/{dataSetKey}/records/bulk (and DELETE /v3/data-sets/{dataSetKey}/records/{recordKey} for one).
  • Example prompt: "Delete the three inactive suppliers from the Suppliers Data Set."
danger

Deleted records cannot be recovered.

create_data_set_view​

Saves a way of looking at the records: which of them, in what order, with which fields hidden. A template field links to a view, so a drop-down that offers only active suppliers is a view with a filter on it. A Data Set holds at most 20 views. A view with no filters, sorts or hidden fields shows every record in the Data Set's own order — which is what the All Records view every Data Set starts with already does.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
namestringYesThe view's name.
filtersarray of objectsNoWhich records, each field, operator and value. field is a field's name or key. operator is eq, neq, contains, not_contains, starts_with, ends_with, gt, gte, lt, lte, is_empty, is_not_empty or in; anything else is refused. value is required except for is_empty and is_not_empty, which refuse one; for in it is a comma-separated list. Filters are combined with AND.
sortsarray of objectsNoThe order, each field and direction (asc or desc, default asc), applied in array order. Any other direction is refused.
hiddenFieldsarray of stringsNoFields the view leaves out, by name or key. Hiding every field is refused.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: the new View object, with key, name, isDefault, filters, sorts, hiddenFieldKeys and hiddenFieldNames.
  • Annotations: destructiveHint false.
  • REST equivalent: POST /v3/data-sets/{dataSetKey}/views.
  • Example prompt: "Create a view of Suppliers called Active UK Suppliers that shows only active suppliers in the United Kingdom, sorted by name."

update_data_set_view​

Changes a view. Send only what changes: a list left out is kept as it is. A list that is sent replaces the old one whole rather than merging clause by clause, and an empty array clears it. A Data Set's default view can be refiltered but not renamed, and which view is the default cannot be changed.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
viewKeystringYesThe view's key, from get_data_set.
namestringNoThe new name. Cannot be cleared, and cannot be set on the default view.
filtersarray of objectsNoThe view's filters, replacing all of them. Same shape and rules as create_data_set_view. [] clears them.
sortsarray of objectsNoThe view's sorts, replacing all of them. [] clears them.
hiddenFieldsarray of stringsNoThe fields the view hides, replacing all of them. [] shows every field again.
  • Returns: the view as it now stands.
  • Annotations: idempotentHint true.
  • REST equivalent: PATCH /v3/data-sets/{dataSetKey}/views/{viewKey}.
  • Example prompt: "Remove the country filter from the Active UK Suppliers view."

delete_data_set_view​

Deletes a view. Unlike deleting a Data Set, deleting a view a template field reads from is allowed: the template field is left pointing at nothing, which the template designer reports and refuses to save over until somebody repoints it. The description tells the model to read list_data_set_connections first. A Data Set's default view cannot be deleted.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
viewKeystringYesThe view's key, from get_data_set.
  • Returns: nothing.
  • Annotations: destructiveHint true, idempotentHint true.
  • REST equivalent: DELETE /v3/data-sets/{dataSetKey}/views/{viewKey}.
  • Example prompt: "Delete the Active UK Suppliers view."

create_data_set_from_csv​

Makes a Data Set from CSV text: the header line becomes the fields, every other line a record, and each field's type is guessed from its values. The types cannot be set here; a field guessed too narrowly can be widened afterwards with update_data_set_field. The answer lists the fields created, in the file's order. See Importing and Exporting CSV.

NameTypeRequiredDescription
namestringYesThe Data Set's name.
csvstringYesThe file's text. The first line names the fields. Quoting follows RFC 4180: a value holding a comma, a quote or a line break is wrapped in double quotes, and its own quotes are doubled. A leading byte-order mark is ignored.
descriptionstringNoWhat the Data Set is for.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: an object with dataSet (the new Data Set with its fields and views), recordsImported and fieldsAdded.
  • Annotations: destructiveHint false.
  • REST equivalent: POST /v3/data-sets/import.
  • Example prompt: "Turn this spreadsheet of suppliers into a CheckFlow Data Set called Suppliers."

replace_data_set_records_from_csv​

Replaces every record of an existing Data Set from CSV text. It replaces rather than appends — create_data_set_records with mode append is the append. Columns are matched to fields by name, ignoring case. A column with no matching field creates one, and a field no column names is kept and left empty in every record. That first rule is why the answer reports fieldsAdded: a misspelled header adds a field, and the answer is the only place that says so.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug. A built-in one is refused with FORBIDDEN.
csvstringYesThe file's text, as create_data_set_from_csv describes it.
idempotencyKeystringNoRetries this call safely. See How to Read This Page.
  • Returns: an object with dataSet, recordsImported and fieldsAdded.
  • Annotations: destructiveHint true.
  • REST equivalent: POST /v3/data-sets/{dataSetKey}/import.
  • Example prompt: "Replace the Suppliers records with the contents of this CSV."

export_data_set_csv​

Returns a Data Set's records as CSV text in the answer, with the file name the app would have used. Anything this exports can be imported again: an export larger than an import would accept (5 MB) is refused rather than truncated. Built-in Data Sets export like any other.

NameTypeRequiredDescription
dataSetKeystringYesThe Data Set, by key or slug.
viewstringNoA view's key. Its filters, sorts and hidden fields apply, and a hidden field is left out of the file. Omit for the Data Set's default view. A view that hides every field is refused.
  • Returns: an object with fileName, contentType, viewKey, viewName, columns, rowCount and csv.
  • Annotations: readOnlyHint true, idempotentHint true.
  • REST equivalent: GET /v3/data-sets/{dataSetKey}/export.
  • Example prompt: "Export the Suppliers Data Set as CSV."
  • Data Sets — the REST routes behind these tools, with the full Data Set, field, record and view objects.
  • Views — how saved views filter and sort records in the app.
  • Linking a Data Set to a Control — what a template field linked to a view offers the people running a checklist.
  • Template Authoring Tools — how a template document links a field to a Data Set with dataSet.
  • Webhook Tools — subscribing to the data_set.record.* events these tools fire.