Notebook Block Operations

Create and manage analysis blocks within notebooks. Blocks are the building blocks of analysis workflows.


Block Types

Type Description
Filter Narrow down data to specific cases or events
Calculator Compute metrics, durations, and derived values
Opportunity Identify improvement opportunities
Insight Generate visualizations and statistics
Dashboard Create shareable report panels
Alert Define monitoring alerts

List Blocks

GET /api/{tenantId}/{projectId}/notebook/{notebookId}/blocks

Returns all blocks in a notebook in execution order.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier
projectId GUID Yes The project identifier
notebookId GUID Yes The notebook identifier

Response (200 OK)

{
  "notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "blocks": [
    {
      "blockId": "11111111-1111-1111-1111-111111111111",
      "blockType": "Filter",
      "operatorName": "ActivityFilter",
      "name": "Select Key Activities",
      "description": "Filter to main process activities",
      "parentId": null,
      "order": 0,
      "configuration": "{\"activities\": [\"Create Order\", \"Approve\", \"Ship\"]}",
      "dateCreated": "2024-01-15T10:30:00Z",
      "createdBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "dateModified": "2024-01-15T10:30:00Z",
      "isActive": true
    },
    {
      "blockId": "22222222-2222-2222-2222-222222222222",
      "blockType": "Calculator",
      "operatorName": "DurationCalculator",
      "name": "Case Duration",
      "description": "Calculate total case duration",
      "parentId": "11111111-1111-1111-1111-111111111111",
      "order": 0,
      "configuration": "{\"unit\": \"days\"}",
      "dateCreated": "2024-01-15T10:35:00Z",
      "createdBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "dateModified": "2024-01-15T10:35:00Z",
      "isActive": true
    }
  ],
  "totalCount": 2
}

Block Fields

Field Type Description
blockId GUID Unique block identifier
blockType string Type (Filter, Calculator, etc.)
operatorName string Specific operator name
name string Block display name
description string Block description
parentId GUID Parent block ID (data flows from parent)
order integer Execution order hint
configuration string JSON configuration for the operator
dateCreated datetime Creation timestamp
createdBy GUID Creator user ID
dateModified datetime Last modification timestamp
isActive boolean Whether block is enabled

Create Block

POST /api/{tenantId}/{projectId}/notebook/{notebookId}/blocks

Creates a new analysis block in the notebook.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier
projectId GUID Yes The project identifier
notebookId GUID Yes The notebook identifier

Request Body

{
  "blockType": "Filter",
  "operatorName": "ActivityFilter",
  "name": "Filter by Status",
  "description": "Keep only completed orders",
  "configuration": "{\"activities\": [\"Complete\", \"Shipped\"]}",
  "insertAfterBlockId": "11111111-1111-1111-1111-111111111111"
}

Request Fields

Field Type Required Description
blockType string No Type (Filter, Calculator, etc.) Default: Filter
operatorName string Yes Specific operator to use
name string Yes Block display name
description string No Block description
configuration string No JSON configuration for the operator
insertAfterBlockId GUID No Insert after this block (default: end)

Response (201 Created)

{
  "blockId": "33333333-3333-3333-3333-333333333333",
  "blockType": "Filter",
  "operatorName": "ActivityFilter",
  "name": "Filter by Status",
  "description": "Keep only completed orders",
  "parentId": "11111111-1111-1111-1111-111111111111",
  "order": 0,
  "configuration": "{\"activities\": [\"Complete\", \"Shipped\"]}",
  "dateCreated": "2024-03-01T10:00:00Z",
  "createdBy": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "dateModified": "2024-03-01T10:00:00Z",
  "isActive": true
}

Get Block Order

GET /api/{tenantId}/{projectId}/notebook/{notebookId}/blocks/order

Returns the current execution order of blocks.

Response (200 OK)

{
  "notebookId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "blockCount": 3,
  "blockOrder": [
    {
      "blockId": "11111111-1111-1111-1111-111111111111",
      "parentId": null,
      "position": 1
    },
    {
      "blockId": "22222222-2222-2222-2222-222222222222",
      "parentId": "11111111-1111-1111-1111-111111111111",
      "position": 2
    },
    {
      "blockId": "33333333-3333-3333-3333-333333333333",
      "parentId": "22222222-2222-2222-2222-222222222222",
      "position": 3
    }
  ]
}

Reorder Blocks

PUT /api/{tenantId}/{projectId}/notebook/{notebookId}/blocks/order

Changes the execution order of blocks in the notebook.

Request Body

{
  "blockIds": [
    "11111111-1111-1111-1111-111111111111",
    "33333333-3333-3333-3333-333333333333",
    "22222222-2222-2222-2222-222222222222"
  ]
}

Request Fields

Field Type Required Description
blockIds array Yes Block IDs in desired execution order

Response (200 OK)

Returns the updated block order.


Block Execution Flow

Blocks form a chain where each block receives data from its parent:

[Investigation Start]
       |
       v
[Filter: Activity Filter] -> Filters to specific activities
       |
       v
[Calculator: Duration] -> Calculates durations for filtered data
       |
       v
[Insight: Statistics] -> Generates statistics on calculated data

When you reorder blocks, the parent chain is updated automatically.


Implementation Examples

Python

import requests
import json

BASE_URL = 'https://your-mindzie-instance.com'
TENANT_ID = '12345678-1234-1234-1234-123456789012'
PROJECT_ID = '87654321-4321-4321-4321-210987654321'

class BlockManager:
    def __init__(self, api_key):
        self.headers = {
            'Authorization': f'Bearer {api_key}',
            'Content-Type': 'application/json'
        }

    def list_blocks(self, notebook_id):
        """List all blocks in a notebook."""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}/blocks'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def create_block(self, notebook_id, block_type, operator_name, name,
                     description=None, configuration=None, insert_after=None):
        """Create a new block."""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}/blocks'
        data = {
            'blockType': block_type,
            'operatorName': operator_name,
            'name': name,
            'description': description,
            'configuration': json.dumps(configuration) if configuration else None,
            'insertAfterBlockId': insert_after
        }
        response = requests.post(url, json=data, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def get_block_order(self, notebook_id):
        """Get current block execution order."""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}/blocks/order'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def reorder_blocks(self, notebook_id, block_ids):
        """Reorder blocks in notebook."""
        url = f'{BASE_URL}/api/{TENANT_ID}/{PROJECT_ID}/notebook/{notebook_id}/blocks/order'
        response = requests.put(url, json={'blockIds': block_ids}, headers=self.headers)
        response.raise_for_status()
        return response.json()

# Usage
manager = BlockManager('your-api-key')
notebook_id = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'

# List blocks
blocks = manager.list_blocks(notebook_id)
print(f"Found {blocks['totalCount']} blocks")

# Create a filter block
filter_block = manager.create_block(
    notebook_id,
    block_type='Filter',
    operator_name='ActivityFilter',
    name='Select Key Activities',
    configuration={'activities': ['Create Order', 'Approve', 'Ship']}
)
print(f"Created filter: {filter_block['blockId']}")

# Create a calculator block after the filter
calc_block = manager.create_block(
    notebook_id,
    block_type='Calculator',
    operator_name='DurationCalculator',
    name='Case Duration',
    configuration={'unit': 'days'},
    insert_after=filter_block['blockId']
)
print(f"Created calculator: {calc_block['blockId']}")

# Check execution order
order = manager.get_block_order(notebook_id)
print(f"Block order: {[b['blockId'] for b in order['blockOrder']]}")

JavaScript/Node.js

const BASE_URL = 'https://your-mindzie-instance.com';
const TENANT_ID = '12345678-1234-1234-1234-123456789012';
const PROJECT_ID = '87654321-4321-4321-4321-210987654321';

class BlockManager {
  constructor(apiKey) {
    this.headers = {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json'
    };
  }

  async listBlocks(notebookId) {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/notebook/${notebookId}/blocks`;
    const response = await fetch(url, { headers: this.headers });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async createBlock(notebookId, blockType, operatorName, name, options = {}) {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/notebook/${notebookId}/blocks`;
    const body = {
      blockType,
      operatorName,
      name,
      description: options.description,
      configuration: options.configuration ? JSON.stringify(options.configuration) : null,
      insertAfterBlockId: options.insertAfter
    };
    const response = await fetch(url, {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify(body)
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async reorderBlocks(notebookId, blockIds) {
    const url = `${BASE_URL}/api/${TENANT_ID}/${PROJECT_ID}/notebook/${notebookId}/blocks/order`;
    const response = await fetch(url, {
      method: 'PUT',
      headers: this.headers,
      body: JSON.stringify({ blockIds })
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }
}

// Usage
const manager = new BlockManager('your-api-key');
const notebookId = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee';

// List blocks
const blocks = await manager.listBlocks(notebookId);
console.log(`Found ${blocks.totalCount} blocks`);

// Create blocks
const filter = await manager.createBlock(notebookId, 'Filter', 'ActivityFilter', 'Key Activities', {
  configuration: { activities: ['Create', 'Approve'] }
});

const calc = await manager.createBlock(notebookId, 'Calculator', 'DurationCalculator', 'Duration', {
  insertAfter: filter.blockId
});

Best Practices

  1. Block Order Matters: Data flows from parent to child - plan your workflow
  2. Use Templates: For complex workflows, create from templates
  3. Configuration JSON: Store operator-specific settings as JSON strings
  4. InsertAfter: Use insertAfterBlockId to control positioning
  5. Execution: After creating blocks, execute the notebook to see results