AI-Enabled Meeting Prep¶
This guide shows how to combine the Meeting Context API (v1.4.6) and the Chat Session API (v1.4.7) to build AI-powered meeting preparation workflows. Partners can upload background materials, let the AI build a fully customized meeting — complete with named templates, structured agendas, talking points, and participants — then inspect and refine the result.
Overview¶
The AI-Enabled Meeting Prep workflow has three phases:
- Upload Context — Provide the AI with background materials (research, briefs, prior notes)
- Build with the AI — The agent analyzes documents and constructs the agenda, talking points, and participant list directly on the meeting
- Review & Refine — Inspect the AI-built meeting via the API and make targeted adjustments using the entity APIs or further chat
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Upload Context │────▶│ Build with AI │────▶│ Review & Refine │
│ Documents │ │ Agent builds │ │ Inspect via API │
│ │ │ agenda, adds │ │ Adjust entities │
│ │ │ participants │ │ or chat further │
└──────────────────┘ └──────────────────┘ └──────────────────┘
POST /meetings/ POST /sessions GET /meetings/{id}/
{id}/context PUT /sessions/{id} agenda-items
GET /meetings/{id}/
participants
Prerequisites¶
- Partner app with OAuth scopes:
meetings:write,context:write,chat:write - A user who has authorized your app via OAuth
Phase 1: Upload Context Documents¶
The Meeting Context API accepts text-based documents that are automatically sanitized and converted to clean Markdown for the AI agent.
Supported Formats¶
| Format | Extensions | Notes |
|---|---|---|
| Plain Text | .txt | Direct pass-through |
| Markdown | .md | HTML embeds sanitized |
| CSV / TSV | .csv, .tsv | Rendered as Markdown tables (up to 1,000 rows) |
| JSON | .json | Structured → nested Markdown headings |
| YAML | .yaml, .yml | Structured → nested Markdown headings |
| XML | .xml | Tree → nested Markdown headings |
| HTML | .html, .htm | Tags stripped, content preserved |
Sanitization Pipeline¶
Every uploaded document passes through a multi-stage sanitization pipeline before the AI agent sees it:
- Format Validation — UTF-8 encoding verified, binary content rejected
- Format Conversion — Source format converted to canonical Markdown with YAML front matter
- PII Redaction — Credit card numbers, SSNs, and email addresses automatically redacted
- Secret Detection — API keys, tokens, and passwords are detected and redacted
- Formula Injection Escaping — Spreadsheet formula patterns (
=,+,-,@prefixes) escaped
Upload Limits¶
| Constraint | Value |
|---|---|
| Maximum file size | 4.5 MB |
| Maximum documents per meeting per partner | 20 |
| Content encoding | UTF-8 only |
Example: Upload a Research Brief¶
const contextDoc = await sdk.user.uploadMeetingContext(meetingId, {
file: researchBriefBuffer,
title: 'Q2 Market Research Summary',
context_type: 'research',
source_format: 'md'
});
// contextDoc.id → use this to prime the chat session
console.log(`Uploaded context: ${contextDoc.id}`);
Phase 2: Converse with the AI Agent¶
With context documents uploaded, create a chat session scoped to the same meeting. The agent has access to all context documents attached to that meeting. Context from prior meetings and other workspace features such as custom templates are also available to the agent.
Start a Meeting-Scoped Session¶
const session = await sdk.user.createChatSession({
meeting_id: meetingId,
message: `Use the "Quarterly Planning" template to build out a
90-minute meeting with the executive team. My talking points should
include insights and key findings from last week's staff meeting.`,
metadata: {
workflow: 'meeting-prep',
template_type: 'quarterly-planning'
}
});
Note: All context documents previously uploaded to this meeting are automatically included in the agent's context window. Simply provide the
meeting_idand the agent will reference all attached documents.
Refine with Follow-Up Messages¶
The agent builds the agenda, adds participants, applies a named template, and structures talking points directly on the meeting. Use follow-up messages to guide the agent's work:
// Ask the agent to adjust the time allocation and focus for a specific agenda item
await sdk.user.sendMessage(session.id, {
message: `For the "Market Expansion" agenda item, adjust
the time allocation to 30 minutes for the research brief discussion
to ensure alignment with our current priorities.`
});
// → Your webhook endpoint receives session.turn.completed when the agent finishes
// Ask the agent to add the right participants
await sdk.user.sendMessage(session.id, {
message: `Add the marketing and product leads as participants.
The budget discussion should also include Jim Gladney from Finance.`
});
// → Another session.turn.completed webhook fires when this turn is done
The agent operates directly on the meeting entity — creating and editing agenda items, adding participants, and updating descriptions.
Asynchronous by design. Both
createChatSessionandsendMessagereturn immediately — they do not block until the agent finishes. Your integration should listen for webhook callbacks to know when each turn is complete:
Event When it fires What to do session.turn.completedAgent finished processing a turn Safe to send follow-up messages or inspect updated meeting entities session.turn.failedAgent encountered an error Inspect error_code/error_messageand decide whether to retrysession.expiredSession timed out due to inactivity Start a new session if more interaction is needed See the Webhook Events reference and the AsyncAPI specification for full payload schemas.
Phase 3: Review & Refine¶
After the agent has built the meeting, use the entity APIs to inspect what was created and make targeted adjustments.
Inspect the AI-Built Agenda¶
// Review agenda items the agent created
const agendaItems = await sdk.user.listAgendaItems(meetingId);
for (const item of agendaItems.items) {
console.log(`[${item.item_type}] ${item.title} (${item.time_allocation_minutes}min)`);
console.log(` ${item.description}\n`);
}
// Review participants the agent added
const participants = await sdk.user.listParticipants(meetingId);
for (const p of participants.items) {
console.log(`${p.name} — ${p.role}`);
}
Refine via Entity APIs¶
Make surgical edits to individual items without re-running the full AI flow:
// Update an agenda item's time allocation
await sdk.user.updateAgendaItem(meetingId, agendaItemId, {
time_allocation_minutes: 25 // Give more time to this discussion
});
// Remove a participant the agent added incorrectly
await sdk.user.removeParticipant(meetingId, participantId);
// Add a missing agenda item manually
await sdk.user.createAgendaItem(meetingId, {
item_type: 'INFORMATION',
title: 'Logistics & Room Setup',
description: 'Conference Room B, video bridge link in calendar invite.',
time_allocation_minutes: 5
});
Refine via Further Chat¶
For larger changes, continue the chat session — the agent still has full context:
await sdk.user.sendMessage(session.id, {
message: `Move the budget discussion to the first agenda slot and
increase its time to 20 minutes. Also add a 5-minute wrap-up
item at the end for action item review.`
});
// → Wait for session.turn.completed webhook before inspecting updated entities
Agenda Item Types¶
The agent uses these item types when building the agenda:
| Type | Purpose | Best For |
|---|---|---|
DISCUSSION | Open-ended conversation topics | Strategy reviews, brainstorming |
DECISION | Items requiring a concrete decision | Budget approvals, go/no-go |
ACTION_ITEM | Tasks to assign and track | Follow-ups, deliverables |
INFORMATION | Read-out or status updates | Metrics reviews, announcements |
Complete Meeting Prep Example¶
import { ContioPartnerSDK } from '@contio/partner-sdk';
async function prepareQuarterlyPlanning(userToken: string) {
const sdk = ContioPartnerSDK.forUser({
clientId: process.env.OAUTH_CLIENT_ID!,
clientSecret: process.env.OAUTH_CLIENT_SECRET!,
accessToken: userToken
});
// 1. Create a draft meeting to attach context to
const meeting = await sdk.user.createMeeting({
title: 'Q2 Quarterly Planning',
start_time: '2026-04-01T14:00:00Z',
end_time: '2026-04-01T15:00:00Z',
template_id: QUARTERLY_TEMPLATE_ID,
detail_level: 'STANDARD'
});
// 2. Upload context documents
const research = await sdk.user.uploadMeetingContext(meeting.id, {
file: fs.readFileSync('./q2-research.md'),
title: 'Q2 Market Research',
source_format: 'md'
});
const retro = await sdk.user.uploadMeetingContext(meeting.id, {
file: fs.readFileSync('./q1-retro.csv'),
title: 'Q1 Retrospective Scores',
source_format: 'csv'
});
// 3. Start a chat session — agent auto-loads all context for this meeting
const session = await sdk.user.createChatSession({
meeting_id: meeting.id,
message: `Build a structured 60-minute quarterly planning agenda
based on the pre-loaded context. Include specific talking points,
time allocations, and add the relevant participants.`,
metadata: { workflow: 'meeting-prep', template: 'quarterly-planning' }
});
// 4. The agent processes asynchronously — your webhook endpoint
// receives `session.turn.completed` when the first turn finishes.
// 5. On receiving the webhook, send a follow-up to refine:
await sdk.user.sendMessage(session.id, {
message: `Add talking points about competitive positioning
for the Market Expansion item, using data from the research brief.
Also add our finance director as a participant for the budget item.`
});
// → Another session.turn.completed webhook fires when this turn completes.
// 6. Once the webhook confirms completion, review and adjust
const agenda = await sdk.user.listAgendaItems(meeting.id);
const participants = await sdk.user.listParticipants(meeting.id);
console.log(`Meeting ${meeting.id} prepared:`);
console.log(` ${agenda.items.length} agenda items`);
console.log(` ${participants.items.length} participants`);
// 7. Optional: make surgical edits via entity APIs
// await sdk.user.updateAgendaItem(meeting.id, itemId, { time_allocation_minutes: 25 });
}
Tips and Best Practices¶
- Upload multiple document types. CSV data and narrative Markdown complement each other — the AI can cross-reference quantitative data with qualitative insights.
- Be specific in your prompts. Instead of "suggest an agenda," ask for "a 60-minute agenda with 4 items, time allocations, and talking points backed by the uploaded data."
- Use metadata for tracking. The
metadatafield on sessions lets you tag workflows (e.g.,workflow: 'meeting-prep') so you can audit which sessions produced which meetings. - Leverage templates. Bind meetings to known templates by name or via
template_idso the AI's suggestions align with your organization's standard meeting structures. - Use webhooks, not polling. Agent turns are asynchronous. Register a webhook endpoint and listen for
session.turn.completedevents rather than polling. This keeps your integration event-driven and responsive. See the Webhook Events reference for all chat session event schemas. - Review before sharing. Always inspect the AI-built agenda and participant list via the entity APIs before distributing the meeting invite. The agent does the heavy lifting, but a human review pass ensures quality.
Related Guides¶
- SDK Examples — Full SDK reference with authentication patterns
- API Guide — REST endpoint reference and pagination
- Webhook Events — Subscribe to meeting and action item events