Back to Proposal & SOW Creation

Integration and API Spec

The reference during the build: every tool connection, field mapping, error scenario, and change-control rule.

4 pagesPDF · Technical
FS-DOC-05Technical

Integration and API Spec

Proposal & SOW Creation

Document code
FS-DOC-05
Process
Proposal & SOW Creation
Audience
Developer
Date
[Today's Date]
Client
[YourCompany.com]
Build option
Standard (recommended)
This document specifies every integration point, auth method, field mapping, and error-handling rule required to build and operate the Proposal & SOW Creation automation. All orchestration runs on FullSpec Automation (n8n-compatible). Developers must not proceed to build without confirming credentials and API access for each tool listed in Section 01.

01Tool inventory

The table below lists every external service involved in the automation, the role it plays, how authentication is established, the minimum paid tier required for API access, and which agent consumes it.

Tool
Role in automation
Auth method
Min plan required
Used by
FullSpec Automation
Orchestration, workflow engine, and monitoring
API key (internal service account)
Standard ($159/month)
All agents
HubSpot
CRM trigger source; scoping notes and deal data
OAuth 2.0 (private app token)
Starter CRM (free tier supports API)
Scope Extraction Agent
Google Docs
Proposal and SOW template rendering and output
OAuth 2.0 (service account or user OAuth)
Google Workspace (free personal tier sufficient)
Estimate & Proposal Agent
PandaDoc
E-signature delivery and open/sign status tracking
API key (Bearer token)
Essentials ($25/month per user)
Send & Track Agent
HubSpot's free CRM tier allows API calls but enforces a 100 requests/10-second burst limit. Confirm the account tier before build to avoid throttling on high-volume days (up to 25 proposals/month equates to roughly 250 to 400 API calls per month under normal operation).

02Per-tool integration detail

HubSpot

Acts as the automation trigger. When a deal's lifecycle stage is set to a configured value (e.g., 'Scoping Call Complete'), FullSpec Automation reads the associated note body, deal properties, and contact record to seed the Scope Extraction Agent.

Auth method
OAuth 2.0 private app token. Generate via HubSpot Developer Portal > Apps > Private Apps. Token is long-lived but must be rotated every 180 days per [YourCompany.com] security policy.
Required scopes
crm.objects.deals.read, crm.objects.contacts.read, crm.objects.notes.read, crm.objects.companies.read, timeline.write (for writing automation status back to deal timeline)
Key endpoints
GET /crm/v3/objects/deals/{dealId} -- GET /crm/v3/objects/notes?associations=deals -- GET /crm/v3/objects/contacts/{contactId}
Webhook / polling
FullSpec Automation polls HubSpot every 5 minutes for deals matching the trigger filter OR a HubSpot workflow webhook fires POST to the FullSpec inbound URL on stage change (preferred; reduces latency to under 30 seconds).
Rate limits
Free/Starter: 100 requests per 10 seconds, 250,000 requests per day. Standard build volume (~25 proposals/month) is well within limits. Implement exponential back-off on 429 responses.
Config notes
Set the trigger deal stage in the FullSpec environment variable HUBSPOT_TRIGGER_STAGE. Default: 'Scoping Call Complete'. Map the scoping notes custom property name in HUBSPOT_NOTES_FIELD. Default: 'hs_note_body'.
// Inbound trigger payload (HubSpot webhook)
{
  "objectId": "<dealId>",
  "objectType": "DEAL",
  "propertyName": "dealstage",
  "propertyValue": "Scoping Call Complete",
  "occurredAt": "<ISO8601 timestamp>"
}

// Data fetched after trigger
deal.dealname, deal.amount, deal.closedate,
deal.hubspot_owner_id, note.hs_note_body,
contact.email, contact.firstname, contact.lastname,
company.name, company.domain
Google Docs

Hosts the proposal and SOW templates. The Estimate & Proposal Agent creates a copy of each master template in the designated output Drive folder, performs field substitution via the Docs API, and returns the resulting document URLs for downstream handoff to PandaDoc.

Auth method
OAuth 2.0 via service account (recommended for server-side automation). Create a service account in Google Cloud Console, download the JSON key, and share the template folder with the service account email. Alternatively, use a user OAuth refresh token stored in the n8n credential store.
Required scopes
https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/documents, https://www.googleapis.com/auth/drive.file
Key endpoints
POST /drive/v3/files/{fileId}/copy -- POST /docs/v1/documents/{documentId}:batchUpdate -- GET /drive/v3/files/{fileId}?fields=webViewLink
Template IDs
Store template file IDs in env vars: GDOCS_PROPOSAL_TEMPLATE_ID and GDOCS_SOW_TEMPLATE_ID. Never hard-code these in workflow nodes.
Rate limits
Docs API: 300 read requests per minute per user, 60 write requests per minute per user. Drive API: 1,000 requests per 100 seconds. Standard build volume is well within these limits.
Config notes
Template placeholders follow {{FIELD_NAME}} syntax. Ensure the master templates use this pattern exactly. Output documents are saved to the Drive folder specified in GDOCS_OUTPUT_FOLDER_ID. Set sharing to 'anyone with link can view' only after owner approval to avoid pre-approval leakage.
// Copy template call
POST /drive/v3/files/{{GDOCS_PROPOSAL_TEMPLATE_ID}}/copy
Body: { "name": "Proposal - {{company_name}} - {{today_date}}" }

// batchUpdate replaceAllText request
{
  "requests": [
    { "replaceAllText": { "containsText": { "text": "{{CLIENT_NAME}}" }, "replaceText": "<company.name>" } },
    { "replaceAllText": { "containsText": { "text": "{{TOTAL_PRICE}}" }, "replaceText": "<calculated_total>" } }
  ]
}

// Output
{ "documentId": "<newDocId>", "webViewLink": "https://docs.google.com/document/d/<newDocId>/edit" }
PandaDoc

Receives the approved proposal as a Google Docs URL or uploaded PDF, creates a PandaDoc document with pre-filled recipient details, sends it for e-signature, and exposes webhook events for open and signed status back into FullSpec Automation.

Auth method
API key authentication. Generate via PandaDoc > Settings > API & Webhooks > API Keys. Pass as Authorization: API-Key <token> header. No OAuth required for server-side use.
Required API access
Documents API (create, send, status), Webhooks (document.state_changed event). Essentials plan ($25/month) enables both. Confirm with account admin that API access is not restricted to higher tiers on the active account.
Key endpoints
POST /public/v1/documents -- POST /public/v1/documents/{id}/send -- GET /public/v1/documents/{id} -- POST /public/v1/webhooks (register status webhook)
Rate limits
100 requests per minute on the Essentials plan. Status polling (if webhook is unavailable) should be throttled to once every 60 seconds per document. Implement 429 back-off with a 90-second retry delay.
Webhook events
Register a webhook for document.state_changed. States of interest: 'sent', 'viewed', 'completed' (signed), 'declined'. FullSpec Automation inbound URL must be registered as the webhook target: https://automation.[YourCompany.com]/webhook/pandadoc.
Config notes
Set PANDADOC_API_KEY and PANDADOC_SENDER_EMAIL in the n8n credential store. Template ID for the PandaDoc wrapper (if using a PandaDoc template rather than import) stored in PANDADOC_TEMPLATE_ID. Fallback: upload the Google Doc export as PDF if direct URL import fails.
// Create document from Google Docs URL
POST /public/v1/documents
{
  "name": "Proposal - {{company_name}}",
  "url": "<gdocs_export_pdf_url>",
  "recipients": [{ "email": "<contact.email>", "first_name": "<contact.firstname>", "last_name": "<contact.lastname>", "role": "Signer" }],
  "fields": { "client_name": { "value": "<company.name>" } }
}

// Send document
POST /public/v1/documents/{documentId}/send
{
  "message": "Please review and sign the attached proposal.",
  "subject": "Your Proposal from [YourCompany.com]"
}

// Inbound webhook payload (state change)
{
  "event": "document.state_changed",
  "data": { "id": "<docId>", "status": "completed", "date_completed": "<ISO8601>" }
}
Integration and API SpecPage 1 of 3
FS-DOC-05Technical

03Field mappings between tools

Three handoff points exist in the workflow. Each table below maps source fields to destination fields with exact property names in monospace. All field names are case-sensitive.

Handoff 1: HubSpot to Scope Extraction Agent (FullSpec Automation internal payload)

Source tool
Source field
Destination
Destination field
Notes
HubSpot
deal.dealname
FullSpec payload
scope.deal_name
Direct string copy
HubSpot
deal.amount
FullSpec payload
scope.budget_indicated
Numeric; may be null -- handle with fallback 0
HubSpot
deal.closedate
FullSpec payload
scope.target_close_date
ISO8601 date string
HubSpot
note.hs_note_body
FullSpec payload
scope.raw_notes
Full text blob; passed to NLP extraction step
HubSpot
contact.email
FullSpec payload
scope.contact_email
Used for PandaDoc recipient later
HubSpot
contact.firstname
FullSpec payload
scope.contact_firstname
HubSpot
contact.lastname
FullSpec payload
scope.contact_lastname
HubSpot
company.name
FullSpec payload
scope.company_name
Used as document naming prefix

Handoff 2: Scope Extraction Agent structured output to Estimate & Proposal Agent (Google Docs template substitution)

Source field (FullSpec)
Google Docs placeholder
Document
Transformation
scope.company_name
{{CLIENT_NAME}}
Proposal + SOW
Direct string
scope.contact_firstname
{{CONTACT_FIRST_NAME}}
Proposal
Direct string
scope.modules[]
{{MODULE_LIST}}
Proposal + SOW
Array joined as newline-separated bullet list
scope.assumptions[]
{{ASSUMPTIONS}}
SOW
Array joined as numbered list
scope.constraints[]
{{CONSTRAINTS}}
SOW
Array joined as numbered list
estimate.total_hours
{{TOTAL_HOURS}}
Proposal + SOW
Integer
estimate.total_price
{{TOTAL_PRICE}}
Proposal
Currency formatted: $X,XXX
estimate.line_items[]
{{LINE_ITEMS_TABLE}}
Proposal
Rendered as inline table rows; requires Docs table row insertion logic
scope.target_close_date
{{PROPOSAL_DATE}}
Proposal
Reformatted: MMM DD, YYYY
estimate.rate_card_version
{{RATE_CARD_VERSION}}
SOW
String e.g. v2.1 -- for audit trail

Handoff 3: Estimate & Proposal Agent output to Send & Track Agent (PandaDoc document creation)

Source field (FullSpec)
PandaDoc API field
Location in API call
Notes
scope.deal_name
name
POST /documents body
Document display name in PandaDoc UI
gdocs.proposal_export_url
url
POST /documents body
PDF export URL from Drive: /export?format=pdf
scope.contact_email
recipients[0].email
POST /documents body
Primary signer
scope.contact_firstname
recipients[0].first_name
POST /documents body
scope.contact_lastname
recipients[0].last_name
POST /documents body
scope.company_name
fields.client_name.value
POST /documents body
Pre-fills any PandaDoc field named client_name
estimate.total_price
fields.total_price.value
POST /documents body
Pre-fills summary pricing field if template includes it
pandadoc.document_id
id
Stored in FullSpec run record
Used for status polling and webhook correlation

04Build stack and orchestration

The orchestration layer is FullSpec Automation, which is built on an n8n-compatible engine. All agents are implemented as n8n workflows. The table below describes the build stack components and their roles.

Component
Technology
Hosted by
Purpose
Version/tier
Workflow engine
n8n (FullSpec Automation wrapper)
FullSpec cloud (Standard plan)
Runs all agent workflows, manages triggers, scheduling, and retries
n8n >= 1.30
Trigger node
Webhook node or Polling node
FullSpec engine
Receives HubSpot stage-change webhook or polls every 5 minutes
Built-in
HTTP Request node
n8n HTTP Request
FullSpec engine
All outbound API calls to HubSpot, Google Docs, PandaDoc
Built-in
Code node
n8n Code (JavaScript)
FullSpec engine
NLP-style extraction logic, line-item calculations, rate card application
Node.js 18
Google Docs node
n8n Google Docs community node
FullSpec engine
Native template copy and batchUpdate calls
n8n-nodes-google-docs >= 1.2
Credential store
n8n Credentials (AES-256 encrypted)
FullSpec engine
Stores all API keys and OAuth tokens securely
n8n built-in
Error workflow
n8n Error Trigger workflow
FullSpec engine
Catches unhandled failures and routes to alert channel
Built-in
Rate card config
JSON file or n8n static data node
FullSpec engine
Stores hourly rates, module prices, and version identifier
Managed in workflow
Notification channel
Slack (optional) or Email via SMTP
External
Sends failure and review-required alerts to the studio owner
Configurable

The n8n credential store entries required for this build are listed below. All credential names must match exactly as referenced in workflow nodes.

n8n credential store and environment variable reference
// n8n Credential Store -- required entries
// (Settings > Credentials > New Credential)

credential: HubSpot_PrivateApp_Token
  type:   hubspotApi
  field:  apiKey = <HubSpot private app token>
  scope:  crm.objects.deals.read, crm.objects.contacts.read,
          crm.objects.notes.read, crm.objects.companies.read,
          timeline.write

credential: Google_ServiceAccount_Docs
  type:   googleServiceAccount
  field:  serviceAccountEmail = automation@<project>.iam.gserviceaccount.com
  field:  privateKey           = <PEM key from JSON key file>
  scope:  https://www.googleapis.com/auth/drive
          https://www.googleapis.com/auth/documents
          https://www.googleapis.com/auth/drive.file

credential: PandaDoc_ApiKey
  type:   httpHeaderAuth
  field:  name  = Authorization
  field:  value = API-Key <pandadoc_api_key>

credential: FullSpec_Internal_ApiKey
  type:   httpHeaderAuth
  field:  name  = X-FullSpec-Key
  field:  value = <fullspec_service_account_key>

// Environment variables (set in FullSpec > Settings > Variables)
HUBSPOT_TRIGGER_STAGE     = Scoping Call Complete
HUBSPOT_NOTES_FIELD       = hs_note_body
GDOCS_PROPOSAL_TEMPLATE_ID = <google_doc_file_id_proposal>
GDOCS_SOW_TEMPLATE_ID      = <google_doc_file_id_sow>
GDOCS_OUTPUT_FOLDER_ID     = <google_drive_folder_id>
PANDADOC_SENDER_EMAIL      = proposals@[YourCompany.com]
PANDADOC_TEMPLATE_ID       = <pandadoc_template_id_if_used>
RATE_CARD_VERSION          = v2.1
ALERT_EMAIL                = owner@[YourCompany.com]
Integration and API SpecPage 2 of 3
FS-DOC-05Technical

05Error handling and retry logic

All errors are caught by the FullSpec Automation error workflow. The table below defines expected error conditions, their classification, the retry strategy, and the fallback action. Developers must implement each row as a dedicated error-handling branch or error workflow route.

Error condition
HTTP code / type
Severity
Retry strategy
Fallback action
HubSpot webhook not received within 10 min of stage change
Timeout (no HTTP)
High
Polling fallback activates; checks every 5 min for up to 30 min
Alert sent to ALERT_EMAIL; run paused pending manual trigger
HubSpot 401 Unauthorized on API call
401
Critical
No retry; credential failure requires manual fix
Error workflow fires; Slack/email alert with credential rotation instructions
HubSpot 429 rate limit exceeded
429
Medium
Exponential back-off: 10s, 30s, 90s (max 3 attempts)
If still failing after 3 attempts, log and queue for 15-minute retry
HubSpot notes field empty or null
200 but null field value
High
No retry; data issue not a transient failure
Pause run; alert Account Lead to add scoping notes; resume link sent via email
Google Docs template copy fails (Drive permission denied)
403
Critical
No retry; permissions issue requires manual fix
Alert developer; verify service account sharing on template folder
Google Docs batchUpdate fails (invalid placeholder)
400 Bad Request
Medium
1 retry after logging the offending placeholder
If retry fails, send partially populated document to owner for manual completion; flag placeholder mismatch in error log
Google Docs API quota exceeded
429
Low
Wait 60s; retry up to 3 times
If quota persists, defer run to next 5-minute polling cycle
PandaDoc document creation fails (invalid URL or file)
422 Unprocessable Entity
High
1 retry using PDF export fallback URL instead of direct link
If both attempts fail, alert studio owner with Google Docs link for manual send
PandaDoc 401 Unauthorized
401
Critical
No retry; API key invalid or expired
Error workflow fires; alert with PandaDoc key rotation steps
PandaDoc 429 rate limit exceeded
429
Medium
Back-off: 90s, 180s (max 2 attempts, respecting 100 req/min limit)
Queue document send for next available window; notify owner of delay
PandaDoc webhook status event not received within 48 hours
Timeout (no webhook)
Low
Poll GET /documents/{id} every 6 hours for up to 5 days
After 5 days with no signature, trigger automated follow-up email to contact
Rate card calculation produces price outside configured range
Internal validation error
High
No retry; logic issue
Route to human review step (Owner reviews pricing) before send; block automated dispatch
All errors at Critical severity must page the developer or system admin immediately. High severity errors block the run and alert the studio owner. Medium and Low severity errors log to the FullSpec run history and do not block the pipeline unless retries are exhausted.

06Versioning and change control

All changes to workflows, credentials, field mappings, and rate card config must follow the process below. FullSpec Automation maintains a run history audit log, but workflow version control must be managed externally in a Git repository.

Change type
Version increment
Process
Approval required
Rollback method
Bug fix or minor config update (e.g., env variable value, email copy)
Patch: v1.0.0 to v1.0.1
Update in FullSpec; commit to main branch with fix description
Developer only
Revert commit; re-import previous workflow JSON
Field mapping change (add or rename a mapped field)
Minor: v1.0.0 to v1.1.0
Update field mapping table in this doc; update workflow; update Google Docs template placeholders if affected; regression test
Developer + Process owner sign-off
Revert workflow JSON and template to prior version from Git
New agent added or agent logic refactored
Minor: v1.1.0 to v1.2.0
Full dev-QA cycle; update Developer Handover Pack and this spec; deploy to staging first
Developer + Process owner + Delivery lead sign-off
Disable new agent node; revert to previous workflow version
Rate card version change (pricing or hours updated)
Patch: tracked separately as RC v2.1 etc.
Update RATE_CARD_VERSION env variable; update rate card JSON/static data node; log change date and author
Studio owner approval
Restore previous rate card JSON from Git; update env variable
Tool swap (e.g., replace PandaDoc with DocuSign)
Major: v1.x.x to v2.0.0
Full re-spec of affected sections; new credential store entries; full regression test; update all six suite documents
All three stakeholders: Studio owner, Account lead, Delivery lead
Maintain v1 workflow as a separate archived workflow for 30 days post-migration
Credential rotation (API key or OAuth token refresh)
No version change; logged in audit notes
Rotate credential in n8n Credential Store; test affected workflow with a dry-run deal; confirm run succeeds
Developer only
Re-enter previous credential value if new key fails validation
Google Docs template redesign (layout or placeholder changes)
Minor: v1.x.0 increment on template change
Update GDOCS_PROPOSAL_TEMPLATE_ID or GDOCS_SOW_TEMPLATE_ID env variables to new file IDs; run end-to-end test on staging before swapping production IDs
Process owner + Account lead review
Revert env variable to previous template file ID
Workflow JSON exports must be committed to the project Git repository after every change. Branch naming convention: feature/<agent-name>-<description> for new work; fix/<description> for patches. The main branch always reflects the live production state. Tag each production release with the version number (e.g., git tag v1.2.0).
  • This specification is version 1.0.0 at time of initial build delivery.
  • The document owner is the assigned developer for [YourCompany.com]. Updates require the process owner to be notified within 2 business days of any Minor or Major change.
  • All six documents in the FullSpec suite must be reviewed for consistency whenever this Integration and API Spec is updated at a Minor or Major version level.
  • A change log comment must be added to the FullSpec Automation workflow description field on every deployment, including the date, version number, and a one-line description of the change.
  • Sensitive credential values must never be committed to Git. Only credential names and types are recorded in version-controlled files.
Integration and API SpecPage 3 of 3

More documents for this process

Every document generated for Proposal & SOW Creation.

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