← Speak AICONTENT HISTORY

Update to Speak AI

Snapshot Nov 2, 2026 · 18:11 UTC · version 1.41.1

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save Speak AI and check future changes in Following.

Up to 10 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Build, update, and share Speak AI analytics dashboards. Use this when someone asks for a dashboard, a recurring report, a chart or widget over their recordings, a speaker breakdown, a view of sentiment or themes over time, a shareable link or embed for stakeholders, or a copy of an existing dashboard scoped to a different folder or date range. Covers list_dashboard_widgets, list_dashboards, get_dashboard, create_dashboard, update_dashboard, duplicate_dashboard, share_dashboard, delete_dashboard and get_dashboard_speakers_insight, and explains the strict widget config rules that reject unknown keys.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 287
    }
  ],
  "name": "dashboards-and-reporting",
  "skill_md_contents": "---\nname: dashboards-and-reporting\ndescription: Build, update, and share Speak AI analytics dashboards. Use this when someone asks for a dashboard, a recurring report, a chart or widget over their recordings, a speaker breakdown, a view of sentiment or themes over time, a shareable link or embed for stakeholders, or a copy of an existing dashboard scoped to a different folder or date range. Covers list_dashboard_widgets, list_dashboards, get_dashboard, create_dashboard, update_dashboard, duplicate_dashboard, share_dashboard, delete_dashboard and get_dashboard_speakers_insight, and explains the strict widget config rules that reject unknown keys.\nmetadata:\n  server-version: \"1.41.1\"\n  categories: \"dashboards, custom-fields, folders-views\"\n---\n\n# Dashboards and reporting\n\nThe user's explicit instructions take priority over this skill. When they ask for something different from the steps below, do what they asked, and confirm with them before any action that deletes, overwrites, or sends data outside Speak AI.\n\nA dashboard is a saved set of widgets over a scope of media. It answers \"how is this\nchanging\" rather than \"what did this call say\", and it can be shared with people who do not\nhave a Speak AI account.\n\n## Step 1: Always call list_dashboard_widgets first\n\n`list_dashboard_widgets` takes no arguments. It returns every widget type, the exact\n`config` shape each one accepts, the metric and filter grammar, date-range presets, design\nrules, and two complete worked examples.\n\nCall it before `create_dashboard` or `update_dashboard`, every time. Widget configs are\nstrict and reject unknown keys, so guessing a field name fails the whole call. The catalog\nis the only place the current vocabulary is written down, and it changes as widgets are\nadded.\n\n## Step 2: Create the dashboard\n\n`create_dashboard` requires only `title`, capped at 60 characters. Everything else is\noptional, so you can create it and then add widgets.\n\nPass `widgets` as a simple ordered list. Widget ids and grid layout are computed for you,\nso do not hand-build an `x`/`y` grid unless the user asks for a specific arrangement.\n\nFour rules from the catalog that cause most failures:\n\n- **Configs are strict.** An unknown key is rejected rather than ignored.\n- **Metrics reference custom fields by NAME, not id.** Get names from `list_fields`.\n- **`field-distribution` requires `config.fieldName`.** Most other widgets render on\n  sensible defaults with no config at all.\n- **`team-activity` is only valid when the source is `{ type: \"team\" }`**, either on the\n  dashboard or on that widget's `binding.source`.\n\nTo group widgets into sections, give each sectioned widget an explicit kebab-case `id` and\nreference those ids in `sections[].widgetIds`.\n\n## Step 3: Scope it\n\nA dashboard has a source, a date range, and optional filters. Each widget can override any\nof them through `binding`, and omitting a key inherits the dashboard's value.\n\nGet the scope right before adding widgets. A dashboard over the whole workspace when the\nuser meant one folder produces charts that look fine and mean nothing. If the user names a\nteam, a project, or a client, find the matching folder with `list_folders` first and scope\nto it.\n\n## Step 4: Share it\n\n`share_dashboard` takes `dashboardId` and enables public sharing, returning a share token\nand an embed. That link is public and unauthenticated, so anyone holding it sees the data.\n\nConfirm with the user before sharing, and say plainly that the link needs no login.\n\n## Let reviewers edit fields\n\n`settings.fieldEdits.fieldIds` lists the custom fields that people on the dashboard's\nFeedback name list (`settings.feedback.submitters`, with `allowOtherSubmitter`) can edit\nfrom a media page opened through the shared dashboard. The fields show in an \"Edit fields\"\ntab, in the order you list them.\n\n- Only list fields that have allowed values. The server rejects any other field with a 400\n  that names it.\n- The field must also show on the dashboard's media pages (`settings.fields.includeIds`, or\n  the company's public fields when that list is empty). Other fields are ignored on the page.\n- Up to 50 ids. Unknown ids are dropped and returned in `droppedFieldIds`.\n- An empty list turns editing off. On update, leaving `fieldEdits` out keeps what is saved.\n\nOnly change this when the user asks. Get field ids from `list_fields`, then call\n`update_dashboard` with metadata only:\n\n```json\n{\n  \"dashboardId\": \"<dashboardId>\",\n  \"settings\": { \"fieldEdits\": { \"fieldIds\": [\"<statusFieldId>\", \"<outcomeFieldId>\"] } }\n}\n```\n\n## Profiles\n\n`settings.profiles` is a list of up to 5 groups, one per custom field. Each group has a label\nand entries that give a value of that field a name, image, description and link:\n`[{ \"fieldId\": \"<speakerFieldId>\", \"label\": \"Speakers\", \"imageShape\": \"round\", \"entries\": [{ \"name\": \"Ada Lovelace\", \"description\": \"Plain text.\", \"link\": \"https://example.org/ada\" }] }]`.\n\n- Each field can have only one group. Label 1-40 chars; `imageShape` is `round` or `square`.\n- Entry names must equal the field's values (trim, case-insensitive). They are matched by\n  display string, so renaming a value in the media fields orphans its entry. A name listed\n  twice in a group is rejected.\n- Names, descriptions, links and images are public to anyone with the dashboard link. Plain\n  text only, no HTML, description max 600 chars, name 1-80, link http or https only, up to 60\n  entries per group. Confirm the descriptions and links with the user first.\n- The MCP cannot upload images. Images come from the in-app upload\n  (`POST /v1/dashboards/:dashboardId/profile-image`); to keep an existing one, copy its\n  `imageKey` unchanged from `get_dashboard`.\n- The list replaces itself when sent, so resend every group and entry you want to keep. A save\n  that contains only `profiles` does not move media pages onto the settings flow.\n- Pass the `revision` from `get_dashboard` with every `profiles` save; a stale one returns a 409.\n- A records table with `display: \"cards\"` can show an entry image through `card.imageColumn`.\n  It must name a raw custom-field column whose field has a profile group in `settings.profiles`;\n  the card shows the image of that group's entry that matches the record's value.\n\n## Speaker breakdowns\n\n`get_dashboard_speakers_insight` computes a speakers breakdown for a folder scope and date\nrange. Use it for talk-time splits and who dominated a set of conversations, which is a\ncommon ask after a batch of sales or research calls.\n\nIt answers the question directly, so reach for it instead of building a dashboard when the\nuser only wants that one number.\n\n## Managing dashboards\n\n- `list_dashboards` returns the dashboards the caller can access, including share state.\n  Check here before creating something that already exists.\n- `get_dashboard` returns a dashboard's full spec: title, description, source, date range,\n  and widgets. Read it before updating so you preserve what is already there.\n- `update_dashboard` takes `dashboardId`. Send the full intended state of what you are\n  changing rather than assuming a partial merge, and re-read with `get_dashboard`\n  afterwards if the user is iterating.\n- `duplicate_dashboard` takes `dashboardId` and clones it. This is the right tool for\n  \"same report, different folder\" or \"same report, last quarter\", so rebuild nothing.\n- `delete_dashboard` is a soft delete. Confirm with the user first.\n\n## What goes wrong\n\n- **Building widgets without calling `list_dashboard_widgets`.** Configs are strict and\n  the vocabulary is not guessable.\n- **Referencing a custom field by id.** Metrics take the field NAME. Use `list_fields`.\n- **Using `team-activity` on a non-team source.** It is only valid with\n  `{ type: \"team\" }`.\n- **Sharing without asking.** The share link needs no login.\n- **Updating blind.** Read with `get_dashboard` first, or you will drop widgets the user\n  wanted.\n- **Building a dashboard for a one-off number.** If the ask is talk time, use\n  `get_dashboard_speakers_insight`.\n\n## Confirm before running\n\n- `share_dashboard`, which exposes data to anyone with the link.\n- `delete_dashboard`, even though it is a soft delete.\n- `update_dashboard` on a dashboard someone else built.\n\n## Tools this skill uses\n\nDashboards: `list_dashboard_widgets`, `list_dashboards`, `get_dashboard`,\n`create_dashboard`, `update_dashboard`, `duplicate_dashboard`, `share_dashboard`,\n`delete_dashboard`, `get_dashboard_speakers_insight`.\n\nSupporting: `list_fields` for custom field names, `list_folders` for scoping.\n\nPer-tool documentation: `https://docs.speakai.co/mcp/tools/dashboards/<tool_name>/`\n"
}

SHA-256 of public snapshot: e159cc8bd9cc1894980e713cf6565f4a14e12ebaa4c852bb7b0a88cb10d007cf