FS-DOC-05Technical
Integration and API Spec
Meeting and Decision Documentation
[YourCompany.com] · Operations Department · Prepared by FullSpec · [Today's Date]
This document is the authoritative technical reference for every integration used in the Meeting and Decision Documentation automation. It covers authentication requirements, exact API scopes, webhook configuration, field mappings between tools, the orchestration layout, and defined failure behaviours for every integration point. The FullSpec team uses this spec as the primary build reference. [YourCompany.com] engineering or IT contacts may use it for security review and access provisioning. Nothing in this document should be acted on against production systems until sandbox validation is complete.
01Tool inventory
Tool
Role in automation
Auth method
Min plan required
Used by agents
Orchestration layer
Hosts all workflow logic, credential store, and inter-agent handoffs
Internal (platform credentials)
N/A (platform choice)
All agents
Zoom
Meeting recording source and session end trigger
OAuth 2.0 (Server-to-Server)
Pro or above (Cloud Recording required)
Agent 1 (Transcription)
Notion
Meeting summary archive and page creation target
OAuth 2.0 / Internal Integration Token
Plus or above (API access)
Agent 2 (Summary and Action Extraction)
ClickUp
Action item task creation destination
Personal API token or OAuth 2.0
Unlimited or above (API access)
Agent 2 (Summary and Action Extraction)
Google Calendar
Attendee list retrieval for distribution
OAuth 2.0 (service account or delegated)
Google Workspace (any tier)
Agent 3 (Distribution)
Gmail
Sending formatted follow-up emails to attendees
OAuth 2.0 (delegated user access)
Google Workspace (any tier)
Agent 3 (Distribution)
Slack
Team channel notification with condensed summary
OAuth 2.0 (Bot token, Slack app)
Free or above
Agent 3 (Distribution)
Before you connect anything: all integrations must be configured and validated in a sandbox or development environment using non-production credentials before any production API keys, tokens, or OAuth grants are introduced. This applies to every tool in the table above without exception. Sandbox Zoom recordings, a test Notion workspace, a ClickUp test space, a non-primary Gmail account, and a private Slack channel should be provisioned before build begins.
02Per-tool integration detail
Zoom
Provides the session end event trigger and the cloud recording file for transcription. Requires Server-to-Server OAuth for unattended access to recording assets without a user present.
Auth method
Server-to-Server OAuth 2.0. Create a Server-to-Server OAuth app in the Zoom Marketplace under the owning account. Store Client ID, Client Secret, and Account ID in the credential store. Access tokens expire every 60 minutes and must be refreshed automatically by the orchestration layer.
Required scopes
recording:read:admin, recording:write:admin, meeting:read:admin, webhook:read:admin, webhook:write:admin
Webhook / trigger setup
Register a webhook endpoint in the Zoom app settings under Event Subscriptions. Subscribe to the event type recording.completed. Zoom sends a POST to the configured endpoint with recording metadata. Validate every inbound request using the Zoom webhook secret token (stored in credential store as ZOOM_WEBHOOK_SECRET_TOKEN): compute HMAC-SHA256 over the raw request body using the secret and compare against the x-zm-signature header. Reject any request where the signature does not match or where the timestamp in x-zm-request-timestamp is older than 300 seconds.
Required configuration
Cloud Recording must be enabled on the Zoom account. Auto-record to cloud must be on for all target meeting types (or enabled per meeting via the Zoom settings portal). The ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET, and ZOOM_WEBHOOK_SECRET_TOKEN must be stored in the credential store, not hardcoded. The download URL from the webhook payload is short-lived (typically valid for 24 hours); the orchestration layer must fetch the recording file immediately on receipt of the event.
Rate limits
Zoom API enforces a rate limit of 30 requests per second per account for most endpoints and a daily cap of 5,000 requests for recording retrieval endpoints. At 20 meetings per month (roughly 1 per business day), current volume is well within limits. No throttling logic is required at this volume, but exponential backoff must still be implemented for transient 429 responses.
Constraints
Cloud Recording is not available on the Zoom Basic (free) plan. Recordings are only accessible via API for accounts where the host has enabled cloud recording. Recordings for meetings longer than 90 minutes may produce files exceeding 500 MB; the orchestration layer must support chunked or streaming download. Deleted recordings cannot be retrieved.
// Trigger payload (key fields from recording.completed webhook)
event: 'recording.completed'
payload.object.uuid // Zoom meeting UUID
payload.object.topic // Meeting title
payload.object.start_time // ISO 8601 datetime
payload.object.duration // Minutes
payload.object.host_id // Zoom user ID of host
payload.object.recording_files[].download_url // Audio/video download URL
payload.object.recording_files[].file_type // 'MP4' | 'M4A' | 'TRANSCRIPT'
// Output passed to Agent 1
zoom_meeting_uuid, meeting_title, start_time, duration, download_url
Notion
Receives the structured meeting summary and creates a new page in the designated Meetings database. Page properties and body content are populated by the automation using the template structure defined during setup.
Auth method
Notion Internal Integration Token (preferred for single-workspace deployments). Create a new integration at notion.so/my-integrations, give it the name 'FullSpec Meeting Bot', and share the target database with it. Store the token as NOTION_API_SECRET in the credential store. If multi-workspace support is needed, use OAuth 2.0 with the public integration flow instead.
Required scopes
For internal integration tokens, scopes are set at integration level: Read content, Update content, Insert content. For OAuth 2.0 public integrations: read_content, update_content, insert_content.
Webhook / trigger setup
Notion does not natively emit webhooks. This integration is purely outbound (write). The orchestration layer calls the Notion API on completion of the summary agent step. No inbound webhook is needed.
Required configuration
The Meetings database ID must be stored in the credential store as NOTION_MEETINGS_DATABASE_ID (not hardcoded). The database schema must include the following properties: Name (title), Meeting Date (date), Attendees (multi-select or relation), Project (select), Summary (rich text), Action Items (rich text), and Zoom Meeting ID (text). A Notion page template ID (NOTION_PAGE_TEMPLATE_ID) should be stored if a template is used for consistent formatting. All database IDs and template IDs are stored in the credential store.
Rate limits
Notion API enforces an average rate limit of 3 requests per second. Each meeting triggers approximately 2 to 3 API calls (create page, add blocks, optionally set properties). At 20 meetings per month, peak load is negligible. No throttling is required; implement retry with exponential backoff on 429 responses.
Constraints
The integration must be explicitly shared with each database it writes to; sharing the workspace root is not sufficient. Rich text blocks have a maximum length of 2,000 characters per block; long summaries must be split across multiple paragraph blocks. API access requires Notion Plus or above for team workspaces.
// Input from Summary Agent
meeting_title, meeting_date, attendees[], summary_text, action_items[], zoom_meeting_uuid
// API call: POST /v1/pages
parent.database_id: NOTION_MEETINGS_DATABASE_ID
properties.Name.title[].text.content: meeting_title
properties['Meeting Date'].date.start: meeting_date
properties.Attendees.multi_select[]: attendees[]
properties['Zoom Meeting ID'].rich_text[].text.content: zoom_meeting_uuid
children[]: formatted summary and action item blocks
// Output
notion_page_id // Stored and passed to Distribution Agent as reference URL
ClickUp
Receives the list of extracted action items and creates one task per item in the designated ClickUp list. Assignees and due dates are pre-populated from the agent output where determinable.
Auth method
ClickUp Personal API Token for single-user service accounts, or OAuth 2.0 for delegated access. Store as CLICKUP_API_TOKEN in the credential store. OAuth 2.0 is preferred for team workspaces to avoid dependency on a single user account.
Required scopes
OAuth 2.0 scopes: task:write, task:read, team:read, space:read, list:read. Personal token grants full account access by default; scope is controlled by token ownership.
Webhook / trigger setup
ClickUp is a write target only in this automation. No inbound webhook is required. The orchestration layer calls the ClickUp API once per action item after the summary agent completes.
Required configuration
The target ClickUp List ID must be stored as CLICKUP_LIST_ID in the credential store. The ClickUp Team ID must be stored as CLICKUP_TEAM_ID. Assignee resolution requires a lookup map from attendee name or email to ClickUp User ID; this map must be configured as a credential store key CLICKUP_ASSIGNEE_MAP (JSON object: { email: clickup_user_id }). Priority defaults to normal unless the action item text contains urgency keywords defined in the workflow config. Due dates are set from the agent output; if the agent cannot determine a due date, the task is created with no due date and flagged for manual review.
Rate limits
ClickUp enforces 100 API requests per minute per token. A meeting with 10 action items triggers 10 task creation calls. At 20 meetings per month with an average of 5 to 8 action items each, the peak burst is well under the limit. No throttling needed; implement retry with backoff on 429.
Constraints
Task assignees must be existing ClickUp workspace members; the automation cannot invite new members. If an assignee email is not found in the CLICKUP_ASSIGNEE_MAP, the task is created unassigned and a Slack alert is sent. API access requires the Unlimited plan or above.
// Input from Summary Agent (one call per action item)
action_item_text, proposed_assignee_email, proposed_due_date, meeting_title, notion_page_url
// API call: POST /v2/list/{CLICKUP_LIST_ID}/task
name: action_item_text
assignees[]: [resolved_clickup_user_id]
due_date: proposed_due_date (Unix ms) or null
description: 'From meeting: ' + meeting_title + ' — ' + notion_page_url
priority: 3 (normal default)
// Output
clickup_task_id, clickup_task_url // Appended to Notion page and included in emailIntegration and API SpecPage 1 of 3
FS-DOC-05Technical
Google Calendar
Read-only source for the attendee list associated with the Zoom meeting. The orchestration layer matches the Zoom meeting to a Calendar event by time range and host email, then extracts the list of attendee email addresses for use by Gmail.
Auth method
OAuth 2.0. Use a service account with domain-wide delegation enabled, or a delegated user OAuth grant for the Operations Manager account. Store the service account JSON key file reference or the OAuth refresh token as GOOGLE_CALENDAR_CREDENTIALS in the credential store.
Required scopes
https://www.googleapis.com/auth/calendar.readonly
Webhook / trigger setup
Google Calendar is read-only in this flow. No webhook is registered. The orchestration layer queries the Calendar Events API using the meeting start time window (plus or minus 5 minutes) and the host email to locate the matching event and retrieve attendees.
Required configuration
The Operations Manager calendar ID (typically their Google Workspace email address) must be stored as GOOGLE_CALENDAR_ID in the credential store. If meetings are hosted under multiple calendars, a list of calendar IDs must be stored. The service account must be granted read access to the relevant calendars via Google Workspace Admin or explicit sharing. No calendar IDs or email addresses are hardcoded in workflow logic.
Rate limits
Google Calendar API enforces a quota of 1,000,000 queries per day and 500 requests per 100 seconds per project. At 20 meetings per month, current volume is negligible. No throttling required. Implement retry with exponential backoff on 429 and 503 responses.
Constraints
Attendees who declined the Calendar invite are still returned in the attendee list; the workflow should filter to status accepted and tentative only, unless configured otherwise. External attendees without Google accounts appear as plain email addresses without profile data. Matching Zoom meetings to Calendar events by time is imprecise if meetings are rescheduled or start late; the matching window must be configurable (default: plus or minus 10 minutes of the Zoom session start time stored in CALENDAR_MATCH_WINDOW_MINUTES).
// Query: GET /calendar/v3/calendars/{GOOGLE_CALENDAR_ID}/events
timeMin: zoom_start_time - CALENDAR_MATCH_WINDOW_MINUTES
timeMax: zoom_start_time + CALENDAR_MATCH_WINDOW_MINUTES
// Output: list of attendee email addresses
attendees[].email // Passed to Gmail send stepGmail
Sends the formatted follow-up email containing the meeting summary and action item list to all resolved attendee addresses. Uses a stored HTML template with defined placeholder variables.
Auth method
OAuth 2.0 delegated access on behalf of the Operations Manager Gmail account. Store the OAuth refresh token as GMAIL_OAUTH_REFRESH_TOKEN in the credential store, along with GMAIL_CLIENT_ID and GMAIL_CLIENT_SECRET. Access tokens are short-lived and refreshed automatically by the orchestration layer.
Required scopes
https://www.googleapis.com/auth/gmail.send
Webhook / trigger setup
Gmail is an outbound send target only. No webhook or polling is needed. The orchestration layer calls the Gmail API once per meeting after Notion page creation and ClickUp task creation are confirmed.
Required configuration
An HTML email template must be configured and stored with the following placeholders: {{meeting_title}}, {{meeting_date}}, {{summary_text}}, {{action_items_html}}, {{notion_page_url}}. The template ID or raw HTML string is stored as GMAIL_EMAIL_TEMPLATE in the credential store. The sender display name is stored as GMAIL_SENDER_NAME. The reply-to address is stored as GMAIL_REPLY_TO. No recipient addresses are hardcoded; all addresses come from the Google Calendar attendee resolution step.
Rate limits
Gmail API enforces a quota of 250 quota units per user per second. Sending a single email costs 100 units. At 20 emails per month with up to 10 recipients each, current volume is far below any limit. No throttling required.
Constraints
The sending account must have Gmail API enabled in Google Cloud Console and the OAuth consent screen must be configured. If the meeting has more than 50 attendees, BCC must be used instead of individual TO addresses to avoid Gmail sending limits. Attachments are not sent; the Notion page URL is included as a hyperlink in the email body.
// API call: POST /gmail/v1/users/me/messages/send
to: attendees[].email (joined as comma-separated string)
subject: 'Meeting Notes: ' + meeting_title + ' — ' + meeting_date
body (HTML): GMAIL_EMAIL_TEMPLATE with placeholders resolved
// Placeholders resolved at send time:
{{meeting_title}}, {{meeting_date}}, {{summary_text}},
{{action_items_html}}, {{notion_page_url}}
// Output
gmail_message_id // Logged to run record for auditSlack
Posts a condensed version of the meeting summary and action items to the designated team Slack channel. Uses a Slack app bot token scoped to message posting only.
Auth method
OAuth 2.0 Slack app with Bot Token. Create a Slack app in the Slack API portal (api.slack.com/apps), install it to the workspace, and store the Bot User OAuth Token as SLACK_BOT_TOKEN in the credential store.
Required scopes
chat:write, chat:write.public (if posting to public channels the bot is not a member of)
Webhook / trigger setup
Outbound only. The orchestration layer calls chat.postMessage after the Gmail send step confirms success. Alternatively, an incoming webhook URL can be used as a simpler configuration; store the URL as SLACK_WEBHOOK_URL in the credential store if using incoming webhooks instead of the full bot token approach. The bot token approach is preferred for flexibility.
Required configuration
The target Slack channel ID must be stored as SLACK_CHANNEL_ID in the credential store (use the channel ID, not the display name, as display names can change). If different meeting types route to different channels, a routing map must be stored as SLACK_CHANNEL_ROUTING_MAP (JSON object: { meeting_type: channel_id }). The condensed message format uses Slack Block Kit; the block template is stored as SLACK_MESSAGE_TEMPLATE in the credential store. No channel names or IDs are hardcoded.
Rate limits
Slack API rate limits chat.postMessage to approximately 1 message per second per channel (Tier 3). At 20 meetings per month, no throttling is needed. Implement retry with backoff on 429 responses.
Constraints
The bot must be invited to private channels before it can post. Slack message text is capped at 40,000 characters; the condensed summary must be kept well below this. Block Kit blocks have a maximum of 50 blocks per message; structured summaries must be flattened or truncated if they exceed this limit. A link to the full Notion page must always be included in the Slack post.
// API call: POST https://slack.com/api/chat.postMessage
channel: SLACK_CHANNEL_ID (or resolved from SLACK_CHANNEL_ROUTING_MAP)
blocks: SLACK_MESSAGE_TEMPLATE with values:
meeting_title, meeting_date, condensed_summary (max 500 chars),
action_items_brief[], notion_page_url
// Output
slack_ts // Thread timestamp, logged to run record
03Field mappings between tools
The tables below document every field handoff between tools at each agent boundary. Field names are shown in exact monospace format as they appear in API payloads and credential store references.
Handoff 1: Zoom to Transcription Agent (Agent 1 input)
Source tool
Source field
Destination tool
Destination field
Zoom webhook
`payload.object.uuid`
Orchestration layer
`zoom_meeting_uuid`
Zoom webhook
`payload.object.topic`
Orchestration layer
`meeting_title`
Zoom webhook
`payload.object.start_time`
Orchestration layer
`meeting_start_time`
Zoom webhook
`payload.object.duration`
Orchestration layer
`meeting_duration_minutes`
Zoom webhook
`payload.object.host_id`
Orchestration layer
`zoom_host_id`
Zoom webhook
`payload.object.recording_files[].download_url`
Agent 1
`recording_download_url`
Zoom webhook
`payload.object.recording_files[].file_type`
Agent 1
`recording_file_type`
Handoff 2: Transcription Agent to Summary and Action Extraction Agent (Agent 2 input)
Source tool
Source field
Destination tool
Destination field
Agent 1 output
`transcript_text`
Agent 2
`transcript_text`
Agent 1 output
`transcript_segments[].speaker`
Agent 2
`speaker_labels[]`
Agent 1 output
`transcript_segments[].timestamp`
Agent 2
`timestamps[]`
Orchestration layer
`meeting_title`
Agent 2
`meeting_title`
Orchestration layer
`meeting_start_time`
Agent 2
`meeting_date`
Orchestration layer
`zoom_meeting_uuid`
Agent 2
`zoom_meeting_uuid`
Handoff 3: Summary Agent to Notion (Agent 2 output to write target)
Source tool
Source field
Destination tool
Destination field
Agent 2 output
`meeting_title`
Notion API
`properties.Name.title[0].text.content`
Agent 2 output
`meeting_date`
Notion API
`properties['Meeting Date'].date.start`
Agent 2 output
`attendees[]`
Notion API
`properties.Attendees.multi_select[]`
Agent 2 output
`summary_text`
Notion API
`children[].paragraph.rich_text[0].text.content`
Agent 2 output
`decisions[]`
Notion API
`children[].bulleted_list_item.rich_text[0].text.content`
Agent 2 output
`action_items[].text`
Notion API
`children[].to_do.rich_text[0].text.content`
Orchestration layer
`zoom_meeting_uuid`
Notion API
`properties['Zoom Meeting ID'].rich_text[0].text.content`
Handoff 4: Summary Agent to ClickUp (one call per action item)
Source tool
Source field
Destination tool
Destination field
Agent 2 output
`action_items[].text`
ClickUp API
`name`
Agent 2 output
`action_items[].proposed_assignee_email`
ClickUp API
`assignees[0]` (resolved via `CLICKUP_ASSIGNEE_MAP`)
Agent 2 output
`action_items[].proposed_due_date`
ClickUp API
`due_date` (Unix ms)
Notion API response
`notion_page_url`
ClickUp API
`description` (appended as reference link)
Orchestration layer
`meeting_title`
ClickUp API
`description` (prefix)
Handoff 5: Google Calendar to Gmail (attendee resolution)
Source tool
Source field
Destination tool
Destination field
Google Calendar API
`items[0].attendees[].email`
Gmail API
`to` (comma-separated)
Google Calendar API
`items[0].summary`
Gmail API
`subject` (confirmation of meeting title match)
Agent 2 output
`summary_text`
Gmail API
`body` (via `GMAIL_EMAIL_TEMPLATE` placeholder `{{summary_text}}`)
Agent 2 output
`action_items_html`
Gmail API
`body` (via `GMAIL_EMAIL_TEMPLATE` placeholder `{{action_items_html}}`)
Notion API response
`notion_page_url`
Gmail API
`body` (via `GMAIL_EMAIL_TEMPLATE` placeholder `{{notion_page_url}}`)
Handoff 6: Distribution Agent to Slack (condensed post)
Source tool
Source field
Destination tool
Destination field
Orchestration layer
`meeting_title`
Slack API
`blocks[].text.text` (header section)
Orchestration layer
`meeting_date`
Slack API
`blocks[].text.text` (context section)
Agent 2 output
`condensed_summary`
Slack API
`blocks[].text.text` (body section, max 500 chars)
Agent 2 output
`action_items_brief[]`
Slack API
`blocks[].elements[].text` (bullet list)
Notion API response
`notion_page_url`
Slack API
`blocks[].elements[].url` (button or link)
Integration and API SpecPage 2 of 3
FS-DOC-05Technical
04Build stack and orchestration
Orchestration layout
Three discrete workflows, one per agent: Workflow 1 (Transcription Agent), Workflow 2 (Summary and Action Extraction Agent), Workflow 3 (Distribution Agent). Each workflow is self-contained with its own error handling. Inter-workflow handoffs are made via a shared internal data store or queue mechanism native to the automation platform. All credentials are sourced from a single shared credential store; no secrets appear in workflow logic nodes.
Workflow 1 trigger
Webhook (inbound POST from Zoom on recording.completed event). Signature validation against ZOOM_WEBHOOK_SECRET_TOKEN is performed as the first node before any further processing. Invalid or expired requests are dropped and logged.
Workflow 2 trigger
Internal event emitted by Workflow 1 on successful transcript completion. Implemented as a queue message or platform-native continuation trigger. Workflow 2 does not poll externally.
Workflow 3 trigger
Internal event emitted by Workflow 2 on successful Notion page creation and ClickUp task creation confirmation. Workflow 3 requires both upstream steps to succeed before proceeding. If either fails, Workflow 3 does not start and an alert is raised.
Human review gate
An optional approval pause is inserted between Workflow 2 completion and Workflow 3 start in the Standard build. The Operations Manager receives a Slack notification with a preview link and approve/reject action. Approval must be received within 30 minutes (configurable as REVIEW_TIMEOUT_MINUTES); if no response is received, the workflow proceeds automatically unless AUTO_SEND_ON_TIMEOUT is set to false in the credential store.
Credential store
All secrets and configuration values are stored in the automation platform's native encrypted credential/secret store. See the code block below for the full list of required keys.
Execution environment
All workflows run server-side within the automation platform. No local agent or self-hosted runner is required unless the platform is deployed on-premises. Cloud-hosted deployment is the default.
Logging and monitoring
Each workflow execution writes a structured run log including: zoom_meeting_uuid, workflow_start_time, workflow_end_time, status (success/failed/partial), error_message (if any), and output artifact references (notion_page_id, clickup_task_ids[], gmail_message_id, slack_ts). Logs are retained for 90 days.
Credential store: complete list of required keys (platform secret store, not source code)
// Credential store — all keys required before first production run
// Zoom
ZOOM_ACCOUNT_ID // Server-to-Server OAuth account ID
ZOOM_CLIENT_ID // Server-to-Server OAuth client ID
ZOOM_CLIENT_SECRET // Server-to-Server OAuth client secret
ZOOM_WEBHOOK_SECRET_TOKEN // HMAC-SHA256 signature validation token
// Notion
NOTION_API_SECRET // Internal integration token (secret_...)
NOTION_MEETINGS_DATABASE_ID // Target database ID (32-char hex)
NOTION_PAGE_TEMPLATE_ID // Optional: template page ID for formatting
// ClickUp
CLICKUP_API_TOKEN // Personal or OAuth token
CLICKUP_TEAM_ID // Workspace/team numeric ID
CLICKUP_LIST_ID // Target list numeric ID
CLICKUP_ASSIGNEE_MAP // JSON: { 'email@domain.com': clickup_user_id }
// Google (Calendar + Gmail — shared OAuth credentials)
GOOGLE_OAUTH_CLIENT_ID // OAuth 2.0 client ID
GOOGLE_OAUTH_CLIENT_SECRET // OAuth 2.0 client secret
GOOGLE_OAUTH_REFRESH_TOKEN // Delegated user refresh token
GOOGLE_CALENDAR_ID // Calendar ID (usually user email address)
CALENDAR_MATCH_WINDOW_MINUTES // Int: window to match Zoom to Calendar event (default: 10)
// Gmail
GMAIL_EMAIL_TEMPLATE // HTML string with placeholders
GMAIL_SENDER_NAME // Display name for From field
GMAIL_REPLY_TO // Reply-to address
// Slack
SLACK_BOT_TOKEN // Bot User OAuth Token (xoxb-...)
SLACK_CHANNEL_ID // Default target channel ID
SLACK_CHANNEL_ROUTING_MAP // JSON: { 'meeting_type': 'channel_id' } (optional)
SLACK_MESSAGE_TEMPLATE // Block Kit JSON template string
// Workflow config
REVIEW_TIMEOUT_MINUTES // Int: approval wait before auto-proceed (default: 30)
AUTO_SEND_ON_TIMEOUT // Bool: true = send after timeout, false = halt and alert05Error handling and retry logic
Unhandled exceptions must never fail silently. Every integration point has a defined failure behaviour. If a step cannot complete after exhausting its retry policy, it must log the failure with full context, alert the Operations Manager via Slack (using a fallback direct message if the bot token is available), and halt the current workflow execution cleanly without partial data corruption.
Integration
Scenario
Required behaviour
Zoom webhook
Inbound request fails HMAC-SHA256 signature validation
Reject immediately with HTTP 401. Log the raw headers and body hash. Do not process. Send no retry. Alert FullSpec monitoring.
Zoom webhook
Request timestamp older than 300 seconds (replay attack window)
Reject with HTTP 400. Log timestamp delta. Do not process or retry.
Zoom API
Recording download URL returns 403 or 404 (deleted or expired link)
Retry once after 60 seconds (URLs may be briefly unavailable post-meeting). On second failure, halt Workflow 1, log error with zoom_meeting_uuid, and send Slack DM to Operations Manager: 'Recording unavailable for [meeting_title]. Manual retrieval required.'
Zoom API
Recording download fails mid-stream (network interruption)
Retry up to 3 times with exponential backoff (60s, 120s, 240s). On third failure, log and alert as above. Do not attempt partial transcription.
Transcription step
Transcript output is empty or below minimum length threshold (configurable, default 50 words)
Do not pass empty transcript to Agent 2. Log the zoom_meeting_uuid and meeting_title. Alert Operations Manager: 'Transcription produced no usable output for [meeting_title]. Review recording quality.' Halt workflow.
Notion API
Page creation returns 4xx (e.g. invalid database ID, integration not shared with database)
Retry once after 30 seconds. On second failure, log full API error response and halt Workflow 2. Do not proceed to ClickUp or Distribution. Alert Operations Manager. Manual fallback: FullSpec provides a formatted summary in the Slack alert for copy-paste.
Notion API
Rate limit 429 response
Back off for the duration specified in the Retry-After header (or 10 seconds if header absent). Retry up to 5 times. Log each retry. If all retries exhausted, halt and alert.
ClickUp API
Assignee email not found in CLICKUP_ASSIGNEE_MAP
Create the task with no assignee. Append a note to the task description: 'Assignee could not be resolved automatically. Please assign manually.' Post a Slack message to SLACK_CHANNEL_ID listing the unassigned task. Do not halt the workflow.
ClickUp API
Task creation returns 5xx (server error)
Retry up to 3 times with exponential backoff (30s, 60s, 120s). If all retries fail, log the action_item_text and meeting reference, alert Operations Manager, and continue to the next action item. Do not halt Distribution Agent for a ClickUp failure.
Google Calendar API
No matching event found for the Zoom meeting time window
Log the zoom_meeting_uuid and meeting_start_time. Proceed to Gmail send step using attendee list sourced from Zoom host email only (single recipient fallback). Append a note to the Notion page: 'Calendar event not matched. Attendee list may be incomplete.'
Gmail API
Send fails with 4xx (invalid recipient address or quota exceeded)
For invalid address errors: remove the offending address, log it, and retry send to remaining recipients. For quota errors: queue and retry after 60 seconds. On persistent failure after 3 retries, log all unsent addresses and alert Operations Manager with the full email body as a Slack DM fallback.
Slack API
chat.postMessage returns 4xx or 5xx (channel not found, bot not in channel, token invalid)
Retry up to 2 times after 15 seconds. On failure, log the slack_channel_id and error code. Do not halt the workflow; Slack notification is non-critical. Write the failure to the run log. If SLACK_BOT_TOKEN itself is invalid, suppress further Slack calls and alert via email to support@gofullspec.com.
Any integration
Unhandled exception or unexpected error not matching defined scenarios above
Catch at workflow level. Log full exception detail including stack trace, step name, input payload, and zoom_meeting_uuid. Halt the current workflow. Send alert to Operations Manager via Slack DM and email. Contact support@gofullspec.com if the error persists across multiple runs.
Integration and API SpecPage 3 of 3