Back to Quote Generation & Follow-up

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

Quote Generation and Follow-up

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

This document is the definitive technical reference for every integration point in the Quote Generation and Follow-up automation. It covers authentication requirements, exact OAuth scopes, webhook configuration, field mappings between tools, credential store layout, and failure handling for each integration. The FullSpec team uses this specification to build and configure all connections. No integration detail should be hardcoded into workflow logic; everything sensitive must live in the shared credential store as described in Section 04.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agents
HubSpot
CRM trigger source; deal stage reads and writes; contact field reads
OAuth 2.0 (private app token)
Sales Hub Starter ($45/mo)
Agent 1, Agent 2, Agent 3
Google Sheets
Master pricing lookup table; product and line-item source
OAuth 2.0 (service account JSON)
Google Workspace (any tier)
Agent 1
PandaDoc
Quote document generation, e-sign, and event webhooks
API key (Bearer token)
Business plan ($49/mo)
Agent 1, Agent 2, Agent 3
Gmail
Quote delivery email; follow-up email sequence
OAuth 2.0 (user-delegated)
Google Workspace (any tier)
Agent 2, Agent 3
Slack
Manager approval request notifications; approval response capture
OAuth 2.0 (bot token)
Pro plan ($8/mo)
Agent 2
Xero
Draft invoice creation on quote acceptance
OAuth 2.0 (PKCE flow)
Starter plan ($13/mo)
Agent 3
Automation platform (orchestration layer)
Workflow host; credential store; trigger listener; retry scheduler
Internal service credential
Vendor-appropriate tier
All agents
Before you connect anything: sandbox-test every integration against the vendor's sandbox or developer environment before supplying production credentials. Confirm all scopes resolve correctly and that webhook endpoints return the expected payloads before promoting any workflow to live. Never store production API keys or tokens in workflow node configuration fields; use the credential store exclusively.

02Per-tool integration detail

HubSpot

Acts as the primary trigger source and the system of record for deal stage. The automation reads deal and contact fields on trigger, and writes stage updates and document metadata back at two points: when the quote is sent and when the deal closes as Won or Lost.

Auth method
OAuth 2.0 private app token. Generate under Settings > Integrations > Private Apps. Token is long-lived but must be rotated annually. Store as credential hs_private_app_token.
Required scopes
crm.objects.deals.read | crm.objects.deals.write | crm.objects.contacts.read | crm.schemas.deals.read | crm.schemas.contacts.read | oauth | timeline
Webhook / trigger setup
Configure a HubSpot workflow (internal) to POST to the automation platform inbound webhook URL when dealstage equals 'Quote Requested'. Alternatively, use the automation platform's HubSpot polling trigger on a 2-minute interval as a fallback. Validate the request signature using the X-HubSpot-Signature-v3 header and the client secret stored as credential hs_client_secret.
Required configuration
HubSpot pipeline ID for the sales pipeline must be stored as credential hs_pipeline_id. Stage internal values for 'Quote Requested', 'Quote Sent', 'Won', and 'Lost' must be stored as credentials hs_stage_quote_requested, hs_stage_quote_sent, hs_stage_won, hs_stage_lost. Do not hardcode stage labels; use internal values only.
Rate limits
Private app tokens are subject to 100 requests per 10 seconds per token and 250,000 requests per day. At ~40 quotes/month (approx. 210 automation runs/month), peak concurrent load is well below limits. No throttling layer is required at current volume.
Constraints
The HubSpot workflow trigger fires on deal stage save; do not rely on contact-level events for the primary trigger. Custom properties used as source fields (e.g. hs_quote_doc_id) must be created in the HubSpot schema before the workflow goes live. Association lookups (deal-to-contact) count as separate API calls.
Google Sheets

Serves as the master pricing lookup table for the Quote Builder Agent. The automation reads rows from a named sheet to match product codes or service identifiers to current unit prices, discount bands, and line-item descriptions. The sheet must be structured as a clean flat lookup table with no merged cells.

Auth method
OAuth 2.0 service account. Create a service account in Google Cloud Console, download the JSON key, and share the target spreadsheet with the service account email (Viewer permission is sufficient for reads). Store the full JSON key as credential gsheets_service_account_json.
Required scopes
https://www.googleapis.com/auth/spreadsheets.readonly | https://www.googleapis.com/auth/drive.readonly (only if spreadsheet must be located by name rather than ID)
Webhook / trigger setup
No webhook required. The Quote Builder Agent queries the sheet synchronously when a quote build is triggered. Use the Sheets API v4 GET spreadsheets/{spreadsheetId}/values/{range} endpoint.
Required configuration
The spreadsheet ID must be stored as credential gsheets_pricing_sheet_id. The named range or sheet tab name for the pricing table must be stored as credential gsheets_pricing_range (e.g. 'Pricing!A1:G200'). Do not hardcode the spreadsheet URL or range in workflow nodes.
Rate limits
Sheets API v4 allows 300 read requests per minute per project and 60 per minute per user. At current volume (40 quotes/month) the workflow makes fewer than 5 read calls per hour on average. No throttling required.
Constraints
The pricing sheet must have a header row with exact column names matching the field mapping in Section 03. Merged cells, formula-dependent values that return blank on API read, and hidden rows will cause lookup failures. The FullSpec team will validate sheet structure during the Discovery and Data Audit stage before build begins.
PandaDoc

Handles quote document generation, hosts the e-sign flow, and emits webhook events when the document is viewed or signed. The Quote Builder Agent creates the draft document via API; the Approval and Send Agent transitions the document status; the Follow-up and Close Agent listens for signing events.

Auth method
API key (Bearer token). Generate under Settings > Integrations > API. Store as credential pandadoc_api_key. For OAuth flows (if workspace SSO is enforced), use Authorization Code flow with credentials pandadoc_client_id and pandadoc_client_secret.
Required scopes
read+write (API key grants full document scope by default). For OAuth: documents:read | documents:write | templates:read | webhooks:read | webhooks:write
Webhook / trigger setup
Register a webhook endpoint in PandaDoc under Settings > Integrations > Webhooks. Subscribe to events: document_state_changed, document_viewed, document_completed. The automation platform must expose a public HTTPS endpoint; store the URL as credential pandadoc_webhook_url. Validate the X-PandaDoc-Signature header using the shared secret stored as credential pandadoc_webhook_secret.
Required configuration
The PandaDoc template ID for the quote template must be stored as credential pandadoc_template_id. Do not reference the template by name; template names are mutable. The workspace folder ID for generated quotes (if folder organisation is in use) must be stored as credential pandadoc_folder_id. Template variable placeholder names must exactly match the values defined in Section 03.
Rate limits
PandaDoc Business plan allows 1,000 API requests per hour. At 40 quotes/month, peak usage is approximately 6 API calls per quote (create, fetch status, send, fetch events), totalling under 250 calls/month. No throttling required.
Constraints
Documents in 'Draft' status cannot be sent externally; the workflow must transition the document to 'Sent' via the API before the prospect receives it. Template variable keys are case-sensitive. A document cannot be edited after it transitions to 'Sent'; any correction requires voiding and regenerating.
Integration and API SpecPage 1 of 3
FS-DOC-05Technical
Gmail

Delivers the approved quote to the prospect and sends the timed follow-up email sequence. The automation sends on behalf of the authenticated user account (typically a shared sales alias). Gmail is not used for inbound parsing in this workflow.

Auth method
OAuth 2.0, user-delegated. Authenticate as the sending Gmail account and store the refresh token as credential gmail_refresh_token and the associated client credentials as gmail_client_id and gmail_client_secret. Use the Google Cloud Console project created for Sheets if sharing a project.
Required scopes
https://www.googleapis.com/auth/gmail.send | https://www.googleapis.com/auth/gmail.compose (do not request gmail.readonly or gmail.modify unless inbound processing is added in a future phase)
Webhook / trigger setup
No inbound webhook required for this workflow. Gmail is used as an outbound action only. Email send actions are triggered programmatically by the automation platform via the Gmail API v1 POST users/{userId}/messages/send endpoint.
Required configuration
The sending email address must be stored as credential gmail_sender_address. The quote email subject line template and the follow-up email subject line templates must be stored as credentials gmail_subject_quote and gmail_subject_followup_d3 and gmail_subject_followup_d7 respectively. Cover message body templates containing merge variables ({prospect_first_name}, {quote_link}, {rep_name}) must be stored in the credential store or a configuration document, not inline in workflow nodes.
Rate limits
Gmail API allows 250 quota units per user per second and 1,000,000,000 quota units per day. Sending one email costs 100 units. At current volume (40 quotes plus up to 80 follow-ups per month) the workflow uses under 12,000 units/month. No throttling required.
Constraints
OAuth refresh tokens expire if unused for 6 months or if the user revokes access. Implement token refresh handling in the automation platform; alert via Slack to the ops channel if a refresh token error is detected. Gmail enforces a 500 recipients per day limit for standard Workspace accounts; this is not a constraint at current volume.
Slack

Receives the approval request message from the Approval and Send Agent and captures the manager's structured response (approve or reject). The workflow uses Block Kit interactive messages so the approval is a button click rather than a free-text reply.

Auth method
OAuth 2.0 bot token. Install a custom Slack app to the workspace and grant bot permissions. Store the bot token as credential slack_bot_token. Store the signing secret as credential slack_signing_secret for payload validation.
Required scopes
chat:write | chat:write.public | channels:read | incoming-webhook | commands (if slash-command override is implemented) | interactivity (must be enabled in the Slack app settings to support button interactions)
Webhook / trigger setup
Enable Interactivity in the Slack app configuration and set the Request URL to the automation platform's Slack interaction endpoint. Store this endpoint URL as credential slack_interactivity_url. Validate incoming payloads using the X-Slack-Signature header and the slack_signing_secret credential. The approval channel ID (not name) must be stored as credential slack_approval_channel_id.
Required configuration
The Slack user ID of the sales manager who receives approval requests must be stored as credential slack_approver_user_id. If multiple approvers are possible in future, this becomes an array. The Block Kit template for the approval message (containing quote value, discount percentage, and PandaDoc review link) must be stored as a configuration asset, not hardcoded in the workflow node.
Rate limits
Slack's Web API tier 3 rate limit is 50 requests per minute for chat.postMessage. At 40 quotes/month this workflow sends at most 40 approval messages plus confirmations, well within limits. No throttling required.
Constraints
Interactive payloads from Slack button clicks have a 3-second response window before Slack marks the interaction as failed. The automation platform must acknowledge the interaction immediately (HTTP 200) and process the approval asynchronously. If the approver does not respond within the configured timeout window (recommended: 24 hours), the workflow must escalate or alert rather than remain blocked indefinitely.
Xero

Receives invoice creation instructions from the Follow-up and Close Agent when a PandaDoc signing event confirms quote acceptance. The automation creates a draft invoice in Xero using line items and values sourced directly from the PandaDoc document, eliminating manual re-entry.

Auth method
OAuth 2.0 with PKCE (Authorization Code flow). Xero does not support API key auth for production. Complete the OAuth flow in the automation platform's Xero credential module and store the resulting refresh token as credential xero_refresh_token, with xero_client_id and xero_client_secret also in the store. Access tokens expire after 30 minutes; use the refresh token flow automatically.
Required scopes
accounting.transactions | accounting.contacts.read | accounting.settings.read (do not request accounting.reports or payroll scopes; principle of least privilege applies)
Webhook / trigger setup
No inbound Xero webhook is required for this workflow. Invoice creation is an outbound API action triggered by the automation platform on receipt of a PandaDoc document_completed event. Use the Xero API v2 POST /api.xro/2.0/Invoices endpoint.
Required configuration
The Xero tenant ID (organisation ID) must be stored as credential xero_tenant_id. The Xero account code for sales revenue (used on invoice line items) must be stored as credential xero_revenue_account_code. The default invoice due-date offset in days must be stored as credential xero_invoice_due_days. Do not hardcode the account code or tenant ID.
Rate limits
Xero allows 60 API calls per minute and 5,000 calls per day per app. At 40 quotes/month the workflow makes approximately 40 invoice creation calls per month. No throttling required.
Constraints
The Xero contact must exist before an invoice can be created against it. The workflow must perform a contact lookup by email before invoice creation and create the contact if absent. Xero draft invoices have status DRAFT and must not be automatically submitted or approved by the automation; that remains a human step. The Xero Starter plan limits the number of invoices per month; confirm the plan allows current and projected volume before go-live.

03Field mappings between tools

The tables below define every field translation that occurs at each agent handoff point. Use exact field names as shown; PandaDoc variable keys are case-sensitive, HubSpot internal property names use snake_case, and Google Sheets column headers must match exactly.

Handoff 1: HubSpot to Quote Builder Agent (Agent 1 input)

Source tool
Source field
Destination tool
Destination field
HubSpot
dealname
Quote Builder Agent (working context)
deal_name
HubSpot
amount
Quote Builder Agent (working context)
deal_value
HubSpot
hubspot_owner_id
Quote Builder Agent (working context)
rep_owner_id
HubSpot
hs_object_id
Quote Builder Agent (working context)
deal_id
HubSpot
closedate
Quote Builder Agent (working context)
expected_close_date
HubSpot
associations.contacts[0].email
Quote Builder Agent (working context)
prospect_email
HubSpot
associations.contacts[0].firstname
Quote Builder Agent (working context)
prospect_first_name
HubSpot
associations.contacts[0].lastname
Quote Builder Agent (working context)
prospect_last_name
HubSpot
associations.companies[0].name
Quote Builder Agent (working context)
prospect_company
HubSpot
hs_custom_discount_pct
Quote Builder Agent (working context)
requested_discount_pct

Handoff 2: Google Sheets to PandaDoc (Agent 1 document build)

Source tool
Source field
Destination tool
Destination field
Google Sheets
product_code
PandaDoc template variable
line_item_sku
Google Sheets
product_name
PandaDoc template variable
line_item_description
Google Sheets
unit_price
PandaDoc template variable
line_item_unit_price
Google Sheets
quantity
PandaDoc template variable (derived from deal)
line_item_quantity
Google Sheets
discount_band_max_pct
Quote Builder Agent (rule check)
discount_threshold
HubSpot (via working context)
prospect_first_name
PandaDoc template variable
client_first_name
HubSpot (via working context)
prospect_last_name
PandaDoc template variable
client_last_name
HubSpot (via working context)
prospect_company
PandaDoc template variable
client_company_name
HubSpot (via working context)
prospect_email
PandaDoc template variable
client_email
HubSpot (via working context)
deal_name
PandaDoc template variable
quote_title
HubSpot (via working context)
expected_close_date
PandaDoc template variable
quote_expiry_date
HubSpot (via working context)
requested_discount_pct
PandaDoc template variable
applied_discount_pct

Handoff 3: PandaDoc to Approval and Send Agent (Agent 2 trigger and payload)

Source tool
Source field
Destination tool
Destination field
PandaDoc
document.id
Approval and Send Agent (working context)
pandadoc_document_id
PandaDoc
document.status
Approval and Send Agent (rule check)
document_status
PandaDoc
document.total
Slack approval message
quote_total_value
PandaDoc
document.links[0].href
Slack approval message
pandadoc_review_link
HubSpot (via working context)
rep_owner_id
Slack approval message
rep_display_name (resolved via HubSpot owners API)
HubSpot (via working context)
requested_discount_pct
Slack approval message
discount_pct_displayed
HubSpot (via working context)
deal_name
Slack approval message
deal_name_displayed

Handoff 4: Approval and Send Agent writes back to HubSpot and Gmail

Source tool
Source field
Destination tool
Destination field
PandaDoc (via working context)
pandadoc_document_id
HubSpot property
hs_quote_doc_id
Approval and Send Agent (timestamp)
send_timestamp (ISO 8601)
HubSpot property
hs_quote_sent_date
Approval and Send Agent (stage value)
hs_stage_quote_sent
HubSpot deal property
dealstage
HubSpot (via working context)
prospect_email
Gmail recipient field
to_address
HubSpot (via working context)
prospect_first_name
Gmail message body merge
{prospect_first_name}
PandaDoc (via working context)
pandadoc_review_link
Gmail message body merge
{quote_link}
HubSpot (owner lookup)
rep_full_name
Gmail message body merge
{rep_name}

Handoff 5: PandaDoc webhook to Follow-up and Close Agent and then Xero (Agent 3)

Source tool
Source field
Destination tool
Destination field
PandaDoc webhook payload
event.data.id
Follow-up and Close Agent (working context)
pandadoc_document_id
PandaDoc webhook payload
event.type
Follow-up and Close Agent (decision branch)
event_type (document_completed or document_viewed)
PandaDoc API (on completed event)
document.pricing.total
Xero invoice
LineItems[].UnitAmount (summed)
PandaDoc API (on completed event)
document.pricing.tables[].items[].name
Xero invoice
LineItems[].Description
PandaDoc API (on completed event)
document.pricing.tables[].items[].qty
Xero invoice
LineItems[].Quantity
PandaDoc API (on completed event)
document.pricing.tables[].items[].price
Xero invoice
LineItems[].UnitAmount
HubSpot (via working context)
prospect_email
Xero contact lookup
EmailAddress (match or create)
HubSpot (via working context)
prospect_company
Xero contact
Name
Follow-up and Close Agent (rule)
outcome (won or lost or expired)
HubSpot deal property
dealstage (hs_stage_won or hs_stage_lost)
Integration and API SpecPage 2 of 3
FS-DOC-05Technical

04Build stack and orchestration

Orchestration layout
One discrete workflow per agent: Workflow 1 (Quote Builder Agent), Workflow 2 (Approval and Send Agent), Workflow 3 (Follow-up and Close Agent). Agents are chained via internal events or shared state variables rather than direct function calls. All three workflows share a single credential store; no credentials are duplicated across workflows.
Workflow 1 trigger (Quote Builder Agent)
Inbound webhook from HubSpot native workflow, firing on dealstage change to hs_stage_quote_requested. Payload validated using HMAC-SHA256 against hs_client_secret before processing begins. Fallback: polling trigger on HubSpot deals API filtered by dealstage every 2 minutes if webhook delivery fails.
Workflow 2 trigger (Approval and Send Agent)
Internal event emitted by Workflow 1 when the PandaDoc draft document is successfully created and the deal is flagged as approval-required. Event carries deal_id and pandadoc_document_id. If discount is below threshold, Workflow 2 is triggered directly without the Slack approval branch (conditional skip).
Workflow 3 trigger (Follow-up and Close Agent)
Internal event emitted by Workflow 2 on confirmed Gmail send, carrying deal_id, pandadoc_document_id, and send_timestamp. Workflow 3 also registers for the PandaDoc webhook events (document_completed, document_viewed) and manages a timer for Day 3 and Day 7 follow-up emails using the automation platform's scheduler. Scheduler entries are keyed by deal_id to allow cancellation on early response.
Slack interaction handling
Workflow 2 exposes an HTTPS endpoint to receive Slack interactivity payloads. Payload validation uses HMAC-SHA256 against slack_signing_secret. The endpoint returns HTTP 200 immediately and queues the approval decision for async processing to satisfy Slack's 3-second acknowledgement requirement.
PandaDoc webhook handling
The automation platform exposes a dedicated HTTPS endpoint for PandaDoc events. Payloads are validated using the X-PandaDoc-Signature header against pandadoc_webhook_secret. Events are filtered by document ID to route to the correct Workflow 3 instance for the relevant deal.
Discount threshold rule
The 15% discount threshold (agreed with sales manager, April 5) is stored as a configuration variable discount_approval_threshold_pct in the credential store. Changing the threshold requires updating only this value; no workflow logic needs rebuilding.

Credential store contents (all values below must be populated before any workflow is activated):

Credential store: all entries reference secrets by key; no plaintext values enter workflow node configuration
// HubSpot
hs_private_app_token          = '<HubSpot private app token>'
hs_client_secret              = '<HubSpot app client secret for signature validation>'
hs_pipeline_id                = '<internal pipeline ID from HubSpot>'
hs_stage_quote_requested      = '<internal stage value>'
hs_stage_quote_sent           = '<internal stage value>'
hs_stage_won                  = '<internal stage value>'
hs_stage_lost                 = '<internal stage value>'

// Google Sheets
gsheets_service_account_json  = '<full JSON key string for service account>'
gsheets_pricing_sheet_id      = '<spreadsheet ID from URL>'
gsheets_pricing_range         = 'Pricing!A1:G200'

// PandaDoc
pandadoc_api_key              = '<PandaDoc API Bearer token>'
pandadoc_client_id            = '<OAuth client ID if OAuth flow used>'
pandadoc_client_secret        = '<OAuth client secret if OAuth flow used>'
pandadoc_template_id          = '<quote template ID from PandaDoc>'
pandadoc_folder_id            = '<target folder ID (optional)>'
pandadoc_webhook_url          = '<automation platform inbound HTTPS endpoint>'
pandadoc_webhook_secret       = '<shared secret set in PandaDoc webhook config>'

// Gmail
gmail_client_id               = '<Google Cloud OAuth client ID>'
gmail_client_secret           = '<Google Cloud OAuth client secret>'
gmail_refresh_token           = '<refresh token from OAuth authorisation>'
gmail_sender_address          = '<sending alias e.g. sales@[YourCompany.com]>'
gmail_subject_quote           = 'Your quote from [YourCompany.com]: {quote_title}'
gmail_subject_followup_d3     = 'Just checking in on your quote, {prospect_first_name}'
gmail_subject_followup_d7     = 'Your quote expires soon — any questions?'

// Slack
slack_bot_token               = '<xoxb- prefixed bot token>'
slack_signing_secret          = '<Slack app signing secret>'
slack_approval_channel_id     = '<channel ID not channel name>'
slack_approver_user_id        = '<Slack user ID of sales manager>'
slack_interactivity_url       = '<automation platform HTTPS endpoint for interactions>'

// Xero
xero_client_id                = '<Xero OAuth app client ID>'
xero_client_secret            = '<Xero OAuth app client secret>'
xero_refresh_token            = '<refresh token from Xero PKCE OAuth flow>'
xero_tenant_id                = '<Xero organisation/tenant ID>'
xero_revenue_account_code     = '<chart of accounts code for sales revenue>'
xero_invoice_due_days         = '30'

// Global configuration
discount_approval_threshold_pct = '15'
followup_day3_offset_hours    = '72'
followup_day7_offset_hours    = '168'
The credential store must be the sole location for all tokens, secrets, and configuration constants. Rotate API keys and OAuth tokens on the schedule required by each vendor. Set calendar reminders: HubSpot private app tokens annually, Xero refresh tokens every 60 days if the app is inactive, Gmail refresh tokens every 6 months if unused. Any rotation must be applied in the credential store only; no workflow code changes are needed.

05Error handling and retry logic

Every integration point must have a defined failure behaviour. Unhandled exceptions must never fail silently. All retry attempts use exponential backoff starting at 30 seconds unless stated otherwise. After the final retry, the workflow must route to the manual fallback defined in each row.

Integration
Scenario
Required behaviour
HubSpot (inbound webhook)
Webhook payload fails HMAC-SHA256 signature check
Reject immediately with HTTP 401. Log the event with timestamp and raw payload hash. Do not process the trigger. Alert to Slack ops channel. No retry (invalid payload).
HubSpot (deal read)
API returns 429 Too Many Requests
Retry with exponential backoff: 30 s, 60 s, 120 s (3 attempts). If all fail, pause workflow and post alert to Slack ops channel. Log deal_id for manual re-trigger.
HubSpot (deal write / stage update)
API returns 5xx server error on stage write
Retry 3 times with backoff (30 s, 60 s, 120 s). On persistent failure, log the intended write payload and post a Slack ops alert with deal_id and target stage value for manual correction.
Google Sheets (pricing lookup)
Spreadsheet returns empty range or row not found for product code
Halt quote generation. Post alert to Slack ops channel with deal_id and unmatched product_code. Do not generate a partial quote. Require manual review of the pricing sheet before re-triggering.
Google Sheets (pricing lookup)
API returns 403 Forbidden (service account permission revoked)
Halt immediately. Alert Slack ops channel with error detail. No retry until service account permissions are restored. Manual fallback: rep generates quote manually until access is confirmed.
PandaDoc (document creation)
API returns 422 Unprocessable Entity (template variable mismatch)
Halt document build. Log the full API error response including which field keys failed. Post Slack ops alert with deal_id. Do not retry automatically; mismatched keys require a configuration fix before re-run.
PandaDoc (document creation)
API returns 5xx or network timeout
Retry 3 times with backoff (30 s, 90 s, 180 s). If all fail, post Slack ops alert and log deal_id. Manual fallback: rep is notified to create the PandaDoc document manually.
Slack (approval message send)
chat.postMessage returns error (channel not found, bot not in channel)
Retry once after 60 s. If second attempt fails, send the approval request via Gmail directly to the sales manager's email address as a fallback. Log the Slack error and alert the ops channel.
Slack (approval interaction)
No approval response received within 24-hour timeout window
Post a reminder message to the approval channel tagging the approver. Wait a further 4 hours. If still no response, escalate by sending an email to the sales manager and logging the deal as 'Approval Pending' in HubSpot. Never allow the workflow to remain blocked indefinitely.
Gmail (quote send)
OAuth token refresh fails (refresh token expired or revoked)
Halt send action immediately. Post Slack ops alert with error detail. No retry until OAuth credentials are re-authorised via the credential store. Manual fallback: sales rep is notified to send the quote directly from Gmail.
Gmail (follow-up email send)
API returns 429 or 5xx during timed follow-up
Retry up to 3 times with backoff (1 min, 5 min, 15 min). If all fail, log the deal_id and scheduled follow-up date and post Slack ops alert. Rescheduled send must be attempted within 2 hours of original scheduled time or skipped with a logged reason.
Xero (invoice creation)
Contact lookup returns no match and contact creation fails
Retry contact creation once after 30 s. If second attempt fails, create the invoice with a placeholder contact name drawn from prospect_company and flag the invoice with a custom reference noting manual contact linkage is required. Post Slack ops alert.
Xero (invoice creation)
API returns 403 Forbidden (OAuth scope insufficient or tenant ID mismatch)
Halt immediately. Do not retry. Post Slack ops alert with full error detail and deal_id. Manual fallback: sales rep is notified to create the Xero invoice manually. Ops team must re-authorise Xero credentials before the automation resumes.
All error events must be written to a persistent log accessible to the FullSpec team and to the designated ops contact at [YourCompany.com]. Log entries must include: timestamp (UTC), workflow name, deal_id, integration name, HTTP status code or error type, retry count, and outcome. Slack ops alerts are the primary real-time notification channel; the ops Slack channel ID must be stored as a credential alongside the approval channel. Contact support@gofullspec.com for any integration failure that cannot be resolved via the manual fallback procedures described above.
Integration and API SpecPage 3 of 3

More documents for this process

Every document generated for Quote Generation & Follow-up.

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