Custom Tables API
Description
The Custom Tables API allows you to programmatically create, read, update, and delete data in user-defined custom tables. Custom tables extend the Skills Workflow data model with additional, tenant-specific tables for storing structured data.
If you are working inside Skills Workflow workspaces or automations, prefer using the SDK methods (SW.Document.CustomTable.*) documented in the SDK Reference instead of calling the API directly.
All endpoints require authentication via the X-AccessToken header.
Base path: api/v3
Endpoints
| Method | Route | Description |
|---|---|---|
| GET | /custom-tables | List all custom tables |
| GET | /custom-tables/{tableName} | Get table schema and columns |
| GET | /custom-tables/{tableName}/rows/values | Get all rows with column values |
| GET | /custom-tables/{tableName}/row | Get a single row by key |
| GET | /custom-tables/{tableName}/rows/columnValue | Get a specific column value from a row |
| POST | /custom-tables/{tableName} | Create table / add columns |
| PUT | /custom-tables/{tableName}/rows | Insert or update rows |
| PUT | /custom-table-definitions/{id} | Update table permissions (Read/Save roles) |
| DELETE | /custom-tables/{tableName}/rows | Delete rows |
| DELETE | /custom-tables/{tableName} | Drop the entire table |
| GET | /custom-tables/{tableName}/export | Export table to JSON file |
| PUT | /custom-tables/{tableName}/import | Import table from JSON file |
Insert / Update Rows
PUT /api/v3/custom-tables/{tableName}/rows
The request body uses OperationType to control the behavior:
| OperationType | Value | Description |
|---|---|---|
Update | 0 | Update a single row |
UpdateMany | 1 | Insert or update multiple rows (batch) |
UpsertMany | 2 | Insert if not exists, update if exists (batch) |
Single row (Update)
{
"OperationType": "Update",
"UpdateModel": {
"KeyColumnName": "Oid",
"KeyValue": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"KeyDataTypeId": 9,
"Columns": [
{ "ColumnName": "Name", "Value": "Updated Product" },
{ "ColumnName": "Price", "Value": 39.99 }
]
}
}
Multiple rows (UpdateMany)
{
"OperationType": "UpdateMany",
"UpdateManyModel": [
{
"KeyColumnName": "Oid",
"KeyValue": "a1b2c3d4-0000-0000-0000-000000000001",
"KeyDataTypeId": 9,
"Columns": [
{ "ColumnName": "Name", "Value": "Product A" },
{ "ColumnName": "Category", "Value": "Electronics" }
]
},
{
"KeyColumnName": "Oid",
"KeyValue": "a1b2c3d4-0000-0000-0000-000000000002",
"KeyDataTypeId": 9,
"Columns": [
{ "ColumnName": "Name", "Value": "Product B" },
{ "ColumnName": "Category", "Value": "Furniture" }
]
}
]
}
Delete Rows
DELETE /api/v3/custom-tables/{tableName}/rows
| OperationType | Value | Description |
|---|---|---|
Delete | 0 | Delete a single row by key |
DeleteAll | 1 | Delete all rows in the table |
DeleteMany | 2 | Delete multiple rows by key values |
Single row (Delete)
{
"OperationType": "Delete",
"DeleteModel": {
"KeyColumnName": "Oid",
"KeyValue": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
Multiple rows (DeleteMany)
{
"OperationType": "DeleteMany",
"DeleteManyModel": {
"KeyColumnName": "Oid",
"KeyValues": [
"a1b2c3d4-0000-0000-0000-000000000001",
"a1b2c3d4-0000-0000-0000-000000000002"
]
}
}
All rows (DeleteAll)
{
"OperationType": "DeleteAll"
}
Create Table
POST /api/v3/custom-tables/{tableName}
Creates a new custom table with the specified schema. If the table already exists, adds the new columns.
{
"KeyColumnName": "Oid",
"KeyDataTypeId": 9,
"Columns": [
{ "ColumnName": "Name", "ColumnDataTypeId": 6 },
{ "ColumnName": "Price", "ColumnDataTypeId": 4 },
{ "ColumnName": "IsActive", "ColumnDataTypeId": 0 }
]
}
Get Row Values
GET /api/v3/custom-tables/{tableName}/rows/values
Returns all rows in the table. Each row includes the KeyColumnName, KeyValue, and a Columns array:
[
{
"TableName": "ProductCatalog",
"KeyValue": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"KeyColumnName": "Oid",
"KeyDataTypeId": 9,
"Columns": [
{ "ColumnName": "Name", "ColumnDataTypeId": 6, "Value": "Product A" },
{ "ColumnName": "Price", "ColumnDataTypeId": 4, "Value": 29.99 }
]
}
]
Reading Data via Queries
You can also read custom table data using Queries (created in Maintenance → Queries).
When writing SQL queries that reference custom tables, use CustomTable as the namespace (schema context).
The actual database schema is [customtables], so the table is accessible as [customtables].[YourTableName] in SQL.
Example query:
SELECT Oid, Name, Price, IsActive
FROM [customtables].[ProductCatalog]
WHERE IsActive = 1
ORDER BY Name
Queries must be created with the namespace set to CustomTable in the query configuration to resolve the correct schema context at runtime.