How it works
What this workflow does
Give the sales team a proposal draft built from the right call and the terms they have already agreed. An authenticated intake validates the commercial fields, verifies that the client email is a participant in the specified Fireflies transcript, and asks Azure OpenAI for a short introduction and objective. PandaDoc receives the approved scope, timeline, and price directly from intake rather than from the model.
The workflow imports inactive with dryRun: true and sendApprovedProposal: false. Run with sample data exercises the field assembly with fictional values and does not call Fireflies, Azure OpenAI, PandaDoc, Slack, or Airtable.
This is the proposal stage of the AI Revenue Operating System blueprint, with the resulting commercial terms carried forward by the Commercial-to-Delivery Project Handoff blueprint.
Approved fields stay deterministic
Validate approved intake checks the proposal and meeting IDs, client identity, scope, timeline, price, currency, and required configuration. The price must be a decimal string and the currency a three-letter code. The client email must exactly match a Fireflies transcript participant before the workflow continues.
Only the proposal introduction and objective come from Azure OpenAI, and both are length-checked before use. The approved scope, timeline, and price populate the PandaDoc tokens Proposal.ApprovedScope, Proposal.ApprovedTimeline, and Proposal.ApprovedPrice. The model cannot set the recipient, price, or commercial terms.
One reviewer, one controlled delivery
The workflow reserves the Airtable record by Proposal ID, creates the PandaDoc draft, records its document ID, and verifies the document is in document.draft with exactly one matching recipient. It then sends a Slack approval request to the configured reviewer and captures who responded. Only that reviewer ID can approve; a decline or expired request is recorded as changes_requested or approval_expired.
Delivery stays off unless sendApprovedProposal is true. When enabled, the workflow re-reads the document and requires the same document ID, name, content version, and recipient before sending. It records delivery_pending, confirms the PandaDoc delivery status, and records sent. Approval requests expire after two days.
Validation scope
The supplied report confirms the isolated n8n 2.47.4 import, inactive state, and sample path. It also covers structural checks, deterministic PandaDoc fields, reviewer restriction, delivery remaining off by default, and replay or changed-draft protection. Live Fireflies, Azure OpenAI, PandaDoc, Slack, and Airtable calls require a staging test with your accounts.
How to use
Before you start
- n8n with Slack's Capture Who Responded support. The package was built for n8n 2.47.4.
- A Fireflies API key with access to the relevant call transcripts.
- An Azure OpenAI resource with a JSON-mode deployment.
- A PandaDoc template with one recipient role, the required variables, and signature fields.
- An Airtable base with a Proposals table.
- A Slack app with a bot token, signing secret, and interactivity configured for the n8n callback.
1. Import and run the sample
Download the complete package, extract the ZIP, and read the full setup guide. Import proposal-draft-and-approval.n8n.json and keep it inactive. Run Run with sample data and inspect the sample tokens in Assemble PandaDoc fields.
2. Prepare PandaDoc and Airtable
Create a PandaDoc template with one recipient role and these exact variables:
Proposal.IntroductionProposal.ObjectiveProposal.ApprovedScopeProposal.ApprovedTimelineProposal.ApprovedPrice
Add the signature fields for that role and check how the approved price appears in your template. Create an Airtable Proposals table with the text fields Proposal ID, Client Email, Document ID, Status, Reviewer ID, Reviewed At. Set airtableBaseId and proposalsTableId in Setup.
3. Configure credentials
| Service | Credential |
|---|---|
Inbound intake | Header Auth with a private X-Uptune-Webhook-Key value |
Fireflies | Header Auth using Authorization: Bearer <Fireflies API key> |
Azure OpenAI | Header Auth using api-key: <Azure OpenAI key> |
PandaDoc | Header Auth using Authorization: API-Key <PandaDoc key> |
Airtable | Header Auth using Authorization: Bearer <Airtable token> with record read and write access |
Slack | Slack API credential with a bot token and signing secret |
Set azureResource, azureDeployment, pandaDocTemplateId, pandaDocRecipientRole, and slackReviewerId in Setup. Configure Slack Interactivity for the n8n callback before testing the approval step.
4. Send a test proposal
Forward the intake fields from an internal form or CRM. Use a new proposalId for each approved revision and keep it stable on delivery retries. Supply approved values for approvedScope, approvedTimeline, approvedPrice, and currency, plus the Fireflies meetingId and verified client identity fields. The supplied test payloads include a complete intake, a missing approved scope, and approve and decline responses.
Run a staging proposal with dryRun: false and sendApprovedProposal: false. Verify that the reviewer can approve or decline in Slack and that Airtable records approved, changes_requested, or approval_expired as appropriate. Confirm that a non-reviewer cannot approve.
5. Enable delivery deliberately
Enable sendApprovedProposal only after a controlled test with an address you own. Before sending, the workflow rechecks the PandaDoc content version and recipient and stops if either changed. If creation or delivery stalls, check the stored document ID or search PandaDoc for the Proposal ID, and confirm its status before releasing a reservation or attempting another send. Use a fresh revision ID to submit a corrected draft after review.
Related automations
Use the HubSpot Ghosted Proposal Follow-Up & Recovery System for later follow-up and the Client Onboarding & Project Handoff Automation after the proposal is signed. The Sales-Call Follow-Up Draft System covers the call recap before the proposal. Read the AI Revenue Operating System blueprint for the wider commercial process.