Template Management

Full CRUD operations for managing notebook templates. All endpoints require a Global API Key.


List Global Templates

GET /api/templates

Returns all global templates available across all tenants.

Response (200 OK)

{
  "templates": [
    {
      "templateId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
      "name": "Process Discovery",
      "description": "Standard process discovery workflow",
      "category": "Templates",
      "processName": "Order to Cash",
      "tenantId": null,
      "isGlobal": true,
      "hasThumbnail": true,
      "autoAddedDefaultSortOrder": 100,
      "dateModified": "2024-01-15T10:30:00Z"
    }
  ],
  "totalCount": 1
}

List Templates for Tenant

GET /api/templates/tenant/{tenantId}

Returns all templates available to a specific tenant, including both global and tenant-specific templates.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier

Response (200 OK)

{
  "templates": [
    {
      "templateId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
      "name": "Process Discovery",
      "description": "Standard process discovery workflow",
      "category": "Templates",
      "processName": "Order to Cash",
      "tenantId": null,
      "isGlobal": true,
      "hasThumbnail": true,
      "autoAddedDefaultSortOrder": 100,
      "dateCreated": "2024-01-01T00:00:00Z",
      "dateModified": "2024-01-15T10:30:00Z",
      "createdByName": "System",
      "modifiedByName": "System"
    },
    {
      "templateId": "bbbbbbbb-cccc-dddd-eeee-ffffffffffff",
      "name": "Custom Analysis",
      "description": "Tenant-specific custom analysis",
      "category": "Custom",
      "processName": null,
      "tenantId": "12345678-1234-1234-1234-123456789012",
      "isGlobal": false,
      "hasThumbnail": false,
      "autoAddedDefaultSortOrder": 0,
      "dateCreated": "2024-02-01T09:00:00Z",
      "dateModified": "2024-02-15T14:30:00Z",
      "createdByName": "API",
      "modifiedByName": "API"
    }
  ],
  "totalCount": 2
}

List Templates by Category

GET /api/templates/category/{category}

Returns templates filtered by category.

Path Parameters

Parameter Type Required Description
category string Yes Category name: Templates, Custom, or BaseKnowledge

Query Parameters

Parameter Type Required Description
tenantId GUID No Filter to specific tenant's templates

Example

# Get all custom templates
curl -X GET "https://your-mindzie-instance.com/api/templates/category/Custom" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY"

# Get custom templates for a specific tenant
curl -X GET "https://your-mindzie-instance.com/api/templates/category/Custom?tenantId=12345678-1234-1234-1234-123456789012" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY"

Get Template Details

GET /api/templates/{templateId}

Returns full template details including the MCL configuration text.

Path Parameters

Parameter Type Required Description
templateId GUID Yes The template identifier

Response (200 OK)

{
  "templateId": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "name": "Process Discovery",
  "description": "Standard process discovery workflow with variant analysis",
  "category": "Templates",
  "processName": "Order to Cash",
  "mclText": "// MCL configuration defining notebook blocks and settings\n{\n  \"blocks\": [...],\n  \"settings\": {...}\n}",
  "tenantId": null,
  "isGlobal": true,
  "hasThumbnail": true,
  "autoAddedDefaultSortOrder": 100,
  "originatingNotebookId": null,
  "dateCreated": "2024-01-01T00:00:00Z",
  "dateModified": "2024-01-15T10:30:00Z",
  "createdBy": null,
  "createdByName": "System",
  "modifiedBy": null,
  "modifiedByName": "System"
}

Response Fields

Field Type Description
templateId GUID Unique identifier
name string Template name
description string Template description
category string Category (Templates, Custom, BaseKnowledge)
processName string Associated process name
mclText string MCL configuration text
tenantId GUID Tenant ID (null for global templates)
isGlobal boolean True if this is a global template
hasThumbnail boolean True if thumbnail image exists
autoAddedDefaultSortOrder integer Display sort order
originatingNotebookId GUID Source notebook if created from existing notebook
dateCreated datetime Creation timestamp
dateModified datetime Last modification timestamp
createdBy GUID Creator user ID
createdByName string Creator user name
modifiedBy GUID Last modifier user ID
modifiedByName string Last modifier user name

Error Responses

Not Found (404)

{
  "error": "Template with ID 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee' not found"
}

Get Template Thumbnail

GET /api/templates/{templateId}/thumbnail

Returns the thumbnail image for a template.

Path Parameters

Parameter Type Required Description
templateId GUID Yes The template identifier

Response (200 OK)

Returns JPEG image data with Content-Type: image/jpeg.

Error Responses

Not Found (404)

{
  "error": "Thumbnail not found for template 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'"
}

Create Template

POST /api/templates/tenant/{tenantId}

Creates a new tenant-specific template. Global templates cannot be created via API.

Path Parameters

Parameter Type Required Description
tenantId GUID Yes The tenant identifier

Request Body

{
  "name": "Custom Analysis Template",
  "description": "Custom analysis workflow for monthly reporting",
  "mclText": "// MCL configuration text",
  "category": "Custom",
  "processName": "Monthly Report",
  "isGlobal": false,
  "autoAddedDefaultSortOrder": 0
}

Request Fields

Field Type Required Description
name string Yes Template name (must be unique)
description string No Template description
mclText string Yes MCL configuration text
category string No Category (default: "Custom")
processName string No Associated process name
isGlobal boolean No Must be false for API creation
autoAddedDefaultSortOrder integer No Display sort order

Response (201 Created)

{
  "templateId": "cccccccc-dddd-eeee-ffff-000000000000",
  "name": "Custom Analysis Template",
  "description": "Custom analysis workflow for monthly reporting",
  "category": "Custom",
  "processName": "Monthly Report",
  "mclText": "// MCL configuration text",
  "tenantId": "12345678-1234-1234-1234-123456789012",
  "isGlobal": false,
  "hasThumbnail": false,
  "autoAddedDefaultSortOrder": 0,
  "dateCreated": "2024-03-01T10:00:00Z",
  "dateModified": "2024-03-01T10:00:00Z",
  "createdByName": "API"
}

Error Responses

Bad Request (400) - Validation Failed

{
  "error": "Validation failed",
  "validationErrors": ["Name is required", "MclText is required"]
}

Conflict (409) - Duplicate Name

{
  "error": "A template with this name already exists"
}

Update Template

PUT /api/templates/{templateId}

Updates an existing tenant-specific template. Global templates cannot be updated via API.

Path Parameters

Parameter Type Required Description
templateId GUID Yes The template identifier

Request Body

{
  "name": "Updated Template Name",
  "description": "Updated description",
  "mclText": "// Updated MCL configuration",
  "category": "Custom",
  "processName": "Updated Process",
  "autoAddedDefaultSortOrder": 10
}

All fields are optional - only provided fields will be updated.

Response (200 OK)

Returns the updated template details.

Error Responses

Bad Request (400) - Global Template

{
  "error": "Cannot update global templates through the API"
}

Not Found (404)

{
  "error": "Template not found"
}

Conflict (409) - Duplicate Name

{
  "error": "A template with this name already exists"
}

Delete Template

DELETE /api/templates/{templateId}

Deletes a tenant-specific template. Global templates cannot be deleted via API.

Path Parameters

Parameter Type Required Description
templateId GUID Yes The template identifier

Response (200 OK)

{
  "message": "Template deleted successfully"
}

Error Responses

Bad Request (400) - Global Template

{
  "error": "Cannot delete global templates"
}

Not Found (404)

{
  "error": "Template not found"
}

Implementation Examples

cURL

# List all templates for a tenant
curl -X GET "https://your-mindzie-instance.com/api/templates/tenant/12345678-1234-1234-1234-123456789012" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY"

# Get template details
curl -X GET "https://your-mindzie-instance.com/api/templates/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY"

# Create a template
curl -X POST "https://your-mindzie-instance.com/api/templates/tenant/12345678-1234-1234-1234-123456789012" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Custom Template",
    "description": "Custom analysis workflow",
    "mclText": "// MCL configuration",
    "category": "Custom"
  }'

# Update a template
curl -X PUT "https://your-mindzie-instance.com/api/templates/cccccccc-dddd-eeee-ffff-000000000000" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Updated Name"}'

# Delete a template
curl -X DELETE "https://your-mindzie-instance.com/api/templates/cccccccc-dddd-eeee-ffff-000000000000" \
  -H "Authorization: Bearer YOUR_GLOBAL_API_KEY"

Python

import requests

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

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

    def list_templates(self, tenant_id=None):
        """List templates, optionally filtered by tenant."""
        if tenant_id:
            url = f'{BASE_URL}/api/templates/tenant/{tenant_id}'
        else:
            url = f'{BASE_URL}/api/templates'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def get_template(self, template_id):
        """Get template details including MCL text."""
        url = f'{BASE_URL}/api/templates/{template_id}'
        response = requests.get(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def create_template(self, tenant_id, name, mcl_text, description=None, category='Custom'):
        """Create a new tenant-specific template."""
        url = f'{BASE_URL}/api/templates/tenant/{tenant_id}'
        data = {
            'name': name,
            'mclText': mcl_text,
            'description': description,
            'category': category
        }
        response = requests.post(url, json=data, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def update_template(self, template_id, **kwargs):
        """Update a template. Pass only fields to update."""
        url = f'{BASE_URL}/api/templates/{template_id}'
        response = requests.put(url, json=kwargs, headers=self.headers)
        response.raise_for_status()
        return response.json()

    def delete_template(self, template_id):
        """Delete a tenant-specific template."""
        url = f'{BASE_URL}/api/templates/{template_id}'
        response = requests.delete(url, headers=self.headers)
        response.raise_for_status()
        return response.json()

# Usage
manager = TemplateManager('your-global-api-key')

# List templates
templates = manager.list_templates(TENANT_ID)
print(f"Found {templates['totalCount']} templates")

for t in templates['templates']:
    print(f"  - {t['name']} ({'Global' if t['isGlobal'] else 'Tenant'})")

# Create a template
new_template = manager.create_template(
    tenant_id=TENANT_ID,
    name='My Analysis Template',
    mcl_text='// MCL configuration here',
    description='Custom workflow'
)
print(f"Created template: {new_template['templateId']}")

# Update the template
updated = manager.update_template(
    new_template['templateId'],
    name='Renamed Template'
)

# Delete the template
manager.delete_template(new_template['templateId'])
print("Template deleted")

JavaScript/Node.js

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

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

  async listTemplates(tenantId = null) {
    const url = tenantId
      ? `${BASE_URL}/api/templates/tenant/${tenantId}`
      : `${BASE_URL}/api/templates`;
    const response = await fetch(url, { headers: this.headers });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async getTemplate(templateId) {
    const url = `${BASE_URL}/api/templates/${templateId}`;
    const response = await fetch(url, { headers: this.headers });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async createTemplate(tenantId, name, mclText, description = null, category = 'Custom') {
    const url = `${BASE_URL}/api/templates/tenant/${tenantId}`;
    const response = await fetch(url, {
      method: 'POST',
      headers: this.headers,
      body: JSON.stringify({ name, mclText, description, category })
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async updateTemplate(templateId, updates) {
    const url = `${BASE_URL}/api/templates/${templateId}`;
    const response = await fetch(url, {
      method: 'PUT',
      headers: this.headers,
      body: JSON.stringify(updates)
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }

  async deleteTemplate(templateId) {
    const url = `${BASE_URL}/api/templates/${templateId}`;
    const response = await fetch(url, {
      method: 'DELETE',
      headers: this.headers
    });
    if (!response.ok) throw new Error(`Failed: ${response.status}`);
    return response.json();
  }
}

// Usage
const manager = new TemplateManager('your-global-api-key');

// List templates
const templates = await manager.listTemplates(TENANT_ID);
console.log(`Found ${templates.totalCount} templates`);

// Create a template
const newTemplate = await manager.createTemplate(
  TENANT_ID,
  'My Analysis Template',
  '// MCL configuration',
  'Custom workflow'
);
console.log(`Created: ${newTemplate.templateId}`);

// Delete the template
await manager.deleteTemplate(newTemplate.templateId);

Best Practices

  1. Use Global API Keys: Template operations require global API keys
  2. Unique Names: Template names must be unique within their scope
  3. MCL Text: Store complete MCL configuration for reproducible notebooks
  4. Categories: Use standard categories for organization
  5. Thumbnails: Templates created via API won't have thumbnails automatically