Back to Board & Investor Reporting

Integration and API Spec

The reference during the build: every tool connection, auth scope, field mapping, and error-handling rule.

4 pagesPDF · Technical
FS-DOC-05Technical

Integration and API Spec

Board and Investor Reporting Automation

[YourCompany.com] · Management Department · Prepared by FullSpec · [Today's Date]

This document defines the exact integration configuration required to build and operate the Board and Investor Reporting automation. It covers every tool in the stack, the precise OAuth scopes and credentials needed, field-level data mappings between agents, orchestration layout, and the error-handling behaviour expected at every integration boundary. This specification is written for the FullSpec build team and assumes familiarity with REST APIs, OAuth 2.0, and webhook configuration. Nothing in this document requires action from [YourCompany.com] unless a credential or configuration item is explicitly flagged as owner-supplied.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agents
Xero
Source of financial data: profit and loss, cash position, balance sheet
OAuth 2.0 (PKCE flow)
Starter or above (API access on all paid plans)
Agent 1 (Data Collector)
HubSpot
Source of pipeline and closed-won revenue data
OAuth 2.0 (private app token)
Starter CRM or above (API access included)
Agent 1 (Data Collector)
Google Sheets
Central staging layer: receives financial, pipeline, and KPI data; signals completion
OAuth 2.0 (service account)
Google Workspace (any tier) or personal Google account
Agents 1, 2, 3 (all agents)
Google Drive
Board pack template storage, draft file assembly, PDF export, board folder distribution
OAuth 2.0 (service account, shared with Sheets auth)
Google Workspace (any tier) or personal Google account
Agent 3 (Pack Assembly)
Slack
KPI prompt delivery to department heads, reminder messages, CEO notification
OAuth 2.0 (bot token via Slack app)
Free tier sufficient; Pro recommended for message retention
Agent 2 (KPI Collection)
Orchestration layer (automation platform)
Workflow engine hosting all three agent workflows, credential store, retry logic, and scheduling
Internal platform credential store; no external auth
N/A (platform-level component)
All agents (platform layer)
Before you connect anything: create sandbox or test credentials for every tool listed above and validate each connection end-to-end before switching to production credentials. For Xero, use the Xero developer demo company. For HubSpot, use a sandbox portal. For Google, use a dedicated test Drive folder and Sheets file. For Slack, use a private test channel. Production credentials must not be used during build or QA.

02Per-tool integration detail

Xero

Used by Agent 1 (Data Collector) to pull profit and loss, cash flow, and balance sheet reports for the closed reporting period via the Xero Accounting API (v2). All calls are read-only. No write operations are performed against Xero.

Auth method
OAuth 2.0 with PKCE. Register a web app in the Xero developer portal. Store client_id, client_secret, refresh_token, and tenant_id in the credential store (never hardcoded). Access tokens expire after 30 minutes; refresh tokens expire after 60 days. The orchestration layer must refresh proactively before each scheduled run.
Required scopes
openid profile email accounting.reports.read accounting.settings.read offline_access
Webhook / trigger setup
No inbound webhook required. Xero is called on a schedule triggered by the orchestration layer. The trigger fires on the configured report date (e.g. third business day after month-end). No event subscription needed.
Required configuration
Store in credential store: XERO_CLIENT_ID, XERO_CLIENT_SECRET, XERO_REFRESH_TOKEN, XERO_TENANT_ID. The tenant_id must be resolved after OAuth consent and stored permanently. Report period dates are passed as dynamic parameters at runtime (fromDate, toDate) derived from the schedule trigger.
Endpoints used
GET /api.xro/2.0/Reports/ProfitAndLoss?fromDate={fromDate}&toDate={toDate} | GET /api.xro/2.0/Reports/BalanceSheet?date={toDate} | GET /api.xro/2.0/Reports/BankSummary?fromDate={fromDate}&toDate={toDate}
Rate limits
60 API calls per minute per tenant; 5,000 calls per day. At current volume (~12 runs/year, 3 report calls per run) this is 36 calls/year. No throttling logic required. Include a 500ms delay between sequential calls as a courtesy measure.
Constraints
Reports API returns XML or JSON depending on Accept header; set Accept: application/json on all calls. The ProfitAndLoss endpoint does not support real-time data; figures reflect the Xero ledger state at call time. If the period is not yet closed in Xero, the report will contain incomplete data. A data completeness check must be implemented before writing to Google Sheets.
// Input
fromDate: string  // e.g. '2024-06-01'
toDate:   string  // e.g. '2024-06-30'
// Output (written to Google Sheets staging layer)
xero.revenue_total:        number
xero.gross_profit:         number
xero.net_profit:           number
xero.cash_position:        number
xero.total_assets:         number
xero.total_liabilities:    number
xero.report_period_label:  string  // e.g. 'June 2024'
HubSpot

Used by Agent 1 (Data Collector) to retrieve sales pipeline data including deals by stage, weighted forecast total, and closed-won revenue for the reporting period. Uses the HubSpot CRM API v3.

Auth method
Private App token (bearer token). Create a Private App in HubSpot under Settings > Integrations > Private Apps. Store the token in the credential store as HUBSPOT_API_TOKEN. No OAuth redirect flow required for server-side automation.
Required scopes
crm.objects.deals.read crm.schemas.deals.read sales-email-read crm.objects.owners.read
Webhook / trigger setup
No inbound webhook required. HubSpot is polled on demand by Agent 1 immediately after the Xero fetch completes. No event subscription is needed for this use case.
Required configuration
Store in credential store: HUBSPOT_API_TOKEN. Pipeline ID for the relevant sales pipeline must be stored as HUBSPOT_PIPELINE_ID (not hardcoded). Stage IDs for each deal stage must be resolved at build time from GET /crm/v3/pipelines/deals/{pipelineId} and stored as static config values per environment.
Endpoints used
POST /crm/v3/objects/deals/search (filter by closedate range and pipeline) | GET /crm/v3/pipelines/deals/{pipelineId} (resolve stage names and IDs at build time)
Rate limits
150 API calls per 10 seconds (burst); 250,000 calls per day on Starter. At current volume this is negligible. No throttling required. Add standard 200ms inter-call delay.
Constraints
The deals search endpoint returns a maximum of 100 results per page. If the pipeline contains more than 100 active deals, pagination via the after cursor parameter must be implemented. Weighted forecast must be calculated in the orchestration layer as (deal_amount * probability) summed per stage; HubSpot does not return a pre-calculated weighted total from the search endpoint.
// Input
pipeline_id:  string   // from credential store
closedate_gte: string  // period start, e.g. '2024-06-01'
closedate_lte: string  // period end,   e.g. '2024-06-30'
// Output (written to Google Sheets staging layer)
hs.pipeline_total_open:    number  // sum of amount across all open stages
hs.weighted_forecast:      number  // calculated: sum(amount * probability)
hs.closed_won_revenue:     number  // sum of amount where dealstage = closed-won
hs.deal_count_by_stage:    object  // { stage_name: count }
hs.report_period_label:    string
Google Sheets

Used by all three agents as the central staging and coordination layer. Agent 1 writes financial and pipeline data. Agent 2 writes KPI submissions. Agent 3 reads the completed dataset to assemble the board pack. A status flag cell signals workflow progression between agents.

Auth method
OAuth 2.0 via a Google service account. Create a service account in Google Cloud Console, download the JSON key, and store as GOOGLE_SERVICE_ACCOUNT_JSON in the credential store. Share the target Sheets file with the service account email address (editor permissions).
Required scopes
https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive.file
Webhook / trigger setup
No webhook. The orchestration layer polls the status cell (sheet: _control, cell: B2) every 5 minutes during the KPI collection window to determine when all KPIs are confirmed and Agent 3 can proceed.
Required configuration
Store GOOGLE_SPREADSHEET_ID in the credential store. The spreadsheet must contain the following named sheets: financials (financial staging), pipeline (HubSpot data), kpi_submissions (KPI responses with submitter and timestamp columns), and _control (workflow status flags). Sheet structure must not be altered after go-live without reconfiguring Agent 1, 2, and 3 range references.
Sheet structure
financials: row 1 = headers [period, revenue_total, gross_profit, net_profit, cash_position, total_assets, total_liabilities]. pipeline: row 1 = headers [period, pipeline_total_open, weighted_forecast, closed_won_revenue]. kpi_submissions: row 1 = headers [kpi_name, value, submitted_by, submitted_at, status]. _control: B1 = run_date, B2 = workflow_status (values: PENDING | FINANCIAL_COMPLETE | KPI_COMPLETE | PACK_ASSEMBLED).
Rate limits
Google Sheets API v4: 300 read/write requests per minute per project. At current volume (12 runs/year, approximately 30 API calls per run) this is negligible. No throttling required.
Constraints
The spreadsheet ID is environment-specific (separate IDs for test and production). Never use the same file for test and production runs. All writes must target explicitly named ranges, not positional A1 notation alone, to guard against row insertion breaking column alignment.
// Reads (Agent 3 input)
spreadsheet_id: string  // from credential store
sheet: 'financials'    // range: A2:G2 (current period row)
sheet: 'pipeline'      // range: A2:D2
sheet: 'kpi_submissions' // range: A2:E{n} where n = number of KPI rows
// Writes (Agent 1 and Agent 2 output)
financials!A2:G2   <- xero output fields
pipeline!A2:D2     <- hubspot output fields
kpi_submissions!A{n}:E{n}  <- one row per KPI submission
_control!B2        <- workflow_status string
Integration and API SpecPage 1 of 3
FS-DOC-05Technical
Google Drive

Used by Agent 3 (Pack Assembly) to read the master board pack template, produce a period-specific working copy, populate it with data from Google Sheets, export the approved version as PDF, and upload the final file to the shared board distribution folder.

Auth method
Same Google service account used for Sheets (GOOGLE_SERVICE_ACCOUNT_JSON). The service account must be granted editor access to the template file and the board distribution folder. Owner access is not required.
Required scopes
https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/documents
Webhook / trigger setup
No inbound webhook. Agent 3 is triggered by the orchestration layer when the _control sheet status flag reads KPI_COMPLETE. The layer monitors this via polling (see Google Sheets entry).
Required configuration
Store in credential store: GDRIVE_TEMPLATE_FILE_ID (the master board pack Google Doc or Slides template ID), GDRIVE_BOARD_FOLDER_ID (the shared distribution folder ID). These IDs must be environment-specific. Template placeholders must use the format {{field_name}} throughout the document (see field mappings, section 03). The template must not contain merged cells or complex scripting that conflicts with API-based substitution.
Template placeholders
{{period_label}} {{revenue_total}} {{gross_profit}} {{net_profit}} {{cash_position}} {{total_assets}} {{total_liabilities}} {{pipeline_total_open}} {{weighted_forecast}} {{closed_won_revenue}} plus one placeholder per KPI in the format {{kpi_<kpi_name>}} e.g. {{kpi_monthly_active_users}}
Rate limits
Drive API v3: 1,000 requests per 100 seconds per user. Docs API: 300 requests per minute. At current volume this is negligible. No throttling required.
Constraints
Google Docs API text replacement (batchUpdate with replaceAllText) is the required method for populating template placeholders. The Slides API equivalent must be used if the template is a Google Slides file. The template file must never be written to directly; Agent 3 must always create a period-named copy using Drive copy endpoint before populating. The original template remains pristine.
// Input
template_file_id:  string  // from credential store
board_folder_id:   string  // from credential store
period_label:      string  // e.g. 'June 2024 Board Pack'
field_map:         object  // all populated fields from Sheets (see section 03)
// Actions
1. POST /drive/v3/files/{templateId}/copy  -> new_file_id
2. POST /docs/v1/documents/{new_file_id}:batchUpdate  -> replaceAllText per placeholder
3. GET  /drive/v3/files/{new_file_id}/export?mimeType=application/pdf  -> pdf_bytes
4. POST /drive/v3/files (multipart upload to board_folder_id)  -> final_pdf_file_id
// Output
draft_doc_url:    string  // link sent to CEO via Slack (Agent 2 channel)
final_pdf_url:    string  // link distributed to board members via email notification
Slack

Used by Agent 2 (KPI Collection) to send structured prompts to each department head, track response status, issue a single automated reminder for non-responders, and notify the CEO when the draft pack is ready. Uses the Slack Web API via a custom bot app.

Auth method
OAuth 2.0 bot token. Create a Slack app in api.slack.com/apps. Install it to the workspace and store the bot token in the credential store as SLACK_BOT_TOKEN. Use the signing secret (SLACK_SIGNING_SECRET) to validate any incoming payloads if interactive components are used.
Required scopes
chat:write chat:write.public im:write users:read users:read.email channels:read groups:read im:read mpim:read
Webhook / trigger setup
Outbound messages use the chat.postMessage method. If interactive Block Kit buttons are used for KPI confirmation, configure a Request URL in the Slack app's Interactivity settings pointing to the orchestration layer's inbound webhook endpoint. All payloads from Slack must be validated using the SLACK_SIGNING_SECRET (HMAC-SHA256 of the raw request body with the signing secret). Replay attack window: reject any request where X-Slack-Request-Timestamp is older than 5 minutes.
Required configuration
Store in credential store: SLACK_BOT_TOKEN, SLACK_SIGNING_SECRET. Store department head Slack user IDs as SLACK_USER_{NAME} (not hardcoded). Store CEO Slack user ID as SLACK_USER_CEO. The KPI prompt template (Block Kit JSON) is stored in the orchestration layer config, not in Slack. KPI deadline window is configurable as SLACK_KPI_DEADLINE_HOURS (default: 24).
Rate limits
Slack Web API Tier 3 (chat.postMessage): 50 calls per minute. At current volume (~5 to 8 department heads per cycle, 12 cycles per year) peak calls per run is under 20. No throttling required. Implement 200ms delay between sequential postMessage calls.
Constraints
The bot must be invited to any private channel it posts into. For direct messages, im:write scope is sufficient without a channel invite. Block Kit interactive messages require the app to have a publicly reachable Request URL at message send time, not just at app configuration time. If the orchestration platform is behind a private network, an outbound webhook relay or ngrok equivalent must be in place during testing.
// Outbound: KPI prompt (per department head)
POST /api/chat.postMessage
{ channel: SLACK_USER_{NAME}, blocks: [ ...KPI_PROMPT_BLOCK_KIT... ] }
// Inbound: department head response (interactive payload)
{ type: 'block_actions', user: { id, name }, actions: [ { action_id, value } ] }
// Outbound: reminder (24h after initial prompt, non-responders only)
POST /api/chat.postMessage
{ channel: SLACK_USER_{NAME}, text: 'Reminder: KPI submission due in 2 hours.' }
// Outbound: CEO notification
POST /api/chat.postMessage
{ channel: SLACK_USER_CEO, text: 'Board pack draft is ready for review.', blocks: [ ...link_button... ] }

03Field mappings between tools

The tables below define every field handoff between tools at each agent boundary. Field names are shown in monospace exactly as they appear in API responses or spreadsheet headers. All currency fields are numeric (not formatted strings) until the Pack Assembly Agent applies formatting during template population.

Source tool
Source field
Destination tool
Destination field
Xero API
`Reports[ProfitAndLoss].Rows[].Cells[1].Value` (Revenue)
Google Sheets
`financials!B2` (revenue_total)
Xero API
`Reports[ProfitAndLoss].Rows[].Cells[1].Value` (Gross Profit)
Google Sheets
`financials!C2` (gross_profit)
Xero API
`Reports[ProfitAndLoss].Rows[].Cells[1].Value` (Net Profit)
Google Sheets
`financials!D2` (net_profit)
Xero API
`Reports[BankSummary].Rows[].Cells[1].Value` (Closing Balance)
Google Sheets
`financials!E2` (cash_position)
Xero API
`Reports[BalanceSheet].Rows[].Cells[1].Value` (Total Assets)
Google Sheets
`financials!F2` (total_assets)
Xero API
`Reports[BalanceSheet].Rows[].Cells[1].Value` (Total Liabilities)
Google Sheets
`financials!G2` (total_liabilities)
HubSpot API
`results[].properties.amount` (sum, all open stages)
Google Sheets
`pipeline!B2` (pipeline_total_open)
HubSpot API
`results[].properties.amount * results[].properties.hs_deal_stage_probability` (calculated)
Google Sheets
`pipeline!C2` (weighted_forecast)
HubSpot API
`results[].properties.amount` (filter: dealstage = closedwon)
Google Sheets
`pipeline!D2` (closed_won_revenue)

Agent 1 to Agent 2 handoff: Agent 2 (KPI Collection) does not read from Agent 1 output directly. It writes independently to the kpi_submissions sheet. The handoff signal is the _control!B2 status flag transitioning from FINANCIAL_COMPLETE to KPI_COMPLETE.

Source tool
Source field
Destination tool
Destination field
Slack (interactive payload)
`actions[0].action_id` (kpi identifier string)
Google Sheets
`kpi_submissions!A{n}` (kpi_name)
Slack (interactive payload)
`actions[0].value` (submitted numeric value)
Google Sheets
`kpi_submissions!B{n}` (value)
Slack (interactive payload)
`user.name`
Google Sheets
`kpi_submissions!C{n}` (submitted_by)
Slack (interactive payload)
`event.ts` (Unix timestamp, converted to ISO 8601)
Google Sheets
`kpi_submissions!D{n}` (submitted_at)
Orchestration layer (derived)
Status set to CONFIRMED after value validation
Google Sheets
`kpi_submissions!E{n}` (status)

Agent 2 to Agent 3 handoff: Agent 3 reads all confirmed rows from kpi_submissions and all data from financials and pipeline sheets, then maps to Google Drive template placeholders as follows.

Source tool
Source field
Destination tool
Destination field
Google Sheets
`financials!B2` (revenue_total)
Google Drive template
`{{revenue_total}}`
Google Sheets
`financials!C2` (gross_profit)
Google Drive template
`{{gross_profit}}`
Google Sheets
`financials!D2` (net_profit)
Google Drive template
`{{net_profit}}`
Google Sheets
`financials!E2` (cash_position)
Google Drive template
`{{cash_position}}`
Google Sheets
`financials!F2` (total_assets)
Google Drive template
`{{total_assets}}`
Google Sheets
`financials!G2` (total_liabilities)
Google Drive template
`{{total_liabilities}}`
Google Sheets
`pipeline!B2` (pipeline_total_open)
Google Drive template
`{{pipeline_total_open}}`
Google Sheets
`pipeline!C2` (weighted_forecast)
Google Drive template
`{{weighted_forecast}}`
Google Sheets
`pipeline!D2` (closed_won_revenue)
Google Drive template
`{{closed_won_revenue}}`
Google Sheets
`kpi_submissions!B{n}` (value, per confirmed KPI row)
Google Drive template
`{{kpi_<kpi_name>}}` (one placeholder per KPI)
Google Sheets
`financials!A2` (period)
Google Drive template
`{{period_label}}`
Integration and API SpecPage 2 of 3
FS-DOC-05Technical

04Build stack and orchestration

Orchestration layout
Three discrete workflows, one per agent, within the automation platform. Each workflow is independently deployable and observable. Agents are linked by status flag polling on Google Sheets (_control!B2) rather than direct inter-workflow calls, so each agent can be restarted independently without affecting upstream state.
Agent 1 trigger mechanism
Schedule (time-based poll). Configured to fire at 06:00 local time on the nominated report date each period (e.g. third business day after month-end). The run date is stored as a configurable parameter (REPORT_TRIGGER_DATE) rather than hardcoded. No inbound webhook.
Agent 2 trigger mechanism
Event-based: triggered by Agent 1 writing FINANCIAL_COMPLETE to _control!B2. The orchestration layer polls that cell every 5 minutes. Upon detection, Agent 2 fires immediately. Inbound Slack payloads from department head interactions are received via a signed webhook endpoint (HMAC-SHA256 validated using SLACK_SIGNING_SECRET before any payload processing).
Agent 3 trigger mechanism
Event-based: triggered by Agent 2 writing KPI_COMPLETE to _control!B2. Same 5-minute polling mechanism as Agent 2. No inbound webhook required; Agent 3 is entirely outbound to Google Sheets, Google Drive, and the CEO Slack notification.
Credential store
All secrets stored in the automation platform's encrypted credential store. No credentials written to code, config files, or Sheets. Environment separation enforced: test credentials and production credentials stored in separate named environments within the credential store. Rotation policy: OAuth refresh tokens reviewed every 60 days; service account keys reviewed every 90 days.
Logging and observability
Each workflow execution logs: run start timestamp, agent name, each API call (endpoint, HTTP status, response time), any retry events, status flag transitions, and run end timestamp. Logs retained for 90 days minimum. Failed runs trigger an alert to support@gofullspec.com and the process owner.
Environment separation
Test environment: separate Xero demo company, HubSpot sandbox portal, dedicated Google Sheets file (TEST_SPREADSHEET_ID), dedicated Google Drive folder (TEST_BOARD_FOLDER_ID), private Slack channel (#board-pack-test). Production credentials activated only after QA sign-off per the Test and QA Plan.
Credential store: all values injected at runtime by the orchestration platform; never written to source code or workflow config files
// Credential store contents (production environment)
// Xero
XERO_CLIENT_ID          = '<from Xero developer portal>'
XERO_CLIENT_SECRET      = '<from Xero developer portal>'
XERO_REFRESH_TOKEN      = '<issued after OAuth consent, rotate every 60 days>'
XERO_TENANT_ID          = '<resolved after OAuth consent, static>'

// HubSpot
HUBSPOT_API_TOKEN       = '<Private App token from HubSpot settings>'
HUBSPOT_PIPELINE_ID     = '<resolved from GET /crm/v3/pipelines/deals at build time>'

// Google (shared service account)
GOOGLE_SERVICE_ACCOUNT_JSON = '<base64-encoded service account key JSON>'
GOOGLE_SPREADSHEET_ID       = '<production Sheets file ID>'
GDRIVE_TEMPLATE_FILE_ID     = '<master board pack template Google Doc/Slides ID>'
GDRIVE_BOARD_FOLDER_ID      = '<shared board distribution folder ID>'

// Slack
SLACK_BOT_TOKEN         = '<xoxb- token from Slack app>'
SLACK_SIGNING_SECRET    = '<from Slack app Basic Information page>'
SLACK_USER_CEO          = '<Slack user ID of CEO>'
SLACK_USER_<NAME>       = '<Slack user ID per department head, one entry each>'

// Orchestration config (not secrets but environment-specific)
REPORT_TRIGGER_DATE     = '<cron expression or date param per reporting schedule>'
SLACK_KPI_DEADLINE_HOURS = '24'

// Test environment overrides (separate named environment)
GOOGLE_SPREADSHEET_ID   = '<test Sheets file ID>'
GDRIVE_TEMPLATE_FILE_ID = '<test template copy ID>'
GDRIVE_BOARD_FOLDER_ID  = '<test Drive folder ID>'
XERO_TENANT_ID          = '<Xero demo company tenant ID>'

05Error handling and retry logic

Unhandled exceptions must never fail silently. Every integration point must produce a logged error entry and, where the failure blocks downstream agents, must alert the process owner and the FullSpec monitoring address (support@gofullspec.com) within 5 minutes of the failure event.
Integration
Scenario
Required behaviour
Xero API
OAuth access token expired at run time
Before each run, check token expiry timestamp. If expired or within 5 minutes of expiry, call the Xero token refresh endpoint using XERO_REFRESH_TOKEN. If refresh fails (invalid grant), halt Agent 1, log the error, alert process owner with instructions to re-authorise. Do not attempt the report fetch with a stale token.
Xero API
Report endpoint returns HTTP 429 (rate limit)
Implement exponential backoff: wait 2s, retry; wait 4s, retry; wait 8s, retry. After 3 failed retries, halt Agent 1, write FAILED to _control!B2, log full response, and alert. Do not proceed to HubSpot fetch if Xero data is incomplete.
Xero API
Reporting period not yet closed in Xero (incomplete data)
After fetching the P&L report, check that the closing date in the response matches the requested toDate. If it does not, or if the report contains zero values across all rows, halt Agent 1 and alert the process owner: 'Xero period may not be closed. Please confirm before re-triggering.' Do not write partial data to Sheets.
HubSpot API
Private App token revoked or invalid (HTTP 401)
Log the 401 response, halt Agent 1, and alert process owner: 'HubSpot API token is invalid. Regenerate the Private App token in HubSpot and update the credential store.' Do not write partial pipeline data to Sheets.
HubSpot API
Deal search returns more than 100 results (pagination required)
Agent 1 must check for a paging.next.after cursor in the search response. If present, issue subsequent paginated requests until all pages are fetched. Accumulate results before writing to Sheets. If pagination loop exceeds 20 pages (2,000 deals), log a warning and continue; flag the result count in the Sheets run log for review.
Google Sheets
Write to staging sheet fails (HTTP 403 or 404)
Retry once after 3 seconds. If the second attempt fails, halt the current agent, log the full error including the spreadsheet ID and range, and alert. A 403 typically indicates the service account has lost editor access; a 404 indicates the spreadsheet ID is wrong. Both require manual resolution before re-run.
Google Sheets
Status flag polling times out (KPI_COMPLETE not received within deadline)
Agent 3 polling loop has a maximum wait of SLACK_KPI_DEADLINE_HOURS + 4 hours. If KPI_COMPLETE is not written within that window, Agent 3 logs a timeout, alerts the process owner listing which KPI rows have status != CONFIRMED, and pauses. The process owner can manually set _control!B2 to KPI_COMPLETE to force Agent 3 to proceed with whatever data is available. Any missing KPIs are flagged in the assembled pack with the placeholder [AWAITING SUBMISSION].
Slack (outbound)
chat.postMessage call fails for one or more department heads (HTTP 4xx)
Retry the failed message once after 5 seconds. If it fails again, log the user ID and error, continue sending to remaining recipients (do not halt the full run), and alert the process owner with the list of users who did not receive a prompt. The process owner must contact those individuals manually.
Slack (inbound webhook)
Interactive payload signature validation fails
Reject the payload with HTTP 400, log the rejection including the source IP and timestamp, and do not write any data to Sheets. Do not alert the department head. If more than 3 validation failures occur within a single run, alert the FullSpec monitoring address as a potential security event.
Google Drive
Template file copy fails (HTTP 403 or file not found)
Halt Agent 3, log the template file ID and error response, and alert process owner: 'Board pack template could not be copied. Confirm the template file ID in the credential store and that the service account has editor access.' Do not attempt placeholder substitution without a valid working copy.
Google Drive
Placeholder substitution finds one or more placeholders with no matching data value
Do not halt. Replace the placeholder with the literal string [MISSING DATA: {{field_name}}] in the assembled document. Log each missing field by name. Alert the process owner after pack assembly is complete with the list of missing fields. The CEO review step is the human gate before distribution.
All integrations
Unhandled exception or unexpected HTTP 5xx from any external API
Catch all unhandled exceptions at the workflow level. Log the full stack trace, the workflow step name, the tool called, and the HTTP status if available. Immediately alert support@gofullspec.com and the process owner. Set _control!B2 to FAILED. Do not allow the workflow to exit silently. The FullSpec team reviews all FAILED status entries within one business day.
Integration and API SpecPage 3 of 3

More documents for this process

Every document generated for Board & Investor Reporting.

Launch Plan
Operations · Owner
View
ROI and Business Case
Finance · Owner
View
Process Runbook / SOP
Operations · Owner
View
Developer Handover Pack
Technical · Developer
View
Test and QA Plan
Quality · Developer
View