Skip to main content

Dashboard SDK Reference

This reference describes window.OutermindSDK, the runtime API available inside every custom dashboard widget rendered in the Boardroom and the PA Hub.

A "dashboard" here is a self-contained HTML document that Outermind renders inside a Shadow DOM inside the host admin app. Agents create and update dashboards using the dashboard_save, dashboard_validate, and dashboard_publish tools. When a published dashboard loads, Outermind injects window.OutermindSDK and the global window.OutermindSDK.container (a ShadowRoot) for DOM access.

Authoring workflow

Dashboards have versioned history. The three stages are:

  1. Save a new version as a draft with dashboard_save({ html, draft: true }). Draft versions are stored but not visible to the user.
  2. Validate the draft with dashboard_validate({ version }). This checks for invalid SDK method calls, incorrect DOM access patterns, and missing required elements.
  3. Publish the draft with dashboard_publish({ version }). Only the active (published) version renders to the user.

Use dashboard_list_versions to inspect history, dashboard_get to read a specific version, and dashboard_delete_version to remove obsolete versions. dashboard_list returns every dashboard owned by the current user or org.

Maximum 50 versions per dashboard. Old versions must be deleted before the limit is reached.

Technology choices

Dashboards are pure static HTML rendered inside a Shadow DOM. You can use any JavaScript library that publishes an ES module build. The recommended loader is esm.sh, which serves ES modules for npm packages with no build step:

<script type="module">
import React from 'https://esm.sh/react@18';
import { createRoot } from 'https://esm.sh/react-dom@18/client';
// ...
</script>

Common libraries known to work: React, D3, Three.js, Chart.js, htm, preact, lit.

Always include:

  • A <style> block or inline styles for CSS. External stylesheets are not loaded across the Shadow DOM boundary.
  • A <script type="module"> block for JavaScript. Classic scripts are not supported.

window.OutermindSDK

The SDK is injected as a frozen, read-only global. All data methods return Promises and handle authentication automatically. Do not access JWT tokens, session cookies, or auth headers; use the SDK.

Data APIs

All methods return { success: boolean, ... }. A failure returns { success: false, error: string }.

goals

MethodReturns
goals.list(params?){ success, goals: [{ goalId, title, status, priority, progressPct, targetDate, projectCount, taskCount }], total }
goals.get(id){ success, goal: { goalId, title, description, status, priority, progressPct, targetDate } }
goals.create({ title, description, priority, targetDate }){ success, goal }
goals.update(id, changes){ success, goal }
goals.delete(id){ success }

projects

MethodReturns
projects.list(params?){ success, projects: [{ projectId, projectName, status, priority, completionPercentage }] }
projects.get(id){ success, project: { projectId, projectName, status, tasks } }

tasks

MethodReturns
tasks.list(params?){ success, tasks: [{ taskId, taskTitle, status, dueDate, priority, projectName }], total }
tasks.update(id, changes){ success, task }
tasks.complete(id){ success, task }
tasks.createNOT AVAILABLE. Tasks are created by agent tools, not by dashboards.

activity

MethodReturns
activity.list(params?){ success, activities: [{ activityId, type, summary, createdAt }], total }

insights (PA only)

MethodReturns
insights.get(period?){ success, insights }

Calling insights.* from a CAIOO dashboard returns an error. PA-only APIs are gated at the SDK level.

linkedin (PA only)

MethodReturns
linkedin.getAnalytics(period?){ analytics }
linkedin.getPostHistory(params?){ posts }

chat

MethodReturns
chat.send(message)Sends a message to the conversation.
chat.getConversations(params?){ conversations: [...] }

Context

OutermindSDK.context is a frozen object with runtime metadata:

const { user, theme, agent, container } = OutermindSDK.context;

// user: { name, email, timezone }
// theme: { mode: "light" | "dark", cssVars: { "--om-primary": "...", ... } }
// agent: { name, status }
// container: ShadowRoot (use for all DOM queries)

DOM access

You are running inside a Shadow DOM. document.getElementById() and document.querySelector() will not find your own elements; they will find (or miss) elements in the host admin app.

Always query through the container:

// Correct
const el = OutermindSDK.container.getElementById('my-chart');
const items = OutermindSDK.container.querySelectorAll('.item');

// Wrong (searches the host app, not your dashboard)
const el = document.getElementById('my-chart');

Theme variables

Use theme.cssVars for styling that tracks the host app's theme:

<style>
.card {
background: var(--om-surface);
color: var(--om-text);
border: 1px solid var(--om-border);
}
.primary-button {
background: var(--om-primary);
}
</style>

The full set of CSS variables is available at runtime via Object.keys(OutermindSDK.context.theme.cssVars).

Rules (must-follow)

  1. Use OutermindSDK.container.getElementById() and OutermindSDK.container.querySelector(). Never call document.getElementById() or document.querySelector() from within a dashboard.
  2. tasks.create() is not available. Dashboards can update and complete tasks but cannot create them; task creation is an agent-only action.
  3. insights and linkedin are PA-only. Calling them from a CAIOO dashboard throws. Branch on OutermindSDK.context.agent.name if your dashboard must support both surfaces.
  4. Do not attempt to access JWT tokens, session cookies, or auth headers. All API methods authenticate automatically. Trying to read tokens is both unnecessary and will fail because the SDK runs in an isolated context.
  5. Use theme.cssVars rather than hard-coded colors so the dashboard matches the host app in both light and dark mode.
  6. Respect the 50-version cap. Delete old draft versions before publishing new ones if you approach the limit.
  7. Keep your HTML self-contained. No external <link rel="stylesheet"> and no classic (non-module) script tags. All CSS inline or inside <style>; all JavaScript inside <script type="module">.

Minimal example

<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<style>
:host { display: block; font-family: var(--om-font-sans, system-ui); padding: 16px; }
.card { background: var(--om-surface); border: 1px solid var(--om-border); border-radius: 8px; padding: 12px; }
h1 { color: var(--om-primary); margin: 0 0 12px; }
</style>
</head>
<body>
<h1>My Goals</h1>
<div id="content" class="card">Loading goals...</div>

<script type="module">
const { container } = OutermindSDK.context;
const el = container.getElementById('content');

try {
const result = await OutermindSDK.goals.list();
if (!result.success) throw new Error(result.error);
el.innerHTML = result.goals
.map(g => `<div>${g.title} (${g.progressPct}%)</div>`)
.join('');
} catch (err) {
el.textContent = `Failed to load goals: ${err.message}`;
}
</script>
</body>
</html>

Save this via dashboard_save({ html: "...", draft: true }), validate with dashboard_validate, then publish with dashboard_publish.