LoopFour
IntegrationsDocuments

PandaDoc

Document automation for contracts, proposals, and e-signatures

PandaDoc

Connect to PandaDoc for document creation, e-signatures, and contract automation.

Overview

PandaDoc is a document automation platform. The integration supports:

  • Templates - List and use document templates
  • Documents - Create, send, and track documents
  • E-signatures - Send for signature and track status
  • Folders - Organize documents
  • Contacts - Manage recipient contacts

Prerequisites

  • PandaDoc account (Free trial, Essentials, Business, or Enterprise)
  • API access enabled
  • OAuth app or API key configured

Authentication

PandaDoc uses OAuth 2.0 for authentication via Nango.

curl "http://localhost:3000/api/v1/connections/pandadoc/auth-url" \
  -H "x-api-key: YOUR_API_KEY"

Available Actions

Template Actions

listTemplates

List available templates.

{
  "action": "pandadoc.listTemplates",
  "config": {
    "q": "Sales Contract",
    "tag": "sales",
    "folderId": "folder-uuid",
    "count": 50,
    "page": 1
  }
}

Parameters:

FieldTypeDescription
qstringSearch query
tagstringFilter by tag
folderIdstringFilter by folder
countnumberResults per page (default: 50)
pagenumberPage number
deletedbooleanInclude deleted

getTemplate

Get template details.

{
  "action": "pandadoc.getTemplate",
  "config": {
    "templateId": "{{input.templateId}}"
  }
}

Document Actions

createDocument

Create a document from a template.

{
  "id": "create-contract",
  "type": "action",
  "action": "pandadoc.createDocument",
  "config": {
    "templateId": "{{input.templateId}}",
    "name": "Contract - {{input.companyName}}",
    "recipients": [
      {
        "email": "{{input.signerEmail}}",
        "first_name": "{{input.signerFirstName}}",
        "last_name": "{{input.signerLastName}}",
        "role": "signer",
        "signing_order": 1
      },
      {
        "email": "{{input.ccEmail}}",
        "first_name": "{{input.ccFirstName}}",
        "last_name": "{{input.ccLastName}}",
        "role": "cc"
      }
    ],
    "tokens": [
      { "name": "Company.Name", "value": "{{input.companyName}}" },
      { "name": "Contract.Amount", "value": "{{input.amount}}" },
      { "name": "Contract.Date", "value": "{{input.contractDate}}" }
    ],
    "pricingTables": [
      {
        "name": "Products",
        "sections": [
          {
            "title": "Services",
            "rows": [
              {
                "options": { "qty_editable": false },
                "data": {
                  "Name": "Professional Services",
                  "Price": 5000,
                  "QTY": 1
                }
              }
            ]
          }
        ]
      }
    ],
    "folderId": "{{input.folderId}}",
    "tags": ["sales", "q1-2024"],
    "metadata": {
      "opportunity_id": "{{input.opportunityId}}",
      "source": "workflow"
    }
  }
}

Parameters:

FieldTypeRequiredDescription
templateIdstringYesTemplate UUID
namestringYesDocument name
recipientsarrayNoDocument recipients
recipients[].emailstringYesRecipient email
recipients[].first_namestringNoFirst name
recipients[].last_namestringNoLast name
recipients[].rolestringNoRole from template
recipients[].signing_ordernumberNoSigning order
tokensarrayNoTemplate variable values
tokens[].namestringYesToken name
tokens[].valuestringYesToken value
pricingTablesarrayNoPricing table data
folderIdstringNoFolder UUID
tagsarrayNoDocument tags
metadataobjectNoCustom metadata

getDocument

Get document details.

{
  "action": "pandadoc.getDocument",
  "config": {
    "documentId": "{{input.documentId}}"
  }
}

getDocumentStatus

Get document status (lighter endpoint for status checks).

{
  "action": "pandadoc.getDocumentStatus",
  "config": {
    "documentId": "{{steps.create.output.id}}"
  }
}

Document Statuses:

StatusDescription
document.draftDraft, not yet sent
document.sentSent for signature
document.completedAll signatures collected
document.viewedViewed by recipient
document.waiting_approvalAwaiting internal approval
document.approvedInternally approved
document.rejectedRejected
document.waiting_payAwaiting payment
document.paidPayment received
document.voidedVoided
document.declinedDeclined by recipient
document.external_reviewExternal review in progress

listDocuments

List documents with filters.

{
  "action": "pandadoc.listDocuments",
  "config": {
    "status": "document.sent",
    "templateId": "{{input.templateId}}",
    "q": "Contract",
    "tag": "sales",
    "folderId": "{{input.folderId}}",
    "createdFrom": "2024-01-01",
    "createdTo": "2024-12-31",
    "orderBy": "date_created",
    "count": 50,
    "page": 1
  }
}

sendDocument

Send a document for signature.

{
  "id": "send-for-signature",
  "type": "action",
  "action": "pandadoc.sendDocument",
  "config": {
    "documentId": "{{steps.create-contract.output.id}}",
    "subject": "Please sign: {{input.documentName}}",
    "message": "Hi {{input.recipientName}},\n\nPlease review and sign the attached document at your earliest convenience.\n\nThank you!",
    "silent": false,
    "forwarding_allowed": true
  }
}

Parameters:

FieldTypeDescription
documentIdstringDocument UUID
subjectstringEmail subject
messagestringEmail message
silentbooleanSend without email (default: false)
forwarding_allowedbooleanAllow forwarding (default: true)

Create a sharing/signing link.

{
  "action": "pandadoc.createDocumentLink",
  "config": {
    "documentId": "{{input.documentId}}",
    "recipient": "{{input.recipientEmail}}",
    "lifetime": 3600
  }
}

Parameters:

FieldTypeDescription
documentIdstringDocument UUID
recipientstringRecipient email (for specific recipient link)
lifetimenumberLink lifetime in seconds (default: 3600)

Response:

{
  "id": "session-uuid",
  "expires_at": "2024-01-15T11:30:00Z",
  "link": "https://app.pandadoc.com/s/..."
}

downloadDocument

Get document download URL.

{
  "action": "pandadoc.downloadDocument",
  "config": {
    "documentId": "{{input.documentId}}",
    "watermark": false,
    "separateFiles": false
  }
}

deleteDocument

Delete a document.

{
  "action": "pandadoc.deleteDocument",
  "config": {
    "documentId": "{{input.documentId}}"
  }
}

updateDocumentStatus

Update document status (void, mark complete, etc.).

{
  "action": "pandadoc.updateDocumentStatus",
  "config": {
    "documentId": "{{input.documentId}}",
    "status": "document.voided",
    "note": "Voided per customer request",
    "notifySigner": true
  }
}

Valid Status Transitions:

FromTo
document.draftdocument.sent
document.sentdocument.voided
document.vieweddocument.voided
document.waiting_approvaldocument.approved, document.rejected

Folder Actions

listFolders

List folders.

{
  "action": "pandadoc.listFolders",
  "config": {
    "parentId": "{{input.parentFolderId}}",
    "count": 50,
    "page": 1
  }
}

createFolder

Create a new folder.

{
  "action": "pandadoc.createFolder",
  "config": {
    "name": "Q1 2024 Contracts",
    "parentId": "{{input.parentFolderId}}"
  }
}

renameFolder

Rename a folder.

{
  "action": "pandadoc.renameFolder",
  "config": {
    "folderId": "{{input.folderId}}",
    "name": "Q1 2024 Contracts - Archived"
  }
}

Contact Actions

listContacts

List contacts.

{
  "action": "pandadoc.listContacts",
  "config": {
    "email": "{{input.email}}"
  }
}

createContact

Create a new contact.

{
  "action": "pandadoc.createContact",
  "config": {
    "email": "{{input.email}}",
    "firstName": "{{input.firstName}}",
    "lastName": "{{input.lastName}}",
    "company": "{{input.companyName}}",
    "jobTitle": "{{input.title}}",
    "phone": "{{input.phone}}",
    "streetAddress": "{{input.address.street}}",
    "city": "{{input.address.city}}",
    "state": "{{input.address.state}}",
    "postalCode": "{{input.address.zip}}",
    "country": "{{input.address.country}}"
  }
}

updateContact

Update a contact.

{
  "action": "pandadoc.updateContact",
  "config": {
    "contactId": "{{input.contactId}}",
    "company": "{{input.newCompanyName}}",
    "jobTitle": "{{input.newTitle}}"
  }
}

deleteContact

Delete a contact.

{
  "action": "pandadoc.deleteContact",
  "config": {
    "contactId": "{{input.contactId}}"
  }
}

Webhook Triggers

PandaDoc webhooks trigger workflows on document events.

{
  "trigger": {
    "type": "webhook",
    "provider": "pandadoc",
    "events": ["document_state_changed", "recipient_completed"]
  }
}

Event Types:

EventDescription
document_state_changedDocument status changed
recipient_completedRecipient completed their actions
document_completedAll recipients completed
document_paidPayment received
document_viewedDocument was viewed
document_deletedDocument was deleted

Example Workflow

Complete contract workflow:

{
  "name": "Send Contract on Deal Close",
  "trigger": {
    "type": "webhook",
    "provider": "hubspot",
    "events": ["deal.propertyChange"]
  },
  "steps": [
    {
      "id": "check-stage",
      "type": "condition",
      "config": {
        "conditions": {
          "left": "{{input[0].propertyName}}",
          "operator": "eq",
          "right": "dealstage"
        },
        "then": ["check-closed"],
        "else": []
      }
    },
    {
      "id": "check-closed",
      "type": "condition",
      "config": {
        "conditions": {
          "left": "{{input[0].propertyValue}}",
          "operator": "eq",
          "right": "closedwon"
        },
        "then": ["get-deal"],
        "else": []
      }
    },
    {
      "id": "get-deal",
      "type": "action",
      "action": "hubspot.getDeal",
      "config": {
        "dealId": "{{input[0].objectId}}",
        "properties": ["dealname", "amount", "closedate"]
      }
    },
    {
      "id": "get-contact",
      "type": "action",
      "action": "hubspot.getAssociations",
      "config": {
        "objectType": "deals",
        "objectId": "{{input[0].objectId}}",
        "toObjectType": "contacts"
      }
    },
    {
      "id": "create-contract",
      "type": "action",
      "action": "pandadoc.createDocument",
      "config": {
        "templateId": "contract-template-uuid",
        "name": "Service Agreement - {{steps.get-deal.output.properties.dealname}}",
        "recipients": [
          {
            "email": "{{steps.get-contact.output.results[0].email}}",
            "role": "signer"
          }
        ],
        "tokens": [
          { "name": "Deal.Name", "value": "{{steps.get-deal.output.properties.dealname}}" },
          { "name": "Deal.Amount", "value": "{{steps.get-deal.output.properties.amount}}" }
        ]
      }
    },
    {
      "id": "wait-for-processing",
      "type": "wait",
      "config": {
        "duration": 5000
      }
    },
    {
      "id": "send-contract",
      "type": "action",
      "action": "pandadoc.sendDocument",
      "config": {
        "documentId": "{{steps.create-contract.output.id}}",
        "subject": "Service Agreement Ready for Signature",
        "message": "Please review and sign the attached service agreement."
      }
    },
    {
      "id": "notify-team",
      "type": "action",
      "action": "slack.sendMessage",
      "config": {
        "channel": "#sales",
        "text": "Contract sent for {{steps.get-deal.output.properties.dealname}}"
      }
    }
  ]
}

Rate Limits

LimitValue
API calls50/minute (standard)
API calls300/minute (enterprise)
Document creation100/hour
Bulk operations10 concurrent

Troubleshooting

Common Errors

ErrorCauseSolution
document_not_foundInvalid document IDVerify document exists
template_not_foundInvalid template IDVerify template ID
invalid_recipientsMissing required recipient dataCheck email format
rate_limit_exceededToo many requestsImplement backoff

Document Processing

Documents take time to process after creation:

  1. Create document (status: document.draft)
  2. Wait 3-5 seconds for processing
  3. Send document (status: document.sent)

Use a wait step between creation and sending.