Skip to main content

Drafts & Versioning

Create and manage draft copies of datasets for safe editing without affecting production data.

Overview

Datasets support a draft workflow that allows users to:

  1. Create a personal draft copy of a dataset
  2. Make changes to the draft (fields, flow, settings) without affecting the production dataset
  3. Preview draft results
  4. Commit changes back to the production dataset or discard the draft

Each user can have their own draft of a dataset, enabling collaborative editing without conflicts.

POST /api/datasets/{id}/_edit

Create or retrieve a draft of a dataset for the current user.

Authentication: Required

Permission: dataset:write

Path Parameters:

ParameterTypeDescription
idstringDataset ID or slug

Response:

Returns the user's draft dataset if it exists, or creates a new draft and returns it.

{
"id": "sales-2024-draft-user123",
"name": "Sales Data 2024 (Draft)",
"description": "Quarterly sales analysis",

"datasourceId": "mysql-prod",
"ownerId": "user:admin",
"parentId": "sales-2024",
"isDraft": true,
"query": "SELECT * FROM sales WHERE year = {{year}}",
"params": [
{
"name": "year",
"dataType": "number",
"defaultValue": 2024,
"required": true
}
],
"fields": [...],
"createdAt": "2024-02-08T15:00:00Z",
"updatedAt": "2024-02-08T15:00:00Z",
"_links": {
"self": { "href": "/api/datasets/sales-2024-draft-user123" },
"inf:parent": { "href": "/api/datasets/sales-2024" }
}
}

Behavior:

  • If draft already exists for current user, returns existing draft
  • If no draft exists, creates new draft as child of parent dataset
  • Draft is created with current state of parent dataset
  • Draft owner is always the current user

Use Case:

Call this endpoint when a user clicks "Edit" on a dataset to enter draft mode.


GET /api/datasets/{id}/draft

Get the draft dataset for the current user.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringParent dataset ID or slug

Response:

{
"id": "sales-2024-draft-user123",
"name": "Sales Data 2024 (Draft)",
"parentId": "sales-2024",
"isDraft": true,
"hasUserSettings": true,
"query": "SELECT * FROM sales WHERE year = {{year}}",
"fields": [...],
"createdAt": "2024-02-08T15:00:00Z",
"updatedAt": "2024-02-08T15:10:00Z"
}

Special Fields:

FieldTypeDescription
hasUserSettingsbooleanIndicates if user has custom settings applied

Status Codes:

  • 200 - Draft found
  • 404 - No draft exists for current user

PUT /api/datasets/{id}/draft

Create a new draft with custom settings, replacing any existing draft.

Authentication: Required

Permission: dataset:write

Path Parameters:

ParameterTypeDescription
idstringParent dataset ID or slug

Request Body:

FieldTypeDescription
flowarrayFlow transformation steps
queryIdstringCreate from existing query
settingsobjectUser-specific view settings

Response:

Returns the newly created draft dataset.

Example Request:

{
"flow": [
{
"type": "filter",
"criteria": { "region": "West" }
},
{
"type": "sort",
"field": "amount",
"order": "desc"
}
],
"settings": {
"defaultView": "table",
"pageSize": 50
}
}

Behavior:

  • Deletes any existing draft for current user
  • Creates new draft with specified configuration
  • Applies custom settings to draft
Replaces Existing Draft

This endpoint will delete any existing draft for the current user before creating the new one. Unsaved changes will be lost.


DELETE /api/datasets/{id}/draft

Delete the draft dataset created by the current user.

Authentication: Required

Path Parameters:

ParameterTypeDescription
idstringParent dataset ID or slug

Response:

204 No Content

Behavior:

  • Looks up draft by parent dataset and current user
  • Deletes draft if found
  • Returns 404 if no draft exists

Use Case:

Call this endpoint when a user clicks "Cancel" or "Discard Draft" to exit draft mode without saving changes.


POST /api/datasets/{id}/draft/_commit

Commit/publish draft changes back to the main dataset.

Authentication: Required

Permission: dataset:write (on parent dataset)

Path Parameters:

ParameterTypeDescription
idstringParent dataset ID or slug

Request Body:

FieldTypeDefaultDescription
clearAllUserSettingsbooleantrueClear all user settings when committing

Response:

{
"id": "sales-2024",
"name": "Sales Data 2024",
"description": "Quarterly sales analysis (Updated)",
"query": "SELECT * FROM sales WHERE year = {{year}} AND region = {{region}}",
"fields": [...],
"updatedAt": "2024-02-08T15:30:00Z"
}

Behavior:

  1. Copies draft configuration (query, flow, fields) to parent dataset
  2. Optionally clears all user-specific settings (default: true)
  3. Creates Activity record for notification
  4. Deletes the draft
  5. Returns updated parent dataset

Activity Notification:

The commit creates an Activity record of type dataset.draft.committed with:

{
"type": "dataset.draft.committed",
"userId": "user:admin",
"datasetId": "sales-2024",
"message": "Draft committed by Admin User",
"createdAt": "2024-02-08T15:30:00Z"
}
Publishing Workflow

Use clearAllUserSettings: false if you want to preserve user-specific view preferences (column widths, sort orders, etc.) after publishing changes.


Draft Workflow Example

Complete workflow for editing a dataset:

// 1. Enter draft mode
const draft = await POST('/api/datasets/sales-2024/_edit');
// Returns existing draft or creates new one

// 2. Make changes to draft
await PUT(`/api/datasets/${draft.id}`, {
query: "SELECT * FROM sales WHERE year = {{year}} AND region = {{region}}",
params: [
{ name: "year", dataType: "number", defaultValue: 2024 },
{ name: "region", dataType: "string", defaultValue: "West" }
]
});

// 3. Preview draft results
const preview = await GET(`/api/datasets/${draft.id}/data?limit=100`);

// 4a. Commit changes (publish)
await POST('/api/datasets/sales-2024/draft/_commit', {
clearAllUserSettings: true
});

// OR

// 4b. Discard changes
await DELETE('/api/datasets/sales-2024/draft');

Best Practices

When to Use Drafts

  • Complex changes - Multi-step changes to query, flow, or fields
  • Testing - Preview results before affecting production
  • Collaboration - Multiple users can work on separate drafts
  • Safety - Revert changes easily without affecting others

When to Skip Drafts

  • Simple updates - Name/description changes don't need drafts
  • Data operations - Adding/deleting records (use data endpoints directly)
  • Administrative changes - Ownership, sharing, tags

User Settings

User settings control personal view preferences like:

  • Default visualization type
  • Page size for tables
  • Column visibility and order
  • Sort preferences
  • Filter presets

Set clearAllUserSettings: false when committing if you want to preserve these across draft publishes.

Multi-User Drafts

Each user can have their own draft of the same dataset. When one user commits their draft, other users' drafts remain intact but may become out of sync with the parent dataset.