Integrations
Connect your CRM, database, or spreadsheet to generate dynamic PDFs with real data. This guide covers all supported integrations and how to set them up.
Overview
Our platform supports four data source integrations:
| Integration | Description | Best For |
|---|---|---|
| Salesforce | Full CRM integration with OAuth | Sales teams, enterprise |
| HubSpot | CRM integration via API token | Marketing, sales teams |
| SQL Database | Direct database connection | Custom data, legacy systems |
| Google Sheets | Spreadsheet integration | Simple data, quick setup |
Salesforce Integration
Overview
Connect your Salesforce org to access all your CRM data for document generation. This includes:
- Standard and custom objects
- Related records and lookups
- Child relationships for tables
- File attachment capabilities
Prerequisites
Before connecting Salesforce, you need to create a Connected App in your Salesforce org. This requires Salesforce administrator privileges.
Creating a Salesforce Connected App
Follow these steps to create and configure a Connected App:
Step 1: Access App Manager
- Log in to Salesforce as an administrator
- Click the gear icon (βοΈ) in the top-right corner
- Select Setup
- In the Quick Find box, type App Manager
- Click App Manager under Apps
Step 2: Create a New Connected App
- Click New Connected App in the top-right corner
- Fill in the Basic Information:
- Connected App Name:
PDF Generator(or your preferred name) - API Name: This auto-fills based on the name
- Contact Email: Your email address
- Connected App Name:
Step 3: Configure OAuth Settings
-
Check Enable OAuth Settings
-
Set the Callback URL to:
https://datatopdf/api/salesforce/callback -
Select the following OAuth Scopes (move from Available to Selected):
Access and manage your data (api)Perform requests on your behalf at any time (refresh_token, offline_access)Access your basic information (id, profile, email, address, phone)Full access (full)- Optional but recommended for full functionality
-
Leave other settings as default:
- Require Secret for Web Server Flow: Checked (default)
- Require Secret for Refresh Token Flow: Checked (default)
-
Click Save
Step 4: Wait for Activation
After saving, Salesforce displays a message that changes can take up to 10 minutes to take effect. In practice, it's usually ready within 2-5 minutes.
Step 5: Retrieve Your Credentials
- After saving, click Continue to view the Connected App details
- Click Manage Consumer Details (you may need to verify your identity)
- Copy and save these values:
- Consumer Key (this is your Client ID)
- Consumer Secret (this is your Client Secret)
Step 6: Configure OAuth Policies (Recommended)
After creating your Connected App, configure the OAuth policies for easier connectivity:
- From the Connected App page, click Manage
- Click Edit Policies
- Configure the following settings under OAuth Policies:

Key settings to configure:
| Setting | Recommended Value | Description |
|---|---|---|
| Permitted Users | All users can self-authorize | Allows any user in your org to connect |
| IP Relaxation | Relax IP restrictions | Avoids IP whitelisting issues |
| Refresh Token Policy | Refresh token is valid until revoked | Keeps the connection active long-term |
- Enable the following Flows :

- Click Save
Connecting Salesforce
Once your Connected App is created, you can connect it to the PDF Generator:
Step 1: Enter Credentials
- Go to Settings β Salesforce
- Enter your Client ID (Consumer Key)
- Enter your Client Secret (Consumer Secret)
- Click Save Credentials
Step 2: Authorize Access
- Click Connect Salesforce
- You'll be redirected to Salesforce login
- Enter your Salesforce credentials
- Review the permission request
- Click Allow to authorize
Step 3: Verify Connection
- You'll be redirected back to the app
- The status should show "Connected"
- Your Salesforce instance URL will be displayed
What Gets Connected
| Feature | Description |
|---|---|
| Objects | Access all standard and custom objects you have permission for |
| Fields | All fields on accessible objects |
| Relationships | Lookup and master-detail relationships |
| Child Objects | Related lists (Contacts on Account, Line Items on Opportunity) |
| Records | Query and select records for PDF generation |
Selecting an Object
When creating a template:
- Choose Salesforce as your data source
- Select the object type (Account, Contact, Opportunity, etc.)
- Available fields for that object are loaded automatically
Standard Objects
Common Salesforce objects available:
- Account
- Contact
- Opportunity
- Lead
- Case
- Quote
- Order
- Custom Objects (ending in
__c)
Field Access
Fields available depend on your Salesforce permissions:
- Standard fields (Name, Email, Phone, etc.)
- Custom fields (My_Field__c)
- Formula fields
- Lookup fields
Parent Relationships
Access related record data:
{{Account.Name}} β Parent account name
{{Owner.Name}} β Record owner
{{CreatedBy.Name}} β User who created record
{{Account.Owner.Name}} β Account owner's name
Child Relationships
For tables, access related records:
{{OpportunityLineItems.Name}} β Line item names
{{Contacts.Email}} β Related contact emails
{{Cases.Subject}} β Related case subjects
Uploading PDFs to Salesforce
Generated PDFs can be uploaded directly to Salesforce:
- Generate your PDF
- Click Upload to Salesforce
- Select the record to attach to
- The PDF is saved as a File attachment
Disconnecting Salesforce
- Go to Settings β Integrations
- Find Salesforce
- Click Disconnect
- Confirm the disconnection
Note: Templates using Salesforce data will no longer work until reconnected.
Troubleshooting Salesforce
"Missing credentials" Error
- Ensure you've saved your Client ID and Client Secret before clicking Connect
- Verify the credentials are for the correct Salesforce org (Production vs Sandbox)
"Invalid client credentials" Error
- Double-check your Consumer Key and Consumer Secret
- Ensure the Connected App has been activated (wait 2-10 minutes after creation)
- Verify you're using Production credentials for Production orgs, and Sandbox credentials for Sandbox orgs
"Redirect URI mismatch" Error
- The Callback URL in your Connected App must exactly match your application URL
- Check for trailing slashes -
https://app.com/callbackis different fromhttps://app.com/callback/ - For local development, ensure you're using
http://localhost:3000/api/salesforce/callback
"Access denied" or Authorization Failed
- Your Salesforce admin may have restricted OAuth access
- Check if your profile has "API Enabled" permission
- Verify the Connected App is assigned to your profile or permission set
Connection Failed
- Verify Salesforce credentials
- Check if your org allows OAuth
- Contact your Salesforce admin if access is restricted
Missing Objects/Fields
- Check your Salesforce profile permissions
- Verify field-level security settings
- Ensure objects are visible in your profile
Session Expired
- Reconnect your Salesforce account
- Token refresh is automatic, but may occasionally fail
"IP not whitelisted" Error
- Set IP Relaxation to "Relax IP restrictions" in Connected App policies
- Or add your server's IP address to the trusted IP ranges
HubSpot Integration
Overview
Connect HubSpot to access contacts, companies, deals, and more for document generation.
Prerequisites
Before connecting HubSpot, you need to create a Private App in your HubSpot account. This requires HubSpot Super Admin privileges.
Creating a HubSpot Private App
Follow these step-by-step instructions to create and configure a Private App:
Step 1: Access Private Apps Settings
- Log in to your HubSpot account as a Super Admin
- Click the Settings icon (βοΈ) in the main navigation bar
- In the left sidebar, navigate to Integrations β Private Apps
- Click Create a private app
Step 2: Configure Basic Information
- Enter a Name for your app (e.g.,
PDF Generator) - Optionally, add a Description (e.g., "Generates PDF documents from CRM data")
- Upload a Logo (optional)
Step 3: Configure Scopes
Click the Scopes tab and enable the following permissions:
CRM Scopes (under "CRM"):
| Scope | Permission Level | Purpose |
|---|---|---|
crm.objects.contacts.read | Read | Access contact records |
crm.objects.companies.read | Read | Access company records |
crm.objects.deals.read | Read | Access deal records |
crm.objects.line_items.read | Read | Access deal line items |
crm.objects.quotes.read | Read | Access quote records (optional) |
crm.objects.owners.read | Read | Access owner information |
crm.schemas.contacts.read | Read | Access contact properties |
crm.schemas.companies.read | Read | Access company properties |
crm.schemas.deals.read | Read | Access deal properties |
Files Scope (under "Files"):
| Scope | Permission Level | Purpose |
|---|---|---|
files | Read/Write | Upload generated PDFs as attachments |
Tip: To find scopes quickly, use the search box at the top of the scopes list.
Step 4: Create the App
- Review your configuration in the Overview tab
- Click Create app in the top-right corner
- A dialog will appear with important information about your access token
Step 5: Copy Your Access Token
- In the dialog that appears, you'll see your Access Token
- Click Copy to copy the token to your clipboard
- Save this token securely - you won't be able to see it again!
β οΈ Important:
- The access token is shown only once. If you lose it, you'll need to create a new one.
- Keep your access token confidential. Never share it publicly or commit it to version control.
- Treat this token like a password.
Step 6: Rotate Token (If Needed)
If you need to generate a new token:
- Go to Settings β Integrations β Private Apps
- Click on your Private App name
- Go to the Auth tab
- Click Rotate token
- Copy and save the new token
- Update your application with the new token
Connecting HubSpot
Once your Private App is created, connect it to the PDF Generator:
Step 1: Navigate to Settings
- Go to Settings β HubSpot
- You'll see a form to enter your access token
Step 2: Enter Your Access Token
- Paste your Private App Access Token in the input field
- Click Connect or Save
- The system will validate your token
Step 3: Verify Connection
- If successful, the status will show "Connected"
- You can now use HubSpot data in your templates
Required Scopes Summary
Your HubSpot private app needs these scopes at minimum:
crm.objects.contacts.readcrm.objects.companies.readcrm.objects.deals.readcrm.objects.line_items.read(for deal products)files(for file uploads)
Using HubSpot Data
Available Objects
- Contacts: Individual people
- Companies: Organizations
- Deals: Sales opportunities
- Tickets: Support tickets
- Products: Product catalog
- Line Items: Deal line items
HubSpot Properties
Access standard and custom properties:
{{firstname}}
{{lastname}}
{{email}}
{{company}}
{{dealname}}
{{amount}}
Associations
Access related records for tables:
{{contacts.firstname}} β Associated contacts
{{line_items.name}} β Deal line items
{{companies.name}} β Associated companies
Uploading to HubSpot
Generated PDFs can be attached to HubSpot records:
- Generate your PDF
- Click Upload to HubSpot
- Select the record type and record
- The PDF is saved as an engagement/attachment
Troubleshooting HubSpot
"Invalid Token" or "Unauthorized" Error
- Verify you copied the complete access token (they are long strings)
- Regenerate your private app token if it may have been compromised
- Check that the token hasn't been rotated or the app deleted
- Ensure you're using the access token, not the app ID
"Insufficient Scopes" Error
- Go to your Private App settings and verify all required scopes are enabled
- After adding scopes, you may need to rotate the token
- The most common missing scope is
filesfor PDF uploads
"Private App Not Found"
- Ensure you're logged into the correct HubSpot portal
- Verify the Private App hasn't been deleted
- Check if another admin may have modified the app
Missing Properties/Fields
- Ensure properties exist in your HubSpot portal
- Use internal property names, not display labels (e.g.,
firstnamenot "First Name") - Check that your private app has read access for the relevant object schemas
- Custom properties require
crm.schemas.[object].readscope
Cannot Upload Files
- Verify the
filesscope is enabled on your Private App - The scope needs both Read and Write permissions
- Check that your HubSpot subscription includes file uploads
Rate Limiting Errors
- HubSpot has API rate limits based on your subscription tier
- Reduce the frequency of requests or implement request queuing
- Consider upgrading your HubSpot subscription for higher limits
Token Expired
- HubSpot Private App tokens do not expire automatically
- If you're seeing expiration errors, the token may have been manually rotated
- Create a new token or check with your HubSpot admin
SQL Database Integration
Overview
Connect directly to your SQL database for custom data sources. Perfect for:
- Legacy systems
- Custom applications
- Data warehouses
- Any SQL-compatible database
Supported Databases
| Database | Support Level |
|---|---|
| PostgreSQL | Full support |
| MySQL | Full support |
| SQL Server | Full support |
| SQLite | Full support |
Connecting a Database
Step 1: Navigate to Integrations
- Go to Settings β Integrations
- Find SQL Database
- Click Configure
Step 2: Enter Connection Details
| Field | Description | Example |
|---|---|---|
| Database Type | Select your database type | PostgreSQL |
| Host | Database server hostname | db.example.com |
| Port | Database port | 5432 |
| Database Name | Name of the database | myapp_production |
| Username | Database username | readonly_user |
| Password | Database password | β’β’β’β’β’β’β’β’β’ |
| SSL | Enable SSL connection | Yes/No |
Step 3: Test Connection
- Click Test Connection
- Verify the connection succeeds
- If failed, check credentials and network access
Step 4: Save Configuration
- Click Save
- The connection is stored securely
- Password is encrypted
Security Best Practices
- Use a read-only user: Create a dedicated database user with SELECT-only permissions
- Limit table access: Grant access only to tables needed for templates
- Enable SSL: Use encrypted connections when possible
- Use strong passwords: Generate complex passwords for database users
- Network security: Consider IP whitelisting if supported
Using SQL Data
Selecting Tables
When creating a template:
- Choose SQL Database as your data source
- Select the table to use
- Available columns are loaded automatically
Field Mapping
Column names become merge fields:
{{customer_name}}
{{email_address}}
{{order_total}}
{{created_at}}
Record Selection
Records are identified by:
- Primary key (usually
id) - Lookup by column value
Limitations
- No joins: Each table is accessed independently
- Simple tables: Limited support for complex relationships
- Performance: Large tables may have slower field loading
Troubleshooting SQL
Connection Failed
- Verify database credentials
- Check if host allows external connections
- Verify firewall rules and network access
- Ensure database is running
Tables Not Showing
- Check user has SELECT permission on tables
- Verify schema access (for PostgreSQL)
- Ensure tables exist in specified database
Google Sheets Integration
Overview
Connect Google Sheets for simple, spreadsheet-based data sources. Great for:
- Quick data setup
- Non-technical users
- Small datasets
- Marketing campaigns
Connecting Google Sheets
Option 1: OAuth Connection
- Go to Settings β Integrations
- Find Google Sheets
- Click Connect with Google
- Log in to your Google account
- Authorize access to Google Sheets
Option 2: API Key
- Go to Settings β Integrations
- Find Google Sheets
- Enter your Google API key
- Click Save
Using Google Sheets
Setting Up Your Spreadsheet
- Create or open a Google Sheet
- Use the first row for column headers
- Each subsequent row is a record
- Column headers become field names
Example Spreadsheet:
| Name | Company | Amount | |
|---|---|---|---|
| John Doe | [email protected] | Acme Inc | 1000 |
| Jane Smith | [email protected] | Tech Co | 2500 |
Connecting a Spreadsheet
- Copy the spreadsheet URL or ID
- In template creation, paste the spreadsheet ID
- Select the sheet (tab) to use
- Fields are loaded from column headers
Field Names
Column headers become merge fields:
{{Name}}
{{Email}}
{{Company}}
{{Amount}}
Tip: Keep column headers simpleβno spaces, special characters, or very long names.
Selecting Records
Records can be selected by:
- Row number: Specify which row (2 = first data row)
- Lookup value: Find row by column value (e.g., Email = "[email protected]")
Best Practices for Google Sheets
- Consistent formatting: Keep data types consistent within columns
- No empty rows: Remove blank rows in your data
- Clear headers: Use descriptive, simple column names
- Share appropriately: Ensure the sheet is accessible to your connected account
- Lock headers: Prevent accidental header changes
Limitations
- Simple structure: One sheet = one table
- No relationships: Cannot link between sheets
- Performance: Large sheets may be slower
- Real-time sync: Data is fetched at generation time
Troubleshooting Google Sheets
Sheet Not Found
- Verify the spreadsheet ID is correct
- Check the sheet is shared with your Google account
- Ensure the sheet hasn't been deleted
Fields Not Loading
- Verify header row is present
- Check for merged cells in headers
- Ensure headers are in row 1
Managing Integrations
Checking Connection Status
- Go to Settings β Integrations
- Each integration shows its status:
- β Connected
- β Not connected
- β οΈ Error (reconnection needed)
Refreshing Connections
For OAuth integrations (Salesforce, HubSpot, Google):
- Tokens refresh automatically
- If issues occur, disconnect and reconnect
Multiple Integrations
You can connect multiple data sources:
- Each template uses one data source
- Different templates can use different sources
- Team members share connection access
Integration Security
| Aspect | How We Handle It |
|---|---|
| OAuth tokens | Encrypted storage, automatic refresh |
| API keys | Encrypted at rest |
| Database passwords | Encrypted with strong encryption |
| Network | HTTPS for all communications |
Comparing Data Sources
| Feature | Salesforce | HubSpot | SQL | Google Sheets |
|---|---|---|---|---|
| Setup complexity | Medium | Easy | Medium | Easy |
| Relationships | Excellent | Good | Limited | None |
| Custom fields | Yes | Yes | Yes | Yes |
| File upload | Yes | Yes | No | No |
| Real-time data | Yes | Yes | Yes | Yes |
| Best for | Enterprise | SMB | Custom | Simple |
Next Steps
- Merge Fields - Use data in templates
- Tables - Display related records
- Templates - Create documents
- API Reference - Programmatic access
