FS-DOC-05Technical
Integration and API Spec
Contract Generation and E-sign
[YourCompany.com] · Sales Department · Prepared by FullSpec · [Today's Date]
This document is the definitive technical reference for every integration point in the Contract Generation and E-sign automation. It covers authentication methods, required OAuth scopes, webhook configuration, exact field mappings between tools, credential storage conventions, orchestration layout, and failure handling for all five tools and the orchestration layer. The FullSpec team uses this document to build, configure, and validate each connection. No credentials should be hardcoded and no production connection should be opened before sandbox verification is complete.
01Tool inventory
Tool
Role in automation
Auth method
Min plan required
Used by agent(s)
HubSpot
Deal data source; CRM record sync and contract status update
OAuth 2.0 (private app token)
Sales Hub Starter or above (API access required)
Agent 1, Agent 3
Google Drive
Contract template storage; merged document output storage
OAuth 2.0 (service account or user OAuth)
Google Workspace Business Starter or above
Agent 1
DocuSign
E-signature envelope creation, dispatch, and status tracking
OAuth 2.0 (JWT grant / Authorization Code)
DocuSign eSignature Standard or above
Agent 2, Agent 3
Gmail
Timed follow-up email delivery to the customer contact
OAuth 2.0 (user OAuth via Google Identity)
Google Workspace (any tier with Gmail API enabled)
Agent 2
Slack
Manager review prompt; post-signature completion notification
OAuth 2.0 (Bot Token via Slack App)
Slack Pro or above (for workflow app installs)
Agent 1, Agent 3
Automation platform (orchestration layer)
Orchestrates all agents; holds credential store; manages triggers, retries, and routing
Platform-managed credential vault (per-tool OAuth tokens stored centrally)
As per selected automation platform subscription ($60/month budgeted)
All agents
Before you connect anything: configure and validate every integration in a sandbox or developer environment before any production credentials are entered. For HubSpot, use a sandbox portal. For DocuSign, use the developer sandbox at account-d.docusign.com. For Google, use a test Workspace account. For Slack, use a private test workspace. Production OAuth tokens must only be added after end-to-end sandbox testing passes.
02Per-tool integration detail
HubSpot
Provides the deal trigger event and deal property payload for Agent 1. Receives the signed PDF attachment and contract status property update from Agent 3. All access is via the HubSpot Private App token model.
Auth method
OAuth 2.0 via HubSpot Private App. Generate a private app token in Settings > Integrations > Private Apps. Store the token in the credential store as HUBSPOT_PRIVATE_APP_TOKEN. Do not use legacy API keys.
Required scopes
crm.objects.deals.read, crm.objects.deals.write, crm.objects.contacts.read, crm.objects.companies.read, crm.objects.files.write, timeline.write
Webhook / trigger setup
Subscribe to the deal property change event for dealstage. Filter on dealstage value equal to the internal identifier for Closed Won (retrieve via GET /crm/v3/pipelines/deals to confirm the stage ID). Register the webhook endpoint in the private app Webhooks tab. Validate the X-HubSpot-Signature-Version: v3 header on every inbound request using HMAC-SHA256 against the app client secret stored as HUBSPOT_WEBHOOK_SECRET.
Required configuration
Store the target pipeline ID and Closed Won stage ID in the credential store (HUBSPOT_PIPELINE_ID, HUBSPOT_CLOSEDWON_STAGE_ID). The deal properties to be read at trigger time are: dealname, amount, closedate, hs_deal_stage_probability, deal_type, customer_name, customer_email, customer_address, product_line, payment_terms, contract_type. Confirm all properties exist and are consistently populated before go-live. The CRM property for contract status (contract_status) must be created as a single-line text property on the Deal object if not already present.
Rate limits
HubSpot Private Apps: 100 requests per 10 seconds, 250,000 per day (Starter tier). At ~62 contracts/month the automation generates fewer than 10 API calls per deal (trigger read, properties read, file attach, property write). Total estimated monthly calls: under 700. No throttling required at current volume.
Constraints
File attachments via the Files API are limited to 100 MB per file. Signed PDFs are typically under 5 MB. The webhook payload does not include all deal properties; a secondary GET /crm/v3/objects/deals/{dealId}?properties=... call is required immediately after the trigger fires to fetch the full property set.
// Trigger payload (webhook POST)
{ "objectId": "<deal_id>", "propertyName": "dealstage", "propertyValue": "<stage_id>" }
// Secondary read (GET /crm/v3/objects/deals/{dealId})
Properties fetched: dealname, amount, closedate, deal_type, customer_name,
customer_email, customer_address, product_line, payment_terms, contract_type
// Write back (PATCH /crm/v3/objects/deals/{dealId})
{ "properties": { "contract_status": "Signed", "hs_file_upload": "<signed_pdf_url>" } }Google Drive
Stores the library of contract templates and receives the merged output document. Agent 1 reads templates and writes the populated draft. A dedicated shared drive folder structure separates templates from outputs.
Auth method
OAuth 2.0 via a Google service account (recommended for server-side automation). Generate a service account in Google Cloud Console, grant it Editor access to the templates folder and output folder. Store the service account JSON key as GOOGLE_SERVICE_ACCOUNT_JSON in the credential store. Alternatively, use a user OAuth 2.0 flow with offline access and store the refresh token as GOOGLE_OAUTH_REFRESH_TOKEN.
Required scopes
https://www.googleapis.com/auth/drive.readonly (template reads), https://www.googleapis.com/auth/drive.file (output creation), https://www.googleapis.com/auth/documents (Google Docs merge operations)
Webhook / trigger setup
No inbound webhook required. Agent 1 reads templates on demand when triggered by HubSpot. If change detection on the template folder is needed in future, use the Drive API push notifications (channels.watch) endpoint.
Required configuration
Store the following IDs in the credential store: GDRIVE_TEMPLATES_FOLDER_ID (folder containing all contract template files), GDRIVE_OUTPUT_FOLDER_ID (folder where merged drafts are saved). Each template file must be a Google Doc (not a PDF or DOCX upload). Template selection logic maps the deal property contract_type to a template file ID stored in the config map GDRIVE_TEMPLATE_MAP (e.g., {"standard": "<file_id>", "enterprise": "<file_id>", "nda": "<file_id>"}). Template placeholders must use the format {{placeholder_name}} and correspond exactly to the deal property keys (e.g., {{customer_name}}, {{amount}}, {{payment_terms}}, {{closedate}}).
Rate limits
Google Drive API: 12,000 read requests per minute per user, 1,200 write requests per minute. Google Docs API: 300 requests per minute per project. At 62 contracts/month, peak load is negligible. No throttling required.
Constraints
The Docs API batchUpdate replaceAllText method is used for placeholder substitution. Nested tables or text inside drawing objects are not substituted by replaceAllText and must be avoided in templates. After merge, export the document as PDF using the Drive export endpoint (application/pdf) before uploading to DocuSign.
// Template read
GET https://docs.googleapis.com/v1/documents/{templateDocId}
// Merge (placeholder substitution)
POST https://docs.googleapis.com/v1/documents/{copiedDocId}:batchUpdate
{ "requests": [ { "replaceAllText": { "containsText": { "text": "{{customer_name}}" },
"replaceText": "<deal.customer_name>" } } ] }
// Export merged doc as PDF
GET https://www.googleapis.com/drive/v3/files/{docId}/export?mimeType=application/pdf
// Output stored at
GDRIVE_OUTPUT_FOLDER_ID / {dealname}_{closedate}_draft.pdfDocuSign
Receives the merged PDF from Google Drive and creates a signature envelope for the customer. Agent 2 polls envelope status to trigger follow-up logic. Agent 3 responds to the envelope completed event to retrieve the signed PDF.
Auth method
OAuth 2.0 JWT Grant (recommended for server-side automation without user interaction). Register an integration key in the DocuSign Developer Console, upload an RSA public key, and store the RSA private key as DOCUSIGN_RSA_PRIVATE_KEY. The JWT assertion is signed with the private key and exchanged for an access token at the /oauth/token endpoint. Store the integration key as DOCUSIGN_INTEGRATION_KEY and the impersonated user GUID as DOCUSIGN_USER_ID.
Required scopes
signature, impersonation
Webhook / trigger setup
Configure a Connect webhook (DocuSign Connect) for the account to POST envelope status events to the automation platform inbound endpoint. Subscribe to the following envelope events: envelope-sent, envelope-delivered, envelope-completed, envelope-voided, envelope-declined. Validate the X-DocuSign-Signature-1 HMAC-SHA256 header on all inbound events using the Connect HMAC key stored as DOCUSIGN_CONNECT_HMAC_KEY. Store the automation platform inbound URL as DOCUSIGN_CONNECT_ENDPOINT.
Required configuration
Store DOCUSIGN_ACCOUNT_ID and DOCUSIGN_BASE_URL (e.g., https://na4.docusign.net for production; https://demo.docusign.net for sandbox) in the credential store. Envelope creation uses the EnvelopeDefinition with a single document (the exported PDF), one signer recipient (customer_email and customer_name from the deal), and pre-placed signature tabs. Tab positions (anchor strings) must be defined per template during setup: store the anchor string map per template in DOCUSIGN_TAB_ANCHOR_MAP. Do not hardcode anchor strings in workflow logic.
Rate limits
DocuSign eSignature API: 1,000 API calls per hour (Standard plan). At 62 envelopes/month plus status polls, estimated monthly API calls are under 500. No throttling required. Connect webhook events do not count toward API call limits.
Constraints
The signed PDF download is available via GET /accounts/{accountId}/envelopes/{envelopeId}/documents/combined only after status is 'completed'. JWT tokens expire after 1 hour; the orchestration layer must refresh the token before expiry. Sandbox envelopes and production envelopes share no state; all testing must use the developer sandbox (account-d.docusign.com) with a separate DOCUSIGN_SANDBOX_ACCOUNT_ID credential.
// Create envelope
POST https://{DOCUSIGN_BASE_URL}/restapi/v2.1/accounts/{DOCUSIGN_ACCOUNT_ID}/envelopes
{ "emailSubject": "Your contract is ready to sign",
"documents": [{ "documentBase64": "<pdf_base64>", "name": "{dealname}_contract.pdf", "documentId": "1" }],
"recipients": { "signers": [{ "email": "{customer_email}",
"name": "{customer_name}", "recipientId": "1",
"tabs": { "signHereTabs": [{ "anchorString": "{DOCUSIGN_TAB_ANCHOR_MAP[contract_type]}",
"anchorUnits": "pixels" }] } }] },
"status": "sent" }
// Poll or receive webhook for status
GET /accounts/{accountId}/envelopes/{envelopeId}
-> { "status": "completed" | "sent" | "delivered" | "voided" | "declined" }
// Download signed PDF
GET /accounts/{accountId}/envelopes/{envelopeId}/documents/combinedIntegration and API SpecPage 1 of 4
FS-DOC-05Technical
Gmail
Delivers timed follow-up emails to the customer if the DocuSign envelope has not been opened or signed within defined windows. Agent 2 controls this step. Emails are sent from the authenticated sales user account, not a generic system address.
Auth method
OAuth 2.0 with offline access via Google Identity. The sales user account (or a dedicated send-from alias) must complete the OAuth consent flow once. Store the refresh token as GMAIL_OAUTH_REFRESH_TOKEN and the sender address as GMAIL_SENDER_ADDRESS in the credential store.
Required scopes
https://www.googleapis.com/auth/gmail.send
Webhook / trigger setup
No inbound webhook. Gmail is an outbound action only. Agent 2 is scheduled by the orchestration layer to run at T+48h and T+96h from the envelope sent timestamp (stored as envelope_sent_at on the run record). Before each send, Agent 2 checks the current DocuSign envelope status; if status is 'completed' or 'voided', the follow-up is suppressed.
Required configuration
Follow-up email templates are stored as plain-text or HTML strings in the credential store or a config table, keyed as GMAIL_FOLLOWUP_48H_TEMPLATE and GMAIL_FOLLOWUP_96H_TEMPLATE. Templates use {{customer_name}}, {{dealname}}, and {{docusign_envelope_link}} as placeholders. The DocuSign signing URL for the recipient is retrieved via GET /accounts/{accountId}/envelopes/{envelopeId}/recipients and stored on the run record at envelope creation time.
Rate limits
Gmail API sending quota: 500 messages per day (Google Workspace). At 62 contracts/month with up to two follow-ups each, maximum daily send volume is approximately 4 emails. No throttling required.
Constraints
The gmail.send scope does not grant read access to the inbox. Access tokens expire after 1 hour; the orchestration layer must use the refresh token to obtain a new access token before each send. If the refresh token is revoked (user re-authenticates or password changes), the automation must alert via Slack (SLACK_OPS_CHANNEL_ID) and halt follow-up sends.
// Send follow-up (48h)
POST https://gmail.googleapis.com/gmail/v1/users/me/messages/send
Authorization: Bearer {access_token}
{ "raw": "<base64url-encoded RFC 2822 message>" }
// Message headers
To: {customer_email}
From: {GMAIL_SENDER_ADDRESS}
Subject: Reminder: Your contract is waiting for your signature
Body: GMAIL_FOLLOWUP_48H_TEMPLATE rendered with {{customer_name}}, {{dealname}}, {{docusign_envelope_link}}Slack
Handles two distinct interactions: the manager review prompt posted by Agent 1 (with an approve action), and the post-signature completion notification posted by Agent 3 to the sales, finance, and delivery channels.
Auth method
OAuth 2.0 via a Slack App Bot Token. Create a Slack App in the Slack API console, install it to the workspace, and store the Bot User OAuth Token as SLACK_BOT_TOKEN. Store the Signing Secret as SLACK_SIGNING_SECRET for validating inbound interaction payloads.
Required scopes
chat:write, chat:write.public, channels:read, incoming-webhook (for notification posts); additionally commands and interactivity must be enabled for the manager approval button interaction
Webhook / trigger setup
Enable Interactivity in the Slack App settings and set the Request URL to the automation platform inbound endpoint (store as SLACK_INTERACTIVITY_ENDPOINT). All inbound payloads from button clicks (manager approve/reject) must be validated using the SLACK_SIGNING_SECRET via HMAC-SHA256 on the raw request body with the X-Slack-Request-Timestamp and X-Slack-Signature headers. Reject any request where the timestamp is older than 5 minutes.
Required configuration
Store channel IDs (not names) in the credential store: SLACK_REVIEW_CHANNEL_ID (the manager review channel), SLACK_SALES_CHANNEL_ID, SLACK_FINANCE_CHANNEL_ID, SLACK_DELIVERY_CHANNEL_ID, SLACK_OPS_CHANNEL_ID (for automation error alerts). The manager review message must be a Block Kit message containing the Google Drive preview link, deal name, deal value, customer name, and two action buttons: Approve (action_id: manager_approve) and Request Changes (action_id: manager_request_changes). The action payload must carry the deal_id and gdrive_doc_id so the orchestration layer can resume the correct workflow run.
Rate limits
Slack Web API: Tier 3 methods (chat.postMessage) allow 50+ requests per minute. At 62 contracts/month the automation posts at most 4 messages per contract (review prompt, completion to sales, completion to finance, completion to delivery). Total estimated monthly posts: under 250. No throttling required.
Constraints
Block Kit interactive messages expire; if the manager does not respond within 7 days the Slack message actions become inactive. The orchestration layer must implement a timeout: if no manager_approve action is received within 24 hours, re-post a reminder to SLACK_REVIEW_CHANNEL_ID and alert SLACK_OPS_CHANNEL_ID. Bot tokens do not grant access to private channels unless the bot is invited.
// Post manager review prompt (Agent 1 output)
POST https://slack.com/api/chat.postMessage
{ "channel": "{SLACK_REVIEW_CHANNEL_ID}",
"blocks": [ { "type": "section", "text": { "type": "mrkdwn",
"text": "*Contract ready for review*\n*Deal:* {dealname} | *Value:* ${amount}\n*Customer:* {customer_name}\n<{gdrive_preview_link}|Open contract draft>" } },
{ "type": "actions", "elements": [
{ "type": "button", "text": { "type": "plain_text", "text": "Approve" },
"style": "primary", "action_id": "manager_approve",
"value": "{deal_id}:{gdrive_doc_id}" },
{ "type": "button", "text": { "type": "plain_text", "text": "Request Changes" },
"style": "danger", "action_id": "manager_request_changes",
"value": "{deal_id}:{gdrive_doc_id}" } ] } ] }
// Post completion notification (Agent 3 output)
POST https://slack.com/api/chat.postMessage
{ "channel": "{SLACK_SALES_CHANNEL_ID}",
"text": ":white_check_mark: Contract signed: {dealname} ({customer_name}). Signed PDF attached to HubSpot deal." }03Field mappings between tools
The tables below define every field handoff between tools at each agent boundary. Use exact field names as shown. All source field names are HubSpot internal property names or API response keys. All destination field names are placeholder keys (Google Docs templates), DocuSign envelope fields, or Slack Block Kit text tokens.
Agent 1 handoff: HubSpot deal to Google Drive template merge
Source tool
Source field
Destination tool
Destination field
HubSpot
dealname
Google Drive (template)
{{dealname}}
HubSpot
amount
Google Drive (template)
{{amount}}
HubSpot
closedate
Google Drive (template)
{{closedate}}
HubSpot
customer_name
Google Drive (template)
{{customer_name}}
HubSpot
customer_email
Google Drive (template)
{{customer_email}}
HubSpot
customer_address
Google Drive (template)
{{customer_address}}
HubSpot
product_line
Google Drive (template)
{{product_line}}
HubSpot
payment_terms
Google Drive (template)
{{payment_terms}}
HubSpot
contract_type
Google Drive (config lookup)
GDRIVE_TEMPLATE_MAP key
HubSpot
hs_object_id (deal ID)
Orchestration run record
deal_id (carried through all agents)
Agent 1 handoff: Google Drive merged document to Slack review prompt
Source tool
Source field
Destination tool
Destination field
Google Drive
webViewLink (merged doc)
Slack Block Kit
gdrive_preview_link
HubSpot (run record)
dealname
Slack Block Kit
Deal name text token
HubSpot (run record)
amount
Slack Block Kit
Deal value text token
HubSpot (run record)
customer_name
Slack Block Kit
Customer name text token
Google Drive
id (merged doc file ID)
Slack action value
gdrive_doc_id
HubSpot (run record)
deal_id
Slack action value
deal_id
Agent 1 to Agent 2 handoff: Slack approval to DocuSign envelope creation
Source tool
Source field
Destination tool
Destination field
Slack interactivity payload
action_id (manager_approve)
Orchestration
Resume trigger condition
Slack interactivity payload
value (deal_id:gdrive_doc_id)
Orchestration run record
deal_id, gdrive_doc_id
Google Drive
exported PDF (binary)
DocuSign
documents[0].documentBase64
HubSpot (run record)
customer_email
DocuSign
recipients.signers[0].email
HubSpot (run record)
customer_name
DocuSign
recipients.signers[0].name
HubSpot (run record)
dealname
DocuSign
emailSubject (composed string)
HubSpot (run record)
contract_type
DocuSign config lookup
DOCUSIGN_TAB_ANCHOR_MAP key
Agent 2 handoff: DocuSign status to Gmail follow-up
Source tool
Source field
Destination tool
Destination field
DocuSign Connect event
envelopeId
Orchestration run record
envelope_id
DocuSign Connect event
status
Orchestration
Follow-up send gate (must be 'sent' or 'delivered')
DocuSign API
recipients.signers[0].recipientIdGuid -> embedded signing URL
Gmail template
{{docusign_envelope_link}}
HubSpot (run record)
customer_name
Gmail template
{{customer_name}}
HubSpot (run record)
dealname
Gmail template
{{dealname}}
HubSpot (run record)
customer_email
Gmail
To: header
Agent 3 handoff: DocuSign completed event to HubSpot and Slack
Source tool
Source field
Destination tool
Destination field
DocuSign Connect event
envelopeId
DocuSign API call
Signed PDF download parameter
DocuSign API
combined signed PDF (binary)
HubSpot Files API
hs_file_upload (attached to deal)
Orchestration run record
deal_id
HubSpot PATCH
Deal object ID for property update
Orchestration constant
"Signed"
HubSpot property
contract_status
HubSpot (run record)
dealname
Slack message
Completion notification text
HubSpot (run record)
customer_name
Slack message
Completion notification text
HubSpot (run record)
deal_id
Slack message
HubSpot deal deep link (optional)
Integration and API SpecPage 2 of 4
FS-DOC-05Technical
04Build stack and orchestration
Orchestration layout
Three discrete workflows, one per agent: (1) Contract Assembly Workflow, (2) Signature Tracking and Follow-up Workflow, (3) Post-Signature CRM and Notification Workflow. Workflows share a single credential store and a shared run-record data store keyed on deal_id. Workflows communicate by writing to and reading from the shared run-record store, not by direct chaining, so each workflow can be monitored, retried, and debugged independently.
Agent 1 trigger mechanism
Webhook (push). HubSpot fires a webhook POST to the automation platform inbound endpoint when the deal stage changes to Closed Won. The platform validates the X-HubSpot-Signature-Version: v3 HMAC-SHA256 signature before processing. No polling is used for the initial trigger.
Agent 2 trigger mechanism
Webhook (push) for envelope status events from DocuSign Connect, combined with a scheduled poll. The DocuSign Connect webhook posts envelope-sent and envelope-delivered events. The scheduled poll runs every 30 minutes to check envelope status for any run records where follow-up is pending, as a fallback in case a Connect event is missed. Follow-up timers (48h, 96h) are implemented as delayed scheduled steps anchored to the envelope_sent_at timestamp stored in the run record.
Agent 3 trigger mechanism
Webhook (push). DocuSign Connect posts an envelope-completed event to the automation platform inbound endpoint. The platform validates the X-DocuSign-Signature-1 HMAC-SHA256 header before processing. A scheduled poll every 60 minutes also checks for completed envelopes as a fallback.
Slack interactivity handling
Manager approval (approve/reject) arrives as an HTTP POST to the SLACK_INTERACTIVITY_ENDPOINT. The platform validates the X-Slack-Signature and X-Slack-Request-Timestamp headers, extracts the action_id and value (deal_id:gdrive_doc_id), and resumes or branches the paused Contract Assembly Workflow run accordingly.
Shared run-record data store
A lightweight key-value or row store (internal to the automation platform) keyed on deal_id. Fields stored per run: deal_id, envelope_id, envelope_sent_at, gdrive_doc_id, gdrive_merged_url, manager_approval_status, followup_48h_sent (bool), followup_96h_sent (bool), signed_pdf_url, workflow_status.
Credential store
All credentials stored in the automation platform's built-in secrets/credential vault. See code block below for the full list of entries. No credential is hardcoded in any workflow step or configuration field.
All secrets stored in platform credential vault. Rotate tokens and refresh credentials at 90-day intervals or on staff offboarding.
# Credential store entries (automation platform secrets vault)
# Do NOT hardcode any of these values in workflow logic or config fields.
# HubSpot
HUBSPOT_PRIVATE_APP_TOKEN = "pat-na1-xxxxxxxxxxxxxxxxxxxx"
HUBSPOT_WEBHOOK_SECRET = "<hmac secret from private app settings>"
HUBSPOT_PIPELINE_ID = "<pipeline_id from GET /crm/v3/pipelines/deals>"
HUBSPOT_CLOSEDWON_STAGE_ID = "<stage_id for Closed Won>"
# Google Drive / Docs
GOOGLE_SERVICE_ACCOUNT_JSON = "<full service account JSON key>"
GDRIVE_TEMPLATES_FOLDER_ID = "<Google Drive folder ID>"
GDRIVE_OUTPUT_FOLDER_ID = "<Google Drive folder ID>"
GDRIVE_TEMPLATE_MAP = '{"standard":"<file_id>","enterprise":"<file_id>","nda":"<file_id>"}'
# Gmail
GMAIL_OAUTH_REFRESH_TOKEN = "<OAuth refresh token>"
GMAIL_SENDER_ADDRESS = "contracts@[YourCompany.com]"
GMAIL_FOLLOWUP_48H_TEMPLATE = "<template string or file reference>"
GMAIL_FOLLOWUP_96H_TEMPLATE = "<template string or file reference>"
# DocuSign
DOCUSIGN_INTEGRATION_KEY = "<integration key / client ID>"
DOCUSIGN_RSA_PRIVATE_KEY = "<RSA private key PEM string>"
DOCUSIGN_USER_ID = "<impersonated user GUID>"
DOCUSIGN_ACCOUNT_ID = "<production account ID>"
DOCUSIGN_BASE_URL = "https://na4.docusign.net"
DOCUSIGN_SANDBOX_ACCOUNT_ID = "<developer sandbox account ID>"
DOCUSIGN_CONNECT_HMAC_KEY = "<Connect HMAC key from DocuSign console>"
DOCUSIGN_CONNECT_ENDPOINT = "https://<platform-inbound-url>/docusign/events"
DOCUSIGN_TAB_ANCHOR_MAP = '{"standard":"[Signature]","enterprise":"[SignHere]","nda":"[Sign]"}'
# Slack
SLACK_BOT_TOKEN = "xoxb-xxxxxxxxxxxx-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"
SLACK_SIGNING_SECRET = "<signing secret from Slack App settings>"
SLACK_INTERACTIVITY_ENDPOINT = "https://<platform-inbound-url>/slack/actions"
SLACK_REVIEW_CHANNEL_ID = "C0XXXXXXXXX"
SLACK_SALES_CHANNEL_ID = "C0XXXXXXXXX"
SLACK_FINANCE_CHANNEL_ID = "C0XXXXXXXXX"
SLACK_DELIVERY_CHANNEL_ID = "C0XXXXXXXXX"
SLACK_OPS_CHANNEL_ID = "C0XXXXXXXXX"Never store credentials as plain text in workflow step inputs, environment variables outside the vault, or in any Google Drive or Slack-accessible file. If a credential is suspected compromised, revoke and rotate it immediately and audit the run logs for the preceding 72 hours. Alert support@gofullspec.com if a production credential rotation is required during the build or hypercare period.
05Error handling and retry logic
Every integration point has a defined failure behaviour. Unhandled exceptions must never fail silently. All retry logic uses exponential backoff unless otherwise stated. All failure alerts are posted to SLACK_OPS_CHANNEL_ID with the deal_id, workflow step name, error code, and timestamp.
Integration
Scenario
Required behaviour
HubSpot webhook inbound
Invalid or missing HMAC signature on inbound deal stage event
Reject request with HTTP 401. Do not process payload. Log the rejection with IP and timestamp to the platform audit log. Alert SLACK_OPS_CHANNEL_ID. No retry (the event is not trusted).
HubSpot API (deal property read)
GET /crm/v3/objects/deals/{dealId} returns 429 Too Many Requests
Retry up to 3 times with exponential backoff: 5s, 15s, 45s. If all retries fail, pause the workflow run and alert SLACK_OPS_CHANNEL_ID with deal_id. Do not drop the event.
HubSpot API (deal property read)
Required deal property is null or empty (e.g. customer_email, amount)
Halt workflow run. Post a Slack message to SLACK_REVIEW_CHANNEL_ID listing the missing fields and the deal link. Update run record workflow_status to 'blocked_missing_fields'. Do not proceed to template merge.
Google Drive (template read)
Template file ID not found in GDRIVE_TEMPLATE_MAP for the given contract_type value
Halt workflow run. Alert SLACK_OPS_CHANNEL_ID with deal_id and the unrecognised contract_type value. Update run record to 'blocked_unknown_template'. No retry until config is updated.
Google Drive (document merge / export)
Docs API batchUpdate or Drive export returns 5xx server error
Retry up to 3 times with exponential backoff: 10s, 30s, 90s. If all retries fail, alert SLACK_OPS_CHANNEL_ID and update run record to 'error_merge_failed'. A FullSpec team member must investigate before the run is restarted.
Slack (manager review prompt)
chat.postMessage fails (channel not found, bot not in channel, or API error)
Retry once after 60 seconds. If the second attempt fails, alert SLACK_OPS_CHANNEL_ID and update run record to 'error_slack_review_failed'. Workflow is paused; no contract is sent until the manager approves.
Slack (manager approval timeout)
No manager_approve or manager_request_changes action received within 24 hours
Re-post the review prompt to SLACK_REVIEW_CHANNEL_ID with a reminder flag. If no response within a further 24 hours (48h total), alert SLACK_OPS_CHANNEL_ID and update run record to 'stalled_awaiting_approval'. Do not auto-approve or auto-send the contract.
DocuSign (envelope creation)
POST /envelopes returns 401 Unauthorized (expired JWT token)
The orchestration layer must detect token expiry before each DocuSign API call and refresh proactively. If a 401 is received, attempt one token refresh and retry the call immediately. If refresh fails, alert SLACK_OPS_CHANNEL_ID and pause the workflow run.
DocuSign Connect (inbound event)
Envelope-completed event is not received within 30 minutes of expected completion (based on scheduled poll)
The 60-minute scheduled poll for Agent 3 serves as fallback. If the poll confirms status is 'completed' but no Connect event was received, process the completion as normal and log the missed event. Alert SLACK_OPS_CHANNEL_ID for Connect configuration review.
DocuSign envelope
Customer declines to sign (envelope status: declined) or envelope is voided
Suppress all further follow-up emails immediately. Post a notification to SLACK_SALES_CHANNEL_ID with deal_id, customer name, and the declined/voided status. Update HubSpot contract_status property to 'Declined' or 'Voided'. Update run record to terminal status. No automatic re-send.
Gmail (follow-up email send)
OAuth refresh token is revoked or invalid when attempting to send at T+48h or T+96h
Halt the Gmail send immediately. Alert SLACK_OPS_CHANNEL_ID with deal_id and the token error. Mark followup_48h_sent or followup_96h_sent as 'failed' on the run record. A FullSpec team member must re-authenticate the Gmail OAuth connection before follow-up resumes. Do not skip silently.
HubSpot API (signed PDF attach and status update)
File upload or PATCH deal property returns 5xx or 429 after envelope-completed event
Retry up to 4 times with exponential backoff: 10s, 30s, 90s, 270s. If all retries fail, store the signed PDF binary in the orchestration platform's temporary storage, update the run record to 'error_hubspot_write_failed', and alert SLACK_OPS_CHANNEL_ID. A manual attach step must be completed before the run record is closed.
Global rule: unhandled exceptions at any workflow step must never fail silently. Every exception that is not caught by the above retry and fallback logic must be caught by a global error handler that posts the raw error, step name, deal_id, and timestamp to SLACK_OPS_CHANNEL_ID and updates the run record workflow_status to 'unhandled_error'. Contact support@gofullspec.com if an unhandled error pattern recurs across multiple runs.
Integration and API SpecPage 3 of 4
FS-DOC-05Technical
For questions about this specification, credential provisioning, or integration configuration, contact the FullSpec team at support@gofullspec.com.
Integration and API SpecPage 4 of 4