Data Sets
Endpoints for managing Data Sets — the reference tables that populate Dropdown, Multi-Choice, Sub-Tasks and Table controls in your templates.
These endpoints require API version 2.0.
All endpoints are rooted at:
Concepts
| Term | Description |
|---|---|
| Data Set | A named table of reference data. Identified by a GUID id, or for System Data Sets by a slug. |
| Field | A column. Has a type and a position. |
| Record | A row. Its values object is keyed by field id. |
| View | A saved set of filters, sorts and hidden fields. |
Data Set Identifier
Everywhere {dataSetId} appears you may pass either:
- the Data Set's GUID, e.g.
9a3b6f88-1f2c-4a7d-9c62-1d7f5b0e4a11, or - a System Data Set's slug, e.g.
system-countries.
Source
Every Data Set has a source:
| Value | Meaning |
|---|---|
organisation | A Data Set belonging to your team. Readable and writable. |
system | A built-in System Data Set. Read-only — any write returns 403. |
Field Types
text, number, date, email, url, boolean.
Note that the True/False field type is called boolean in the API.
Response Codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Resource created |
204 | Success, no content returned |
400 | Validation failed — the body contains { "error": "..." } explaining why |
401 | The API key is missing or invalid |
403 | The Data Set is a read-only System Data Set |
404 | The Data Set, field, record or view was not found |
409 | The item is linked to one or more templates — see Conflicts |
Conflicts
Deleting a Data Set that is linked to template controls returns 409 with the templates that use it:
Pass ?force=true to delete anyway. See Deleting a Data Set for what that does to the affected templates.
List Data Sets
Returns every Data Set in your team, plus the built-in System Data Sets.
Request Headers
| Header | Required | Description |
|---|---|---|
X-API-KEY | Yes | Your API key |
Example Response
createdAt and updatedAt are always null for System Data Sets.
Create Data Set
Creates a Data Set, optionally with its fields.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters. |
description | string | No | Up to 1,000 characters. |
fields | array | No | Fields to create. If omitted, a single Text field named Name is created. |
fields[].name | string | Yes | Up to 200 characters. Must be unique within the Data Set. |
fields[].type | string | Yes | One of text, number, date, email, url, boolean. |
fields[].description | string | No | Free text, for your own reference. |
Example Response
201 Created
A Data Set created through the API is Unfiled — it is not placed in a Library folder. Move it in the Library if you want it filed.
Get Data Set
Returns a single Data Set with its fields and views. Records are not included — use List Records.
Example Request
The response is the same shape as Create Data Set.
Update Data Set
Updates the name and description.
Request Body
Returns the updated Data Set.
Delete Data Set
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
force | bool | No | Defaults to false. When false, a Data Set that is linked to template controls returns 409. When true, it is deleted and the affected links are cleared. |
Response Codes
| Code | Description |
|---|---|
204 | Deleted. |
403 | The Data Set is a System Data Set. |
409 | Linked to one or more templates and force was not set. |
List Fields
Example Response
Create Field
Request Body
Returns 201 with the new field. Existing records gain the field with an empty value.
A Data Set can have at most 50 fields.
Update Field
Renames a field, changes its type, or moves it.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Must be unique within the Data Set. |
type | string | Yes | Changing the type is rejected with 400 if any existing value would become invalid. Changing to text always succeeds. |
position | int | No | The field's position, left to right. This is the only way to reorder fields — the web UI does not support it. |
Delete Field
Deletes the field and its values in every record.
Returns 400 if the field is the Data Set's only field — a Data Set must always have at least one.
Returns 409 if the field is used as a Display Field or in a Table Column Mapping by a linked template control. Re-point or remove those links first.
List Records
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | int | No | Defaults to 1. |
pageSize | int | No | Defaults to 50. Maximum 200. |
viewId | string (GUID) | No | Apply a View's filters, sorts and hidden fields. Omit to return every record in creation order. |
Example Request
Example Response
The values object is keyed by field id. Fields with no value for a record are omitted.
Create Record
Request Body
Every value is validated against its field's type. Empty values are always allowed. A record's total cell text must not exceed 5 KB, and a Data Set may hold at most 10,000 records.
Returns 201 with the new record.
Creating a record raises the data_set.record.created webhook event.
Update Record
The body is the same as Create Record. Fields omitted from values are cleared, so send the complete record.
Raises the data_set.record.updated webhook event, whose payload contains only the fields that actually changed.
Delete Record
Returns 204. Raises the data_set.record.deleted webhook event.
Deleting a record does not affect checklist answers that already reference it — see Answers Are Snapshots.
Bulk Create Records
Adds many records in one call, or atomically replaces the whole contents of a Data Set.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | Yes | append adds to the existing records; replace deletes every existing record first. |
records | array | Yes | At least one record. |
Returns 201 with the created records.
note
Bulk operations deliberately do not raise per-record webhook events — a 5,000-record replace would otherwise generate 5,000 deliveries.
Bulk Delete Records
Request Body
Returns 204.
List Views
Example Response
Create View
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Up to 200 characters. |
filters | array | No | Combined with AND. |
filters[].fieldId | string (GUID) | Yes | Must be a field of this Data Set. |
filters[].operator | string | Yes | See the operator table below. |
filters[].value | string | Conditional | Not used by is_empty / is_not_empty. For in, a comma-separated list. |
sorts[].direction | string | No | asc (default) or desc. |
sorts[].position | int | No | Sort priority, lowest first. |
hiddenFields | array | No | Field ids to hide from the View. |
Filter Operators
| Operator | Meaning |
|---|---|
eq | Equals |
neq | Does not equal |
contains | Contains the text |
not_contains | Does not contain the text |
starts_with | Starts with the text |
ends_with | Ends with the text |
gt | Greater than |
gte | Greater than or equal to |
lt | Less than |
lte | Less than or equal to |
is_empty | The cell has no value |
is_not_empty | The cell has a value |
in | Matches any value in a comma-separated list |
An unrecognised operator returns 400.
A Data Set can have at most 20 Views. Returns 201 with the new View.
Get View
Update View
The body is the same as Create View and replaces the View's filters, sorts and hidden fields entirely.
The default All Records View cannot be renamed.
Delete View
Returns 204. The All Records View cannot be deleted.
Deleting a View that template controls are linked to is allowed — those templates will show a link warning until they are re-pointed. See Warnings About Broken Links.
Import CSV
Creates a Data Set from a CSV file, or replaces every record in an existing one.
The request is multipart/form-data.
| Form field | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The CSV file. Maximum 5 MB. |
mode | string | No | create (default) or replace. |
dataSetId | string | Conditional | Required when mode is replace. |
name | string | No | The Data Set name. Defaults to the uploaded file's name without its extension. |
description | string | No | Up to 1,000 characters. |
Example Request
Example Response
The import is synchronous — the response is returned once it has completed. There is no job to poll.
The whole file must be valid or nothing is imported. See Importing and Exporting CSV for column type detection, format rules and the full list of validation messages.
Export CSV
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
viewId | string (GUID) | No | Export a specific View. Omit to use the default View. |
Returns a text/csv file encoded as UTF-8 with a byte-order mark, named <data-set>-<view>-<date>.csv.
Only the View's visible columns are included, and only the records that pass its filters, in its sort order.
Exporting a System Data Set returns 403.
Webhooks
Record changes made through the API — or in the web UI — can be delivered to your own endpoint:
data_set.record.createddata_set.record.updateddata_set.record.deleted
See Webhooks for subscription management and payload shapes.
Related Pages
- Data Sets Overview — the model behind the endpoints.
- Importing and Exporting CSV — the same validation rules apply.
- Webhooks — record created, updated and deleted events, and why a CSV replace raises none.