Handleidingen · Claude

Automatisch offertes genereren vanuit CRM-data met Claude en PandaDoc

Automatisch offertes genereren vanuit CRM-data met Claude en PandaDoc. Minder typewerk, snellere deals.

🟡 Gevorderd — beetje technisch ⏱ 90 minuten
Tools: n8nClaudePandaDocHubSpot
Goud-op-zwart illustratie: facturen gaan door een AI-scan naar de boekhouding en een getekende offerte

Offertes maken is tijdrovend en vaak repetitief. Je haalt klantgegevens op, vult een template in, personaliseert de tekst, stuurt ter review en wacht op ondertekening. Dit proces duurt gemiddeld 45 tot 90 minuten per offerte. Met Claude, n8n en PandaDoc comprimeer je dat naar 5 minuten kwaliteitscheck.

In deze handleiding bouw je een workflow waarbij een salesmedewerker in HubSpot op een knop klikt, waarna n8n automatisch CRM-data ophaalt, Claude een gepersonaliseerde offerte schrijft en PandaDoc de offerte opstelt en verstuurt voor elektronische ondertekening.

Wat je nodig hebt

  • HubSpot CRM (gratis of betaald, webhook functionaliteit vereist)
  • PandaDoc account (Essentials plan, 19 dollar per maand)
  • Claude API key (Anthropic Console)
  • n8n (workflow automatisering)
  • PandaDoc offerte-template (maak deze eerst handmatig aan als basis)

Stap 1: PandaDoc template aanmaken

Maak in PandaDoc een offerte-template aan met variabele velden (tokens). PandaDoc gebruikt dubbele accolades voor tokens: {{klant_naam}}, {{bedrijfsnaam}}, {{offerte_inhoud}}, {{totaalbedrag}}, {{geldigheid}}. Ontwerp de template met je eigen huisstijl, logo en standaardclausules.

// PandaDoc token structuur
{
  "tokens": [
    { "name": "klant_naam", "value": "" },
    { "name": "bedrijfsnaam", "value": "" },
    { "name": "offerte_datum", "value": "" },
    { "name": "geldig_tot", "value": "" },
    { "name": "offerte_inhoud", "value": "" },
    { "name": "totaalbedrag", "value": "" }
  ]
}

Noteer de Template ID na het opslaan (te vinden in de URL van de template: pandadoc.com/templates/TEMPLATE_ID). Die heb je later nodig.

Stap 2: HubSpot webhook instellen

In HubSpot maak je een Custom Action aan die een webhook triggert wanneer een deal naar de fase 'Offerte aangevraagd' gaat. Ga naar HubSpot Settings, Workflow, maak een deal-based workflow en voeg de webhook actie toe met jouw n8n webhook URL.

// HubSpot webhook payload (automatisch verzonden)
{
  "dealId": "12345",
  "dealName": "Software implementatie ABC Logistiek",
  "amount": 4500,
  "contactId": "67890",
  "companyId": "11111",
  "ownerId": "22222"
}

Stap 3: n8n Webhook node

Maak een nieuwe n8n workflow aan met een Webhook node als trigger. Kopieer de webhook URL en plak die in HubSpot. Stel de webhook in op POST met JSON body.

Stap 4: HubSpot klantdata ophalen

Voeg HubSpot nodes toe om extra klantdata op te halen die niet in de webhook zit: contactpersoon details (naam, e-mail, telefoonnummer) en bedrijfsinformatie (sector, bedrijfsgrootte, website). Gebruik de contactId en companyId uit de webhook payload.

// HubSpot Get Contact node configuratie
{
  "resource": "contact",
  "operation": "get",
  "contactId": "={{ $json.contactId }}",
  "additionalFields": {
    "properties": ["firstname", "lastname", "email", "phone", "jobtitle"]
  }
}

Stap 5: Claude offerte-inhoud genereren

Voeg een HTTP Request node toe voor de Claude API. Dit is de kern: Claude schrijft de gepersonaliseerde offerte-inhoud op basis van de klantdata en dealinformatie.

{
  "model": "claude-sonnet-4-6",
  "max_tokens": 2000,
  "messages": [{
    "role": "user",
    "content": "Schrijf de inhoud van een professionele offerte voor:\n\nKlant: {{ $('HubSpot Contact').item.json.properties.firstname }} {{ $('HubSpot Contact').item.json.properties.lastname }}\nBedrijf: {{ $('HubSpot Company').item.json.properties.name }}\nSector: {{ $('HubSpot Company').item.json.properties.industry }}\nDealwaarde: {{ $json.amount }} euro\nDeal: {{ $json.dealName }}\n\nOns bedrijf levert: [JOUW DIENSTBESCHRIJVING]\n\nSchrijf:\n1. Een gepersonaliseerde aanhef die de klantuitdaging benoemt\n2. Onze aanpak in 3 tot 5 punten\n3. Wat de klant van ons mag verwachten\n4. Een korte succesverhaal-alinea (fictief maar geloofwaardig voor sector {{ $('HubSpot Company').item.json.properties.industry }})\n5. Een duidelijke call-to-action\n\nTon: professioneel, zelfverzekerd, klantgericht. Geen harde verkooptaal."
  }]
}

Stap 6: Prijs berekenen

Voeg een Code node toe voor eventuele prijsberekening op basis van dealwaarde en BTW:

const bedragExBtw = $input.first().json.amount;
const btw = bedragExBtw * 0.21;
const totaalIncBtw = bedragExBtw + btw;
const geldigTot = new Date();
geldigTot.setDate(geldigTot.getDate() + 30);

return [{
  json: {
    bedragExBtw: bedragExBtw.toFixed(2),
    btw: btw.toFixed(2),
    totaalIncBtw: totaalIncBtw.toFixed(2),
    geldigTot: geldigTot.toISOString().split('T')[0]
  }
}];

Stap 7: PandaDoc document aanmaken

Voeg een HTTP Request node toe voor de PandaDoc API om het document aan te maken vanuit je template:

{
  "method": "POST",
  "url": "https://api.pandadoc.com/public/v1/documents",
  "headers": {
    "Authorization": "API-Key {{ $credentials.pandadocApiKey }}",
    "Content-Type": "application/json"
  },
  "body": {
    "name": "Offerte {{ $('HubSpot Contact').item.json.properties.firstname }} - {{ $now.format('YYYY-MM-DD') }}",
    "template_uuid": "YOUR_TEMPLATE_ID",
    "recipients": [{
      "email": "{{ $('HubSpot Contact').item.json.properties.email }}",
      "first_name": "{{ $('HubSpot Contact').item.json.properties.firstname }}",
      "last_name": "{{ $('HubSpot Contact').item.json.properties.lastname }}",
      "role": "Signer"
    }],
    "tokens": [
      { "name": "klant_naam", "value": "{{ $('HubSpot Contact').item.json.properties.firstname }} {{ $('HubSpot Contact').item.json.properties.lastname }}" },
      { "name": "bedrijfsnaam", "value": "{{ $('HubSpot Company').item.json.properties.name }}" },
      { "name": "offerte_datum", "value": "{{ $now.format('DD-MM-YYYY') }}" },
      { "name": "geldig_tot", "value": "{{ $('Code').item.json.geldigTot }}" },
      { "name": "offerte_inhoud", "value": "{{ $('Claude').item.json.content[0].text }}" },
      { "name": "totaalbedrag", "value": "{{ $('Code').item.json.totaalIncBtw }}" }
    ]
  }
}

Stap 8: Document versturen

Na aanmaak wacht je 5 seconden (PandaDoc heeft tijd nodig om het document te genereren) en stuur je het vervolgens:

// Stap 8a: Wacht 5 seconden
// Gebruik n8n Wait node: 5000ms

// Stap 8b: Verstuur document
{
  "method": "POST",
  "url": "https://api.pandadoc.com/public/v1/documents/{{ $('PandaDoc Create').item.json.id }}/send",
  "headers": {
    "Authorization": "API-Key {{ $credentials.pandadocApiKey }}"
  },
  "body": {
    "message": "Geachte {{ $('HubSpot Contact').item.json.properties.firstname }}, hierbij ontvangt u onze offerte. U kunt het document online bekijken en direct ondertekenen.",
    "subject": "Offerte {{ $('HubSpot Company').item.json.properties.name }}",
    "silent": false
  }
}

Stap 9: HubSpot deal updaten

Update de HubSpot deal met de PandaDoc document ID en verplaats de deal naar de volgende fase 'Offerte verzonden':

{
  "resource": "deal",
  "operation": "update",
  "dealId": "={{ $('Webhook').item.json.dealId }}",
  "updateFields": {
    "dealstage": "offerte_verzonden",
    "hs_custom_pandadoc_id": "={{ $('PandaDoc Create').item.json.id }}"
  }
}

Stap 10: Notificatie naar salesmedewerker

Stuur als laatste stap een Slack of e-mail notificatie naar de verantwoordelijke salesmedewerker met een link naar het PandaDoc document voor review:

{
  "channel": "#sales",
  "text": "Offerte verstuurd naar *{{ $('HubSpot Contact').item.json.properties.firstname }} {{ $('HubSpot Contact').item.json.properties.lastname }}* ({{ $('HubSpot Company').item.json.properties.name }})\n\nBedrag: {{ $('Code').item.json.totaalIncBtw }} euro incl. BTW\nGeldig tot: {{ $('Code').item.json.geldigTot }}\n\nBekijk document: https://app.pandadoc.com/a/#/documents/{{ $('PandaDoc Create').item.json.id }}"
}

Stap 11: PandaDoc signing webhook (bonus)

Maak een tweede n8n workflow die luistert op PandaDoc webhooks voor document_state_changed events. Zodra de klant ondertekent, update deze workflow automatisch de HubSpot deal naar 'Gewonnen' en stuurt een felicitatie naar het sales team. PandaDoc webhook instellen: ga naar Settings, Notifications, Webhook URL.

Troubleshooting

Probleem: PandaDoc geeft 'template not found'

Controleer of de template UUID correct is (niet de naam, maar de UUID uit de URL). Controleer ook of je PandaDoc API key de juiste rechten heeft (Documents: Create en Send).

Probleem: Claude tekst te lang voor PandaDoc token

PandaDoc tokens hebben een maximale lengte. Voeg in het Claude prompt toe: 'Max 600 woorden totaal'. Controleer ook de token limieten in jouw PandaDoc plan.

Probleem: HubSpot webhook triggert niet

Controleer of de workflow in HubSpot actief staat ('On'). Test handmatig door een deal handmatig naar de triggerfase te verplaatsen. Controleer in n8n de Execution History of de webhook payload binnenkomt.

Uitbreidingen

  • Voeg productprijzen toe vanuit een Google Sheets prijslijst die Claude gebruikt voor nauwkeurige prijsberekening
  • Maak meerdere Claude prompts voor verschillende diensten of marktsegmenten
  • Voeg een goedkeuringsflow toe: laat de salesmanager eerst de offerte bekijken via Slack approval voor je verstuurt
  • Genereer ook direct een opvolg-e-mail schema in HubSpot Sequences voor deals die niet binnen 7 dagen ondertekend worden

De ROI van deze workflow is snel berekend: als een salesmedewerker 10 offertes per maand maakt en dit systeem bespaart 70 minuten per offerte, levert dat 700 minuten per maand op. Dat is bijna twee volledige werkdagen die de salesmedewerker kan besteden aan klantgesprekken in plaats van administratie.

Gerelateerd

Nieuwsbrief

Meer handleidingen en tips?

Elke week de beste agentic AI inzichten en nieuwe handleidingen in je inbox.

Gratis aanmelden →