FS-DOC-05Technical
Integration and API Spec
Compliance Deadline Tracking
[YourCompany.com] · Legal Department · Prepared by FullSpec · [Today's Date]
This document is the authoritative integration reference for the Compliance Deadline Tracking automation. It covers every tool connected to the orchestration layer, the exact OAuth scopes and webhook configurations required, field-level mappings between tools at each agent handoff, credential store layout, and the defined error handling and retry behaviour for every integration point. This document is written for the FullSpec build team and is intended to be read alongside the Developer Handover Pack (FS-DOC-04). All credentials must be stored in the shared credential store and never hardcoded in workflow logic.
01Tool inventory
Tool
Role in automation
Auth method
Min plan required
Used by agents
Orchestration layer
Hosts all workflow logic, polls triggers, routes data between tools, manages credentials
N/A (self-hosted or SaaS tier)
Paid tier with webhook support and credential store
All agents
Google Sheets
Central compliance register: read/write for deadline records, status updates, and reminder date columns
OAuth 2.0 (Google identity)
Google Workspace (any paid tier) or free Google account with Sheets API enabled
Agent 1, Agent 2, Agent 3
Gmail
Sends tiered reminder emails, escalation follow-ups, and the Monday weekly digest
OAuth 2.0 (Google identity)
Google Workspace (any paid tier) or free Google account with Gmail API enabled
Agent 1, Agent 2, Agent 3
Google Calendar
Creates deadline events assigned to responsible owners with links back to register rows
OAuth 2.0 (Google identity)
Google Workspace (any paid tier) or free Google account with Calendar API enabled
Agent 1
Slack
Sends escalation direct messages to obligation owners and posts to the compliance manager channel
OAuth 2.0 (Slack Bot Token, xoxb)
Slack Pro or higher (DM to non-admin users requires Pro+)
Agent 2
Notion
Evidence and audit log storage: creates timestamped log entries per completed obligation
Notion Internal Integration Token
Notion Plus or Team (for API access and shared workspace)
Agent 3
Before you connect anything: all six integration connections must be tested against sandbox or development instances before any production credential is introduced. For Google services, use a dedicated service account or a test Google Workspace user. For Slack, create a test workspace. For Notion, duplicate the evidence database into a sandbox workspace. Production credentials are added only after successful end-to-end tests in the staging environment.
02Per-tool integration detail
Google Sheets
The compliance register lives in a single Google Sheets workbook. The Deadline Monitor Agent reads and writes deadline records. The Escalation Agent writes status updates to the Escalation_Status column. The Completion and Reporting Agent marks rows Complete and reads open items for the weekly digest.
Auth method
OAuth 2.0 via Google identity platform. A dedicated service account (JSON key) is preferred for server-side access. The service account must be granted Editor access to the register workbook.
Required scopes
https://www.googleapis.com/auth/spreadsheets (read and write all sheets in connected workbooks). Do not use the broader Drive scope.
Webhook/trigger setup
Google Sheets does not support native webhooks. The orchestration layer must poll the register on a scheduled basis: every 15 minutes for new row detection (Deadline Monitor Agent) and every 60 minutes for acknowledgement status checks (Escalation Agent). Use the Sheets API v4 endpoint GET /v4/spreadsheets/{spreadsheetId}/values/{range} for polls.
Required configuration
Workbook ID stored in credential store as SHEETS_REGISTER_ID. Named ranges must be configured: ComplianceRegister (full data range), HeaderRow (row 1 column definitions). Sheet tab must be named 'Register'. Column structure must match the agreed schema before the build begins.
Rate limits
Google Sheets API: 300 requests per minute per project, 60 requests per minute per user. At current volume (30 to 60 items per month, polling every 15 minutes), peak usage is well under 10 requests per minute. No throttling required at this volume. Implement exponential backoff on 429 responses regardless.
Constraints
Rows must never be deleted by the automation: status changes only. Blank rows in the register will cause polling logic to terminate early; the register must have no gaps between data rows. Column order must not be changed after the automation is deployed without updating the field mapping configuration.
Gmail
Gmail is used by all three agents to send reminder emails (Agent 1), escalation follow-up emails (Agent 2), and the Monday weekly digest (Agent 3). All outbound email uses a single designated sender address stored in the credential store.
Auth method
OAuth 2.0 via Google identity. A dedicated service account with domain-wide delegation is preferred, or a dedicated Gmail sender account with OAuth consent. The sender address must match the account authorised in the OAuth flow.
Required scopes
https://www.googleapis.com/auth/gmail.send (send-only; do not request gmail.readonly or gmail.modify unless acknowledgement-link parsing via email is implemented in a future phase).
Webhook/trigger setup
Outbound only at this stage. No inbound Gmail trigger is used. Acknowledgement is handled via a web endpoint (see acknowledgement link note below), not by parsing reply emails.
Required configuration
GMAIL_SENDER_ADDRESS stored in credential store. Email templates are stored as plain-text and HTML strings in the orchestration layer configuration, not inside Gmail drafts. Template placeholders: {{obligation_name}}, {{deadline_date}}, {{owner_name}}, {{acknowledgement_url}}, {{register_row_id}}. All five placeholders must be resolved before dispatch.
Rate limits
Gmail API: 250 quota units per user per second; each send costs 100 units, allowing approximately 2 sends per second per sender. At 30 to 60 items per month with up to 3 reminder tiers each, peak burst is under 20 sends per day. No throttling required. Add a 500 ms inter-send delay as a safety margin.
Constraints
Emails must include a plain-text fallback body alongside the HTML version. The acknowledgement URL must be unique per obligation row and per reminder tier: structure it as https://[ack-endpoint]/ack?row={register_row_id}&tier={reminder_tier}&token={hmac_token}. The HMAC token must be validated server-side on receipt.
Google Calendar
The Deadline Monitor Agent creates a single Calendar event per compliance obligation, assigned to the responsible owner's Google account. The event serves as a visible deadline marker and contains a deep link back to the register row.
Auth method
OAuth 2.0 via Google identity. The same service account used for Sheets can be reused if domain-wide delegation is enabled, allowing event creation on behalf of the owner's calendar. Alternatively, events are created on the service account's calendar and the owner is added as a guest.
Required scopes
https://www.googleapis.com/auth/calendar.events (create and update events only). Do not request calendar.readonly or the full calendar scope.
Webhook/trigger setup
No inbound Calendar trigger is used. The orchestration layer writes events outbound only via the Calendar API v3 POST /calendars/{calendarId}/events endpoint.
Required configuration
CALENDAR_ID stored in credential store (use 'primary' for the service account's calendar or the specific calendar ID if a dedicated compliance calendar is created). Event description must include the string 'ComplianceRegisterRow:{register_row_id}' to enable future cross-referencing. Event colour ID 11 (Tomato) is used for overdue items; colour ID 2 (Sage) for active items.
Rate limits
Calendar API: 1,000,000 queries per day, 500 per 100 seconds per project. At current volume, event creation peaks at 60 events per month. No throttling required. Backoff on 403 rateLimitExceeded responses.
Constraints
Events must not be deleted by the automation. If a deadline changes, update the existing event using the stored event ID (saved in the register row under calendar_event_id). The automation must store the returned event ID in the register immediately after creation to support future updates.
Integration and API SpecPage 1 of 3
FS-DOC-05Technical
Slack
The Escalation Agent uses Slack to send direct messages to obligation owners who have not acknowledged a reminder within 48 hours, and to post a notification to the designated compliance manager channel.
Auth method
OAuth 2.0 Bot Token (xoxb-...). The Slack app must be installed into the workspace by a Workspace Admin and granted the required Bot Token Scopes. The Bot Token is stored in the credential store as SLACK_BOT_TOKEN.
Required scopes
chat:write (post messages to channels and DMs), im:write (open DM channels with users), users:read (look up user ID by email address), users:read.email (required to resolve owner email to Slack user ID).
Webhook/trigger setup
Outbound only. No Slack event subscription or incoming webhook is used in this phase. The orchestration layer calls POST https://slack.com/api/chat.postMessage for both DMs and channel posts. The compliance manager channel ID is stored in the credential store as SLACK_COMPLIANCE_CHANNEL_ID.
Required configuration
SLACK_BOT_TOKEN and SLACK_COMPLIANCE_CHANNEL_ID stored in credential store. Owner Slack user IDs are resolved at runtime by calling users.lookupByEmail using the owner_email field from the register row. The resolved user_id must be used as the channel parameter for DMs. Do not hardcode user IDs.
Rate limits
Slack Web API tier 3: 50 requests per minute for chat.postMessage. At current volume (up to 60 escalations per month), peak usage is under 5 messages per day. No throttling required. Respect Retry-After headers on 429 responses.
Constraints
If users.lookupByEmail returns no match (owner not in Slack workspace), the escalation must fall back to a Gmail escalation email and log the lookup failure. The Slack app must be added to the compliance channel by a channel admin before go-live. Bot messages must include Block Kit formatting with the obligation name, deadline date, and a link to the register row.
Notion
The Completion and Reporting Agent writes a timestamped evidence log entry to a Notion database whenever an obligation is marked complete. Each entry captures the obligation name, completion date, confirming owner, and any attached document references.
Auth method
Notion Internal Integration Token. Create a dedicated integration in the Notion workspace, copy the secret token, and store it in the credential store as NOTION_API_TOKEN. The integration must be explicitly connected to the evidence log database via the database Share settings.
Required scopes
Notion integrations use capability permissions rather than OAuth scopes. Required capabilities: Read content, Update content, Insert content. These are set at integration creation time in the Notion developer portal. The integration must not be granted Comment or User capabilities unless required by a future phase.
Webhook/trigger setup
Outbound only. The orchestration layer calls POST https://api.notion.com/v1/pages to create a new database entry. The Notion API version header must be set to '2022-06-28' or later.
Required configuration
NOTION_EVIDENCE_DB_ID stored in credential store (the 32-character database ID from the database URL). NOTION_API_VERSION stored in credential store as '2022-06-28'. Database property schema must include: Obligation_Name (title), Deadline_Date (date), Completion_Date (date), Confirmed_By (rich text), Register_Row_ID (rich text), Document_References (rich text), Created_At (created_time, auto-populated by Notion).
Rate limits
Notion API: 3 requests per second average, burst to 10 per second. At current volume (30 to 60 completions per month), usage is negligible. No throttling required. Implement retry with backoff on 429 responses as the API can apply rate limits during high-traffic periods on Notion's infrastructure.
Constraints
Notion page creation is append-only from the automation: the automation must never update or delete existing evidence log entries. If a completion event fires twice for the same register row (duplicate trigger), the orchestration layer must check for an existing Notion page with matching Register_Row_ID before writing a new entry.
03Field mappings between tools
The following tables define the exact field mappings at each agent handoff. All field names are shown as they appear in the source and destination systems. Google Sheets column headers must match these names exactly before the automation is deployed.
Agent 1 handoff: Intake form to Google Sheets (Deadline Monitor Agent writes the validated record)
Source tool
Source field
Destination tool
Destination field
Intake form
`obligation_name`
Google Sheets
`Obligation_Name`
Intake form
`deadline_date`
Google Sheets
`Deadline_Date`
Intake form
`owner_email`
Google Sheets
`Owner_Email`
Intake form
`obligation_category`
Google Sheets
`Category`
Intake form
`required_action`
Google Sheets
`Required_Action`
Intake form
`supporting_notes`
Google Sheets
`Notes`
Orchestration (computed)
`reminder_date_30d`
Google Sheets
`Reminder_30d`
Orchestration (computed)
`reminder_date_14d`
Google Sheets
`Reminder_14d`
Orchestration (computed)
`reminder_date_3d`
Google Sheets
`Reminder_3d`
Orchestration (computed)
`status_initial`
Google Sheets
`Status`
Google Calendar API (response)
`event.id`
Google Sheets
`Calendar_Event_ID`
Orchestration (computed)
`row_id`
Google Sheets
`Row_ID`
Agent 1 handoff: Google Sheets to Google Calendar (Deadline Monitor Agent creates the calendar event)
Source tool
Source field
Destination tool
Destination field
Google Sheets
`Obligation_Name`
Google Calendar
`event.summary`
Google Sheets
`Deadline_Date`
Google Calendar
`event.start.date`
Google Sheets
`Deadline_Date`
Google Calendar
`event.end.date`
Google Sheets
`Owner_Email`
Google Calendar
`event.attendees[0].email`
Google Sheets
`Row_ID`
Google Calendar
`event.description` (embedded as ComplianceRegisterRow:{Row_ID})
Google Sheets
`Required_Action`
Google Calendar
`event.description` (appended)
Agent 1 handoff: Google Sheets to Gmail (Deadline Monitor Agent sends tiered reminder emails)
Source tool
Source field
Destination tool
Destination field
Google Sheets
`Owner_Email`
Gmail
`message.to`
Google Sheets
`Obligation_Name`
Gmail
`template.{{obligation_name}}`
Google Sheets
`Deadline_Date`
Gmail
`template.{{deadline_date}}`
Google Sheets
`Owner_Email`
Gmail
`template.{{owner_name}}` (resolved via users.lookupByEmail or display name field)
Google Sheets
`Row_ID`
Gmail
`template.{{register_row_id}}`
Orchestration (computed)
`acknowledgement_url`
Gmail
`template.{{acknowledgement_url}}`
Orchestration (computed)
`reminder_tier`
Gmail
`message.subject` (e.g. 30-day, 14-day, 3-day label)
Integration and API SpecPage 2 of 3
FS-DOC-05Technical
Agent 2 handoff: Google Sheets to Slack (Escalation Agent posts DM and channel alert)
Source tool
Source field
Destination tool
Destination field
Google Sheets
`Owner_Email`
Slack
`users.lookupByEmail email` (resolves to `user_id`)
Google Sheets
`Obligation_Name`
Slack
`blocks[].text.text` (Block Kit body)
Google Sheets
`Deadline_Date`
Slack
`blocks[].text.text` (Block Kit body)
Google Sheets
`Row_ID`
Slack
`blocks[].accessory.url` (deep link to register row)
Orchestration (computed)
`escalation_reason`
Slack
`blocks[].context.text` (e.g. 'No acknowledgement after 48 hours')
Credential store
`SLACK_COMPLIANCE_CHANNEL_ID`
Slack
`chat.postMessage channel` (for manager channel notification)
Agent 2 handoff: Escalation Agent writes status back to Google Sheets
Source tool
Source field
Destination tool
Destination field
Orchestration (computed)
`status_escalated`
Google Sheets
`Status` (value: 'Escalated')
Orchestration (computed)
`escalation_timestamp`
Google Sheets
`Escalation_Timestamp`
Orchestration (computed)
`escalation_channel`
Google Sheets
`Escalation_Channel`
Agent 3 handoff: Google Sheets and acknowledgement endpoint to Notion (Completion and Reporting Agent logs evidence)
Source tool
Source field
Destination tool
Destination field
Google Sheets
`Obligation_Name`
Notion
`Obligation_Name` (title property)
Google Sheets
`Deadline_Date`
Notion
`Deadline_Date` (date property)
Acknowledgement endpoint
`confirmed_by`
Notion
`Confirmed_By` (rich text property)
Acknowledgement endpoint
`completion_date`
Notion
`Completion_Date` (date property)
Google Sheets
`Row_ID`
Notion
`Register_Row_ID` (rich text property)
Acknowledgement endpoint
`document_references`
Notion
`Document_References` (rich text property)
Orchestration (computed)
`status_complete`
Google Sheets
`Status` (value: 'Complete')
Agent 3 handoff: Google Sheets to Gmail (Completion and Reporting Agent sends Monday weekly digest)
Source tool
Source field
Destination tool
Destination field
Credential store
`DIGEST_RECIPIENT_EMAIL`
Gmail
`message.to`
Google Sheets
`Status` (filtered: Open, Overdue, Complete in last 7d)
Gmail
`template.{{digest_table}}`
Orchestration (computed)
`digest_date`
Gmail
`message.subject` (e.g. 'Compliance Digest: {date}')
Orchestration (computed)
`open_count`
Gmail
`template.{{open_count}}`
Orchestration (computed)
`overdue_count`
Gmail
`template.{{overdue_count}}`
Orchestration (computed)
`completed_last_7d`
Gmail
`template.{{completed_last_7d}}`
04Build stack and orchestration
Orchestration layout
One workflow per agent: three independent workflows in the automation platform (Deadline Monitor Agent workflow, Escalation Agent workflow, Completion and Reporting Agent workflow). All three workflows share a single credential store. Inter-agent communication happens via Google Sheets as the shared state layer: each workflow reads and writes to the central register rather than calling each other directly.
Agent 1 trigger
Deadline Monitor Agent: scheduled poll every 15 minutes against the Google Sheets register. On each poll, the workflow reads all rows where Row_ID is present and Status is empty (new, unprocessed rows). A second scheduled run fires daily at 06:00 UTC to check all rows for reminder dates falling on the current day (30d, 14d, 3d columns).
Agent 2 trigger
Escalation Agent: scheduled poll every 60 minutes. Reads all rows where Status is 'Open' or 'Reminder Sent' and Last_Reminder_Sent is more than 48 hours ago with no acknowledgement token recorded in Acknowledgement_Received. No inbound webhook; escalation logic is entirely poll-driven at this volume.
Agent 3 trigger
Completion and Reporting Agent: two triggers. First, an inbound webhook from the acknowledgement endpoint fires immediately when an owner clicks the acknowledgement link (signature validation required: HMAC-SHA256 using HMAC_SECRET from credential store, verified before any register write). Second, a scheduled run at 07:00 UTC every Monday generates and sends the weekly digest.
Webhook signature validation
The acknowledgement endpoint computes HMAC-SHA256 over the raw request body using HMAC_SECRET. The computed digest is compared to the x-ack-signature header value using a constant-time comparison. Requests failing validation are rejected with HTTP 403 and logged to the platform error log. No register writes occur on failed validation.
Credential store
All secrets and configuration IDs are stored in the orchestration platform's native encrypted credential store. No secret is written into workflow node configuration fields or email template strings. See the credential store manifest below.
Credential store manifest (all entries required before first workflow activation)
// Google Services
GOOGLE_SERVICE_ACCOUNT_JSON // Full JSON key for service account with Sheets, Gmail, Calendar scopes
SHEETS_REGISTER_ID // Google Sheets workbook ID (from URL: /d/{SHEETS_REGISTER_ID}/edit)
GMAIL_SENDER_ADDRESS // Authorised sender email address for all outbound email
CALENDAR_ID // 'primary' or dedicated compliance calendar ID
// Slack
SLACK_BOT_TOKEN // xoxb-... Bot Token from Slack app OAuth install
SLACK_COMPLIANCE_CHANNEL_ID // Channel ID (not name) for compliance manager alerts (e.g. C0123456789)
// Notion
NOTION_API_TOKEN // Internal integration token (secret_...)
NOTION_EVIDENCE_DB_ID // 32-character database ID from Notion evidence log URL
NOTION_API_VERSION // '2022-06-28'
// Acknowledgement endpoint
HMAC_SECRET // 32-byte random secret for HMAC-SHA256 signature generation and validation
ACK_ENDPOINT_BASE_URL // Base URL of the acknowledgement web endpoint (e.g. https://ack.yourcompany.com)
// Digest
DIGEST_RECIPIENT_EMAIL // Email address of the legal manager receiving the Monday digest
// Optional
SLACK_FALLBACK_EMAIL // Fallback email address if Slack user lookup fails during escalation05Error handling and retry logic
Every integration point has a defined failure behaviour. Unhandled exceptions must never fail silently: all errors must be logged to the platform error log with a timestamp, the affected Row_ID, and the failure reason. Where a manual fallback is specified, the fallback must also be logged so the FullSpec team can identify and resolve the root cause.
Integration
Scenario
Required behaviour
Google Sheets (read/write)
API returns 429 (rate limit exceeded)
Retry with exponential backoff: wait 2s, 4s, 8s, 16s (max 4 attempts). If all retries fail, log the error with Row_ID and trigger a SLACK_FALLBACK_EMAIL alert to the FullSpec team. Do not silently skip the row.
Google Sheets (read)
Register row missing required fields (e.g. Deadline_Date or Owner_Email is blank)
Mark the row Status as 'Validation_Error'. Send a Gmail alert to DIGEST_RECIPIENT_EMAIL listing the row number and missing fields. Do not attempt Calendar event creation or reminder dispatch for this row.
Gmail (send)
API returns 5xx server error on reminder or digest send
Retry up to 3 times with 60-second intervals. If all retries fail, log the failure with the recipient address, Row_ID, and reminder tier. Update the Sheets row Reminder_Send_Error column to 'true'. Send a platform error log alert to DIGEST_RECIPIENT_EMAIL.
Gmail (send)
Invalid or bounced recipient address (422 or permanent delivery failure)
Do not retry. Log the failure. Update the Sheets row Status to 'Owner_Email_Invalid'. Trigger Slack fallback to SLACK_COMPLIANCE_CHANNEL_ID notifying the manager of the invalid address. No further reminders sent to that address until corrected.
Google Calendar (event creation)
API returns 403 (insufficient permissions or calendar not shared)
Log the error with Row_ID and calendar_id. Mark the Sheets row Calendar_Event_ID as 'CREATION_FAILED'. Send a single alert to DIGEST_RECIPIENT_EMAIL. Continue remainder of the workflow (reminder emails are not blocked by Calendar failure). Retry is not automatic: requires credential fix by the FullSpec team.
Google Calendar (event update)
Stored Calendar_Event_ID not found (event was deleted manually)
Attempt to create a new event. Store the new event ID in the Sheets row. Log the replacement action with a note that the original event was not found.
Slack (chat.postMessage)
users.lookupByEmail returns no match for owner email
Skip the Slack DM. Send a Gmail escalation email to the owner's email address and to DIGEST_RECIPIENT_EMAIL instead. Log the lookup failure with the owner email and Row_ID. Update Escalation_Channel in Sheets to 'Email_Fallback'.
Slack (chat.postMessage)
API returns 429 (rate limit)
Respect the Retry-After header value. Retry once after the specified delay. If the second attempt fails, fall back to Gmail escalation as above and log the Slack failure.
Notion (page creation)
API returns 409 or duplicate Row_ID detected in existing pages
Do not create a second Notion page. Log a duplicate suppression event with the Row_ID and timestamp. Update the Sheets row to mark Notion_Log_ID with the existing page ID if retrievable. The Status in Sheets is still updated to 'Complete'.
Notion (page creation)
API returns 5xx or connection timeout
Retry up to 3 times with 30-second intervals. If all retries fail, mark the Sheets row Notion_Log_Status as 'PENDING_RETRY'. Add the row to a daily retry queue that re-attempts Notion writes at 08:00 UTC. Alert DIGEST_RECIPIENT_EMAIL if an item has been in PENDING_RETRY for more than 24 hours.
Acknowledgement endpoint
Inbound webhook fails HMAC-SHA256 signature validation
Reject the request immediately with HTTP 403. Log the rejection with the raw x-ack-signature header value and the source IP. Do not write to the register or Notion. Do not retry. Alert the FullSpec team if more than 3 failed validations occur from the same IP within 10 minutes.
Orchestration layer (any workflow)
Unhandled exception in workflow execution (unexpected error type not caught by above rules)
The orchestration platform's global error handler must catch all unhandled exceptions, log the full error payload with timestamp and workflow name, and send an immediate alert to support@gofullspec.com and DIGEST_RECIPIENT_EMAIL. The affected workflow must not silently complete. A status of 'System_Error' must be written to the Sheets row if a Row_ID is available in the execution context.
All retry logic must use exponential backoff with jitter to avoid thundering-herd behaviour during platform outages. The maximum total retry window for any single operation is 10 minutes. After that window, the failure is escalated to the error alert path and the item is queued for manual review. Contact support@gofullspec.com for any integration failure that persists beyond one retry cycle in production.
Integration and API SpecPage 3 of 3