This workflow corresponds to n8n.io template #16754 — we link there as the canonical source.
This workflow follows the Gmail → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "DocuSign Connect Listener (Part 2 of 2)",
"nodes": [
{
"name": "DocuSign Connect Listener",
"type": "n8n-nodes-base.webhook",
"position": [
-368,
-1328
],
"parameters": {
"path": "docusign-connect",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"name": "If Envelope Completed",
"type": "n8n-nodes-base.if",
"position": [
-144,
-1328
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "YOUR-ID-HERE",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ (($json.body && $json.body.event) === 'envelope-completed') || ($json.body && $json.body.data && $json.body.data.envelopeSummary && $json.body.data.envelopeSummary.status === 'completed') || ($json.event === 'envelope-completed') || ($json.status === 'completed') }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"name": "Fetch Assessment by ID",
"type": "n8n-nodes-base.httpRequest",
"position": [
128,
-1344
],
"parameters": {
"url": "=https://YOUR-PROJECT.supabase.co/rest/v1/assessments?select=*&contract_envelope_id=eq.{{ $json.body && $json.body.data ? $json.body.data.envelopeId : ($json.data ? $json.data.envelopeId : $json.envelopeId) }}&limit=1",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "supabaseApi"
},
"typeVersion": 4.4
},
{
"name": "Normalize Assessment Data",
"type": "n8n-nodes-base.code",
"position": [
336,
-1344
],
"parameters": {
"jsCode": "// Shape-agnostic: Supabase REST may arrive as an array, a single row object, or split items.\nconst items = $input.all();\nlet row = null;\nfor (const it of items) {\n const j = it.json;\n if (Array.isArray(j)) { if (j.length && j[0] && j[0].id) { row = j[0]; break; } }\n else if (j && j.id) { row = j; break; }\n}\nconst wh = ($node[\"DocuSign Connect Listener\"] && $node[\"DocuSign Connect Listener\"].json) || {};\nconst envId = (wh.body && wh.body.data && wh.body.data.envelopeId) || (wh.data && wh.data.envelopeId) || wh.envelopeId || null;\nif (!row) {\n return [{ json: { found: false, reason: \"No assessment row found for envelopeId\", envelopeId: envId } }];\n}\nreturn [{ json: { found: true, assessment: row, envelopeId: envId } }];"
},
"typeVersion": 2
},
{
"name": "If Assessment Exists",
"type": "n8n-nodes-base.if",
"position": [
544,
-1344
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "YOUR-ID-HERE",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ $json.found }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2.3
},
{
"name": "Update Contract Status in Supabase",
"type": "n8n-nodes-base.supabase",
"position": [
784,
-1360
],
"parameters": {
"filters": {
"conditions": [
{
"keyName": "id",
"keyValue": "={{ $json.assessment.id }}",
"condition": "eq"
}
]
},
"tableId": "assessments",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "contract_status",
"fieldValue": "completed"
},
{
"fieldId": "contract_envelope_id",
"fieldValue": "={{ $json.envelopeId }}"
},
{
"fieldId": "contract_signed_at",
"fieldValue": "={{ $node[\"DocuSign Connect Listener\"].json.completedDateTime ?? $node[\"DocuSign Connect Listener\"].json.statusDateTime ?? new Date().toISOString() }}"
}
]
},
"operation": "update"
},
"typeVersion": 1
},
{
"name": "Upsert Client in Supabase",
"type": "n8n-nodes-base.httpRequest",
"position": [
976,
-1360
],
"parameters": {
"url": "https://YOUR-PROJECT.supabase.co/rest/v1/clients?on_conflict=assessment_id",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify({ assessment_id: $('Normalize Assessment Data').item.json.assessment.id, business_name: $('Normalize Assessment Data').item.json.assessment.business_name, primary_contact_name: $('Normalize Assessment Data').item.json.assessment.contact_name, primary_contact_email: $('Normalize Assessment Data').item.json.assessment.contact_email, docusign_envelope_id: $('Normalize Assessment Data').item.json.envelopeId, contract_signed_at: new Date().toISOString(), status: 'active' }) }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "resolution=merge-duplicates,return=representation"
}
]
},
"nodeCredentialType": "supabaseApi"
},
"typeVersion": 4.2
},
{
"name": "Create Onboarding Session in Supabase",
"type": "n8n-nodes-base.supabase",
"position": [
240,
-768
],
"parameters": {
"tableId": "onboarding_sessions",
"fieldsUi": {
"fieldValues": [
{
"fieldId": "client_id",
"fieldValue": "={{ $node[\"Upsert Client in Supabase\"].json.id }}"
},
{
"fieldId": "assessment_id",
"fieldValue": "={{ $node[\"Normalize Assessment Data\"].json.assessment.id }}"
},
{
"fieldId": "assigned_to_name",
"fieldValue": "={{ $node[\"Normalize Assessment Data\"].json.assessment.contact_name }}"
},
{
"fieldId": "assigned_to_email",
"fieldValue": "={{ $node[\"Normalize Assessment Data\"].json.assessment.contact_email }}"
},
{
"fieldId": "initiated_by_email",
"fieldValue": "={{ $node[\"Normalize Assessment Data\"].json.assessment.contact_email }}"
},
{
"fieldId": "status",
"fieldValue": "created"
},
{
"fieldId": "resume_token",
"fieldValue": "={{ $node[\"Generate Session Token\"].json.resume_token }}"
},
{
"fieldId": "expires_at",
"fieldValue": "={{ new Date(Date.now() + 1000 * 60 * 60 * 24 * 30).toISOString() }}"
},
{
"fieldId": "answers_json",
"fieldValue": "={{ {} }}"
}
]
}
},
"typeVersion": 1
},
{
"name": "Generate Session Token",
"type": "n8n-nodes-base.code",
"position": [
48,
-768
],
"parameters": {
"jsCode": "let resume_token;\ntry { resume_token = crypto.randomUUID(); }\ncatch (e) {\n resume_token = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (ch) => {\n const r = Math.random() * 16 | 0; const v = ch === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16);\n });\n}\nreturn [{ json: { resume_token } }];"
},
"typeVersion": 2
},
{
"name": "Send Onboarding Invite via Outlook",
"type": "n8n-nodes-base.microsoftOutlook",
"position": [
608,
-768
],
"parameters": {
"subject": "={{ $('Normalize Assessment Data').item.json.assessment.is_pilot ? 'Your Company Pilot, Onboarding Questionnaire' : 'Welcome to Your Company, Let\u2019s Get You Onboarded' }}",
"bodyContent": "=<p>Hi {{ $node[\"Normalize Assessment Data\"].json.assessment.contact_name }},</p>\n\n<p>\n{{ $('Normalize Assessment Data').item.json.assessment.is_pilot ? 'Thank you for joining the Use-Case Pilot. Your onboarding is now ready.' : 'Thank you for signing your agreement with Your Company. Your onboarding is now ready.' }}\n</p>\n\n<p>\nPlease use the link below to complete your onboarding questionnaire:\n</p>\n\n<p>\n<a href=\"https://your-domain.com/onboarding?token={{ $node['Generate Session Token'].json.resume_token }}\">\n Start Onboarding\n</a>\n</p>\n\n<p>\nThis form is simple and can be completed in stages. If you need to stop at any time, your progress can be resumed later using the same link.\n</p>\n\n<p>\nIf someone else on your team should complete onboarding, the form will give you the option to delegate it.\n</p>\n\n<p>\nBest regards,<br/>\n<strong>Your Company</strong><br/>\nyou@your-domain.com\n</p>",
"toRecipients": "={{ $node[\"Normalize Assessment Data\"].json.assessment.contact_email }}",
"additionalFields": {
"from": "user@example.com",
"bodyContentType": "html"
}
},
"typeVersion": 2
},
{
"name": "Wait 24 Hours Before Invite",
"type": "n8n-nodes-base.wait",
"position": [
416,
-768
],
"parameters": {
"unit": "hours",
"amount": 24
},
"typeVersion": 1.1
},
{
"name": "Send Internal Notification via Gmail",
"type": "n8n-nodes-base.gmail",
"position": [
784,
-768
],
"parameters": {
"sendTo": "user@example.com",
"message": "=<p>Hi our team,</p>\n\n<p>\nA new onboarding invite was successfully sent to the client.\n</p>\n\n<p><strong>Client:</strong> {{ $node[\"Normalize Assessment Data\"].json.assessment.business_name }}<br/>\n<strong>Primary Contact:</strong> {{ $node[\"Normalize Assessment Data\"].json.assessment.contact_name }}<br/>\n<strong>Email:</strong> {{ $node[\"Normalize Assessment Data\"].json.assessment.contact_email }}<br/>\n<strong>Assessment ID / Contract ID:</strong> {{ $node[\"Normalize Assessment Data\"].json.assessment.id }}<br/>\n<strong>DocuSign Envelope ID:</strong> {{ $json.envelopeId || $node[\"Normalize Assessment Data\"].json.envelopeId || $node[\"DocuSign Connect Listener\"].json.envelopeId }}<br/>\n<strong>Onboarding Session Status:</strong> created\n</p>\n\n<p>\n<strong>Client onboarding link:</strong><br/>\n<a href=\"https://your-domain.com/onboarding?token={{ $node['Generate Session Token'].json.resume_token }}\">\n https://your-domain.com/onboarding?token={{ $node['Generate Session Token'].json.resume_token }}\n</a>\n</p>\n\n<p>\nThis onboarding invite was scheduled and sent 24 hours after contract completion.\n</p>\n\n<p>\nBest,<br/>\nYour Company\n</p>",
"options": {
"appendAttribution": true
},
"subject": "=New client onboarding sent, {{ $node[\"Normalize Assessment Data\"].json.assessment.business_name }}"
},
"typeVersion": 2.2
},
{
"name": "Create Welcome Email Draft",
"type": "n8n-nodes-base.httpRequest",
"maxTries": 4,
"position": [
-352,
-768
],
"parameters": {
"url": "https://api.anthropic.com/v1/messages",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify({ model: \"claude-sonnet-4-6\", max_tokens: 1000, messages: [{ role: \"user\", content: \"You are writing a new client welcome email for Your Company, an AI-driven IT solutions company in Central Florida. Write a warm, professional, and energetic welcome email to a business owner who just signed their agreement.\\n\\nClient name: \" + (($('Normalize Assessment Data').item.json.assessment.contact_name) || \"\") + \"\\nBusiness name: \" + (($('Normalize Assessment Data').item.json.assessment.business_name) || \"\") + \"\\nServices recommended: \" + ((() => { const s = $('Normalize Assessment Data').item.json.assessment.recommended_services; if (Array.isArray(s)) return s.join(', '); if (typeof s === 'string') { try { const p = JSON.parse(s); return Array.isArray(p) ? p.join(', ') : s; } catch (e) { return s; } } return s ? String(s) : ''; })()) + \"\\n\\nRules:\\n- Maximum 4 sentences\\n- Warm, confident, personal tone\\n- Reference their business name naturally\\n- Make them feel they made the right decision\\n- Mention our team is their direct point of contact\\n- Never make specific outcome guarantees\\n- Plain text only, no markdown, no asterisks, no bold\\n- Do NOT start with a greeting, the email template already includes Hi [name]\\n- Sign off as: Your Name, Your Company\\n\\nReturn ONLY the email body text. No subject line. Nothing else.\" }] }) }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "anthropic-version",
"value": "2023-06-01"
},
{
"name": "content-type",
"value": "application/json"
}
]
},
"nodeCredentialType": "anthropicApi"
},
"retryOnFail": true,
"typeVersion": 4.4,
"waitBetweenTries": 5000
},
{
"name": "Send Welcome Email via Outlook",
"type": "n8n-nodes-base.microsoftOutlook",
"position": [
-160,
-768
],
"parameters": {
"subject": "=Welcome to Your Company, {{ $('Normalize Assessment Data').item.json.assessment.business_name }}",
"bodyContent": "=<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; color: #1a1a2e;\">\n\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n <tr>\n <td style=\"background: #1B4F8A; padding: 24px 32px; border-radius: 8px 8px 0 0;\">\n <h1 style=\"color: #ffffff; margin: 0; font-size: 22px;\">Welcome to Your Company!</h1>\n <p style=\"color: #DDDDDD; margin: 4px 0 0; font-size: 14px;\">\n AI-Powered IT Solutions | Central Florida\n </p>\n </td>\n </tr>\n </table>\n\n <div style=\"padding: 32px;\">\n <p style=\"font-size: 16px;\">\n Hi {{ $('Normalize Assessment Data').item.json.assessment.contact_name }},\n </p>\n\n <p style=\"line-height: 1.8;\">\n {{ $('Create Welcome Email Draft').item.json.content[0].text.replace(/\\n/g, '<br/>') }}\n </p>\n\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin: 24px 0;\">\n <tr>\n <td style=\"background: #EBF2FB; border-left: 4px solid #1B4F8A; border-radius: 8px; padding: 20px 24px;\">\n <p style=\"margin: 8px 0;\"><strong>Your Business:</strong> {{ $('Normalize Assessment Data').item.json.assessment.business_name }}</p>\n <p style=\"margin: 8px 0;\"><strong>Your Point of Contact:</strong> Your Name</p>\n <p style=\"margin: 8px 0;\"><strong>Direct Email:</strong> you@your-domain.com</p>\n <p style=\"margin: 8px 0;\"><strong>Website:</strong> your-domain.com</p>\n </td>\n </tr>\n </table>\n\n <div style=\"text-align: center; margin: 32px 0;\">\n <a href=\"https://your-domain.com\"\n style=\"background: #F97316; color: #ffffff; padding: 14px 32px;\n border-radius: 8px; text-decoration: none; font-weight: bold;\n font-size: 16px;\">\n Visit Our Portal\n </a>\n </div>\n\n <p style=\"margin-top: 32px; color: #666666; font-size: 13px;\">\n Your Company Inc.<br/>\n Automate. Relentlessly. Ruthlessly.\u2122\n </p>\n </div>\n\n</div>",
"toRecipients": "={{ $('Normalize Assessment Data').item.json.assessment.contact_email }}",
"additionalFields": {
"from": "user@example.com",
"bccRecipients": "user@example.com",
"bodyContentType": "html"
}
},
"typeVersion": 2
},
{
"name": "Record Draft Email Cost",
"type": "n8n-nodes-base.executeWorkflow",
"position": [
-160,
-592
],
"parameters": {
"mode": "each",
"options": {
"waitForSubWorkflow": false
},
"workflowId": {
"__rl": true,
"mode": "id",
"value": "YOUR-COST-LOG-SUBWORKFLOW-ID"
},
"workflowInputs": {
"value": {
"model": "={{ $('Create Welcome Email Draft').item.json.model || '' }}",
"provider": "anthropic",
"node_name": "Draft Welcome Email",
"request_id": "={{ $('Create Welcome Email Draft').item.json.id || '' }}",
"agent_label": "",
"input_tokens": "={{ $('Create Welcome Email Draft').item.json.usage?.input_tokens || 0 }}",
"output_tokens": "={{ $('Create Welcome Email Draft').item.json.usage?.output_tokens || 0 }}",
"workflow_name": "={{ $workflow.name }}"
},
"mappingMode": "defineBelow"
}
},
"typeVersion": 1.3
},
{
"name": "If Client Is Pilot",
"type": "n8n-nodes-base.if",
"position": [
1152,
-1360
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "YOUR-ID-HERE",
"operator": {
"type": "boolean",
"operation": "true",
"singleValue": true
},
"leftValue": "={{ String($('Normalize Assessment Data').item.json.assessment.is_pilot) === 'true' }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"name": "Send Pilot Welcome via Outlook",
"type": "n8n-nodes-base.microsoftOutlook",
"position": [
-160,
-944
],
"parameters": {
"subject": "=Welcome to the Use-Case Pilot, {{ $('Normalize Assessment Data').item.json.assessment.business_name }}",
"bodyContent": "=<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; color: #1a1a2e;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n <tr><td style=\"background: #1B4F8A; padding: 24px 32px; border-radius: 8px 8px 0 0;\">\n <h1 style=\"color:#fff; margin:0; font-size:22px;\">Welcome to the Use-Case Pilot!</h1>\n <p style=\"color:#DDD; margin:4px 0 0; font-size:14px;\">AI-Powered Automation | Central Florida</p>\n </td></tr>\n </table>\n <div style=\"padding: 32px; font-size:15px; line-height:1.6;\">\n <p>Hi {{ $('Normalize Assessment Data').item.json.assessment.contact_name }},</p>\n <p>You're in. {{ $('Normalize Assessment Data').item.json.assessment.business_name }} is officially part of the Use-Case Pilot. This is a focused, no-charge pilot where we build one real automation for your business so you can see the value before deciding anything.</p>\n <p>Here is what happens next:</p>\n <ul style=\"color:#333;\">\n <li>We start building your use-case (up to three automations) within about two weeks.</li>\n <li>You run it for a 60-day evaluation. Real workflow, real data.</li>\n <li>It costs you nothing, and you own what we build.</li>\n </ul>\n <p>Within the next business day you will receive a short onboarding questionnaire so we can scope your pilot route correctly. That is the only thing we need from you to get started.</p>\n <p>Let's build something that actually saves you time.</p>\n <div style=\"background:#eef2f8; border-left:4px solid #1B4F8A; padding:16px 20px; margin:24px 0; font-size:14px;\">\n <p style=\"margin:0 0 6px;\"><strong>Your Business:</strong> {{ $('Normalize Assessment Data').item.json.assessment.business_name }}</p>\n <p style=\"margin:0 0 6px;\"><strong>Program:</strong> Use-Case Pilot (60-day, no charge)</p>\n <p style=\"margin:0 0 6px;\"><strong>Your Point of Contact:</strong> Your Company Team</p>\n <p style=\"margin:0;\"><strong>Website:</strong> your-domain.com</p>\n </div>\n </div>\n <div style=\"padding:0 32px 24px; color:#888; font-size:12px;\">Your Company Inc.<br/>Automate. Relentlessly. Ruthlessly.™</div>\n</div>",
"toRecipients": "={{ $('Normalize Assessment Data').item.json.assessment.contact_email }}",
"additionalFields": {
"from": "user@example.com",
"bccRecipients": "user@example.com",
"bodyContentType": "html"
}
},
"typeVersion": 2
},
{
"name": "Build Stripe Parameters",
"type": "n8n-nodes-base.code",
"onError": "continueErrorOutput",
"position": [
1040,
-768
],
"parameters": {
"jsCode": "const a = $('Normalize Assessment Data').item.json.assessment || {};\nconst toCents = (v) => Math.round(Number(String(v ?? '').replace(/[^0-9.]/g, '')) * 100) || 0;\nreturn [{ json: {\n name: a.business_name || a.contact_name || 'New Client',\n email: a.contact_email || '',\n contact_name: a.contact_name || '',\n retainer_cents: toCents(a.proposal_monthly_retainer),\n setup_cents: toCents(a.proposal_one_time_fee)\n} }];"
},
"typeVersion": 2
},
{
"name": "Create Customer in Stripe",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"maxTries": 2,
"position": [
1232,
-768
],
"parameters": {
"url": "https://api.stripe.com/v1/customers",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "form-urlencoded",
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "name",
"value": "={{ $json.name }}"
},
{
"name": "email",
"value": "={{ $json.email }}"
}
]
},
"nodeCredentialType": "stripeApi"
},
"retryOnFail": true,
"typeVersion": 4.2,
"waitBetweenTries": 2000
},
{
"name": "Create Checkout in Stripe",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"maxTries": 2,
"position": [
1440,
-768
],
"parameters": {
"url": "https://api.stripe.com/v1/checkout/sessions",
"method": "POST",
"options": {},
"sendBody": true,
"contentType": "form-urlencoded",
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "mode",
"value": "subscription"
},
{
"name": "customer",
"value": "={{ $('Create Customer in Stripe').item.json.id }}"
},
{
"name": "success_url",
"value": "https://your-domain.com/portal?checkout=success"
},
{
"name": "cancel_url",
"value": "https://your-domain.com/portal?checkout=cancel"
},
{
"name": "line_items[0][price_data][currency]",
"value": "usd"
},
{
"name": "line_items[0][price_data][product_data][name]",
"value": "Your Company Monthly Retainer"
},
{
"name": "line_items[0][price_data][recurring][interval]",
"value": "month"
},
{
"name": "line_items[0][price_data][unit_amount]",
"value": "={{ $('Build Stripe Parameters').item.json.retainer_cents }}"
},
{
"name": "line_items[0][quantity]",
"value": "1"
},
{
"name": "line_items[1][price_data][currency]",
"value": "usd"
},
{
"name": "line_items[1][price_data][product_data][name]",
"value": "One-Time Setup Fee"
},
{
"name": "line_items[1][price_data][unit_amount]",
"value": "={{ $('Build Stripe Parameters').item.json.setup_cents }}"
},
{
"name": "line_items[1][quantity]",
"value": "1"
},
{
"name": "payment_method_types[0]",
"value": "card"
},
{
"name": "payment_method_types[1]",
"value": "us_bank_account"
}
]
},
"nodeCredentialType": "stripeApi"
},
"retryOnFail": true,
"typeVersion": 4.2,
"waitBetweenTries": 2000
},
{
"name": "Save Customer ID in Supabase",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
1632,
-768
],
"parameters": {
"url": "=https://YOUR-PROJECT.supabase.co/rest/v1/clients?id=eq.{{ $('Upsert Client in Supabase').item.json.id }}",
"method": "PATCH",
"options": {},
"jsonBody": "={{ JSON.stringify({ stripe_customer_id: $('Create Customer in Stripe').item.json.id }) }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=minimal"
}
]
},
"nodeCredentialType": "supabaseApi"
},
"typeVersion": 4.2
},
{
"name": "Send Payment Link via Outlook",
"type": "n8n-nodes-base.microsoftOutlook",
"onError": "continueErrorOutput",
"position": [
1824,
-768
],
"parameters": {
"subject": "=Complete your setup, Your Company",
"bodyContent": "=<div style=\"font-family: Arial, sans-serif; max-width:600px; margin:0 auto; color:#1a1a2e;\">\n <table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\"><tr><td style=\"background:#1B4F8A; padding:24px 32px; border-radius:8px 8px 0 0;\">\n <h1 style=\"color:#fff; margin:0; font-size:22px;\">You're all set, one last step</h1>\n <p style=\"color:#DDD; margin:4px 0 0; font-size:14px;\">Your Company | Billing</p>\n </td></tr></table>\n <div style=\"padding:32px; font-size:15px; line-height:1.7;\">\n <p>Hi {{ $('Normalize Assessment Data').item.json.assessment.contact_name }},</p>\n <p>Thank you for signing your agreement with Your Company. To activate your services, please complete your secure payment setup below. You can pay by card or by bank transfer (ACH).</p>\n <div style=\"text-align:center; margin:32px 0;\"><a href=\"{{ $('Create Checkout in Stripe').item.json.url }}\" style=\"background:#F97316; color:#fff; padding:14px 32px; border-radius:8px; text-decoration:none; font-weight:bold; font-size:16px;\">Complete Payment Setup</a></div>\n <p style=\"color:#666; font-size:13px;\">This is a secure checkout powered by Stripe. If you have any questions, just reply to this email.</p>\n <p style=\"margin-top:24px; color:#666; font-size:13px;\">Your Company Inc.<br/>Automate. Relentlessly. Ruthlessly.™</p>\n </div>\n</div>",
"toRecipients": "={{ $('Normalize Assessment Data').item.json.assessment.contact_email }}",
"additionalFields": {
"from": "user@example.com",
"bccRecipients": "user@example.com",
"bodyContentType": "html"
}
},
"typeVersion": 2
},
{
"name": "Fetch Signed Contract via HTTP",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueRegularOutput",
"position": [
1360,
-1360
],
"parameters": {
"url": "https://YOUR-N8N-INSTANCE/webhook/docusign/fetch-signed-contract",
"method": "POST",
"options": {},
"jsonBody": "={{ JSON.stringify({ envelope_id: $('Normalize Assessment Data').item.json.envelopeId, client_id: $('Upsert Client in Supabase').item.json.id }) }}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "x-fetch-token",
"value": "YOUR-FETCH-TOKEN"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.2
},
{
"name": "Sticky: Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-928,
-1536
],
"parameters": {
"width": 484,
"height": 762,
"content": "## DocuSign Connect listener (part 2 of 2)\n\nThe receiving half almost nobody publishes. A DocuSign Connect webhook fires on envelope events; when a contract is signed this records it, creates the client, sends a welcome, kicks off onboarding, and (for non-pilot deals) starts billing by creating a Stripe customer plus a checkout session and emailing the client their payment link. Pair with **DocuSign Send Envelope** (part 1) for the full lifecycle.\n\n### Setup (replace before running)\n- Point your **DocuSign Connect** config at this workflow's webhook URL\n- Credentials: database (Supabase), email (Outlook + Gmail), Anthropic (Claude) for the welcome draft, and **Stripe** for billing\n- In the Stripe checkout node set your own success and cancel URLs and product wording; the price is read from the deal record\n- Replace the `YOUR-PROJECT.supabase.co` and other `YOUR-...` placeholders\n\n### Customization\n- Swap the Claude-drafted welcome for a fixed template, or adjust its tone in the draft node\n- Change the onboarding wait (24 hours) to fit your cadence\n- In the Stripe checkout, edit the product wording, add a coupon, or adjust the line items\n- The cost-logging node is optional, delete it if you do not track token spend"
},
"typeVersion": 1
},
{
"name": "Sticky: 1 Receive",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
-1536
],
"parameters": {
"color": 7,
"width": 470,
"height": 386,
"content": "## 1. Receive the signed event\n**DocuSign Connect Listener** receives DocuSign Connect events. **If Envelope Completed** continues only when the contract is actually signed."
},
"typeVersion": 1
},
{
"name": "Sticky: 2 Match",
"type": "n8n-nodes-base.stickyNote",
"position": [
80,
-1536
],
"parameters": {
"color": 7,
"width": 620,
"height": 386,
"content": "## 2. Match the deal\n**Fetch Assessment by ID** and **Normalize Assessment Data** look up the original deal in your database; **If Assessment Exists** guards against unknown envelopes."
},
"typeVersion": 1
},
{
"name": "Sticky: 3 Record",
"type": "n8n-nodes-base.stickyNote",
"position": [
720,
-1536
],
"parameters": {
"color": 7,
"width": 814,
"height": 390,
"content": "## 3. Record and branch\n**Update Contract Status in Supabase** and **Upsert Client in Supabase** save the signed deal. **If Client Is Pilot** splits pilot vs standard, and **Fetch Signed Contract via HTTP** pulls the signed PDF."
},
"typeVersion": 1
},
{
"name": "Sticky: 4 Welcome + onboarding",
"type": "n8n-nodes-base.stickyNote",
"position": [
-416,
-1120
],
"parameters": {
"color": 7,
"width": 1384,
"height": 700,
"content": "## 4. Welcome and onboarding\nSend the welcome email (**Create Welcome Email Draft** + **Send Welcome Email via Outlook** for standard, **Send Pilot Welcome via Outlook** for pilots; **Record Draft Email Cost** logs token usage). **Generate Session Token** and **Create Onboarding Session in Supabase**, then after **Wait 24 Hours Before Invite** send **Send Onboarding Invite via Outlook** plus a **Send Internal Notification via Gmail**."
},
"typeVersion": 1
},
{
"name": "Sticky: 5 Start billing",
"type": "n8n-nodes-base.stickyNote",
"position": [
992,
-1120
],
"parameters": {
"color": 7,
"width": 1052,
"height": 698,
"content": "## 5. Start billing (Stripe)\nOn the standard (non-pilot) branch, payment kicks off. **Build Stripe Parameters** reads the setup fee and monthly retainer from the deal. **Create Customer in Stripe** then **Create Checkout in Stripe** build a subscription checkout (one-time setup fee plus the recurring retainer). **Save Customer ID in Supabase** writes it back, and **Send Payment Link via Outlook** emails the client their branded checkout link."
},
"typeVersion": 1
}
],
"settings": {
"executionOrder": "v1"
},
"connections": {
"If Client Is Pilot": {
"main": [
[
{
"node": "Send Pilot Welcome via Outlook",
"type": "main",
"index": 0
}
],
[
{
"node": "Create Welcome Email Draft",
"type": "main",
"index": 0
},
{
"node": "Build Stripe Parameters",
"type": "main",
"index": 0
}
]
]
},
"If Assessment Exists": {
"main": [
[
{
"node": "Update Contract Status in Supabase",
"type": "main",
"index": 0
}
],
[]
]
},
"If Envelope Completed": {
"main": [
[
{
"node": "Fetch Assessment by ID",
"type": "main",
"index": 0
}
],
[]
]
},
"Fetch Assessment by ID": {
"main": [
[
{
"node": "Normalize Assessment Data",
"type": "main",
"index": 0
}
]
]
},
"Generate Session Token": {
"main": [
[
{
"node": "Create Onboarding Session in Supabase",
"type": "main",
"index": 0
}
]
]
},
"Build Stripe Parameters": {
"main": [
[
{
"node": "Create Customer in Stripe",
"type": "main",
"index": 0
}
]
]
},
"Create Checkout in Stripe": {
"main": [
[
{
"node": "Save Customer ID in Supabase",
"type": "main",
"index": 0
}
]
]
},
"Create Customer in Stripe": {
"main": [
[
{
"node": "Create Checkout in Stripe",
"type": "main",
"index": 0
}
]
]
},
"DocuSign Connect Listener": {
"main": [
[
{
"node": "If Envelope Completed",
"type": "main",
"index": 0
}
]
]
},
"Normalize Assessment Data": {
"main": [
[
{
"node": "If Assessment Exists",
"type": "main",
"index": 0
}
]
]
},
"Upsert Client in Supabase": {
"main": [
[
{
"node": "If Client Is Pilot",
"type": "main",
"index": 0
},
{
"node": "Fetch Signed Contract via HTTP",
"type": "main",
"index": 0
}
]
]
},
"Create Welcome Email Draft": {
"main": [
[
{
"node": "Record Draft Email Cost",
"type": "main",
"index": 0
},
{
"node": "Send Welcome Email via Outlook",
"type": "main",
"index": 0
}
]
]
},
"Wait 24 Hours Before Invite": {
"main": [
[
{
"node": "Send Onboarding Invite via Outlook",
"type": "main",
"index": 0
}
]
]
},
"Save Customer ID in Supabase": {
"main": [
[
{
"node": "Send Payment Link via Outlook",
"type": "main",
"index": 0
}
]
]
},
"Send Pilot Welcome via Outlook": {
"main": [
[
{
"node": "Generate Session Token",
"type": "main",
"index": 0
}
]
]
},
"Send Welcome Email via Outlook": {
"main": [
[
{
"node": "Generate Session Token",
"type": "main",
"index": 0
}
]
]
},
"Send Onboarding Invite via Outlook": {
"main": [
[
{
"node": "Send Internal Notification via Gmail",
"type": "main",
"index": 0
}
]
]
},
"Update Contract Status in Supabase": {
"main": [
[
{
"node": "Upsert Client in Supabase",
"type": "main",
"index": 0
}
]
]
},
"Create Onboarding Session in Supabase": {
"main": [
[
{
"node": "Wait 24 Hours Before Invite",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow listens for DocuSign Connect envelope-completed events, looks up the related assessment in Supabase, updates contract and client records, sends a welcome email (optionally drafted with Anthropic), creates an onboarding session and invite, and for non-pilot clients…
Source: https://n8n.io/workflows/16754/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates a document approval process using Supabase and Gmail. Teams that need structured multi-level document approvals. Companies managing policies, contracts, or proposals. Medical d
Automate WhatsApp communication for recruitment agencies with an interactive, structured customer experience. This workflow handles pricing inquiries, request submissions, tracking, complaints, and hu
This workflow automates HR onboarding by capturing new hires via a webhook, saving them to Google Sheets, emailing a Slack invite via Gmail, and notifying managers in Slack, then listening for Slack t
Fluxo Cadastro Original. Uses httpRequest, gmail. Webhook trigger; 67 nodes.
Hectelion | Evaluation d'entreprise. Uses googleDrive, httpRequest, microsoftOutlook, googleSheets. Webhook trigger; 64 nodes.