Toolkit Authoring Guide¶
This guide walks you through creating custom toolkits for your Contio-powered offering. Whether you're building meeting workflows for your own platform or enabling your customers to extend their experience, this guide covers the complete authoring process.
Two Distribution Models¶
Before you begin authoring, decide how your toolkit will be distributed:
| Model | How It's Installed | Who Controls Updates | Best For |
|---|---|---|---|
| Partner-Administered | Via Partner Admin API | You (the partner) | Core functionality you manage for all customers |
| Customer-Administered | Via Settings UI (file import) | Your customer | Extensions your customers create and customize |
Partner-Administered Toolkits¶
When you install a toolkit via the Partner Admin API (POST /v1/partner/admin/toolkits), you retain control over the entities. You can push updates, fix prompts, and add new templates—all changes propagate to your customers' workspaces automatically.
Use this model when:
- The toolkit is core to your product offering
- You need to maintain consistency across all customer workspaces
- You want to push updates without customer intervention
Customer-Administered Toolkits¶
When your customers import a toolkit via the Contio Settings UI, they own the resulting entities. They can customize prompts, add shortcuts, and modify workflows freely.
Use this model when:
- You're providing a starter kit that customers will tailor
- Your customers have unique meeting formats
- Customization is a key value proposition
See Ownership & Distribution for detailed governance implications.
Planning Your Toolkit¶
1. Define the Meeting Lifecycle¶
Start by mapping the meeting types your toolkit supports:
Example — Recruiting Interview Suite:
| Meeting Type | During Meeting | After Meeting |
|---|---|---|
| Phone Screen | Quick-capture shortcuts | Candidate summary, next interview recommendation |
| Technical Interview | Competency flags, code review notes | Technical assessment scorecard |
| Panel Debrief | Voting shortcuts | Hiring recommendation, stakeholder notification |
2. Identify Entity Types¶
Once you've mapped the lifecycle, identify which entities you need:
| Entity Type | Purpose | When to Use |
|---|---|---|
| Meeting Templates | Define agenda structure and default settings | Every toolkit needs at least one |
| Next Steps | AI-powered post-meeting outputs | When you want automated summaries, scorecards, or analysis |
| Action Buttons | Deliver content (email, clipboard, webhook) | Pair with next steps for content distribution |
| Shortcuts | Quick in-meeting actions | Rapid note-taking, flags, structured captures |
| Workflows | Multi-step automation | Review gates, approval chains, notifications |
| Canvas Templates | Structured document templates | Scorecards, dashboards, collaborative docs |
3. Sketch the Reference Graph¶
Entities reference each other. Before writing JSON, sketch the relationships:
Template: "Sales Discovery"
├── Next Step: "Meeting Summary"
│ └── Action Button: "Email Summary"
│ └── Action Button: "Copy to Clipboard"
├── Next Step: "Follow-up Email Draft"
│ └── Action Button: "Open Email Client"
└── Workflow: "CRM Update Pipeline"
└── Node: Execute "Meeting Summary"
└── Node: Review Gate (Sales Manager)
└── Node: Webhook to CRM
Writing the Manifest¶
Manifest Structure¶
Every toolkit uses a wrapper containing provenance metadata and the manifest content:
{
"name": "My Toolkit",
"slug": "my-toolkit",
"version": "1.0.0",
"license": "LicenseRef-MyCompany",
"license_url": "https://mycompany.com/toolkit-license",
"manifest": {
"schema_version": "1",
"toolkit_prompt": "You are a helpful assistant for...",
"templates": [...],
"next_steps": [...],
"action_buttons": [...],
"shortcuts": [...],
"workflows": [...],
"canvas_templates": [...]
}
}
| Field | Purpose |
|---|---|
name | Human-readable display name |
slug | URL-safe identifier (used for updates and deduplication) |
version | Semantic version for upgrade detection |
toolkit_prompt | Global AI persona applied to all next steps |
Entity IDs and References¶
Use $id to declare entities and $ref to link them:
{
"next_steps": [
{
"spec": {
"$id": "ns-summary",
"name": "Meeting Summary",
"type": "ai",
"ai_prompt": "Summarize this meeting..."
},
"action_buttons": [
{ "action_button": { "$ref": "ab-email" }, "sort_order": 1 }
]
}
],
"action_buttons": [
{
"spec": {
"$id": "ab-email",
"name": "Email Summary",
"delivery_mechanism": "email",
"content_format": "rich_text"
}
}
]
}
When installed, these local identifiers resolve to database UUIDs.
Entity Deep Dive¶
Meeting Templates¶
Templates define the structure users see when creating meetings:
{
"templates": [
{
"spec": {
"$id": "standup",
"name": "Daily Standup",
"slug": "daily-standup",
"description": "15-minute team sync",
"meeting_duration_seconds": 900,
"agenda_items": [
{
"item_type": "DISCUSSION",
"title": "Yesterday's Progress",
"time_allocation_minutes": 5,
"sequence": "1"
},
{
"item_type": "DISCUSSION",
"title": "Today's Plan",
"time_allocation_minutes": 5,
"sequence": "2"
},
{
"item_type": "DISCUSSION",
"title": "Blockers",
"time_allocation_minutes": 5,
"sequence": "3"
}
]
},
"next_steps": [
{ "next_step": { "$ref": "ns-summary" }, "sort_order": 1, "autopilot": true }
]
}
]
}
Key fields:
| Field | Purpose |
|---|---|
agenda_items | Structured agenda with types: DISCUSSION, ACTION_ITEM_RECAP, BREAK, ADJOURN |
next_steps | AI outputs that appear after the meeting |
workflow_ref | Optional automation workflow |
autopilot | When true, next step executes automatically on meeting completion |
Next Steps (AI Prompts)¶
Next steps generate content from meeting transcripts:
{
"next_steps": [
{
"spec": {
"$id": "ns-summary",
"name": "Meeting Summary",
"type": "ai",
"ai_prompt": "Create a concise summary including:\n\n**Key Discussion Points**\n- ...\n\n**Decisions Made**\n- ...\n\n**Action Items**\n| Owner | Task | Due Date |\n|-------|------|----------|",
"icon_name": "scroll-text",
"color": "#1E40AF"
},
"action_buttons": [
{ "action_button": { "$ref": "ab-email" }, "sort_order": 1 },
{ "action_button": { "$ref": "ab-copy" }, "sort_order": 2 }
]
}
]
}
Prompt writing tips:
- Be specific about output format (tables, bullet lists, sections)
- State what to include and what to exclude
- Use domain-specific terminology your users expect
- Keep prompts under 2,000 characters
Shortcuts¶
Shortcuts provide quick in-meeting actions:
{
"shortcuts": [
{
"spec": {
"$id": "sc-blocker",
"name": "🚧 Blocker",
"description": "Flag a blocker that needs attention",
"icon": "bolt",
"color": "#DC2626",
"prompt": "**🚧 BLOCKER**\n**Issue**: [describe the blocker]\n**Owner**: [who is blocked]\n**Needed**: [what would unblock this]",
"surfaces": [
{ "surface": "MEETING_RUN", "position": 1 }
]
}
}
]
}
Surface options: HOME, MEETING_PREPARE, MEETING_RUN, MEETING_REVIEW, CANVAS
Workflows¶
Workflows chain multiple steps with review gates:
{
"workflows": [
{
"spec": {
"$id": "wf-distribution",
"name": "Summary Distribution",
"description": "Generate summary, review, then distribute",
"spec": {
"schema_version": "1.0",
"entry": "generate",
"nodes": [
{
"id": "generate",
"type": "next_step",
"data": { "next_step_id": "$ref:ns-summary" }
},
{
"id": "review",
"type": "review",
"data": {
"assignee": { "ref": "specific_role", "role": "Reviewer" },
"notes": "Review the summary for accuracy."
}
},
{
"id": "distribute",
"type": "deliver",
"data": {
"destination_type": "email",
"input_from": "generate"
}
}
],
"edges": [
{ "id": "e1", "source": "generate", "target": "review", "type": "default" },
{ "id": "e2", "source": "review", "target": "distribute", "type": "approve" }
]
}
},
"default_role_mappings": {
"Reviewer": { "group": "meeting_owner" }
}
}
]
}
Node types: next_step, review, deliver, alert, create_canvas
Assignee Types¶
Review and alert nodes require an assignee or recipient. Two reference types are available:
| Type | Syntax | Use Case |
|---|---|---|
object_owner | { "ref": "object_owner" } | Always assigns to the meeting owner |
specific_role | { "ref": "specific_role", "role": "Chair" } | Assigns to a named role resolved at runtime |
Use object_owner for simple workflows. Use specific_role when you need distinct reviewers (e.g., Secretary → Chair → Distribute).
Default Role Mappings¶
When using specific_role, provide portable defaults via default_role_mappings at the workflow level:
{
"default_role_mappings": {
"Secretary": { "group": "meeting_editor" },
"Chair": {
"group": "meeting_owner",
"fallback": { "group": "workspace_owner" }
}
}
}
Available groups:
| Group | Description |
|---|---|
meeting_owner | User who owns the meeting |
meeting_editor | Meeting editors (includes owner) |
meeting_viewer | Meeting viewers (includes editors) |
workspace_owner | Workspace owner |
workspace_admin | Workspace admins (includes owner) |
workspace_participant | Meeting participants from the workspace |
workspace_any | Any workspace member |
workflow_initiator | User who started the run |
Fallback chains: If a group is empty (e.g., no workspace admins), the fallback property specifies the next target:
Optional roles: Set "optional": true to skip a role if it cannot be resolved instead of failing the workflow:
See Manifest Format Reference for complete documentation.
Testing Your Toolkit¶
1. Validate JSON Syntax¶
2. Test in a Development Workspace¶
For partner-administered toolkits:
// Create the toolkit
const toolkit = await sdk.admin.createToolkit(manifest);
// Install on a test workspace
await sdk.admin.installToolkit(toolkit.id, {
workspace_id: 'ws_test123'
});
For customer-administered toolkits:
- Go to Settings → Toolkits in a test workspace
- Click Import Toolkit
- Upload your JSON file
- Verify entities appear correctly
3. Run Through Meeting Lifecycle¶
- Create a meeting using your template
- Test all shortcuts during the meeting
- Complete the meeting and verify next steps execute
- Confirm action buttons deliver content correctly
- If using workflows, verify the full automation chain
Best Practices¶
Naming Conventions¶
| Element | Convention | Example |
|---|---|---|
$id | Prefix by type, lowercase with hyphens | ns-meeting-summary, ab-email-notes |
slug | Lowercase, hyphens, globally unique | acme-sales-discovery |
name | Title case, user-friendly | Sales Discovery Call |
Versioning Strategy¶
Use semantic versioning for your toolkit:
| Change Type | Version Bump | Example |
|---|---|---|
| New entities added | Minor | 1.0.0 → 1.1.0 |
| Prompt improvements | Patch | 1.1.0 → 1.1.1 |
| Breaking restructure | Major | 1.1.1 → 2.0.0 |
Customization-Friendly Design¶
If you expect customers to customize your toolkit:
- Use clear, descriptive
$idvalues - Add
usage_guidancefields explaining when to use each entity - Include comments in prompts (via markdown) explaining customization points
- Provide a customization guide alongside your toolkit
Production Examples¶
Study these complete, production-ready toolkits for inspiration:
| Toolkit | Entities | Use Case |
|---|---|---|
| Recruiting Interview Suite | 4 templates, 6 next steps, 8 shortcuts, 2 workflows | Hiring workflows |
| Agile Ceremonies Suite | 5 templates, 7 next steps, 10 shortcuts, 2 workflows | Scrum team meetings |
| Robert's Rules Collection | 3 editions with varying complexity | Parliamentary procedure |
Each example includes a downloadable JSON manifest and detailed documentation.
See Also¶
- Manifest Format Reference — Complete field documentation
- Reference Patterns — Advanced
$refand$idpatterns - Entity Lifecycle — Runtime usage via Partner API
- Ownership & Distribution — Governance and distribution strategies
- JSON Schema — Machine-readable schema