User Guide mdi-view-dashboard Guide Contents

Welcome to DSiloed

mdi-link
Looking for the user guide? Documentation for the Portablemind app — getting started, AI setup, agents, chat, files, sharing, SiloLink, and orchestration — has moved to app.portablemind.ai/docs. This guide now focuses on the platform API and building your own applications.

AI Enabler Built on Enterprise Data Models

DSiloed is the platform behind Portablemind: an AI enablement engine built on comprehensive enterprise data models, exposed through a REST API, WebSockets, and MCP tools.

This guide covers the developer surface of the platform — API integration and authentication, the MCP tools your agents can call, sandboxed Dynamic Functions, and building your own applications on the data foundation. For using the Portablemind app itself (chat, agents, files, sharing, orchestration), see the user guide.

Core Architecture mdi-link

DSiloed is built on a flexible, enterprise-grade data model designed for extensibility and integration. Here are the key components:

Party Model

  • People and Organizations - Represented as Parties
  • Flexible Relationships - Connect parties with typed relationships
  • Role-based - Assign roles for different contexts

Business Transaction Events

  • Event-based Transactions - Track business events
  • Typed Event Relations - Connect related events
  • Party Roles in Events - Associates parties with roles in events

Security System

  • Capabilities - Fine-grained permissions
  • Security Roles - Group capabilities for assignment
  • Tenant Isolation - Multi-tenant architecture

AI & Memory System

  • Rich Memory Graphs - Persistent knowledge with pattern recognition
  • Real-time Chat - WebSocket-based conversations with AI models
  • Document Processing - PDF, DOCX, Markdown, and image support
  • Autonomous Agents - Self-improving AI with tool execution
AI-First, API-Driven Platform mdi-link

DSiloed is designed with an AI-first, API-driven approach. Every AI capability—from chat conversations to memory graphs to autonomous agents—is accessible through our comprehensive REST API and WebSocket connections. Build any AI-powered interface on top of our enterprise data foundation.

All sample applications in this demo are built using static JavaScript frameworks that interact with the API, demonstrating how you can create sophisticated AI-enabled applications with standard web technologies.

Quick Start

Ready to build? Head to API Documentation for authentication and endpoints, the MCP Tools Reference for agent tooling, or Building Your Own App to scaffold an application. Check out Sample Apps to see real-world AI applications in action.

MCP Tools Reference

mdi-link
About MCP Tools mdi-link

Model Context Protocol (MCP) tools provide a standardized interface for AI models to interact with your DSiloed platform. These tools enable LLMs to perform operations, access data, manage agents, handle communications, and more.

All MCP tools are available through the MCP server and can be used by external applications, AI agents, and LLM conversations. This reference lists all 35+ available MCP tools with their descriptions and use cases.

Note: These tools are automatically available to LLM agents configured in your tenant. External applications can also access these tools through the MCP protocol.
mdi-folder-multiple Tool Categories mdi-link

Tools are organized into categories for easier filtering and discovery. Use these category names with the categories query parameter to load specific tool groups.

Category Description Tools
agents Create, configure, execute, and monitor AI agents list_available_agents, execute_agent, check_agent_status, complete_agent_run, create_agent, get_tool_configuration, list_available_agent_tools, list_available_agent_resources, list_available_llm_models, list_available_prompts, set_agent_state, update_agent, delete_agent
communication Email, conversation/guest invitations, voice calls send_email, send_conversation_invitation, send_guest_invitation, outbound_call
data CRUD, schema discovery, file management, status, Tier-3 document generation general_crud, model_schema, create_llm_file, update_llm_file, read_llm_file, list_llm_files, move_llm_file, llm_cost_stats, apply_status, run_python_skill, convert_to_pdf
memory Persistent memory: store, load, and curate AI context store_memory, load_memories, update_memory, forget_memory, link_memories, update_memory_profile
conversation Chat messaging and direct messages conversation_chat, start_dm_with_user
research Web search and page fetch web_research
dynamic_functions Serverless JavaScript function management list_dynamic_functions, get_dynamic_function, execute_dynamic_function, dynamic_function_executions, manage_dynamic_function
llm_tools Custom LLM tool creation and management list_llm_tools, get_llm_tool, manage_llm_tool, test_llm_tool
documentation Platform + app-development documentation assistants dmapi_assistant, app_docs_assistant
admin Administrative tools (logs, cost statistics) tail_rails_log, llm_cost_stats
utility General utilities current_date_time
mdm Master Data Management for external system mappings external_mappings_by_system
workflow Workflow artifacts create_workflow_artifact
coordination Agent coordination / resource leases coordination_tool
Filtering Tools: Add ?categories=data,memory to your MCP endpoint URL to load only specific categories, or ?tools= to name individual tools.
mdi-email Communication Tools mdi-link

Tools for sending emails and managing conversation invitations.

send_email_tool

Send emails with customizable subject, body, recipients, and sender information.

Use Cases:

  • Send notifications to users
  • Email reports and summaries
  • Bulk communications to multiple recipients

Key Parameters:

  • subject - Email subject line
  • email_body - HTML email content
  • to_email - Recipient(s), semicolon-separated
  • from_email - Optional sender address
send_conversation_invitation_tool

Send single-use invitation links for one-time feedback in LLM conversations.

Use Cases:

  • Request specific feedback or answers
  • One-time input collection
  • Quick survey responses
send_guest_invitation_tool

Send guest trial invitations allowing multiple messages before signup.

Use Cases:

  • Progressive user engagement
  • Trial conversation access
  • Guest-to-member conversion flows
outbound_call_tool

Make outbound AI voice calls.

mdi-database Data Management Tools mdi-link

Tools for CRUD operations, schema discovery, and file management.

general_crud_tool Most Used

Comprehensive CRUD operations for all data models with advanced filtering, relationships, and aggregations.

Capabilities:

  • Create, Read, Update, Delete operations
  • Advanced search with JSON query syntax
  • Relationship management (link/unlink)
  • Aggregations and analytics
  • Field-level selection for performance

Supported Models:

Party, Individual, Organization, Contact, BizTxnEvent, Project, Task, LlmConversation, and 30+ more

model_schema_tool

Discover schema information, available columns, required fields, and data types for any model.

Use Cases:

  • Understand model structure before queries
  • Identify required fields for creation
  • Discover available relationships
create_llm_file_tool

Create text-based documents (Markdown, TXT, CSV, PDF, DOCX) programmatically.

Use Cases:

  • Generate reports and summaries
  • Create documentation
  • Save analysis results
update_llm_file_tool

Update existing documents with new content, titles, or move to different directories.

read_llm_file_tool

Read file contents including text files, documents (PDF/DOCX), images, and media files.

llm_cost_stats_tool

Retrieve comprehensive LLM usage statistics, costs, and token consumption by model, user, and conversation.

apply_status_tool

Apply tracked statuses to entities (Tasks, Projects, BizTxnEvents, etc.) with proper history tracking.

run_python_skill_tool

Run an admin-reviewed, registered Python script (Tier-3, sandboxed subprocess) by id — e.g. generate a .pptx deck or a print-quality PDF — and persist the output as an attached file. Generates .pptx decks and print-quality PDFs from registered scripts.

convert_to_pdf_tool

Convert an existing Office document (.pptx/.docx/.xlsx) already stored as a file into a PDF, attached back to the conversation.

list_llm_files_tool

List files and directories in the LLM file system.

move_llm_file_tool

Move files or directories to a new location in the LLM file system.

mdi-robot Agent Management Tools mdi-link

Tools for creating, managing, and executing autonomous AI agents.

create_agent_tool

Create complete LLM agents with custom tools, resources, prompts, and role assignments.

update_agent_tool

Modify existing agent configurations, prompts, tools, and settings.

delete_agent_tool

Permanently remove agents from the system.

list_available_agents_tool

List all available agents with their capabilities and descriptions.

execute_agent_tool

Execute an agent with specific prompts and monitor execution status.

check_agent_status_tool

Check the execution status and output of running agents.

complete_agent_run_tool

Mark agent runs as complete with success/failure status.

list_available_agent_tools_tool

List all tools that can be assigned to agents during creation.

list_available_agent_resources_tool

List all resources available for agent configuration.

list_available_llm_models_tool

List configured LLM models available for agent creation.

list_available_prompts_tool

List available system and user prompts for agents.

get_tool_configuration_tool

Get configuration requirements for specific tools before assigning to agents.

mdi-brain Memory Tools mdi-link

Tools for persistent memory management across AI sessions.

store_memory_tool

Save a short memory (title and content required; optional memory_type, importance_score 0–1, tags, private). A save in a private conversation (except a group DM) or by a private agent is private automatically; a shared save is screened for secrets.

Recommended Memory Types:

  • Fact (default) - Something true about the work, the people or the world
  • Preference - How someone likes things done
  • Decision - A choice that was made, and why
  • Learning - A lesson, pattern or fix worth reusing
  • Context - Background that explains a situation

Other canonical types (e.g. insight, solution, goal) are still accepted.

load_memories_tool

Search or browse the memories the caller may read. Each result is tagged provenance: own or shared.

Retrieval Modes:

  • Search - Stemmed word match fused with meaning-based similarity (when embeddings are on); weak matches below a relevance floor are dropped; an optional per-workspace rerank model only reorders the top results, never drops one
  • Semantic - Meaning-based similarity only
  • Recent / Important / All - Browse by date or importance
  • Type / Conversation / Agent - Browse by memory type, conversation or agent
  • Related - The graph neighbours of a memory

Optional as_of (ISO-8601) answers “what did we know on that date”, including versions since corrected.

update_memory_tool

Correct a memory you authored. A new title or content creates a new version (the new id is returned; the old version is kept as history and no longer recalled). Importance or tags alone are edited in place.

forget_memory_tool

Retire (soft-archive, recoverable) a memory you authored so it stops surfacing in recall. Pass superseded_by_memory_id to mark it as replaced by a newer memory instead.

link_memories_tool

Create a typed relationship between two memories (builds the memory graph). Recommended types: related_to, supersedes, exemplifies; also caused_by, depends_on, leads_to, references, spawns, validates.

update_memory_profile_tool

Agents only: rewrite the agent's own always-on “About me” block (up to 1,500 characters), injected into every prompt the agent runs with. Every change is versioned.

mdi-chat Conversation Tools mdi-link

Tools for managing LLM conversations and messaging.

conversation_chat_tool

Send messages to LLM conversations and trigger AI responses.

Use Cases:

  • External system integration
  • Automated message sending
  • Custom chat interfaces
mdi-book-open Documentation Tools mdi-link

Tools for accessing platform documentation.

dmapi_assistant_tool

Ask questions about the Data Model API platform implementation and features.

Topics Covered:

  • Security and capability system
  • API endpoints and responses
  • Model relationships
  • MCP integration
  • Webhook system
app_docs_assistant_tool

Access app development documentation for building applications on the platform.

Topics Covered:

  • Authentication setup
  • API client usage
  • Shared components
  • Best practices
mdi-tools Utility & Admin Tools mdi-link

Utility and administrative tools for system operations.

current_date_time_tool

Get current date and time with timezone support and multiple formats.

tail_rails_log_tool Admin Only

Root tenant only: Tail Rails application logs for debugging and monitoring.

external_mappings_by_system_tool

Get external system mappings for MDM integration and data synchronization.

mdi-function Dynamic Functions Tools mdi-link

Tools for creating, managing, and executing serverless JavaScript functions.

list_dynamic_functions_tool

List available dynamic functions with their status, schedule, and recent execution info.

Filtering Options:

  • active_only - Only show active functions
  • scheduled_only - Only show scheduled functions
  • callbacks_only - Only show callback functions
  • callback_model - Filter by callback model name
  • name - Filter by function name (partial match)
get_dynamic_function_tool

Get full details of a specific function by ID or name, including JavaScript code and execution history.

Key Parameters:

  • id or name - Function identifier
  • include_executions - Include recent execution history
  • execution_limit - Number of executions to include (max 20)
execute_dynamic_function_tool

Execute a dynamic function by ID or name and return results.

Key Parameters:

  • function_id or function_name - Function to execute
  • params - Parameters passed to the function
  • async - Execute asynchronously (queued)

Returns:

  • success - Execution status
  • result - Function return value
  • execution_id - For tracking history
  • execution_time_ms - Duration
manage_dynamic_function_tool CRUD

Create, update, or delete dynamic functions with full configuration support.

Actions:

  • create - Create new function with name, code, schedule, callbacks
  • update - Modify existing function (can rename with new_name)
  • delete - Remove function

Configuration Options:

  • schedule - Cron expression for scheduled execution
  • callback_model - Model to trigger callback on
  • callback_event - Event type (create, update, destroy, all)
  • timeout_seconds - Max execution time (1-300)
  • configuration - Custom config including OAuth
dynamic_function_executions_tool

View execution history and logs for debugging and monitoring.

Filtering Options:

  • function_id or function_name - Filter by function
  • execution_id - Get specific execution details
  • trigger_type - Filter by trigger (manual, api, schedule, mcp_tool, webhook, nested_call, callback)
  • success_only / failed_only - Filter by status
  • limit - Number of records (max 100)
Tip: Dynamic Functions can access tenant data via executeAction(), make HTTP requests with fetch(), call other functions with executeFunction(), and integrate with external systems via OAuth. See the Dynamic Functions section for full documentation.
mdi-webResearch research

web_research_tool — Search and fetch the public web (DuckDuckGo / Tavily / Brave / Wikipedia).

mdi-toolsLLM Tools llm_tools

list_llm_tools_tool — List available custom LLM Tools with their status and configuration.

get_llm_tool_tool — Get details of a specific custom LLM Tool by ID or name.

manage_llm_tool_tool — Create, update, and delete custom LLM Tools.

test_llm_tool_tool — Test-execute a custom LLM Tool with provided parameters.

mdi-database-syncMDM mdm

external_mappings_by_system_tool — Get external-system ID mappings for integrated systems (Master Data Management).

mdi-shield-accountAdmin admin

tail_rails_log_tool — Tail Rails logs for debugging (tenant-scoped access).

llm_cost_stats_tool — Get LLM cost and token-usage statistics.

mdi-cog-transferWorkflow & Coordination workflow coordination

create_workflow_artifact_tool — File an organized, work-item-linked structured-work artifact (any domain).

coordination_tool — Claim / release / inspect advisory leases on shared resources (e.g. the shared DEV/PROD environment).

Using MCP Tools

MCP tools can be accessed in multiple ways:

In LLM Agents

Agents can be granted these tools and use them autonomously during execution.

In Conversations

LLMs in conversations can invoke tools as needed to answer questions, retrieve data, or perform actions.

External Applications

Connect external applications via MCP protocol to access all tools programmatically.

Custom Tools

Create custom JavaScript tools for tenant-specific functionality via the Dynamic Functions system.

Pro Tip: Combine multiple tools in agent workflows for complex automation. For example, use general_crud_tool to fetch data, create_llm_file_tool to generate a report, and send_email_tool to distribute it.

API Documentation

mdi-link
RESTful API Overview mdi-link

DSiloed provides a comprehensive RESTful API for building applications. All endpoints follow consistent RESTful conventions with JSON responses.

Authentication

Authentication uses JWT (JSON Web Tokens) passed in the Authorization header.

curl -X GET "https://example-model-api.com/api/v1/parties" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

Content Types

All API requests should use JSON for request bodies and accept JSON responses.

-H "Content-Type: application/json" \
-H "Accept: application/json"

Response Format

Responses follow a consistent format with data returned in an object named after the resource.

// Single resource example (e.g., GET /api/v1/users/123)
{
  "success": true,
  "user": {
    "id": 123,
    "description": "John Doe",
    "created_at": "2025-05-01T12:34:56Z",
    "updated_at": "2025-05-02T10:11:12Z"
  }
}

// Multiple resources example (e.g., GET /api/v1/users)
{
  "success": true,
  "total_count": 42,
  "users": [
    {
      "id": 123,
      "description": "John Doe",
      "created_at": "2025-05-01T12:34:56Z"
    },
    {
      "id": 124,
      "description": "Jane Smith",
      "created_at": "2025-05-02T08:15:30Z"
    }
    // ... more users
  ]
}

Error Handling

Errors return a simple format with success set to false and an error message.

{
  "success": false,
  "message": "Invalid Access"
}
Core Resources mdi-link Parties Contacts Business Events Security LLM Integration

Parties API

Parties represent individuals and organizations. The Party model is the foundation of your application's data model.

List all parties

curl -X GET "https://example-model-api.com/api/v1/parties" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

Get a specific party

curl -X GET "https://example-model-api.com/api/v1/parties/123" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

Create an individual

curl -X POST "https://example-model-api.com/api/v1/individuals" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id" \
    -H "Content-Type: application/json" \
    -d '{
      "first_name": "John",
      "last_name": "Doe",
      "dob": "1990-01-01"
    }'

Create an organization

curl -X POST "https://example-model-api.com/api/v1/organizations" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id" \
    -H "Content-Type: application/json" \
    -d '{
      "description": "Acme Corporation"
    }'

Contacts API

Contacts represent various contact methods like email addresses, phone numbers, and postal addresses.

List all contacts

curl -X GET "https://example-model-api.com/api/v1/contacts" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

Create an email address

curl -X POST "https://example-model-api.com/api/v1/email_addresses" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id" \
    -H "Content-Type: application/json" \
    -d '{
      "party_id": 123,
      "description": "Work Email",
      "email_address": "john.doe@example.com"
    }'

Create a phone number

curl -X POST "https://example-model-api.com/api/v1/phone_numbers" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id" \
    -H "Content-Type: application/json" \
    -d '{
      "party_id": 123,
      "description": "Mobile",
      "phone_number": "+15551234567"
    }'

Business Events API

Business events track activities and transactions within your application.

List all business events

curl -X GET "https://example-model-api.com/api/v1/biz_txn_events" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

Create a business event

curl -X POST "https://example-model-api.com/api/v1/biz_txn_events" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id" \
    -H "Content-Type: application/json" \
    -d '{
      "biz_txn_event_type_id": 1,
      "description": "Order Placed",
      "event_date": "2025-05-11T14:30:00Z",
      "amount": 99.99,
      "payload": {
        "order_number": "ORD-12345",
        "items": 3
      }
    }'

Security API

Manage security, roles, and capabilities within your application.

List all security roles

curl -X GET "https://example-model-api.com/api/v1/security_roles" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

List all capabilities

curl -X GET "https://example-model-api.com/api/v1/capabilities" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

LLM Integration API

APIs for managing LLM models, tools, and conversations.

List all LLM models

curl -X GET "https://example-model-api.com/api/v1/llm_models" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

List all LLM tools

curl -X GET "https://example-model-api.com/api/v1/llm_tools" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

Share a private memory with the workspace

For people holding the share LlmMemories capability (workspace admins; basic members do not hold it), on a live, current private memory they may both write and read. The confirmation confirm_audience: "workspace" is required. Shared text is screened for secrets. Sharing creates a new, shared version; the private version is retired (kept as history) and the share is recorded on the audit trail. Response: { success, llm_memory, shared_from_id }. 403 when the memory is not yours, 422 without the confirmation, on a replaced version or on refused content, 409 on a concurrent edit.

curl -X POST "https://example-model-api.com/api/v1/llm_memories/123/share" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id" \
    -H "Content-Type: application/json" \
    -d '{"confirm_audience": "workspace"}'
Swagger Documentation mdi-link

For complete API documentation, refer to the Swagger UI which provides interactive documentation for all available endpoints.

Open Swagger Documentation

Dynamic Functions

mdi-link
Serverless JavaScript Functions mdi-link

Dynamic Functions provide a serverless JavaScript execution environment within the DSiloed platform. They allow you to create, manage, and execute custom JavaScript functions that can integrate with external APIs, process data, and automate workflows—all without managing any infrastructure.

mdi-shield-lock Sandboxed Execution JavaScript runs in a secure V8 sandbox with memory and CPU limits. Functions are tenant-isolated with no filesystem access. mdi-key OAuth Integration Configuration-based OAuth 2.0 support for any provider. Automatic token refresh keeps your integrations running. mdi-clock-outline Scheduled Execution Use cron expressions to schedule functions to run automatically. Perfect for data syncs, reports, and automated workflows. mdi-webhook Model Callbacks Trigger functions automatically when records are created, updated, or deleted. Build event-driven automation workflows. mdi-database Data Access Full access to tenant data via executeAction. Query, create, update, and delete records from your functions. mdi-robot MCP Integration AI agents can manage and execute functions via MCP tools. Empower your AI to automate complex workflows.
Creating Your First Function mdi-link

Create a dynamic function using the REST API. Functions receive a context object with parameters, configuration, OAuth tokens, and tenant information.

Tip: Function names must be 1-128 characters using alphanumeric characters, underscores, or hyphens.
// Create a function via REST API
POST /api/v1/dynamic_functions
Content-Type: application/json

{
  "dynamic_function": {
    "name": "hello_world",
    "description": "A simple greeting function",
    "javascript_code": "return { message: 'Hello, ' + (params.name || 'World') + '!' };",
    "active": true,
    "timeout_seconds": 30
  }
}

Execute the function by ID or name:

// Execute by name
POST /api/v1/dynamic_functions/hello_world/execute
Content-Type: application/json

{
  "params": {
    "name": "DSiloed"
  }
}

// Response:
{
  "success": true,
  "result": { "message": "Hello, DSiloed!" },
  "execution_id": 456,
  "execution_time_ms": 12
}
JavaScript Execution Context mdi-link

Functions receive a rich context with access to parameters, configuration, and built-in functions for data access and HTTP requests.

// Available context properties
params                    // Parameters passed when executing
config                    // Function configuration (excluding secrets)
functionId                // Database ID of this function
functionName              // Function name
tenantId                  // Current tenant ID

// OAuth tokens (if connected)
oauth.accessToken         // OAuth access token
oauth.tokenType           // Token type (usually "Bearer")

// Callback context (only in callback executions)
event                     // 'create', 'update', or 'destroy'
model_name                // Model class name (e.g., 'Task')
record_id                 // ID of the affected record
record                    // Full record data
changes                   // Changed attributes (update only)
// Make HTTP requests to external APIs
const response = await fetch('https://api.example.com/data', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${oauth.accessToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ key: 'value' })
});

const data = await response.json();
return { fetched: data };
// Query tenant data
var customers = executeAction('Individual', 'list', {
  filters: { role_type_id: 'customer' },
  limit: 100
});

// Create records
var newContact = executeAction('PhoneNumber', 'create', {
  attributes: {
    party_id: 123,
    phone_number: '555-1234'
  }
});

// Update records
executeAction('Individual', 'update', {
  id: 456,
  attributes: { custom_fields: { synced: true } }
});

// Convenience wrappers also available:
listRecords(modelName, options)
getRecord(modelName, id)
createRecord(modelName, attributes)
updateRecord(modelName, id, attributes)
deleteRecord(modelName, id)
findOrCreateRecord(modelName, findAttrs, createAttrs)
// Execute another DynamicFunction by name (synchronous by default)
const result = executeFunction('helper_function', { key: 'value' });

if (result.success) {
  console.log('Helper returned:', result.result);
} else {
  console.error('Helper failed:', result.error);
}

// Execute asynchronously (queued for background execution)
const asyncResult = executeFunction('long_running_task', { data: params.input }, true);
// Returns immediately: { success: true, message: '...', execution_id: ... }

// Chain multiple functions together
const validation = executeFunction('validate_data', { data: params.input });
if (!validation.success || !validation.result.valid) {
  return { success: false, error: 'Validation failed' };
}

const processed = executeFunction('process_data', {
  data: params.input,
  validationResult: validation.result
});

return processed.result;

// executeFunction(functionNameOrId, params, async)
// - functionNameOrId: Name or ID of the function
// - params: Parameters object (optional)
// - async: If true, queues for background execution (optional, default: false)
// Look up external ID for a local record
var result = getExternalId('Party', partyId, 'xero', 'xero_user_id');
if (result.found) {
  console.log('Xero user ID:', result.external_id);
}

// Find local record by external ID
var projectMapping = findByExternalId('Project', 'xero', xeroProjectId);
if (projectMapping.found) {
  var localProject = projectMapping.record;
}

// Store a new mapping
storeExternalMapping('Project', localProjectId, 'xero', xeroProjectId, {
  column_name: 'xero_project_id',
  table_name: 'xero_projects',
  is_primary_key: true
});
Scheduling Functions

Functions can be scheduled to run automatically using cron expressions. The scheduler checks every 30 seconds for functions due to execute.

Schedule Cron Expression
Every minute* * * * *
Every hour0 * * * *
Daily at 9am0 9 * * *
Every Monday at 8am0 8 * * 1
First of month at midnight0 0 1 * *
Every 15 minutes*/15 * * * *
Required: Scheduled functions must specify run_as_user_id to define which user's permissions are used during background execution. The user must belong to the same tenant.
// Create a scheduled function
POST /api/v1/dynamic_functions
{
  "dynamic_function": {
    "name": "daily_sync",
    "description": "Sync contacts with CRM every morning",
    "javascript_code": "/* sync logic */",
    "schedule": "0 9 * * *",
    "timeout_seconds": 120,
    "run_as_user_id": 123,
    "active": true
  }
}
Model Lifecycle Callbacks mdi-link

Functions can be triggered automatically when records are created, updated, or destroyed. This enables event-driven automation without polling.

Supported Models

Individual Organization Party Task Project TimeEntry BizTxnEvent BizTxnAccount

Callback Events

create update destroy all
Required: Callback functions must specify run_as_user_id to define which user's permissions are used during callback execution. The user must belong to the same tenant.
// Create a callback function for task creation
POST /api/v1/dynamic_functions
{
  "dynamic_function": {
    "name": "on_task_created",
    "description": "Notify team when tasks are created",
    "callback_model": "Task",
    "callback_event": "create",
    "run_as_user_id": 123,
    "javascript_code": `
      // Context includes: event, model_name, record_id, record
      console.log('Task created:', record.name);

      // Send notification to external system
      await fetch('https://slack.com/api/chat.postMessage', {
        method: 'POST',
        headers: {
          'Authorization': 'Bearer ' + oauth.accessToken,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          channel: '#tasks',
          text: 'New task created: ' + record.name
        })
      });

      return { notified: true };
    `
  }
}
OAuth Integration mdi-link

Dynamic Functions support OAuth 2.0 for integrating with external services. OAuth is configuration-based, meaning any OAuth 2.0 provider can be used without code changes.

OAuth Configuration

{
  "oauth": {
    "provider": "xero",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "authorize_url": "https://login.xero.com/identity/connect/authorize",
    "token_url": "https://identity.xero.com/connect/token",
    "scopes": ["openid", "profile", "accounting.transactions.read"]
  }
}

OAuth Flow

1. Configure - Set OAuth config on the function 2. Authorize - Call /oauth/authorize to get authorization URL 3. Redirect - User authorizes access at the provider 4. Callback - Provider redirects with authorization code 5. Token Exchange - System exchanges code for tokens 6. Usage - Access tokens via oauth.accessToken Auto-refresh: Tokens are automatically refreshed before execution when they are expired or expiring within 5 minutes.
REST API Reference mdi-link
Endpoint Description
GET /api/v1/dynamic_functions List all functions
POST /api/v1/dynamic_functions Create a new function
GET /api/v1/dynamic_functions/:id Get function details
PUT /api/v1/dynamic_functions/:id Update a function
DELETE /api/v1/dynamic_functions/:id Delete a function
POST /api/v1/dynamic_functions/:id/execute Execute a function (sync or async)
GET /api/v1/dynamic_functions/:id/export Export function configuration
POST /api/v1/dynamic_functions/import Import a function
POST /api/v1/dynamic_functions/:id/oauth/authorize Start OAuth authorization
GET /api/v1/dynamic_functions/:id/oauth/status Check OAuth connection status
POST /api/v1/dynamic_functions/:id/oauth/disconnect Disconnect OAuth
Tip: Functions can be referenced by ID (numeric) or name (string) in URLs. For example: /api/v1/dynamic_functions/my_function/execute
MCP Tools for AI Agents mdi-link

AI agents can manage and execute Dynamic Functions via five dedicated MCP tools. This enables intelligent automation where AI can create, modify, and run custom code.

list_dynamic_functions_tool List functions with filtering by active status, schedule, callbacks, and name. get_dynamic_function_tool Get full function details including JavaScript code and execution history. execute_dynamic_function_tool Execute a function by ID or name with parameters (sync or async). manage_dynamic_function_tool Create, update, or delete functions. Supports scheduling and callbacks. Use run_as_user_id: "current_user" for scheduled/callback functions. dynamic_function_executions_tool View execution history with filtering by function, trigger type, and status.
Example: Xero Integration Function mdi-link

Here's a complete example of a function that syncs time entries to Xero, demonstrating OAuth, data access, and MDM mapping helpers.

// Function: sync_time_entries_to_xero
// Schedule: 0 * * * * (every hour)

// Get unsynced time entries
var entries = listRecords('TimeEntry', {
  filters: { status: 'approved' },
  limit: 50
});

var synced = 0;
var skipped = 0;

for (var entry of entries.data) {
  // Skip if already synced
  var existingMapping = getExternalId('TimeEntry', entry.id, 'xero', 'xero_timeentry_id');
  if (existingMapping.found) {
    skipped++;
    continue;
  }

  // Look up Xero user ID for this party
  var userMapping = getExternalId('Party', entry.party_id, 'xero', 'xero_user_id');
  if (!userMapping.found) {
    console.log('No Xero user mapping for party:', entry.party_id);
    continue;
  }

  // Create time entry in Xero
  var xeroResponse = await fetch('https://api.xero.com/projects/timeEntries', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer ' + oauth.accessToken,
      'Content-Type': 'application/json',
      'Xero-Tenant-Id': config.xero_tenant_id
    },
    body: JSON.stringify({
      userId: userMapping.external_id,
      projectId: entry.custom_fields.xero_project_id,
      duration: entry.hours * 60,
      description: entry.description
    })
  });

  var xeroEntry = await xeroResponse.json();

  // Store mapping for future reference
  storeExternalMapping('TimeEntry', entry.id, 'xero', xeroEntry.timeEntryId, {
    column_name: 'xero_timeentry_id'
  });

  synced++;
}

return {
  success: true,
  synced: synced,
  skipped: skipped,
  message: `Synced ${synced} entries, skipped ${skipped} already synced`
};

Sample Applications

mdi-link
Available Sample Apps mdi-link

DSiloed comes with several sample applications that demonstrate different capabilities of the platform. Each app is built as a static JavaScript application that interacts with the API.

{{ app.name }}

{{ app.description }}

{{ feature }}
Open App
App Architecture mdi-link

Each sample application follows a similar architecture pattern:

Static HTML/CSS/JavaScript Apps are built with HTML, CSS, and JavaScript without a server-side component. Vue.js + Vuetify Front-end built with Vue.js and styled with Vuetify components. RESTful API Integration Apps communicate with the DSiloed backend using RESTful endpoints. JWT Authentication Authentication managed through JWT tokens stored in localStorage. Responsive Design Applications are designed to work on desktop and mobile devices.

Building Your Own App

mdi-link
How an App Is Built mdi-link

An app built on PortableMind lives on its own origin (your domain, your hosting) and talks to the platform API from its own server. The browser talks to your server; your server holds the credentials and forwards authenticated requests to https://www.dsiloed.com/api/v1/.... Never ship a platform credential to the browser.

Signing in

Exchange a user's credentials for a session token with POST /api/v1/authenticate (email or username, plus password). A successful response carries the token as jwt; a user with multi-factor authentication gets an MFA challenge instead, which your app must complete.

curl -X POST "https://www.dsiloed.com/api/v1/authenticate" \
    -H "Content-Type: application/json" \
    -H "Tenant-Id: your-tenant-id" \
    -d '{"email": "user@example.com", "password": "..."}'

Send the token on every later call, together with the tenant header, exactly as described in API Documentation:

curl "https://www.dsiloed.com/api/v1/parties" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id"

Request and response schemas for every public endpoint are in the interactive API reference.

Template Apps: Fork a Working Example mdi-link

Two complete open-source apps are published as public repos, each structured as a template you can fork. Both use the same minimal architecture: a single-page HTML + vanilla JavaScript frontend and a tiny zero-dependency Node proxy that injects runtime configuration and forwards authenticated requests to the platform. No framework, no build step.

Repo What it is
pm-ticket-portal White-label customer support portal: clients register with an access key, submit tickets, and chat with an AI support agent, with human staff able to step in at any time.
pm-payer-portal White-label healthcare payer portal: prior-authorization workflows driven by intake agents, with turnaround-time tracking and clinician-controlled denials.

Each repo's README and integration guide cover setup, the role files it ships and its deployment. The fastest path to a custom app is to hand one of them to a coding agent and describe what you want to build; see the developer resources page for a ready-made prompt.

Shipping a Role with Your App mdi-link

Your app's security role is part of your app, not the platform. Build it once in a development workspace (Administration → Roles), export it (GET /api/v1/security_roles/:id/export or the Export button), keep the JSON file in your repo, and import it into each workspace on every release:

curl -X POST "https://www.dsiloed.com/api/v1/security_roles/import" \
    -H "Authorization: Bearer YOUR_JWT_TOKEN" \
    -H "Tenant-Id: your-tenant-id" \
    -H "Content-Type: application/json" \
    -d "$(jq -n --slurpfile d roles/my_role.json '{data: $d[0], overwrite: false}')"
  • The import must be run by a workspace admin: an admin user's session, or an API key that itself holds the workspace's admin role. A plain API key is refused.
  • It is exact and repeatable: the role is created if missing, then its capabilities are replaced by the file's. Run it on every release.
  • Prefer scoped capabilities: an unscoped grant applies to every record of that kind in the workspace, not just your app's.
  • Who holds the role is separate from the file. When your app server creates users at runtime with an ordinary (non-admin) API key, it can only assign roles marked external, plus the app section roles (app_chat, app_files, app_projects, app_tickets; never app_admin) when the same call also assigns an external role; any other internal role is assigned by an admin.
White-label Single Sign-on mdi-link

To drop your app's signed-in users into the full PortableMind web app under your branding, with no second login, a workspace admin enables white-label (PUT /api/v1/white_label) and mints a sign-on key (POST /api/v1/white_label/sso_key, shown once). Your server then signs a short-lived, single-use assertion (HS256, with sub, tenant_enterprise_identifier, jti, iat and an exp at most two minutes out) and redirects the browser to the web app's /sso?assertion=... route, which exchanges it through POST /api/v1/sso/exchange for an ordinary session.

Keep the sign-on key on your server: whoever holds it can sign in as anyone in the workspace. Setup is described in the user guide under White-label Branding & Single Sign-on.

External Members mdi-link

Your app's end users (customers, clients, anyone outside the organization running the workspace) should be external members: they hold at least one role marked external. For them:

  • an unscoped capability counts only when it comes from an external role;
  • private records reach them only through ownership, an explicit share or membership;
  • the built-in External Member role gives the personal basics the web app needs (notifications, preferences) and no business data.

Give such users External Member plus your app's own role, marked external, with every read scoped to the records they should see (for example, conversations they are a member of).

Next Steps

mdi-link
Continue Your Journey mdi-link

Now that you've explored the DSiloed platform, here are some next steps to continue your journey:

Create Your Tenant

Set up your tenant environment to begin building applications (see the user guide for a walkthrough).
Sign Up

Explore Sample Apps

Review the sample applications to understand the platform's capabilities.
Open Dashboard

Read API Documentation

Understand the API endpoints available for your application.
API Docs

Build Your First App

Create a simple application using the DSiloed platform.
Read Guide

Launch Your Application

Deploy your application and share it with users.
Get Help mdi-link

Need help with the DSiloed platform? Here are some resources to assist you:

mdi-book-open-variant Documentation

Access comprehensive documentation for the DSiloed platform.

Open Documentation
mdi-home Intro mdi-rocket-launch Start mdi-api API mdi-apps Apps mdi-code-tags Build {{ snackbar.text }}