
Open-source CRMs work when they connect to your existing tools. Twenty CRM delivers on that promise with four API types, real-time webhooks, and a developer ecosystem that treats custom integrations as first-class features — not afterthoughts.
This guide covers how Twenty’s integration architecture works, what you can build, and how to choose between REST, GraphQL, webhooks, and marketplace apps for your specific use case.
Twenty was built developer-first. That means integration capabilities weren’t added after launch — they’re foundational to how the platform works.
| Aspect | Traditional CRMs | Twenty CRM |
|---|---|---|
| API Generation | Manual, version-locked | Auto-generated from your data model |
| Custom Objects | Limited or enterprise-only | Same API treatment as built-in objects |
| Endpoint Structure | Long IDs, complex paths | Human-readable names you define |
You’re not adapting to a rigid API schema. The API adapts to your business model.
Both deployment models offer the same API capabilities with minor operational differences:
| Feature | Cloud | Self-Hosted |
|---|---|---|
| Base URL | https://api.twenty.com/ | https://your-domain/ |
| API Keys | Managed in cloud console | Managed in your instance |
| Rate Limits | Shared infrastructure | Configurable on your server |
| Webhook IPs | Fixed IP range | Your server’s IP |
Self-hosted instances give you full control over rate limits, logging, and firewall rules. Cloud instances handle scaling and uptime for you.
Twenty provides four distinct API surfaces. Each serves a specific purpose in your integration architecture.
The Core API manages your actual CRM records — the people, companies, opportunities, and custom objects you’ve created.
Access: /rest/ or /graphql/
What It Does:
Use Cases:
The Metadata API controls your workspace structure — the objects, fields, and relationships that define your data model.
Access: /rest/metadata/ or /metadata/
What It Does:
Use Cases:
Both Core and Metadata APIs are available in REST and GraphQL formats:
| API Type | REST Operations | GraphQL Advantages |
|---|---|---|
| Core | CRUD, batch, upserts | Batch upserts, nested queries |
| Metadata | Schema management | Relationship queries in one call |
You can mix and match. Use REST for straightforward operations, GraphQL when you need complex, nested data retrieval.
Twenty generates API documentation specific to your workspace. If you create a custom object called “Projects” with fields for budget, deadline, and status, the API documentation reflects that immediately.
Access the Playground:
The interactive playground lets you test queries against your actual data model with autocomplete based on your custom objects and fields.
Understanding when to use Core vs. Metadata APIs prevents common integration mistakes.
Endpoint Pattern: “ /rest/companies /rest/people /rest/opportunities /rest/your-custom-object “
Example: Create a Company (REST) “json POST /rest/companies { "name": "Acme Corp", "domain": "acme.com", "employees": 150 } “
Example: Query Companies (GraphQL) “graphql query { companies(filter: { employees: { gte: 100 } }) { edges { node { id name domain employees } } } } “
Endpoint Pattern: “ /rest/metadata/objects /rest/metadata/fields /metadata/objects “
Example: Create a Custom Object (REST) “json POST /rest/metadata/objects { "name": "projects", "labelSingular": "Project", "labelPlural": "Projects", "description": "Customer project tracking" } “
Example: Add a Field (GraphQL) “graphql mutation { createField( input: { objectId: "projects" name: "budget" type: CURRENCY label: "Project Budget" } ) { id name type } } “
| Scenario | Use Metadata API? |
|---|---|
| Creating records | No — use Core API |
| Adding a custom field | Yes |
| Querying existing data | No — use Core API |
| Building workspace templates | Yes |
| Migrating schema between environments | Yes |
| Daily operational tasks | No — use Core API |
Most integrations use Core API 90% of the time. Metadata API is for setup, configuration changes, and infrastructure automation.
Both formats access the same data. Your choice depends on operational needs, not feature availability.
Best for:
Example: Update a Person (REST) “json PATCH /rest/people/abc12345 { "phone": "+1-555-0199", "jobTitle": "VP of Sales" } “
Best for:
Example: Fetch Company with Related People (GraphQL) “graphql query { company(id: "xyz98765") { name domain people { edges { node { firstName lastName email jobTitle } } } } } “
This single GraphQL query replaces two REST calls (one for company, one for people).
| Operation | REST Calls | GraphQL Calls |
|---|---|---|
| Get company + people | 2 | 1 |
| Update 10 records | 10 | 1 (batch) |
| Get 3 fields from 1 record | 1 (returns all fields) | 1 (returns only requested fields) |
GraphQL reduces network overhead when fetching related data. REST is simpler for single-object operations.
Both formats support batch operations with a 60-record limit per request:
REST Batch Create: “json POST /rest/companies/batch { "records": [ {"name": "Company A", "domain": "companya.com"}, {"name": "Company B", "domain": "companyb.com"} ] } “
GraphQL Batch Create: “graphql mutation { CreateCompanies( input: [ { name: "Company A", domain: "companya.com" } { name: "Company B", domain: "companyb.com" } ] ) { id name } } “
GraphQL-only feature: Batch Upsert (create or update in one call using plural object names like CreateCompanies instead of CreateCompany).
Ready to build your integration? Book a free consultation to map out your Twenty CRM setup →
See How BoardBridge Handles This Workflow
Book a free demo to see BoardBridge solve this exact problem — live, with your data.
Webhooks push data to your systems when events occur in Twenty — no polling required. Use them to keep external tools synchronized, trigger automations, or send alerts.
When a record is created, updated, or deleted in Twenty, the platform sends an HTTP POST request to your specified URL with the event details.
Webhook Endpoint Setup:
The webhook activates immediately.
| Event Type | Example Events |
|---|---|
| Created | person.created, company.created, opportunity.created |
| Updated | person.updated, company.updated, note.updated |
| Deleted | person.deleted, company.deleted, opportunity.deleted |
All event types are sent to your webhook URL. (Event filtering may be added in future releases.)
Each webhook sends a JSON payload:
“json { "event": "person.created", "data": { "id": "abc12345", "firstName": "Alice", "lastName": "Doe", "email": "alice@example.com", "createdAt": "2025-02-10T15:30:45Z", "createdBy": "user_123" }, "timestamp": "2025-02-10T15:30:50Z" } “
| Field | Description |
|---|---|
| event | What happened (e.g., person.created) |
| data | Full record that was created/updated/deleted |
| timestamp | When the event occurred (UTC) |
Twenty signs each webhook request with HMAC SHA256. Validate signatures to ensure requests are authentic.
Headers:
X-Twenty-Webhook-Signature: HMAC SHA256 signatureX-Twenty-Webhook-Timestamp: Request timestampValidation Process (Node.js): “`javascript const crypto = require(“crypto”);
const timestamp = req.headers[“x-twenty-webhook-timestamp”]; const payload = JSON.stringify(req.body); const secret = “your-webhook-secret”;
const stringToSign = ${timestamp}:${payload}; const expectedSignature = crypto .createHmac(“sha256”, secret) .update(stringToSign) .digest(“hex”);
const isValid = expectedSignature === req.headers[“x-twenty-webhook-signature”]; “`
Always validate signatures before processing webhook data. This prevents replay attacks and unauthorized requests.
| Method | Direction | Use Case |
|---|---|---|
| Webhooks | OUT | Notify external systems of ANY record change |
| Workflow + HTTP | OUT | Send data with custom filters/transformations |
| Workflow Webhook Trigger | IN | Receive data into Twenty from external systems |
Webhooks are “fire and forget” — they notify your endpoint whenever something changes. Workflows let you add conditional logic before sending data out.
Every API request requires authentication via an API key passed in the request header.
Authorization Header: “ Authorization: Bearer YOUR_API_KEY “
Include this header in every API request.
For better security, assign specific roles to limit API key access:
The key inherits that role’s permissions. This allows you to:
| Action | How To |
|---|---|
| Regenerate | Settings → APIs & Webhooks → Click key → Regenerate |
| Delete | Settings → APIs & Webhooks → Click key → Delete |
| View Usage | Currently unavailable (planned feature) |
Best practices:
Twenty enforces rate limits to ensure platform stability. Design your integrations to work within these constraints.
| Limit Type | Value |
|---|---|
| Requests per minute | 100 calls |
| Batch size | 60 records per request |
| Concurrent requests | Not specified (use sequential for safety) |
These limits apply per API key. Self-hosted instances can adjust limits in configuration.
Single-record loops (inefficient): “ Create Company 1 → 1 API call Create Company 2 → 1 API call Create Company 3 → 1 API call Total: 3 calls “
Batch operation (efficient): “ Create Companies [1, 2, 3] → 1 API call Total: 1 call “
Always batch when creating, updating, or deleting multiple records.
When you exceed rate limits, Twenty returns: “json { "error": "Rate limit exceeded", "retryAfter": 32 } “
Response Strategy:
retryAfter (seconds)Example Implementation: “javascript async function callAPIWithRetry(endpoint, data) { try { return await fetch(endpoint, { method: 'POST', body: JSON.stringify(data) }); } catch (error) { if (error.status === 429) { const retryAfter = error.retryAfter || 60; await sleep(retryAfter * 1000); return callAPIWithRetry(endpoint, data); } throw error; } } “
| Technique | API Calls Saved |
|---|---|
| Batch operations | 10x-60x reduction |
| GraphQL for nested data | 50% fewer calls |
| Cache frequent reads | 30-70% reduction |
| Webhook-triggered updates (vs. polling) | 99% reduction |
Webhooks are the most efficient pattern. Instead of polling for changes every minute (1,440 API calls per day), you receive updates only when changes occur.
Twenty’s marketplace ecosystem is developer-driven. While the platform is relatively new compared to Salesforce or HubSpot, the open-source model accelerates extension development.
Twenty connects to external platforms through:
| Integration Type | Examples | Setup Method |
|---|---|---|
| Email Sync | Gmail, Outlook | OAuth connection in Settings |
| Calendar | Google Calendar, Outlook Calendar | OAuth connection |
| Zapier | 8,000+ apps | Zapier Twenty connector |
| n8n | Self-hosted automation | n8n Twenty node |
| Pipedream | Serverless workflows | Pipedream Twenty app |
Zapier provides the fastest path to connecting Twenty with mainstream business tools.
Available Triggers:
Available Actions:
Example Zap:
This takes 5 minutes to set up with no code.
n8n is an open-source automation platform ideal for self-hosted Twenty instances.
Why n8n + Twenty:
Example n8n Workflow:
n8n fills the gap for advanced automation logic until Twenty’s native workflow engine matures.
Twenty’s marketplace is open to community-built extensions. The platform uses a standard app framework:
App Structure:
Documentation for building marketplace apps is available at docs.twenty.com/developers.
Need Help With Your monday.com Setup?
TaskRhino has implemented monday.com for 110+ teams. Get a free consultation.
These patterns solve real business problems we’ve encountered at TaskRhino.
Business Need: Consolidate leads from website forms, LinkedIn ads, and partner referrals into Twenty.
Architecture:
Key Decision: Use Zapier for marketing tools (no code, easy to maintain). Use direct API integration for partner portal (tighter control, custom validation).
Business Need: Notify sales team in Slack when high-value opportunities are created or updated.
Architecture:
Why not Zapier? Webhooks don’t cost Zapier tasks. This pattern triggers 200+ times per month for active sales teams — using the API is more cost-effective.
Business Need: Keep customer data synchronized between Twenty (CRM) and QuickBooks (accounting).
Architecture:
Challenge: Avoiding infinite loops. Use a lastSyncedAt timestamp field in both systems. Only sync if the record was modified after the last sync timestamp.
Business Need: Build a public-facing dashboard showing real-time deal pipeline without exposing the CRM interface.
Architecture:
Query Example: “graphql query { opportunities(filter: { stage: { in: ["Qualified", "Proposal"] } }) { edges { node { name amount stage closeDate } } } } “
This pattern lets you share CRM insights with stakeholders without giving them Twenty access.
Client: Mid-sized physical therapy clinic with 12 locations
Problem: Patient intake forms were paper-based. Front desk staff manually entered data into their CRM, leading to errors and 20+ hours of admin work per week.
Solution:
Result:
Integration Cost: $0/month (Zapier Free plan, Twenty self-hosted, Twilio pay-as-you-go)
Need help automating your intake process? Let’s talk about your specific workflow →
Client: Early-stage SaaS company (project management tool)
Problem: Sales team had no visibility into which trial users were actively using the product. Outreach was random rather than data-driven.
Solution:
lastLoginDate, projectsCreated, teamSize, usageScoreusageScore > 75 for sales to prioritize outreachArchitecture:
Result:
Key Insight: Custom fields in Twenty allowed them to track product-specific metrics without needing a separate tool like Intercom.
Client: Habitat for Humanity affiliate covering 3 states
Problem: Volunteer coordination happened in spreadsheets. Regional managers couldn’t see availability, skills, or assignment history. Double-booking and no-shows were common.
Solution:
Result:
Integration Stack: Twenty API + custom Next.js portal + SendGrid for emails
Moving from another CRM to Twenty requires planning. Here’s what to consider.
| Current CRM | Export Format | Twenty Import Method |
|---|---|---|
| Salesforce | CSV via Data Loader | REST API batch import |
| HubSpot | CSV from export tool | GraphQL batch import |
| Pipedrive | CSV or JSON via API | REST API batch import |
| Spreadsheets | CSV or XLSX | REST API batch import (via script) |
Twenty doesn’t have a built-in import UI yet (as of 2026). You’ll need to write a script or use a tool like n8n to process your CSV and make batch API calls.
Before migrating data:
| Step | Action |
|---|---|
| 1. Audit Current Schema | List all objects, fields, and relationships in your current CRM |
| 2. Design Twenty Schema | Use Metadata API to create matching objects and fields |
| 3. Map Field Types | Text → Text, Number → Number, Picklist → Select, Date → Date |
| 4. Handle Relationships | One-to-many and many-to-many relationships need linking records |
Example Migration Script (Pseudocode): “`javascript // 1. Create Custom Object via Metadata API createObject({ name: “projects”, labelSingular: “Project” });
// 2. Create Custom Fields createField({ objectId: “projects”, name: “budget”, type: “CURRENCY” }); createField({ objectId: “projects”, name: “deadline”, type: “DATE” });
// 3. Import Data via Core API const projects = readCSV(“projects.csv”); const batches = chunkArray(projects, 60); // 60-record batches for (const batch of batches) { await createRecordsBatch(“projects”, batch); } “`
Don’t break existing integrations when migrating:
| Integration Type | Migration Strategy |
|---|---|
| Zapier/Make | Run both CRMs in parallel for 2 weeks; gradually switch Zaps |
| Custom APIs | Use feature flags to route traffic to new CRM |
| Webhooks | Set up new webhook endpoints; keep old ones active until verified |
| Email Sync | Re-authenticate email accounts in Twenty; archive old CRM |
Plan for a 2-4 week parallel run period where both systems are active. This gives you time to verify data accuracy and integration behavior before fully cutting over.
Stop Creating Duplicates
BoardBridge forms update existing items — no Enterprise plan, no workarounds, no duplicates.
Use GraphQL when dealing with complex, nested data structures or when you need to minimize payload size and reduce API calls—it’s ideal for sophisticated queries across related objects. REST is better for simpler, straightforward data synchronization tasks where you’re pulling or pushing flat data structures. Your choice depends on data complexity: if you’re syncing conference objects with nested attendee lists and custom fields, GraphQL’s query flexibility wins; if you’re doing basic lead imports, REST’s simplicity is sufficient.
Self-hosted instances give you direct control over rate limits, logging, and firewall rules, allowing you to optimize webhook delivery for your infrastructure, while cloud instances handle scaling and uptime automatically but with less granular control. The API capabilities are identical between both models, so the trade-off is operational control versus managed reliability—self-hosted requires more monitoring but offers customization for high-throughput webhook scenarios.
Marketplace integrations are pre-built, vendor-maintained connectors that work out-of-the-box but may not fit niche workflows, while custom API connectors require development effort but adapt to your specific business logic. Since Twenty’s open-source model means you’re not locked into vendor-controlled integrations, building custom connectors is viable if your legacy system isn’t in the marketplace—the API architecture is flexible enough to fill gaps that native connectors don’t cover.
The search results indicate that implementing error handling and retry logic is a critical step in the integration readiness checklist, though specific architectural patterns aren’t detailed. Based on webhook best practices, you should implement exponential backoff for failed webhook deliveries, store failed payloads for manual replay, and monitor webhook delivery rates to catch integration failures before they impact your data sync. TaskRhino consulting can help design fault-tolerant webhook architectures specific to your system dependencies.
Twenty lets you create custom objects from scratch—like a conference object with nested attendee relationships—without adapting your business logic to Salesforce’s predefined schemas. This flexibility means you define the data model around your business needs rather than forcing your workflows into Salesforce’s standard objects, reducing the need for workarounds and custom fields that bloat your metadata.
Salesforce typically requires outsourcing integration work to certified partners and professional services, adding significant cost and vendor lock-in, while Twenty’s open-source, developer-first model lets you build integrations in-house or with independent developers. For teams with technical resources, Twenty’s approach eliminates the “Salesforce Ecosystem Trusted Partners” markup and gives you ownership of your integration code, though it requires upfront engineering investment rather than outsourced implementation.
Editor's Choice

How to Calculate Hidden Costs of Salesforce Admin & Consulting

Asana vs monday.com vs Trello 2026: The Bicycle, The Sedan, and The SUV

Asana vs Monday vs Trello vs Basecamp: Complete 2026 Comparison Guide