Back to Contract Generation & Management

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

Contract Generation and Management

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

This document defines every integration point, authentication method, required API scope, field mapping, and error-handling rule for the Contract Generation and Management automation. It is written for the FullSpec build team and covers HubSpot, DocuSign, Google Drive, Gmail, Xero, and Notion as named integration targets, plus the orchestration layer that connects them. Nothing in this document is intended for the business owner to configure directly. All credential storage, webhook registration, and scope grant steps are carried out by the FullSpec team during the build phase.

01Tool inventory

Tool
Role in automation
Auth method
Min plan required
Used by agents
HubSpot
Deal data source; CRM status update on contract execution
OAuth 2.0
Sales Hub Starter (API access required)
Agent 1, Agent 2
Google Drive
Contract template library; draft and executed contract storage
OAuth 2.0 (service account for server-side writes)
Google Workspace Business Starter
Agent 1, Agent 2
Notion
Template selection logic lookup; contract type registry
Bearer token (Notion internal integration)
Notion Free or above
Agent 1
Gmail
Internal approval notification dispatch; approval response parsing
OAuth 2.0
Google Workspace (any tier)
Agent 1, Agent 2
DocuSign
Envelope creation, signature field placement, reminder sequences, completed document retrieval
OAuth 2.0 (JWT Grant for server-to-server)
DocuSign Business Pro
Agent 2
Xero
Draft invoice creation on contract execution
OAuth 2.0 (PKCE flow)
Xero Starter or above
Agent 2
Automation platform (orchestration layer)
Workflow orchestration, credential store, trigger management, retry logic
Native platform credential vault; per-connector OAuth flows
Paid tier with webhook support and multi-step workflows
All agents
Before you connect anything: register and test every connection against a sandbox or developer account before any production credentials are entered into the credential store. Use HubSpot sandbox, DocuSign developer account, Xero demo company, and a dedicated Google Workspace test user. Only after all sandbox tests pass should production credentials be rotated in.

02Per-tool integration detail

HubSpot

Source of deal data for Agent 1. Receives contract status updates from Agent 2. Trigger mechanism is a webhook fired when deal stage changes to Closed Won.

Auth method
OAuth 2.0 (Authorization Code flow). Register a private app in HubSpot and store the client_id, client_secret, and refresh_token in the credential store. Access tokens expire after 30 minutes; the platform must refresh automatically using the stored refresh_token.
Required scopes
crm.objects.deals.read | crm.objects.deals.write | crm.objects.contacts.read | crm.objects.companies.read | crm.schemas.deals.read | crm.schemas.contacts.read | crm.objects.owners.read | oauth
Webhook / trigger setup
Create a HubSpot workflow (native) or register a subscription via the Webhooks API (v3) on the object type 'deal', property 'dealstage', event type 'propertyChange'. Filter server-side to the internal value of the Closed Won stage ID (stored in the credential store, not hardcoded). Validate inbound payloads using the X-HubSpot-Signature-v3 header with the app's client secret.
Required configuration
Store in credential store: hs_closed_won_stage_id (internal deal stage ID), hs_portal_id, hs_app_client_id, hs_app_client_secret, hs_refresh_token. Ensure the following HubSpot deal properties are marked mandatory: client_entity_name, service_type, contract_start_date, fee_amount, payment_terms, primary_contact_email.
Rate limits
HubSpot enforces 100 API requests per 10 seconds and 250,000 requests per day on Starter. At 35 contracts/month (roughly 1.2/day), peak load is well under 10 requests per contract trigger cycle. No throttling required at current volume; log 429 responses and implement exponential backoff starting at 2 seconds.
Constraints
Deal property updates (step 9 CRM sync) must use PATCH on /crm/v3/objects/deals/{dealId}. Attaching a file link uses the notes/associations endpoint, not a direct file attach. The Closed Won stage ID differs per portal; it must be resolved at setup time and stored, never hardcoded.
// Input (trigger payload excerpt)
{ "objectId": "<deal_id>", "propertyName": "dealstage", "propertyValue": "<closed_won_stage_id>", "portalId": "<portal_id>" }
// Enrichment read
GET /crm/v3/objects/deals/{dealId}?properties=client_entity_name,service_type,contract_start_date,fee_amount,payment_terms,primary_contact_email,dealname,hubspot_owner_id
// Output (Agent 2 status write-back)
PATCH /crm/v3/objects/deals/{dealId}  body: { "properties": { "contract_status": "executed", "executed_contract_url": "<gdrive_link>" } }
Google Drive

Stores contract templates (read by Agent 1) and receives populated draft files and executed contract PDFs (written by Agents 1 and 2). A service account is used for all server-side writes to avoid dependency on a named user's OAuth session.

Auth method
OAuth 2.0 service account (JSON key). The service account is granted Editor access to the contracts folder hierarchy. Store service_account_json (base64-encoded) in the credential store. For approval-link reads by the manager, standard user OAuth is not required; the link grants time-limited viewer access.
Required scopes
https://www.googleapis.com/auth/drive.file | https://www.googleapis.com/auth/drive.readonly (template reads) | https://www.googleapis.com/auth/drive (full scope scoped to shared drive only via domain delegation)
Webhook / trigger setup
No inbound webhook required. Agent 2 polls the executed-contracts folder using the Drive Changes API (changes.list with a stored pageToken) on a 5-minute interval to detect newly completed DocuSign files dropped by the filing step. Store gdrive_changes_page_token in the credential store and update on each poll.
Required configuration
Store in credential store: gdrive_template_folder_id, gdrive_drafts_folder_id, gdrive_executed_folder_id, gdrive_service_account_json. File naming convention: {YYYY-MM-DD}_{ClientEntityName}_{ServiceType}_{ContractType} (e.g. 2024-06-10_Acme_Ltd_Retainer_MSA). Template files must contain placeholder tokens in the format {{field_name}} for field substitution.
Rate limits
Google Drive API v3 allows 12,000 requests per minute per project. At 35 contracts/month the automation generates fewer than 10 Drive API calls per contract. No throttling needed. Handle 403 userRateLimitExceeded with a 30-second backoff and one retry.
Constraints
Google Docs native substitution (batchUpdate replaceAllText) is preferred over downloading and re-uploading binary files; it preserves formatting. Export to PDF using the Drive export endpoint before sending to DocuSign. Shared drives (Team Drives) require supportsAllDrives=true on all API calls.
// Template read (Agent 1)
GET /drive/v3/files/{templateFileId}/export?mimeType=application/vnd.google-apps.document
// Field substitution (Agent 1)
POST /v1/documents/{documentId}:batchUpdate  body: replaceAllText requests per mapped field
// Export draft to PDF (Agent 1)
GET /drive/v3/files/{draftDocId}/export?mimeType=application/pdf
// Save executed contract (Agent 2)
POST /upload/drive/v3/files?uploadType=multipart  body: metadata { name, parents: [gdrive_executed_folder_id] } + PDF binary
Notion

Hosts the contract type registry used by Agent 1 to select the correct template file ID based on the HubSpot service_type field value. Acts as a lookup table, not a file store.

Auth method
Notion internal integration token (Bearer token). Create the integration in Notion workspace settings, grant it read access to the contract registry database, and store notion_integration_token in the credential store.
Required scopes
Read content (read_content capability on the integration). No user OAuth required. The integration must be explicitly shared with the contract registry database page in Notion.
Webhook / trigger setup
No webhook. Agent 1 queries the Notion database synchronously at runtime using a filter on the service_type property to return the matching gdrive_template_file_id and any jurisdiction or clause flags.
Required configuration
Store in credential store: notion_integration_token, notion_template_registry_db_id. The Notion database must contain columns: service_type (title/select), gdrive_template_file_id (text), jurisdiction (select), clause_flags (multi-select), active (checkbox). Only rows where active=true should be returned.
Rate limits
Notion API allows 3 requests per second. One query per contract trigger is well within limits. No throttling required. Handle 429 with a 2-second retry, maximum 3 attempts.
Constraints
Notion API v1 only. The database must not use linked databases as the source; it must be a standalone database the integration is directly shared with. If no matching service_type is found, Agent 1 must halt and send a flag notification rather than selecting a fallback template.
// Template lookup query (Agent 1)
POST /v1/databases/{notion_template_registry_db_id}/query
body: { "filter": { "and": [ { "property": "service_type", "select": { "equals": "<hs_service_type_value>" } }, { "property": "active", "checkbox": { "equals": true } } ] } }
// Expected response fields
results[0].properties.gdrive_template_file_id.rich_text[0].plain_text
results[0].properties.clause_flags.multi_select[].name
Gmail

Used by Agent 1 to send the internal approval notification to the designated manager, and by Agent 2 to parse the approval response (approve or request changes) via a callback mechanism.

Auth method
OAuth 2.0 (Authorization Code flow) scoped to a dedicated sending account (e.g. contracts-automation@[YourCompany.com]). Store gmail_client_id, gmail_client_secret, gmail_refresh_token in the credential store against this account.
Required scopes
https://www.googleapis.com/auth/gmail.send | https://www.googleapis.com/auth/gmail.readonly (for approval reply polling)
Webhook / trigger setup
Use Gmail Push Notifications (Gmail API watch endpoint) on the dedicated account's inbox to detect approval replies. Register a Cloud Pub/Sub topic endpoint or use the automation platform's inbound webhook URL as the push destination. Renew the watch subscription every 7 days (Gmail watch expires after 7 days maximum). Store gmail_watch_expiry_ts in the credential store and trigger auto-renewal 24 hours before expiry. Alternative: poll the inbox every 5 minutes filtering by subject thread ID if push is not available on the chosen platform.
Required configuration
Store in credential store: gmail_client_id, gmail_client_secret, gmail_refresh_token, gmail_approval_sender_address, gmail_default_approver_email. Approval email must embed a unique approval_token (UUID v4, generated per contract run) in both the approve and request-changes links. The approval_token maps back to the workflow run in the orchestration layer's state store.
Rate limits
Gmail API allows 1,000,000 quota units per day; sending one email costs 100 units. At 35 contracts/month, total quota usage is negligible. No throttling required.
Constraints
Do not use a personal Gmail account; use the dedicated service address to avoid OAuth session invalidation. Approval links must use HTTPS callback URLs. If the approver does not respond within 48 hours, the orchestration layer must send a single chase notification and then pause the run, not cancel it.
// Approval email dispatch (Agent 1)
POST /gmail/v1/users/me/messages/send
body: base64-encoded MIME message containing:
  To: <manager_email>  Subject: [Action Required] Contract Draft Ready - {dealname}
  Body: Google Drive link, approve URL (?token={approval_token}&action=approve),
        request-changes URL (?token={approval_token}&action=changes)
// Approval callback parse (Agent 2)
Inbound GET ?token={approval_token}&action=approve|changes
Resolve approval_token -> workflow_run_id in state store, resume or branch accordingly
Integration and API SpecPage 1 of 3
FS-DOC-05Technical
DocuSign

Used exclusively by Agent 2. Creates the signing envelope from the approved contract PDF, places signature and date fields using a stored template anchor, dispatches to the client, manages day-3 and day-5 reminder sequences, and returns the completed document.

Auth method
OAuth 2.0 JWT Grant (server-to-server). Generate an RSA key pair; upload the public key to the DocuSign app; store docusign_integration_key, docusign_user_id, docusign_account_id, docusign_rsa_private_key_pem in the credential store. JWT access tokens expire after 1 hour; the platform must request a fresh token before each envelope operation.
Required scopes
signature | impersonation (required for JWT grant acting on behalf of the sender user)
Webhook / trigger setup
Register a DocuSign Connect webhook (EventNotification) on the envelope creation call with the automation platform's inbound HTTPS URL as the endpoint. Subscribe to events: envelope-completed, envelope-declined, envelope-voided, recipient-autoresponded. Validate inbound Connect payloads by checking the X-DocuSign-Signature-1 HMAC-SHA256 header against docusign_connect_hmac_key (stored in credential store).
Required configuration
Store in credential store: docusign_integration_key, docusign_user_id, docusign_account_id, docusign_rsa_private_key_pem, docusign_connect_hmac_key, docusign_base_url (e.g. https://na4.docusign.net). Anchor strings for signature field placement: /sig1/ for client signature, /date1/ for date signed. Reminder schedule: firstReminderDelay=3 days, reminderFrequency=2 days, expireAfter=30 days, expireWarn=3 days. Store these as docusign_reminder_first_delay, docusign_reminder_frequency in credential store, not hardcoded.
Rate limits
DocuSign Business Pro allows 100 API calls per hour per account by default (burst to 1,000). At 35 envelopes/month, peak is approximately 5 API calls per envelope creation (create, add document, add recipient, add tabs, send). Total monthly calls under 200. No throttling required. Handle 429 with 60-second backoff.
Constraints
Document must be uploaded as a base64-encoded PDF in the envelopes POST body; multi-part upload is only available on Enterprise plans. Anchor tag strings (/sig1/, /date1/) must be present in the contract PDF before upload; verify at export time. Voided or declined envelopes must trigger an immediate Slack or email alert to the operations manager; the run must not auto-retry a void without human confirmation.
// Envelope creation (Agent 2)
POST /restapi/v2.1/accounts/{docusign_account_id}/envelopes
body: { status: 'sent', documents: [{ documentBase64: '<pdf_b64>', name: '{contract_filename}', documentId: '1' }],
  recipients: { signers: [{ email: '<client_email>', name: '<client_name>', recipientId: '1',
    tabs: { signHereTabs: [{ anchorString: '/sig1/' }], dateSignedTabs: [{ anchorString: '/date1/' }] } }] },
  notification: { reminders: { reminderEnabled: true, reminderDelay: '{docusign_reminder_first_delay}',
    reminderFrequency: '{docusign_reminder_frequency}' }, expirations: { expireEnabled: true, expireAfter: '30' } },
  eventNotification: { url: '<platform_inbound_webhook>', envelopeEvents: ['envelope-completed','envelope-declined','envelope-voided'] } }
// Completed document retrieval (Agent 2, on envelope-completed event)
GET /restapi/v2.1/accounts/{docusign_account_id}/envelopes/{envelopeId}/documents/combined
Xero

Used by Agent 2 to create a draft invoice immediately after the contract is executed. Invoice data is sourced from the HubSpot deal record (fee_amount, payment_terms, client_entity_name).

Auth method
OAuth 2.0 with PKCE (Authorization Code + PKCE). Register the automation as a Xero app (Web App type). Store xero_client_id, xero_client_secret, xero_refresh_token, xero_tenant_id in the credential store. Access tokens expire after 30 minutes; refresh tokens expire after 60 days and must be rotated on each use. Store the new refresh_token after every refresh call.
Required scopes
accounting.transactions | accounting.contacts.read | offline_access (required for refresh token grant)
Webhook / trigger setup
No inbound webhook from Xero is required. Agent 2 makes a single outbound POST to create the draft invoice. Optionally register a Xero webhook on Invoice events to confirm creation, but this is not required for the current scope.
Required configuration
Store in credential store: xero_client_id, xero_client_secret, xero_refresh_token, xero_tenant_id, xero_default_account_code (revenue account code, e.g. '200'), xero_default_tax_type (e.g. 'OUTPUT2'). Invoice is created as Status=DRAFT; do not auto-approve. Line item description is populated from the HubSpot dealname and service_type fields. Due date is calculated from contract_start_date plus payment_terms (net days).
Rate limits
Xero API allows 60 calls per minute and 5,000 calls per day. At 35 contracts/month, this automation generates 1-2 API calls per contract. No throttling required. Handle 429 with 60-second backoff, maximum 3 retries.
Constraints
The Xero contact must already exist (matched by client_entity_name or primary_contact_email) or be created as part of the invoice POST. If no match is found, create a new contact inline within the same request. Never post an approved invoice automatically; always leave as DRAFT for finance review. Currency defaults to USD unless xero_default_currency is overridden in the credential store.
// Draft invoice creation (Agent 2)
POST /api.xro/2.0/Invoices  Header: Xero-tenant-id: {xero_tenant_id}
body: { Type: 'ACCREC', Status: 'DRAFT',
  Contact: { Name: '<client_entity_name>' },
  Date: '<contract_execution_date>',
  DueDate: '<contract_start_date + payment_terms_days>',
  LineItems: [{ Description: '<dealname> - <service_type>',
    Quantity: 1, UnitAmount: <fee_amount>,
    AccountCode: '{xero_default_account_code}', TaxType: '{xero_default_tax_type}' }],
  Reference: '<contract_filename>' }

03Field mappings between tools

The tables below define exact field mappings for each agent handoff. Field names are shown in monospace. All mappings use the resolved values from HubSpot deal properties as the authoritative source. No field value should be entered manually at runtime.

Source tool
Source field
Destination tool
Destination field
Agent 1 Handoff: HubSpot deal record to Google Docs template substitution
HubSpot
`deal.client_entity_name`
Google Docs template
`{{client_entity_name}}`
HubSpot
`deal.primary_contact_email`
Google Docs template
`{{client_email}}`
HubSpot
`deal.dealname`
Google Docs template
`{{contract_title}}`
HubSpot
`deal.service_type`
Google Docs template
`{{service_type}}`
HubSpot
`deal.contract_start_date`
Google Docs template
`{{start_date}}`
HubSpot
`deal.fee_amount`
Google Docs template
`{{fee_amount}}`
HubSpot
`deal.payment_terms`
Google Docs template
`{{payment_terms}}`
HubSpot
`deal.hubspot_owner_id` (resolved to owner name)
Google Docs template
`{{account_manager_name}}`
Notion registry
`gdrive_template_file_id`
Google Drive
Template file selected for copy and substitution
Notion registry
`clause_flags[]`
Google Docs template
Conditional section visibility (show/hide clause blocks)
Source tool
Source field
Destination tool
Destination field
Agent 1 Handoff: Google Drive draft to Gmail approval notification
Google Drive
`file.webViewLink`
Gmail approval email body
`{{contract_draft_url}}`
Google Drive
`file.name`
Gmail approval email subject
`{dealname}` (for subject line context)
Orchestration state
`run.approval_token`
Gmail approval email links
`?token={approval_token}&action=approve|changes`
HubSpot
`deal.hubspot_owner_id` (resolved to email)
Gmail To: header
Manager / approver email address
Source tool
Source field
Destination tool
Destination field
Agent 2 Handoff: Google Drive approved PDF to DocuSign envelope
Google Drive
Exported PDF binary (base64)
DocuSign
`documents[0].documentBase64`
Google Drive
`file.name`
DocuSign
`documents[0].name`
HubSpot
`deal.primary_contact_email`
DocuSign
`recipients.signers[0].email`
HubSpot
`deal.client_entity_name`
DocuSign
`recipients.signers[0].name`
Orchestration state
`run.workflow_run_id`
DocuSign
`envelope.clientUserId` (correlation reference)
Source tool
Source field
Destination tool
Destination field
Agent 2 Handoff: DocuSign completed envelope to Google Drive and HubSpot
DocuSign
`envelopeId`
Google Drive
Embedded in filename: `{date}_{client}_{type}_executed_{envelopeId}.pdf`
DocuSign
Combined document PDF (binary)
Google Drive
File body uploaded to `gdrive_executed_folder_id`
Google Drive
`file.webViewLink` (executed file)
HubSpot
`deal.executed_contract_url` (custom property)
Orchestration state
Execution timestamp
HubSpot
`deal.contract_status` = 'executed'
Source tool
Source field
Destination tool
Destination field
Agent 2 Handoff: HubSpot deal data to Xero draft invoice
HubSpot
`deal.client_entity_name`
Xero
`Invoice.Contact.Name`
HubSpot
`deal.primary_contact_email`
Xero
`Invoice.Contact.EmailAddress`
HubSpot
`deal.fee_amount`
Xero
`Invoice.LineItems[0].UnitAmount`
HubSpot
`deal.dealname` + `deal.service_type`
Xero
`Invoice.LineItems[0].Description`
HubSpot
`deal.contract_start_date`
Xero
`Invoice.Date` (execution date) and `Invoice.DueDate` (+ payment_terms days)
Google Drive
`file.name` (executed contract)
Xero
`Invoice.Reference`
Integration and API SpecPage 2 of 3
FS-DOC-05Technical

04Build stack and orchestration

Orchestration layout
Two discrete workflows in the automation platform: one per agent. Workflow 1 handles Agent 1 (Contract Drafting Agent). Workflow 2 handles Agent 2 (Signature and Filing Agent). Workflows share a single credential store. Workflow 2 is initiated by the approval callback event, not by a scheduled trigger, ensuring no polling gap between approval and envelope dispatch.
Agent 1 trigger mechanism
Webhook (event-driven). HubSpot fires a deal property change event to the platform's registered inbound URL when dealstage = hs_closed_won_stage_id. Payload signature validated using X-HubSpot-Signature-v3 HMAC-SHA256 before any processing begins. No polling; near-real-time response.
Agent 1 approval pause
After dispatching the Gmail approval notification, Workflow 1 enters a wait-for-webhook state keyed on approval_token. The workflow resumes only when the approval callback URL is hit with a valid token. Maximum wait: 48 hours, after which a chase notification is sent and the run stays paused (not cancelled) awaiting human action.
Agent 2 trigger mechanism
Webhook (approval callback). When the manager clicks the approve link, the inbound HTTPS callback URL is hit with approval_token and action=approve. The orchestration layer resolves the token to the paused Workflow 1 run, extracts the draft file reference, and hands off to Workflow 2. DocuSign Connect webhooks then drive subsequent steps (envelope-completed, envelope-declined, envelope-voided) with HMAC-SHA256 validation on each inbound payload.
State management
Each workflow run stores: workflow_run_id, deal_id, approval_token, draft_file_id, envelope_id, current_step, step_timestamps. State must persist across the approval wait window. Use the platform's built-in execution state or an external key-value store if the platform does not natively support multi-day wait states.
Credential store scope
All secrets are stored in the automation platform's encrypted credential vault. No credential value appears in workflow logic, step configurations, or log output. Credentials are referenced by key name only. See code block below for the full credential store manifest.
Logging
Every workflow step writes a structured log entry: run_id, step_name, tool, http_status, duration_ms, error_code (if any). Logs are retained for 90 days minimum. PII in log payloads (client_email, client_entity_name) must be masked after the first 3 characters.
Notification routing
Operational alerts (approval timeout, envelope voided, Xero invoice failure) are sent to the Gmail address stored as ops_alert_email in the credential store. No Slack integration is in scope for the current build; extend if required post-launch.
Credential store manifest: all keys required before first workflow run
# HubSpot
hs_portal_id                    # HubSpot portal/account ID
hs_app_client_id                # OAuth app client ID
hs_app_client_secret            # OAuth app client secret
hs_refresh_token                # OAuth refresh token (auto-rotated by platform)
hs_closed_won_stage_id          # Internal deal stage ID for 'Closed Won'

# Google Drive (service account)
gdrive_service_account_json     # Base64-encoded service account key JSON
gdrive_template_folder_id       # Folder ID: contract template library
gdrive_drafts_folder_id         # Folder ID: draft contracts awaiting approval
gdrive_executed_folder_id       # Folder ID: executed/signed contracts archive
gdrive_changes_page_token       # Drive Changes API pageToken (updated on each poll)

# Notion
notion_integration_token        # Internal integration bearer token
notion_template_registry_db_id  # Database ID of the contract type registry

# Gmail
gmail_client_id                 # OAuth app client ID (dedicated service account)
gmail_client_secret             # OAuth app client secret
gmail_refresh_token             # OAuth refresh token
gmail_approval_sender_address   # Sending address: contracts-automation@[YourCompany.com]
gmail_default_approver_email    # Default manager approval recipient
gmail_watch_expiry_ts           # Unix timestamp of current watch subscription expiry

# DocuSign
docusign_integration_key        # App integration key (client ID)
docusign_user_id                # Sender user GUID
docusign_account_id             # DocuSign account ID
docusign_rsa_private_key_pem    # RSA private key for JWT grant (PEM format)
docusign_connect_hmac_key       # HMAC key for Connect webhook signature validation
docusign_base_url               # API base URL (e.g. https://na4.docusign.net)
docusign_reminder_first_delay   # Days before first reminder (default: 3)
docusign_reminder_frequency     # Days between subsequent reminders (default: 2)

# Xero
xero_client_id                  # OAuth app client ID
xero_client_secret              # OAuth app client secret
xero_refresh_token              # OAuth refresh token (must be rotated on every refresh)
xero_tenant_id                  # Connected Xero organisation tenant ID
xero_default_account_code       # Revenue account code (e.g. '200')
xero_default_tax_type           # Tax type string (e.g. 'OUTPUT2')
xero_default_currency           # ISO currency code (default: 'USD')

# Orchestration / Ops
ops_alert_email                 # Email address for operational failure alerts
platform_inbound_webhook_url    # Public HTTPS URL for DocuSign Connect and Gmail callbacks
approval_callback_base_url      # Base URL for approve/request-changes links in Gmail
Every credential key listed above must be populated before the first workflow run is activated. A missing key will cause a silent credential resolution failure unless the platform is configured to halt and alert on undefined credential references. Verify all keys resolve correctly in sandbox before rotating to production values.

05Error handling and retry logic

Every integration point in the automation has a defined failure behaviour. Unhandled exceptions must never fail silently. Any error not matched by the rules below must be caught by a global exception handler that logs the full error payload, halts the workflow run, and sends an alert to ops_alert_email with the run_id, step_name, and error detail.

Integration
Scenario
Required behaviour
HubSpot (trigger)
Inbound webhook signature validation fails
Reject payload with HTTP 401. Do not start workflow run. Log event with source IP and payload hash. Alert ops_alert_email if 3 failures occur within 5 minutes (potential replay attack).
HubSpot (deal read)
Required deal fields missing or blank
Halt workflow run. Do not attempt template selection. Send a flag notification via Gmail to gmail_default_approver_email listing each missing field name and the deal URL. Workflow enters a paused state; it resumes automatically if a HubSpot property update event for the same deal is received within 24 hours.
HubSpot (deal read)
API returns 429 (rate limit)
Exponential backoff: wait 2s, 4s, 8s. Maximum 3 retries. If all retries fail, halt and alert ops_alert_email with run_id. Do not drop the trigger event.
Notion (template lookup)
No matching service_type found in registry
Halt workflow. Do not select a fallback template. Alert ops_alert_email with the unmatched service_type value and deal URL. Log for manual resolution. Workflow remains paused until a matching row is added to the registry and the run is manually restarted.
Google Drive (template read / export)
Template file not found or export fails
Retry export once after 30 seconds. If the second attempt fails, halt workflow and alert ops_alert_email with the gdrive_template_file_id and error code. Do not proceed to field substitution with a partial or missing document.
Google Drive (draft save)
Write permission denied (403)
Do not retry. Alert ops_alert_email immediately. Log service account email and folder ID. Manual intervention required to confirm the service account has Editor access to gdrive_drafts_folder_id before the run is restarted.
Gmail (approval dispatch)
Send fails (5xx from Gmail API)
Retry up to 3 times with 60-second backoff. If all retries fail, halt workflow and alert ops_alert_email. The draft file remains in Google Drive; the run can be restarted manually from the approval dispatch step.
Gmail (approval wait)
No approval response within 48 hours
Send a single chase notification to gmail_default_approver_email. Workflow remains paused. Do not cancel or void the run. If no response within a further 24 hours (72 hours total), alert ops_alert_email and flag the run for manual review.
DocuSign (envelope creation)
API returns 400: anchor tag not found in PDF
Halt and alert ops_alert_email with envelope ID attempt and the specific error message. Do not retry automatically. The contract PDF must be inspected to confirm /sig1/ and /date1/ anchor strings are present before the run is restarted.
DocuSign (Connect webhook)
envelope-declined or envelope-voided event received
Halt workflow run immediately. Do not retry envelope creation automatically. Alert ops_alert_email with envelopeId, decline reason (if provided by recipient), deal URL, and run_id. Require explicit human instruction before re-sending.
DocuSign (Connect webhook)
Inbound Connect event signature validation fails
Reject payload with HTTP 403. Log event. If 5 consecutive validation failures occur from the same source, alert ops_alert_email. Do not advance workflow state on an unvalidated payload.
Xero (invoice creation)
OAuth refresh token expired or revoked
Catch token refresh failure. Alert ops_alert_email with run_id and instruction to re-authorise the Xero connection. Halt only the Xero invoice step; all prior steps (Drive filing, HubSpot update) have already completed and must not be re-run. The Xero invoice step can be retried independently once re-authorisation is confirmed.
All integrations
Unhandled exception (any step, any tool)
Global exception handler catches the error. Log full stack trace, step_name, tool, run_id, and timestamp. Send immediate alert to ops_alert_email. Halt the workflow run. Mark run status as 'error' in the state store. Never fail silently. Contact support@gofullspec.com if the exception recurs across multiple runs.
Retry logic summary: HubSpot 429 uses 2s/4s/8s backoff (3 attempts). Google Drive export and Gmail send use 30-60 second flat retry (1-3 attempts). DocuSign JWT token refresh retries once immediately. Xero token refresh does not retry and requires manual re-authorisation. All retry counts and backoff intervals should be stored as configuration values in the credential store or platform settings, not hardcoded in workflow logic.
Integration and API SpecPage 3 of 3

More documents for this process

Every document generated for Contract Generation & Management.

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