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:
- Save a new version as a draft with
dashboard_save({ html, draft: true }). Draft versions are stored but not visible to the user. - Validate the draft with
dashboard_validate({ version }). This checks for invalid SDK method calls, incorrect DOM access patterns, and missing required elements. - 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
| Method | Returns |
|---|---|
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
| Method | Returns |
|---|---|
projects.list(params?) | { success, projects: [{ projectId, projectName, status, priority, completionPercentage }] } |
projects.get(id) | { success, project: { projectId, projectName, status, tasks } } |
tasks
| Method | Returns |
|---|---|
tasks.list(params?) | { success, tasks: [{ taskId, taskTitle, status, dueDate, priority, projectName }], total } |
tasks.update(id, changes) | { success, task } |
tasks.complete(id) | { success, task } |
tasks.create | NOT AVAILABLE. Tasks are created by agent tools, not by dashboards. |
activity
| Method | Returns |
|---|---|
activity.list(params?) | { success, activities: [{ activityId, type, summary, createdAt }], total } |
insights (PA only)
| Method | Returns |
|---|---|
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)
| Method | Returns |
|---|---|
linkedin.getAnalytics(period?) | { analytics } |
linkedin.getPostHistory(params?) | { posts } |
chat
| Method | Returns |
|---|---|
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)
- Use
OutermindSDK.container.getElementById()andOutermindSDK.container.querySelector(). Never calldocument.getElementById()ordocument.querySelector()from within a dashboard. tasks.create()is not available. Dashboards can update and complete tasks but cannot create them; task creation is an agent-only action.insightsandlinkedinare PA-only. Calling them from a CAIOO dashboard throws. Branch onOutermindSDK.context.agent.nameif your dashboard must support both surfaces.- 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.
- Use
theme.cssVarsrather than hard-coded colors so the dashboard matches the host app in both light and dark mode. - Respect the 50-version cap. Delete old draft versions before publishing new ones if you approach the limit.
- 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.