Twenty CRM Integration

Generate PDFs from Twenty CRM records using DataToPDF. Twenty is an open-source CRM that supports both cloud and self-hosted deployments.

Prerequisites

  1. A DataToPDF account
  2. A Twenty CRM account (cloud or self-hosted)
  3. A Twenty API key with appropriate permissions

Setup

Step 1: Get Your Twenty API Key

  1. Log in to your Twenty CRM instance
  2. Go to Settings → API & Webhooks
  3. Click Create API Key
  4. Give it a name and select the appropriate permissions
  5. Copy the API key (it's only shown once!)

Note: Make sure "Advanced mode" is enabled in your app settings to see the API & Webhooks section.

Step 2: Connect Twenty CRM in DataToPDF

  1. Go to Settings in DataToPDF
  2. Click on Twenty CRM in the integrations list
  3. Enter your connection details:
FieldDescription
Instance URLhttps://api.twenty.com for cloud, or your self-hosted URL (e.g., https://twenty.yourcompany.com)
API KeyYour Twenty API key from Step 1
  1. Click Connect Twenty
  2. You'll see a green "Connected" status when successful

Self-Hosted Instances

If you're running a self-hosted Twenty instance, enter your instance URL instead of api.twenty.com. For example:

  • https://twenty.yourcompany.com
  • https://crm.example.com

The connection process is the same for both cloud and self-hosted deployments.


Creating Templates with Twenty Data

Step 1: Create a New Template

  1. Click New Template from the dashboard
  2. Enter a name and optional description
  3. Select Twenty as the data source
  4. Choose an object type (e.g., Person, Company, Opportunity)
  5. Click Continue to open the template designer

Step 2: Select Twenty Object

When creating a template with Twenty as the data source, you'll see a dropdown with all available objects from your Twenty instance, including:

Standard Objects:

  • People (contacts)
  • Companies (accounts)
  • Opportunities (deals)
  • Notes
  • Tasks
  • And more...

Custom Objects: Any custom objects you've created in Twenty will also appear in the list.

Step 3: Add Merge Fields

Once you select an object, the available fields will be loaded. You can insert merge fields using the {{FieldName}} syntax:

{{name}}
{{email}}
{{phone}}
{{company.name}}

Related Records

Access data from related records using dot notation:

{{company.name}}
{{company.address}}
{{assignedTo.name}}

Twenty supports various relationship types:

  • MANY_TO_ONE - Lookup to parent record (e.g., Person → Company)
  • ONE_TO_MANY - Child records (e.g., Company → People)

Supported Field Types

Twenty CRM supports various field types that are automatically handled:

Field TypeDescriptionExample
TEXTPlain textName, description
EMAILEmail addressesWork email, personal email
PHONEPhone numbersMobile, office
NUMBERNumeric valuesAmount, quantity
CURRENCYMoney valuesDeal value
DATEDate valuesCreated date, due date
DATE_TIMEDate and timeMeeting time
BOOLEANTrue/falseActive status
SELECTSingle selectionStatus, stage
MULTI_SELECTMultiple selectionsTags, categories
RELATIONRelated recordsCompany, assigned user
FULL_NAMEName with first/lastContact name
LINKURLsWebsite
ADDRESSFull addressCompany address

API Usage

Generate PDF via API

You can generate PDFs programmatically using the DataToPDF API with Twenty records.

Endpoint:

POST https://datatopdf.app/api/v1/pdf/generate

Request:

{
  "templateId": "your_template_id",
  "recordId": "twenty_record_uuid"
}

The recordId should be the Twenty record's UUID for the object type configured in your template.

Example - cURL

curl -X POST https://datatopdf.app/api/v1/pdf/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: pk_your_api_key_here" \
  -d '{
    "templateId": "clx1234567890",
    "recordId": "550e8400-e29b-41d4-a716-446655440000"
  }'

Example - JavaScript

const response = await fetch('https://datatopdf.app/api/v1/pdf/generate', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'pk_your_api_key_here'
  },
  body: JSON.stringify({
    templateId: 'clx1234567890',
    recordId: '550e8400-e29b-41d4-a716-446655440000'
  })
});

const { pdf } = await response.json();
const pdfBuffer = Buffer.from(pdf, 'base64');

Example - Python

import requests
import base64

response = requests.post(
    'https://datatopdf.app/api/v1/pdf/generate',
    headers={
        'Content-Type': 'application/json',
        'X-API-Key': 'pk_your_api_key_here'
    },
    json={
        'templateId': 'clx1234567890',
        'recordId': '550e8400-e29b-41d4-a716-446655440000'
    }
)

data = response.json()
pdf_bytes = base64.b64decode(data['pdf'])

with open('output.pdf', 'wb') as f:
    f.write(pdf_bytes)

Uploading PDFs to Twenty Records

After generating a PDF, you can automatically upload it as an attachment to the Twenty record. This creates an attachment record linked to your source record.

When using the template designer, enable the Upload to CRM option to automatically attach generated PDFs to the source record in Twenty.


Twenty Webhooks Integration

You can automate PDF generation using Twenty's webhook capabilities.

Setup Webhook in Twenty

  1. Go to Settings → API & Webhooks in Twenty
  2. Create a new webhook
  3. Configure the webhook URL to point to your automation endpoint
  4. Select the events to trigger (e.g., record created, record updated)

Example Webhook Handler (Node.js)

const express = require('express');
const app = express();

app.use(express.json());

app.post('/webhook/twenty', async (req, res) => {
  const { event, data } = req.body;

  // Check if this is an event we want to handle
  if (event === 'opportunity.won') {
    const recordId = data.id;
    const templateId = 'your_template_id';

    // Generate PDF
    const pdfResponse = await fetch('https://datatopdf.app/api/v1/pdf/generate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': process.env.DATATOPDF_API_KEY
      },
      body: JSON.stringify({ templateId, recordId })
    });

    const { pdf } = await pdfResponse.json();
    // Process the PDF (send via email, store, etc.)
  }

  res.status(200).json({ received: true });
});

app.listen(3000);

Use Cases

Use CaseTwenty ObjectDescription
ProposalsOpportunityGenerate proposal documents when deals reach a certain stage
ContractsOpportunityCreate contracts for won deals
Contact SheetsPersonGenerate contact information sheets
Company ProfilesCompanyCreate company overview documents
Meeting NotesNoteExport meeting notes as PDFs
Task ReportsTaskGenerate task summary reports

Response Format

Success (200)

{
  "pdf": "base64-encoded-pdf-data",
  "contentType": "application/pdf"
}

Error Response

{
  "error": "Human-readable error message",
  "code": "ERROR_CODE"
}

Error Codes

CodeDescription
UNAUTHORIZEDMissing API key
INVALID_API_KEYInvalid or revoked API key
RATE_LIMIT_EXCEEDEDToo many requests
SUBSCRIPTION_REQUIREDActive subscription required
TEMPLATE_NOT_FOUNDTemplate not found
CONNECTION_NOT_FOUNDTwenty connection not configured
DATA_FETCH_ERRORFailed to fetch Twenty data
GENERATION_FAILEDPDF generation failed

Troubleshooting

Connection Issues

"Twenty CRM not connected" error:

  • Verify your API key is correct and hasn't been revoked
  • Check that your instance URL is correct
  • For self-hosted instances, ensure your server is accessible

"Failed to fetch objects" error:

  • Verify your API key has the correct permissions
  • Check that "Advanced mode" is enabled in Twenty settings

Data Issues

Fields not appearing:

  • Some system fields may be hidden by default
  • Check field permissions in Twenty
  • Ensure the field is marked as active in Twenty

Related records not loading:

  • Verify the relationship exists in Twenty's schema
  • Check that the related records have data

Self-Hosted Specific

SSL/Certificate errors:

  • Ensure your instance has a valid SSL certificate
  • Check that the URL uses HTTPS

Connection timeout:

  • Verify your instance is accessible from the internet
  • Check firewall rules allow incoming connections

Best Practices

  1. Use descriptive template names - Include the Twenty object type in the name
  2. Test with sample records - Preview PDFs with real data before production use
  3. Handle missing data gracefully - Use conditional formatting for optional fields
  4. Keep API keys secure - Never expose keys in client-side code
  5. Monitor usage - Track API calls to stay within rate limits

Next Steps